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 0f708433a..447ee4c25 100644 --- a/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java +++ b/api/src/main/java/net/kyori/adventure/text/ComponentCompaction.java @@ -33,8 +33,6 @@ import org.jetbrains.annotations.Nullable; final class ComponentCompaction { - private static final TextDecoration[] DECORATIONS = TextDecoration.values(); - private ComponentCompaction() { } @@ -42,7 +40,7 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa final List children = self.children(); Component optimized = self.children(Collections.emptyList()); if (parentStyle != null) { - optimized = optimized.style(simplifyStyle(self.style(), parentStyle)); + optimized = optimized.style(self.style().asChildOf(parentStyle)); } final int childrenSize = children.size(); @@ -153,49 +151,6 @@ static Component compact(final @NotNull Component self, final @Nullable Style pa return optimized.children(childrenToAppend); } - /** - * Simplify the provided style to remove any information that is redundant. - * - * @param style style to simplify - * @param parentStyle parent to compare against - * @return a new, simplified style - */ - private static @NotNull Style simplifyStyle(final @NotNull Style style, final @NotNull Style parentStyle) { - if (style.isEmpty()) { - // the target style is empty, so there is nothing to simplify - return style; - } - - final Style.Builder builder = style.toBuilder(); - if (Objects.equals(style.font(), parentStyle.font())) { - builder.font(null); - } - - if (Objects.equals(style.color(), parentStyle.color())) { - builder.color(null); - } - - for (final TextDecoration decoration : DECORATIONS) { - if (style.decoration(decoration) == parentStyle.decoration(decoration)) { - builder.decoration(decoration, TextDecoration.State.NOT_SET); - } - } - - if (Objects.equals(style.clickEvent(), parentStyle.clickEvent())) { - builder.clickEvent(null); - } - - if (Objects.equals(style.hoverEvent(), parentStyle.hoverEvent())) { - builder.hoverEvent(null); - } - - if (Objects.equals(style.insertion(), parentStyle.insertion())) { - builder.insertion(null); - } - - return builder.build(); - } - /** * Checks whether the Component is blank (a TextComponent containing only space characters). * diff --git a/api/src/main/java/net/kyori/adventure/text/format/Style.java b/api/src/main/java/net/kyori/adventure/text/format/Style.java index 55015acc4..cd331d38f 100644 --- a/api/src/main/java/net/kyori/adventure/text/format/Style.java +++ b/api/src/main/java/net/kyori/adventure/text/format/Style.java @@ -529,6 +529,15 @@ default boolean hasDecoration(final @NotNull TextDecoration decoration) { */ @NotNull Style merge(final @NotNull Style that, final Merge.@NotNull Strategy strategy, final @NotNull Set merges); + /** + * Simplify this style to remove any information that is redundant. + * + * @param that parent to compare against + * @return a new, simplified style + * @since 4.12.0 + */ + @NotNull Style asChildOf(final @NotNull Style that); + /** * Tests if this style is empty. * diff --git a/api/src/main/java/net/kyori/adventure/text/format/StyleImpl.java b/api/src/main/java/net/kyori/adventure/text/format/StyleImpl.java index b0d945a50..7dd92c01e 100644 --- a/api/src/main/java/net/kyori/adventure/text/format/StyleImpl.java +++ b/api/src/main/java/net/kyori/adventure/text/format/StyleImpl.java @@ -183,6 +183,45 @@ final class StyleImpl implements Style { return builder.build(); } + @Override + public @NotNull Style asChildOf(final @NotNull Style that) { + if (this.isEmpty()) { + // the target style is empty, so there is nothing to simplify + return this; + } + + final Style.Builder builder = new BuilderImpl(this); + + if (Objects.equals(this.font(), that.font())) { + builder.font(null); + } + + if (Objects.equals(this.color(), that.color())) { + builder.color(null); + } + + for (int i = 0, length = DecorationMap.DECORATIONS.length; i < length; i++) { + final TextDecoration decoration = DecorationMap.DECORATIONS[i]; + if (this.decoration(decoration) == that.decoration(decoration)) { + builder.decoration(decoration, TextDecoration.State.NOT_SET); + } + } + + if (Objects.equals(this.clickEvent(), that.clickEvent())) { + builder.clickEvent(null); + } + + if (Objects.equals(this.hoverEvent(), that.hoverEvent())) { + builder.hoverEvent(null); + } + + if (Objects.equals(this.insertion(), that.insertion())) { + builder.insertion(null); + } + + return builder.build(); + } + @SuppressWarnings("RedundantIfStatement") static boolean nothingToMerge(final @NotNull Style mergeFrom, final Merge.@NotNull Strategy strategy, final @NotNull Set merges) { if (strategy == Merge.Strategy.NEVER) return true; diff --git a/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java b/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java index 8df6d2b5e..9d2057fc8 100644 --- a/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java +++ b/api/src/test/java/net/kyori/adventure/text/format/StyleTest.java @@ -370,6 +370,32 @@ void testBuilderMerge_color() { ); } + @Test + void testAsChildOfEmpty() { + final Style s0 = Style.empty(); + final Style s1 = Style.style(NamedTextColor.DARK_RED, TextDecoration.BOLD, TextDecoration.ITALIC); + final Style s2 = s1.asChildOf(s0); + assertEquals(NamedTextColor.DARK_RED, s2.color()); + assertDecorations(s2, ImmutableSet.of(TextDecoration.BOLD, TextDecoration.ITALIC), ImmutableSet.of()); + } + + @Test + void testAsChildOf() { + final Style s0 = Style.style(NamedTextColor.DARK_RED, TextDecoration.BOLD); + final Style s1 = Style.style(NamedTextColor.DARK_RED, TextDecoration.BOLD, TextDecoration.ITALIC); + final Style s2 = s1.asChildOf(s0); + assertNull(s2.color()); + assertDecorations(s2, ImmutableSet.of(TextDecoration.ITALIC), ImmutableSet.of()); + } + + @Test + void testAsChildOfWithEmptyChild() { + final Style s0 = Style.style(NamedTextColor.DARK_RED, TextDecoration.BOLD); + final Style s1 = Style.empty(); + final Style s2 = s1.asChildOf(s0); + assertSame(s1, s2); + } + @Test void testEquals() { new EqualsTester()