Skip to content

Commit

Permalink
feature(api): Replace text ignoring hover events
Browse files Browse the repository at this point in the history
  • Loading branch information
kezz committed Jan 7, 2025
1 parent 685e642 commit 67a59c8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import net.kyori.adventure.builder.AbstractBuilder;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.util.Buildable;
import net.kyori.adventure.util.IntFunction2;
import net.kyori.examination.Examinable;
Expand Down Expand Up @@ -220,6 +221,18 @@ default Builder matchLiteral(final String literal) {
*/
@Contract("_ -> this")
@NotNull Builder replacement(final @NotNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement);

/**
* Set if the replacement should replace inside {@link HoverEvent hover events}.
*
* <p>This defaults to {@code true}.</p>
*
* @param replace if it should replace inside hover events
* @return this builder
* @since 4.19.0
*/
@Contract("_ -> this")
@NotNull Builder replaceInsideHoverEvents(final boolean replace);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ final class TextReplacementConfigImpl implements TextReplacementConfig {
private final Pattern matchPattern;
private final BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
private final Condition continuer;
private final boolean replaceInsideHoverEvents;

TextReplacementConfigImpl(final Builder builder) {
this.matchPattern = builder.matchPattern;
this.replacement = builder.replacement;
this.continuer = builder.continuer;
this.replaceInsideHoverEvents = builder.replaceInsideHoverEvents;
}

@Override
Expand All @@ -51,7 +53,7 @@ final class TextReplacementConfigImpl implements TextReplacementConfig {
}

TextReplacementRenderer.State createState() {
return new TextReplacementRenderer.State(this.matchPattern, this.replacement, this.continuer);
return new TextReplacementRenderer.State(this.matchPattern, this.replacement, this.continuer, this.replaceInsideHoverEvents);
}

@Override
Expand All @@ -77,6 +79,7 @@ static final class Builder implements TextReplacementConfig.Builder {
@Nullable Pattern matchPattern;
@Nullable BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
TextReplacementConfig.Condition continuer = (matchResult, index, replacement) -> PatternReplacementResult.REPLACE;
boolean replaceInsideHoverEvents = true;

Builder() {
}
Expand Down Expand Up @@ -105,6 +108,12 @@ static final class Builder implements TextReplacementConfig.Builder {
return this;
}

@Override
public TextReplacementConfig.@NotNull Builder replaceInsideHoverEvents(final boolean replace) {
this.replaceInsideHoverEvents = replace;
return this;
}

@Override
public @NotNull TextReplacementConfig build() {
if (this.matchPattern == null) throw new IllegalStateException("A pattern must be provided to match against");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,13 @@ private TextReplacementRenderer() {
// Only visit children if we're running
if (state.running) {
// hover event
final HoverEvent<?> event = oldStyle.hoverEvent();
if (event != null) {
final HoverEvent<?> rendered = event.withRenderedValue(this, state);
if (event != rendered) {
modified = modified.style(s -> s.hoverEvent(rendered));
if (state.replaceInsideHoverEvents) {
final HoverEvent<?> event = oldStyle.hoverEvent();
if (event != null) {
final HoverEvent<?> rendered = event.withRenderedValue(this, state);
if (event != rendered) {
modified = modified.style(s -> s.hoverEvent(rendered));
}
}
}
// Children
Expand Down Expand Up @@ -200,15 +202,17 @@ static final class State {
final Pattern pattern;
final BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
final TextReplacementConfig.Condition continuer;
final boolean replaceInsideHoverEvents;
boolean running = true;
int matchCount = 0;
int replaceCount = 0;
boolean firstMatch = true;

State(final @NotNull Pattern pattern, final @NotNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement, final TextReplacementConfig.@NotNull Condition continuer) {
State(final @NotNull Pattern pattern, final @NotNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement, final TextReplacementConfig.@NotNull Condition continuer, final boolean replaceInsideHoverEvents) {
this.pattern = pattern;
this.replacement = replacement;
this.continuer = continuer;
this.replaceInsideHoverEvents = replaceInsideHoverEvents;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,16 @@ void testReplacementHoverWithOriginalHoverAlsoMatching() {

TextAssertions.assertEquals(expected, replaced);
}

@Test
void testIgnoringHover() {
final Component original = Component.text("one")
.hoverEvent(Component.text("meow"));

final Component replaced = original.replaceText(c -> c.match("meow")
.replacement(Component.text("woof"))
.replaceInsideHoverEvents(false));

TextAssertions.assertEquals(original, replaced);
}
}

0 comments on commit 67a59c8

Please sign in to comment.