]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fixed connector so it no longer overwrites all style attributes (#8664)
authorPekka Hyvönen <pekka@vaadin.com>
Thu, 28 Jun 2012 13:42:33 +0000 (16:42 +0300)
committerArtur Signell <artur@vaadin.com>
Thu, 28 Jun 2012 13:49:55 +0000 (16:49 +0300)
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractFieldConnector.java
src/com/vaadin/terminal/gwt/client/ui/datefield/AbstractDateFieldConnector.java
src/com/vaadin/terminal/gwt/client/ui/datefield/PopupDateFieldConnector.java
src/com/vaadin/terminal/gwt/client/ui/embedded/EmbeddedConnector.java
src/com/vaadin/terminal/gwt/client/ui/embedded/VEmbedded.java
tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.java [new file with mode: 0644]

index 2f55cc4d16a8a7a23bca3c5d1f81da0118725e64..6105c545f60b9fd842a9f62191d0c8dc2525f22a 100644 (file)
@@ -3,6 +3,8 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 import com.google.gwt.dom.client.Element;
@@ -22,6 +24,7 @@ import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VConsole;
 import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
+import com.vaadin.terminal.gwt.client.ui.datefield.PopupDateFieldConnector;
 import com.vaadin.terminal.gwt.client.ui.root.RootConnector;
 
 public abstract class AbstractComponentConnector extends AbstractConnector
@@ -32,6 +35,12 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     private String lastKnownWidth = "";
     private String lastKnownHeight = "";
 
+    /**
+     * The style names from getState().getStyles() which are currently applied
+     * to the widget.
+     */
+    protected List<String> styleNames = new ArrayList<String>();
+
     /**
      * Default constructor
      */
@@ -41,7 +50,11 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     @Override
     protected void init() {
         super.init();
+
         getConnection().getVTooltip().connectHandlersToWidget(getWidget());
+
+        // Set v-connector style names for the widget
+        getWidget().setStyleName("v-connector", true);
     }
 
     /**
@@ -103,8 +116,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         super.onStateChanged(stateChangeEvent);
 
         // Style names
-        String styleName = getStyleNames(getWidget().getStylePrimaryName());
-        getWidget().setStyleName(styleName);
+        updateWidgetStyleNames();
 
         // Set captions
         if (delegateCaptionHandling()) {
@@ -127,12 +139,14 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     }
 
     public void setWidgetEnabled(boolean widgetEnabled) {
+        // add or remove v-disabled style name from the widget
+        setWidgetStyleName(ApplicationConnection.DISABLED_CLASSNAME,
+                !widgetEnabled);
+
         if (getWidget() instanceof HasEnabled) {
             // set widget specific enabled state
             ((HasEnabled) getWidget()).setEnabled(widgetEnabled);
-            // add or remove v-disabled style name from the widget
-            getWidget().setStyleName(ApplicationConnection.DISABLED_CLASSNAME,
-                    !widgetEnabled);
+
             // make sure the caption has or has not v-disabled style
             if (delegateCaptionHandling()) {
                 ServerConnector parent = getParent();
@@ -210,58 +224,112 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     }
 
     /**
-     * Generates the style name for the widget based on the given primary style
-     * name and the shared state.
+     * Updates the user defined, read-only and error style names for the widget
+     * based the shared state. User defined style names are prefixed with the
+     * primary style name of the widget returned by {@link #getWidget()}
      * <p>
      * This method can be overridden to provide additional style names for the
-     * component
+     * component, for example see
+     * {@link AbstractFieldConnector#updateWidgetStyleNames()}
      * </p>
-     * 
-     * @param primaryStyleName
-     *            The primary style name to use when generating the final style
-     *            names
-     * @return The style names, settable using
-     *         {@link Widget#setStyleName(String)}
      */
-    protected String getStyleNames(String primaryStyleName) {
+    protected void updateWidgetStyleNames() {
         ComponentState state = getState();
 
-        StringBuilder styleBuf = new StringBuilder();
-        styleBuf.append(primaryStyleName);
-        styleBuf.append(" v-connector");
+        String primaryStyleName = getWidget().getStylePrimaryName();
 
-        // Uses connector methods to enable connectors to take hierarchy or
-        // multiple state variables into account
-        if (!isEnabled()) {
-            styleBuf.append(" ");
-            styleBuf.append(ApplicationConnection.DISABLED_CLASSNAME);
-        }
-        if (isReadOnly()) {
-            styleBuf.append(" ");
-            styleBuf.append("v-readonly");
-        }
+        // should be in AbstractFieldConnector ?
+        // add / remove read-only style name
+        setWidgetStyleName("v-readonly", isReadOnly());
+
+        // add / remove error style name
+        setWidgetStyleNameWithPrefix(primaryStyleName,
+                ApplicationConnection.ERROR_CLASSNAME_EXT,
+                null != state.getErrorMessage());
 
-        // add additional styles as css classes, prefixed with component default
-        // stylename
+        // add additional user defined style names as class names, prefixed with
+        // component default class name. remove nonexistent style names.
         if (state.hasStyles()) {
-            for (String style : state.getStyles()) {
-                styleBuf.append(" ");
-                styleBuf.append(primaryStyleName);
-                styleBuf.append("-");
-                styleBuf.append(style);
-                styleBuf.append(" ");
-                styleBuf.append(style);
+            // add new style names
+            List<String> newStyles = new ArrayList<String>();
+            newStyles.addAll(state.getStyles());
+            newStyles.removeAll(styleNames);
+            for (String newStyle : newStyles) {
+                setWidgetStyleName(newStyle, true);
+                setWidgetStyleNameWithPrefix(primaryStyleName + "-", newStyle,
+                        true);
+            }
+            // remove nonexistent style names
+            styleNames.removeAll(state.getStyles());
+            for (String oldStyle : styleNames) {
+                setWidgetStyleName(oldStyle, false);
+                setWidgetStyleNameWithPrefix(primaryStyleName + "-", oldStyle,
+                        false);
+            }
+            styleNames.clear();
+            styleNames.addAll(state.getStyles());
+        } else {
+            // remove all old style names
+            for (String oldStyle : styleNames) {
+                setWidgetStyleName(oldStyle, false);
+                setWidgetStyleNameWithPrefix(primaryStyleName + "-", oldStyle,
+                        false);
             }
+            styleNames.clear();
         }
 
-        // add error classname to components w/ error
-        if (null != state.getErrorMessage()) {
-            styleBuf.append(" ");
-            styleBuf.append(primaryStyleName);
-            styleBuf.append(ApplicationConnection.ERROR_CLASSNAME_EXT);
-        }
+    }
 
-        return styleBuf.toString();
+    /**
+     * This is used to add / remove state related style names from the widget.
+     * <p>
+     * Override this method for example if the style name given here should be
+     * updated in another widget in addition to the one returned by the
+     * {@link #getWidget()}.
+     * </p>
+     * 
+     * @param styleName
+     *            the style name to be added or removed
+     * @param add
+     *            <code>true</code> to add the given style, <code>false</code>
+     *            to remove it
+     */
+    protected void setWidgetStyleName(String styleName, boolean add) {
+        getWidget().setStyleName(styleName, add);
+    }
+
+    /**
+     * This is used to add / remove state related prefixed style names from the
+     * widget.
+     * <p>
+     * Override this method if the prefixed style name given here should be
+     * updated in another widget in addition to the one returned by the
+     * <code>Connector</code>'s {@link #getWidget()}, or if the prefix should be
+     * different. For example see
+     * {@link PopupDateFieldConnector#setWidgetStyleNameWithPrefix(String, String, boolean)}
+     * </p>
+     * 
+     * @param styleName
+     *            the style name to be added or removed
+     * @param add
+     *            <code>true</code> to add the given style, <code>false</code>
+     *            to remove it
+     * @deprecated This will be removed once styles are no longer added with
+     *             prefixes.
+     */
+    @Deprecated
+    protected void setWidgetStyleNameWithPrefix(String prefix,
+            String styleName, boolean add) {
+        if (!styleName.startsWith("-")) {
+            if (!prefix.endsWith("-")) {
+                prefix += "-";
+            }
+        } else {
+            if (prefix.endsWith("-")) {
+                styleName.replaceFirst("-", "");
+            }
+        }
+        getWidget().setStyleName(prefix + styleName, add);
     }
 
     /*
index 4be0f02c2ae99945ecdec8f20691d22a38f3abed..5bff88c774e6449341a559f21973879912c86d0b 100644 (file)
@@ -35,20 +35,15 @@ public abstract class AbstractFieldConnector extends AbstractComponentConnector
     }
 
     @Override
-    protected String getStyleNames(String primaryStyleName) {
-        String styleNames = super.getStyleNames(primaryStyleName);
+    protected void updateWidgetStyleNames() {
+        super.updateWidgetStyleNames();
 
-        if (isModified()) {
-            // add modified classname to Fields
-            styleNames += " " + ApplicationConnection.MODIFIED_CLASSNAME;
-        }
+        // add / remove modified style name to Fields
+        setWidgetStyleName(ApplicationConnection.MODIFIED_CLASSNAME,
+                isModified());
 
-        if (isRequired()) {
-            // add required classname to Fields
-            styleNames += " " + primaryStyleName
-                    + ApplicationConnection.REQUIRED_CLASSNAME_EXT;
-        }
-
-        return styleNames;
+        // add / remove error style name to Fields
+        setWidgetStyleNameWithPrefix(getWidget().getStylePrimaryName(),
+                ApplicationConnection.REQUIRED_CLASSNAME_EXT, isRequired());
     }
 }
index b55f480bac4ad5f5c63320d26bc8c077383316fd..72555214fa70491127144a45ca94049d5dc11e4f 100644 (file)
@@ -63,15 +63,17 @@ public class AbstractDateFieldConnector extends AbstractFieldConnector
             newResolution = VDateField.RESOLUTION_YEAR;
         }
 
+        // Remove old stylename that indicates current resolution
+        setWidgetStyleNameWithPrefix(VDateField.CLASSNAME,
+                VDateField.resolutionToString(getWidget().currentResolution),
+                false);
+
         getWidget().currentResolution = newResolution;
 
         // Add stylename that indicates current resolution
-        getWidget()
-                .addStyleName(
-                        VDateField.CLASSNAME
-                                + "-"
-                                + VDateField
-                                        .resolutionToString(getWidget().currentResolution));
+        setWidgetStyleNameWithPrefix(VDateField.CLASSNAME,
+                VDateField.resolutionToString(getWidget().currentResolution),
+                true);
 
         final int year = uidl.getIntVariable("year");
         final int month = (getWidget().currentResolution >= VDateField.RESOLUTION_MONTH) ? uidl
index e169d83b486705aeb8e57bdc72a5d2b478d1b208..dfe0b327ac46c4bf3307f578dcfe209cb56232eb 100644 (file)
@@ -35,14 +35,6 @@ public class PopupDateFieldConnector extends TextualDateConnector {
 
         super.updateFromUIDL(uidl, client);
 
-        String popupStyleNames = getStyleNames(VPopupCalendar.POPUP_PRIMARY_STYLE_NAME);
-        popupStyleNames += " "
-                + VDateField.CLASSNAME
-                + "-"
-                + VPopupCalendar
-                        .resolutionToString(getWidget().currentResolution);
-        getWidget().popup.setStyleName(popupStyleNames);
-
         getWidget().calendar.setDateTimeService(getWidget()
                 .getDateTimeService());
         getWidget().calendar.setShowISOWeekNumbers(getWidget()
@@ -114,4 +106,30 @@ public class PopupDateFieldConnector extends TextualDateConnector {
     public VPopupCalendar getWidget() {
         return (VPopupCalendar) super.getWidget();
     }
+
+    @Override
+    protected void setWidgetStyleName(String styleName, boolean add) {
+        super.setWidgetStyleName(styleName, add);
+
+        // update the style change to popup calendar widget
+        getWidget().popup.setStyleName(styleName, add);
+    }
+
+    @Override
+    protected void setWidgetStyleNameWithPrefix(String prefix,
+            String styleName, boolean add) {
+        super.setWidgetStyleNameWithPrefix(prefix, styleName, add);
+
+        // update the style change to popup calendar widget with the correct
+        // prefix
+        if (!styleName.startsWith("-")) {
+            getWidget().popup.setStyleName(
+                    VPopupCalendar.POPUP_PRIMARY_STYLE_NAME + "-" + styleName,
+                    add);
+        } else {
+            getWidget().popup.setStyleName(
+                    VPopupCalendar.POPUP_PRIMARY_STYLE_NAME + styleName, add);
+        }
+    }
+
 }
index af3ad67db4d130d0482e03add03c885ca8acdf1f..fe3549e7f2ef2f80c43a6669a1958a2da0ffebc1 100644 (file)
@@ -54,6 +54,16 @@ public class EmbeddedConnector extends AbstractComponentConnector implements
         clickEventHandler.handleEventHandlerRegistration();
 
         if (uidl.hasAttribute("type")) {
+            // remove old style name related to type
+            if (getWidget().type != null) {
+                getWidget().removeStyleName(
+                        VEmbedded.CLASSNAME + "-" + getWidget().type);
+            }
+            // remove old style name related to mime type
+            if (getWidget().mimetype != null) {
+                getWidget().removeStyleName(
+                        VEmbedded.CLASSNAME + "-" + getWidget().mimetype);
+            }
             getWidget().type = uidl.getStringAttribute("type");
             if (getWidget().type.equals("image")) {
                 getWidget().addStyleName(VEmbedded.CLASSNAME + "-image");
@@ -118,13 +128,25 @@ public class EmbeddedConnector extends AbstractComponentConnector implements
                 VConsole.log("Unknown Embedded type '" + getWidget().type + "'");
             }
         } else if (uidl.hasAttribute("mimetype")) {
+            // remove old style name related to type
+            if (getWidget().type != null) {
+                getWidget().removeStyleName(
+                        VEmbedded.CLASSNAME + "-" + getWidget().type);
+            }
+            // remove old style name related to mime type
+            if (getWidget().mimetype != null) {
+                getWidget().removeStyleName(
+                        VEmbedded.CLASSNAME + "-" + getWidget().mimetype);
+            }
             final String mime = uidl.getStringAttribute("mimetype");
             if (mime.equals("application/x-shockwave-flash")) {
+                getWidget().mimetype = "flash";
                 // Handle embedding of Flash
                 getWidget().addStyleName(VEmbedded.CLASSNAME + "-flash");
                 getWidget().setHTML(getWidget().createFlashEmbed(uidl));
 
             } else if (mime.equals("image/svg+xml")) {
+                getWidget().mimetype = "svg";
                 getWidget().addStyleName(VEmbedded.CLASSNAME + "-svg");
                 String data;
                 Map<String, String> parameters = VEmbedded.getParameters(uidl);
index 5edd31174d50d8b926ad951bbcf200527708b738..1d2a5a156ab2288005a92eba5b2371896325f7f7 100644 (file)
@@ -26,6 +26,7 @@ public class VEmbedded extends HTML {
     protected Element browserElement;
 
     protected String type;
+    protected String mimetype;
 
     protected ApplicationConnection client;
 
diff --git a/tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.html b/tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.html
new file mode 100644 (file)
index 0000000..a09a1e0
--- /dev/null
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">\r
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
+<link rel="selenium.base" href="http://localhost:8888/" />\r
+<title>AddRemoveSetStyleNamesTest</title>\r
+</head>\r
+<body>\r
+<table cellpadding="1" cellspacing="1" border="1">\r
+<thead>\r
+<tr><td rowspan="1" colspan="3">AddRemoveSetStyleNamesTest</td></tr>\r
+</thead><tbody>\r
+<tr>\r
+       <td>open</td>\r
+       <td>run/com.vaadin.tests.components.AddRemoveSetStyleNamesTest?restartApplication</td>\r
+       <td></td>\r
+</tr>\r
+<!--add style 1. assert style1-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<!--add style 2. assert style1, style2-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<!--remove style 1. assertNot style1. assert style2-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<!--remove style 2. assertNot style1, style2-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style2</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style2</td>\r
+</tr>\r
+<!--add style1. set thestyle. assertNot style1. assert thestyle.-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<!--remove thestyle. assertNot thestyle-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<!--set thestyle. add style1. assert thestyle, style1-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<!--remove style 1. assertNot style1. assert thestyle-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<!--add style 1. remove thestyle. assertNot style1, thestyle-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>v-datefield-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::/VVerticalLayout[0]/VVerticalLayout[0]/VPopupCalendar[0]#popupButton</td>\r
+       <td></td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>style1</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>v-datefield-popup-thestyle</td>\r
+</tr>\r
+<tr>\r
+       <td>assertNotCSSClass</td>\r
+       <td>vaadin=runcomvaadintestscomponentsAddRemoveSetStyleNamesTest::Root/VOverlay[0]</td>\r
+       <td>thestyle</td>\r
+</tr>\r
+\r
+</tbody></table>\r
+</body>\r
+</html>\r
diff --git a/tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.java b/tests/testbench/com/vaadin/tests/components/AddRemoveSetStyleNamesTest.java
new file mode 100644 (file)
index 0000000..21cf9e4
--- /dev/null
@@ -0,0 +1,81 @@
+package com.vaadin.tests.components;\r
+\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.PopupDateField;\r
+\r
+public class AddRemoveSetStyleNamesTest extends TestBase {\r
+\r
+    private String style1 = "style1";\r
+    private String style2 = "style2";\r
+    private String thestyle = "thestyle";\r
+\r
+    private PopupDateField popupDateField;\r
+    private Button button1;\r
+    private Button button2;\r
+    private Button button3;\r
+\r
+    private Button.ClickListener listener;\r
+\r
+    @Override\r
+    protected void setup() {\r
+        popupDateField = new PopupDateField("PopupDateField");\r
+        popupDateField.setRequired(true);\r
+        popupDateField.setRequiredError("abcd");\r
+        addComponent(popupDateField);\r
+\r
+        listener = new Button.ClickListener() {\r
+\r
+            public void buttonClick(ClickEvent event) {\r
+                String style = (String) event.getButton().getData();\r
+                setComponentsStyle(style, !popupDateField.getStyleName()\r
+                        .contains(style), event.getButton());\r
+            }\r
+        };\r
+\r
+        button1 = new Button("Add style1", listener);\r
+        button1.setData(style1);\r
+        addComponent(button1);\r
+\r
+        button2 = new Button("Add style2", listener);\r
+        button2.setData(style2);\r
+        addComponent(button2);\r
+\r
+        button3 = new Button("Set thestyle", new Button.ClickListener() {\r
+\r
+            public void buttonClick(ClickEvent event) {\r
+                if (popupDateField.getStyleName().contains(thestyle)) {\r
+                    popupDateField.removeStyleName(thestyle);\r
+                    button3.setCaption("Set thestyle");\r
+                } else {\r
+                    popupDateField.setStyleName(thestyle);\r
+                    button1.setCaption("Add style1");\r
+                    button2.setCaption("Add style2");\r
+                    button3.setCaption("Remove thestyle");\r
+                }\r
+            }\r
+        });\r
+        addComponent(button3);\r
+    }\r
+\r
+    private void setComponentsStyle(String style, boolean add, Button button) {\r
+        if (add) {\r
+            popupDateField.addStyleName(style);\r
+            button.setCaption("Remove " + style);\r
+        } else {\r
+            popupDateField.removeStyleName(style);\r
+            button.setCaption("Add " + style);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "If a widget has set multiple css class names, AbtractComponentConnector.getStyleNames() removes all but first one of them. This is not acceptable, because we should be able to create connector for any existing GWT component and thus we do not know it it depends on multiple css class names.";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 8664;\r
+    }\r
+\r
+}
\ No newline at end of file