diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java b/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java index 7e4aca0af..09517aa31 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java @@ -61,10 +61,26 @@ public class ComponentBuilder * @return this ComponentBuilder for chaining */ public ComponentBuilder append(String text) + { + return append( text, FormatRetention.ALL ); + } + + /** + * Appends the text to the builder and makes it the current target for + * formatting. You can specify the amount of formatting retained. + * + * @param text the text to append + * @param retention the formatting to retain + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder append(String text, FormatRetention retention) { parts.add( current ); + current = new TextComponent( current ); current.setText( text ); + retain( retention ); + return this; } @@ -164,6 +180,47 @@ public class ComponentBuilder return this; } + /** + * Sets the current part back to normal settings. Only text is kept. + * + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder reset() + { + return retain( FormatRetention.NONE ); + } + + /** + * Retains only the specified formatting. Text is not modified. + * + * @param retention the formatting to retain + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder retain(FormatRetention retention) + { + BaseComponent previous = current; + + switch ( retention ) + { + case NONE: + current = new TextComponent( current.getText() ); + break; + case ALL: + // No changes are required + break; + case EVENTS: + current = new TextComponent( current.getText() ); + current.setClickEvent( previous.getClickEvent() ); + current.setHoverEvent( previous.getHoverEvent() ); + break; + case FORMATTING: + current.setClickEvent( null ); + current.setHoverEvent( null ); + break; + } + return this; + } + /** * Returns the components needed to display the message created by this * builder. @@ -175,4 +232,25 @@ public class ComponentBuilder parts.add( current ); return parts.toArray( new BaseComponent[ parts.size() ] ); } + + public static enum FormatRetention + { + + /** + * Specify that we do not want to retain anything from the previous component. + */ + NONE, + /** + * Specify that we want the formatting retained from the previous component. + */ + FORMATTING, + /** + * Specify that we want the events retained from the previous component. + */ + EVENTS, + /** + * Specify that we want to retain everything from the previous component. + */ + ALL + } } diff --git a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java index 118972e85..b5ea88338 100644 --- a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java +++ b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java @@ -4,6 +4,7 @@ import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TranslatableComponent; import org.junit.Assert; @@ -80,6 +81,48 @@ public class ComponentsTest + "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) ); } + @Test + public void testBuilderReset() + { + BaseComponent[] components = new ComponentBuilder( "Hello " ).color(ChatColor.RED) + .append("World").reset().create(); + + Assert.assertEquals( components[0].getColor(), ChatColor.RED ); + Assert.assertEquals( components[1].getColor(), ChatColor.WHITE ); + } + + @Test + public void testBuilderFormatRetention() + { + BaseComponent[] noneRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) + .append( "World", ComponentBuilder.FormatRetention.NONE ).create(); + + Assert.assertEquals( noneRetention[0].getColor(), ChatColor.RED ); + Assert.assertEquals( noneRetention[1].getColor(), ChatColor.WHITE ); + + HoverEvent testEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "test" ).create() ); + + BaseComponent[] formattingRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) + .event( testEvent ).append( "World", ComponentBuilder.FormatRetention.FORMATTING ).create(); + + Assert.assertEquals( formattingRetention[0].getColor(), ChatColor.RED ); + Assert.assertEquals( formattingRetention[0].getHoverEvent(), testEvent ); + Assert.assertEquals( formattingRetention[1].getColor(), ChatColor.RED ); + Assert.assertNull( formattingRetention[1].getHoverEvent() ); + + ClickEvent testClickEvent = new ClickEvent( ClickEvent.Action.OPEN_URL, "http://www.example.com" ); + + BaseComponent[] eventRetention = new ComponentBuilder( "Hello " ).color( ChatColor.RED ) + .event( testEvent ).event(testClickEvent).append("World", ComponentBuilder.FormatRetention.EVENTS).create(); + + Assert.assertEquals( eventRetention[0].getColor(), ChatColor.RED ); + Assert.assertEquals( eventRetention[0].getHoverEvent(), testEvent ); + Assert.assertEquals( eventRetention[0].getClickEvent(), testClickEvent ); + Assert.assertEquals( eventRetention[1].getColor(), ChatColor.WHITE ); + Assert.assertEquals( eventRetention[1].getHoverEvent(), testEvent ); + Assert.assertEquals( eventRetention[1].getClickEvent(), testClickEvent ); + } + @Test(expected = IllegalArgumentException.class) public void testLoopSimple() {