diff options
author | Jonas Zipprick <jonas.zipprick@gmail.com> | 2017-12-29 11:36:05 +0100 |
---|---|---|
committer | Aleksi Hietanen <aleksi@vaadin.com> | 2017-12-29 12:36:05 +0200 |
commit | 0663acc47174bf86c02cdb7291e1c0d7b98551ed (patch) | |
tree | 2c3076f2a1b2d376575555b7eb2a8aee7a5ce893 /server | |
parent | 1619d1f0bbd41de3f175b9eb2f34b468ec7e0367 (diff) | |
download | vaadin-framework-0663acc47174bf86c02cdb7291e1c0d7b98551ed.tar.gz vaadin-framework-0663acc47174bf86c02cdb7291e1c0d7b98551ed.zip |
Add ContentMode for the description of MenuItems (#9984)
Adds the ability to set the content mode for the description of a menu item that is part of a menu bar.
This functionality was already available for every AbstractComponent but missing for the menu items of menu bars.
If no content mode is specified it defaults to the PREFORMATED content mode.
Diffstat (limited to 'server')
-rw-r--r-- | server/src/main/java/com/vaadin/ui/MenuBar.java | 69 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java | 25 |
2 files changed, 89 insertions, 5 deletions
diff --git a/server/src/main/java/com/vaadin/ui/MenuBar.java b/server/src/main/java/com/vaadin/ui/MenuBar.java index 544b93ea6a..72a3671d4e 100644 --- a/server/src/main/java/com/vaadin/ui/MenuBar.java +++ b/server/src/main/java/com/vaadin/ui/MenuBar.java @@ -31,6 +31,7 @@ import org.jsoup.parser.Tag; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; +import com.vaadin.shared.ui.ContentMode; import com.vaadin.shared.ui.menubar.MenuBarConstants; import com.vaadin.shared.ui.menubar.MenuBarState; import com.vaadin.ui.Component.Focusable; @@ -142,6 +143,14 @@ public class MenuBar extends AbstractComponent target.addAttribute(MenuBarConstants.ATTRIBUTE_ITEM_DESCRIPTION, description); } + + ContentMode contentMode = item.getContentMode(); + // If the contentMode is equal to ContentMode.PREFORMATTED, we don't add any attribute. + if (contentMode != null && contentMode != ContentMode.PREFORMATTED) { + target.addAttribute(MenuBarConstants.ATTRIBUTE_ITEM_CONTENT_MODE, + contentMode.name()); + } + if (item.isCheckable()) { // if the "checked" attribute is present (either true or false), // the item is checkable @@ -457,6 +466,7 @@ public class MenuBar extends AbstractComponent private boolean isSeparator = false; private String styleName; private String description; + private ContentMode contentMode = ContentMode.PREFORMATTED; private boolean checkable = false; private boolean checked = false; @@ -782,20 +792,46 @@ public class MenuBar extends AbstractComponent } /** - * Sets the items's description. See {@link #getDescription()} for more + * Analogous method to {@link AbstractComponent#setDescription(String)}. + * Sets the item's description. See {@link #getDescription()} for more * information on what the description is. * * @param description * the new description string for the component. */ public void setDescription(String description) { + setDescription(description, ContentMode.PREFORMATTED); + } + + /** + * Analogous method to + * {@link AbstractComponent#setDescription(String, ContentMode)}. Sets + * the item's description using given content mode. See + * {@link #getDescription()} for more information on what the + * description is. + * <p> + * If the content {@code mode} is {@literal ContentMode.HTML} the + * description is displayed as HTML in tooltips or directly in certain + * components so care should be taken to avoid creating the possibility + * for HTML injection and possibly XSS vulnerabilities. + * + * @see ContentMode + * + * @param description + * the new description string for the component. + * @param mode + * the content mode for the description + * @since + */ + public void setDescription(String description, ContentMode mode) { this.description = description; + this.contentMode = mode; markAsDirty(); } /** * <p> - * Gets the items's description. The description can be used to briefly + * Gets the item's description. The description can be used to briefly * describe the state of the item to the user. The description string * may contain certain XML tags: * </p> @@ -854,6 +890,23 @@ public class MenuBar extends AbstractComponent } /** + * Gets the content mode of the description of the menu item. The + * description is displayed as the tooltip of the menu item in the UI. + * <p> + * If no content mode was explicitly set using the + * {@link #setDescription(String, ContentMode)} method, the content mode + * will be {@link ContentMode#PREFORMATTED} + * </p> + * + * @return the {@link ContentMode} of the description of this menu item + * @see ContentMode + * @since + */ + public ContentMode getContentMode() { + return contentMode; + } + + /** * Gets the checkable state of the item - whether the item has checked * and unchecked states. If an item is checkable its checked state (as * returned by {@link #isChecked()}) is indicated in the UI. @@ -982,6 +1035,9 @@ public class MenuBar extends AbstractComponent DesignAttributeHandler.writeAttribute("description", attr, item.getDescription(), def.getDescription(), String.class, context); + DesignAttributeHandler.writeAttribute("contentmode", attr, + item.getContentMode().name(), def.getContentMode().name(), String.class, + context); DesignAttributeHandler.writeAttribute("style-name", attr, item.getStyleName(), def.getStyleName(), String.class, context); @@ -1041,8 +1097,13 @@ public class MenuBar extends AbstractComponent attr, boolean.class)); } if (menuElement.hasAttr("description")) { - menu.setDescription(DesignAttributeHandler - .readAttribute("description", attr, String.class)); + String description = DesignAttributeHandler.readAttribute("description", attr, String.class); + if (menuElement.hasAttr("contentmode")) { + String contentModeString = DesignAttributeHandler.readAttribute("contentmode", attr, String.class); + menu.setDescription(description, ContentMode.valueOf(contentModeString)); + } else { + menu.setDescription(description); + } } if (menuElement.hasAttr("style-name")) { menu.setStyleName(DesignAttributeHandler.readAttribute("style-name", diff --git a/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java index 5a67d2bcce..68f1fad864 100644 --- a/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java +++ b/server/src/test/java/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java @@ -28,6 +28,7 @@ import com.vaadin.server.ThemeResource; import com.vaadin.tests.design.DeclarativeTestBase; import com.vaadin.ui.MenuBar; import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.shared.ui.ContentMode; /** * Tests declarative support for menu bars. @@ -69,6 +70,27 @@ public class MenuBarDeclarativeTest extends DeclarativeTestBase<MenuBar> { } @Test + public void testDescriptionContentMode() { + String design = "<vaadin-menu-bar plain-text>" + + "<menu description=\"This description is implicitly preformatted\">One</menu>" + + "<menu description=\"This description\nis explicitly\n\npreformatted\">preformatted</menu>" + + "<menu contentmode=\"HTML\" description=\"<b>I</b> contain <br/> <e>html</e>\">HTML</menu>" + + "<menu contentmode=\"TEXT\" description=\"Just plain text\">plain text</menu>" + + "</vaadin-menu-bar>"; + MenuBar menuBar = new MenuBar(); + menuBar.addItem("One", null).setDescription("This description is implicitly preformatted"); + menuBar.addItem("preformatted", null) + .setDescription("This description\nis explicitly\n\npreformatted", ContentMode.PREFORMATTED); + menuBar.addItem("HTML", null) + .setDescription("<b>I</b> contain <br/> <e>html</e>", ContentMode.HTML); + menuBar.addItem("plain text", null) + .setDescription("Just plain text", ContentMode.TEXT); + + testWrite(design, menuBar); + testRead(design, menuBar); + } + + @Test // #16328 public void testTicketSpec1() throws IOException { String design = "<vaadin-menu-bar auto-open plain-text tabindex=5> " @@ -165,12 +187,13 @@ public class MenuBarDeclarativeTest extends DeclarativeTestBase<MenuBar> { actual.isSeparator()); assertEquals(baseError + "Enabled", expected.isEnabled(), actual.isEnabled()); - assertEquals(baseError + "Text", expected.getText(), actual.getText()); assertEquals(baseError + "Description", expected.getDescription(), actual.getDescription()); assertEquals(baseError + "Style Name", expected.getStyleName(), actual.getStyleName()); + assertEquals(baseError + "Content Mode", expected.getContentMode(), + actual.getContentMode()); if (expected.getIcon() != null) { assertNotNull(baseError + "Icon was null", actual.getIcon()); |