Skip to content

Commit

Permalink
api: Style#asChildOf
Browse files Browse the repository at this point in the history
  • Loading branch information
kashike committed Jul 4, 2022
1 parent 40ed1df commit fbbd63f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 46 deletions.
Expand Up @@ -33,16 +33,14 @@
import org.jetbrains.annotations.Nullable;

final class ComponentCompaction {
private static final TextDecoration[] DECORATIONS = TextDecoration.values();

private ComponentCompaction() {
}

static Component compact(final @NotNull Component self, final @Nullable Style parentStyle) {
final List<Component> 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();
Expand Down Expand Up @@ -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).
*
Expand Down
9 changes: 9 additions & 0 deletions api/src/main/java/net/kyori/adventure/text/format/Style.java
Expand Up @@ -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<Merge> 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.
*
Expand Down
39 changes: 39 additions & 0 deletions api/src/main/java/net/kyori/adventure/text/format/StyleImpl.java
Expand Up @@ -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<Merge> merges) {
if (strategy == Merge.Strategy.NEVER) return true;
Expand Down
26 changes: 26 additions & 0 deletions api/src/test/java/net/kyori/adventure/text/format/StyleTest.java
Expand Up @@ -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()
Expand Down

0 comments on commit fbbd63f

Please sign in to comment.