From 8cdca8b6323956de699d79f1218c47b2be7e2175 Mon Sep 17 00:00:00 2001 From: zml Date: Mon, 13 Mar 2023 22:23:12 -0700 Subject: [PATCH] fix(api): Handle virtual components in compaction --- .../adventure/text/ComponentCompaction.java | 16 ++++++++++------ .../adventure/text/ComponentCompactingTest.java | 9 +++++++++ .../text/flattener/ComponentFlattenerTest.java | 10 +++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java b/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java index a0300af28..7382f5ff3 100644 --- a/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java +++ b/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java @@ -60,7 +60,7 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa } // if there is only one child, check if self a useless empty component - if (childrenSize == 1 && optimized instanceof TextComponent) { + if (childrenSize == 1 && isText(optimized)) { final TextComponent textComponent = (TextComponent) optimized; if (textComponent.content().isEmpty()) { @@ -87,7 +87,7 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa child = compact(child, childParentStyle); // ignore useless empty children (regardless of its style) - if (child.children().isEmpty() && child instanceof TextComponent) { + if (child.children().isEmpty() && isText(child)) { final TextComponent textComponent = (TextComponent) child; if (textComponent.content().isEmpty()) { @@ -99,12 +99,12 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa } // try to merge children into this parent component - if (optimized instanceof TextComponent) { + if (isText(optimized)) { while (!childrenToAppend.isEmpty()) { final Component child = childrenToAppend.get(0); final Style childStyle = child.style().merge(childParentStyle, Style.Merge.Strategy.IF_ABSENT_ON_TARGET); - if (child instanceof TextComponent && Objects.equals(childStyle, childParentStyle)) { + if (isText(child) && Objects.equals(childStyle, childParentStyle)) { // merge child components into the parent if they are a text component with the same effective style // in context of their parent style optimized = joinText((TextComponent) optimized, (TextComponent) child); @@ -125,7 +125,7 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa final Component child = childrenToAppend.get(i); final Component neighbor = childrenToAppend.get(i + 1); - if (child.children().isEmpty() && child instanceof TextComponent && neighbor instanceof TextComponent) { + if (child.children().isEmpty() && isText(child) && isText(neighbor)) { // calculate the children's styles in context of their parent style final Style childStyle = child.style().merge(childParentStyle, Style.Merge.Strategy.IF_ABSENT_ON_TARGET); final Style neighborStyle = neighbor.style().merge(childParentStyle, Style.Merge.Strategy.IF_ABSENT_ON_TARGET); @@ -162,7 +162,7 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa * @return true if the provided component is blank, false otherwise */ private static boolean isBlank(final Component component) { - if (component instanceof TextComponent) { + if (isText(component)) { final TextComponent textComponent = (TextComponent) component; final String content = textComponent.content(); @@ -215,4 +215,8 @@ private static boolean isBlank(final Component component) { private static TextComponent joinText(final TextComponent one, final TextComponent two) { return TextComponentImpl.create(two.children(), one.style(), one.content() + two.content()); } + + private static boolean isText(final Component component) { + return component instanceof TextComponent && !(component instanceof VirtualComponent); + } } diff --git a/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java b/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java index 2cd8be6a4..a5eb07e88 100644 --- a/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java +++ b/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java @@ -38,6 +38,7 @@ import static net.kyori.adventure.text.Component.empty; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; +import static net.kyori.adventure.text.Component.virtual; import static net.kyori.adventure.text.JoinConfiguration.noSeparators; import static net.kyori.adventure.text.format.Style.style; import static net.kyori.adventure.text.format.TextColor.color; @@ -417,4 +418,12 @@ void testColorPreservedWithDecorations() { assertEquals(expectedComponent, expectedComponent.compact()); } + @Test + void testVirtualComponentsPreserved() { + final Component expectedComponent = virtual(() -> "meow :3") + .append(text("3")); + + assertEquals(expectedComponent, expectedComponent.compact()); + } + } diff --git a/api/src/test/java/net/kyori/adventure/text/flattener/ComponentFlattenerTest.java b/api/src/test/java/net/kyori/adventure/text/flattener/ComponentFlattenerTest.java index 79300b918..8c6be6988 100644 --- a/api/src/test/java/net/kyori/adventure/text/flattener/ComponentFlattenerTest.java +++ b/api/src/test/java/net/kyori/adventure/text/flattener/ComponentFlattenerTest.java @@ -31,6 +31,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.NBTComponent; import net.kyori.adventure.text.TranslatableComponent; +import net.kyori.adventure.text.VirtualComponentHolder; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; @@ -43,7 +44,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; class ComponentFlattenerTest { - static class TrackingFlattener implements FlattenerListener { int pushCount; int popCount; @@ -192,6 +192,14 @@ void testKeybind() { .assertContents(); } + @Test + void testVirtualComponent() { + this.testFlatten(ComponentFlattener.basic(), Component.virtual((VirtualComponentHolder) () -> "test123")) + .assertBalanced() + .assertPushesAndPops(1) + .assertContents("test123"); + } + @Test void testCustomHandler() { final ComponentFlattener customized = ComponentFlattener.basic()