From 4a073fb84f5b32900e8dd11260977ad07afbbc7f Mon Sep 17 00:00:00 2001 From: zml Date: Sun, 6 Nov 2022 22:07:45 -0800 Subject: [PATCH] fix(text-minimessage): Preserve non-text components in color changing tags Fixes GH-827 --- .../tag/standard/AbstractColorChangingTag.java | 11 ++++++++++- .../minimessage/tag/standard/GradientTagTest.java | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java index c761b9dd1..f797a9cd3 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java @@ -55,6 +55,11 @@ */ abstract class AbstractColorChangingTag implements Modifying, Examinable { + private static final ComponentFlattener LENGTH_CALCULATOR = ComponentFlattener.builder() + .mapper(TextComponent.class, TextComponent::content) + .unknownMapper(x -> "_") // every unknown component gets a single colour + .build(); + private boolean visited; private int size = 0; private int disableApplyingColorDepth = -1; @@ -76,7 +81,7 @@ public final void visit(final @NotNull Node current, final int depth) { final TagNode tag = (TagNode) current; if (tag.tag() instanceof Inserting) { // ComponentTransformation.apply() returns the value of the component placeholder - ComponentFlattener.textOnly().flatten(((Inserting) tag.tag()).value(), s -> this.size += s.codePointCount(0, s.length())); + LENGTH_CALCULATOR.flatten(((Inserting) tag.tag()).value(), s -> this.size += s.codePointCount(0, s.length())); } } } @@ -124,6 +129,10 @@ public final Component apply(final @NotNull Component current, final int depth) } return parent.build(); + } else if (!(current instanceof TextComponent)) { + final Component ret = current.children(Collections.emptyList()).colorIfAbsent(this.color()); + this.advanceColor(); + return ret; } return Component.empty().mergeStyle(current); diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java index 36fed421a..0931e113f 100644 --- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java @@ -32,6 +32,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.event.HoverEvent.showText; import static net.kyori.adventure.text.format.NamedTextColor.BLACK; import static net.kyori.adventure.text.format.NamedTextColor.BLUE; @@ -542,4 +543,18 @@ void testDecorationsPreserved() { this.assertParsedEquals(expected, input, Placeholder.component("placeholder", placeholder)); } + + // https://github.com/KyoriPowered/adventure/issues/827 + @Test + void testLangTagInGradient() { + final String input = "ab!"; + final Component expected = Component.textOfChildren( + text("a", RED), + text("b", color(0xd55580)), + translatable("block.minecraft.diamond_block", color(0xaa55aa)) + .append(text("!", color(0x8055d5))) + ); + + this.assertParsedEquals(expected, input); + } }