Fixes Issue #1079.
Re-establishes backward compatibility for set/getStyleName, including the
following changes:
+ Revert setStyleName(...) and getStyleName(...)
+ Add explicit get/setStylePrimaryName(..) methods.
+ Define primary style name to be the first token in the className property.
+ Remove the constraint that there always be an explicit primary style name.
+ Added methods get/setStyleDependentName(...) to promote the form
primary-depdendent for dependent style names.
Patch by: jgw, knorton
Review by: knorton, bruce, scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1277 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/CustomButton.java b/user/src/com/google/gwt/user/client/ui/CustomButton.java
index 2ef524f..da4b6aa 100644
--- a/user/src/com/google/gwt/user/client/ui/CustomButton.java
+++ b/user/src/com/google/gwt/user/client/ui/CustomButton.java
@@ -753,11 +753,11 @@
*/
if (curFace != newFace) {
if (curFace != null) {
- super.removeStyleName(getCSSStyleName());
+ removeStyleDependentName(curFace.getName());
}
curFace = newFace;
setCurrentFaceElement(newFace.getFace());
- super.addStyleName(getCSSStyleName());
+ addStyleDependentName(curFace.getName());
}
}
@@ -806,15 +806,6 @@
};
}
- /**
- * Gets the modified style name.
- *
- * @return the modified style name
- */
- private String getCSSStyleName() {
- return getStyleName() + "-" + curFace.getName();
- }
-
private Face getFaceFromID(int id) {
switch (id) {
case DOWN:
diff --git a/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java b/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java
index adf7868..8b35d4a 100644
--- a/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java
+++ b/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java
@@ -153,9 +153,9 @@
// Stylename constants.
private static final String STYLENAME_DEFAULT = "gwt-DisclosurePanel";
- private static final String STYLENAME_SUFFIX_OPEN = "-open";
+ private static final String STYLENAME_SUFFIX_OPEN = "open";
- private static final String STYLENAME_SUFFIX_CLOSED = "-closed";
+ private static final String STYLENAME_SUFFIX_CLOSED = "closed";
private static final String STYLENAME_HEADER = "header";
@@ -417,14 +417,12 @@
}
private void setContentDisplay() {
- // UIObject#replaceStylename has been suggested and would replace this.
- String primaryStyleName = getStyleName();
if (isOpen) {
- removeStyleName(primaryStyleName + STYLENAME_SUFFIX_CLOSED);
- addStyleName(primaryStyleName + STYLENAME_SUFFIX_OPEN);
+ removeStyleDependentName(STYLENAME_SUFFIX_CLOSED);
+ addStyleDependentName(STYLENAME_SUFFIX_OPEN);
} else {
- removeStyleName(primaryStyleName + STYLENAME_SUFFIX_OPEN);
- addStyleName(primaryStyleName + STYLENAME_SUFFIX_CLOSED);
+ removeStyleDependentName(STYLENAME_SUFFIX_OPEN);
+ addStyleDependentName(STYLENAME_SUFFIX_CLOSED);
}
if (content != null) {
diff --git a/user/src/com/google/gwt/user/client/ui/HTMLTable.java b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
index 2662d3b..f35ca86 100644
--- a/user/src/com/google/gwt/user/client/ui/HTMLTable.java
+++ b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-
package com.google.gwt.user.client.ui;
import com.google.gwt.user.client.DOM;
@@ -67,16 +66,29 @@
}
/**
- * Gets a style from a specified row.
+ * Gets the style of a specified cell.
*
- * @param row the row of the cell which the style while be added to
- * @param column the column of the cell which the style will be added to
+ * @param row the cell's row
+ * @param column the cell's column
* @see UIObject#getStyleName()
* @return returns the style name
* @throws IndexOutOfBoundsException
*/
public String getStyleName(int row, int column) {
- return DOM.getElementProperty(getElement(row, column), "className");
+ return UIObject.getStyleName(getElement(row, column));
+ }
+
+ /**
+ * Gets the primary style of a specified cell.
+ *
+ * @param row the cell's row
+ * @param column the cell's column
+ * @see UIObject#getStylePrimaryName()
+ * @return returns the style name
+ * @throws IndexOutOfBoundsException
+ */
+ public String getStylePrimaryName(int row, int column) {
+ return UIObject.getStylePrimaryName(getElement(row, column));
}
/**
@@ -165,10 +177,21 @@
*/
public void setStyleName(int row, int column, String styleName) {
prepareCell(row, column);
- Element elem = getCellElement(bodyElem, row, column);
- // IE uses attribute "className", FireFox uses attribute "class", so
- // avoiding the problem by using properties instead.
- DOM.setElementProperty(elem, "className", styleName);
+ UIObject.setStyleName(getCellElement(bodyElem, row, column), styleName);
+ }
+
+ /**
+ * Sets the primary style name associated with the specified cell.
+ *
+ * @param row the row of the cell whose style name is to be set
+ * @param column the column of the cell whose style name is to be set
+ * @param styleName the new style name
+ * @see UIObject#setStylePrimaryName(String)
+ * @throws IndexOutOfBoundsException
+ */
+ public void setStylePrimaryName(int row, int column, String styleName) {
+ UIObject.setStylePrimaryName(getCellElement(bodyElem, row, column),
+ styleName);
}
/**
@@ -310,7 +333,7 @@
/**
* Adds a style to the specified column.
*
- * @param col the col to which the style while be added
+ * @param col the col to which the style will be added
* @param styleName the style name to be added
* @see UIObject#addStyleName(String)
* @throws IndexOutOfBoundsException
@@ -320,21 +343,33 @@
}
/**
- * Gets a style from a specified column.
+ * Gets the style of the specified column.
*
- * @param column the column to which the style while be added
+ * @param column the column to be queried
+ * @return the style name
* @see UIObject#getStyleName()
* @throws IndexOutOfBoundsException
- * @return the style name
*/
public String getStyleName(int column) {
- return DOM.getElementProperty(ensureColumn(column), "className");
+ return UIObject.getStyleName(ensureColumn(column));
+ }
+
+ /**
+ * Gets the primary style of the specified column.
+ *
+ * @param column the column to be queried
+ * @return the style name
+ * @see UIObject#getStylePrimaryName()
+ * @throws IndexOutOfBoundsException
+ */
+ public String getStylePrimaryName(int column) {
+ return UIObject.getStylePrimaryName(ensureColumn(column));
}
/**
* Removes a style from the specified column.
*
- * @param column the column to which the style while be removed
+ * @param column the column from which the style will be removed
* @param styleName the style name to be removed
* @see UIObject#removeStyleName(String)
* @throws IndexOutOfBoundsException
@@ -352,7 +387,19 @@
* @throws IndexOutOfBoundsException
*/
public void setStyleName(int column, String styleName) {
- UIObject.resetStyleName(ensureColumn(column), styleName);
+ UIObject.setStyleName(ensureColumn(column), styleName);
+ }
+
+ /**
+ * Sets the primary style name associated with the specified column.
+ *
+ * @param column the column whose style name is to be set
+ * @param styleName the new style name
+ * @see UIObject#setStylePrimaryName(String)
+ * @throws IndexOutOfBoundsException
+ */
+ public void setStylePrimaryName(int column, String styleName) {
+ UIObject.setStylePrimaryName(ensureColumn(column), styleName);
}
/**
@@ -395,7 +442,7 @@
/**
* Adds a style to the specified row.
*
- * @param row the row to which the style while be added
+ * @param row the row to which the style will be added
* @param styleName the style name to be added
* @see UIObject#addStyleName(String)
* @throws IndexOutOfBoundsException
@@ -417,15 +464,27 @@
}
/**
- * Gets a style from a specified row.
+ * Gets the style of the specified row.
*
- * @param row the row to which the style while be added
+ * @param row the row to be queried
+ * @return the style name
* @see UIObject#getStyleName()
* @throws IndexOutOfBoundsException
- * @return the style name
*/
public String getStyleName(int row) {
- return DOM.getElementProperty(getElement(row), "className");
+ return UIObject.getStyleName(getElement(row));
+ }
+
+ /**
+ * Gets the primary style of the specified row.
+ *
+ * @param row the row to be queried
+ * @return the style name
+ * @see UIObject#getStylePrimaryName()
+ * @throws IndexOutOfBoundsException
+ */
+ public String getStylePrimaryName(int row) {
+ return UIObject.getStylePrimaryName(getElement(row));
}
/**
@@ -443,7 +502,7 @@
/**
* Removes a style from the specified row.
*
- * @param row the row to which the style while be removed
+ * @param row the row from which the style will be removed
* @param styleName the style name to be removed
* @see UIObject#removeStyleName(String)
* @throws IndexOutOfBoundsException
@@ -461,7 +520,19 @@
* @throws IndexOutOfBoundsException
*/
public void setStyleName(int row, String styleName) {
- UIObject.resetStyleName(ensureElement(row), styleName);
+ UIObject.setStyleName(ensureElement(row), styleName);
+ }
+
+ /**
+ * Sets the primary style name associated with the specified row.
+ *
+ * @param row the row whose style name is to be set
+ * @param styleName the new style name
+ * @see UIObject#setStylePrimaryName(String)
+ * @throws IndexOutOfBoundsException
+ */
+ public void setStylePrimaryName(int row, String styleName) {
+ UIObject.setStylePrimaryName(ensureElement(row), styleName);
}
/**
diff --git a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
index f701041..241b1cd 100644
--- a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
+++ b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
@@ -251,11 +251,11 @@
*/
public void setReadOnly(boolean readOnly) {
DOM.setElementPropertyBoolean(getElement(), "readOnly", readOnly);
- String readOnlyStyle = getStyleName() + "-readonly";
+ String readOnlyStyle = "readonly";
if (readOnly) {
- addStyleName(readOnlyStyle);
+ addStyleDependentName(readOnlyStyle);
} else {
- removeStyleName(readOnlyStyle);
+ removeStyleDependentName(readOnlyStyle);
}
}
diff --git a/user/src/com/google/gwt/user/client/ui/UIObject.java b/user/src/com/google/gwt/user/client/ui/UIObject.java
index ef55535..62d8115 100644
--- a/user/src/com/google/gwt/user/client/ui/UIObject.java
+++ b/user/src/com/google/gwt/user/client/ui/UIObject.java
@@ -59,10 +59,10 @@
* <p>
* Every <code>UIObject</code> has a <i>primary style name</i> that
* identifies the key CSS style rule that should always be applied to it. Use
- * {@link #setStyleName(String)} to specify an object's primary style name. In
- * most cases, the primary style name is set in a widget's constructor and never
- * changes again during execution. In the case that no primary style name is
- * specified, it defaults to <code>gwt-nostyle</code>.
+ * {@link #setStylePrimaryName(String)} to specify an object's primary style
+ * name. In most cases, the primary style name is set in a widget's constructor
+ * and never changes again during execution. In the case that no primary style
+ * name is specified, it defaults to the first style name that is added.
* </p>
*
* <p>
@@ -87,8 +87,6 @@
private static final String NULL_HANDLE_MSG = "Null widget handle. If you "
+ "are creating a composite, ensure that initWidget() has been called.";
- private static final String STYLE_EMPTY = "gwt-nostyle";
-
public static native boolean isVisible(Element elem) /*-{
return (elem.style.display != 'none');
}-*/;
@@ -98,32 +96,50 @@
}-*/;
/**
- * Sets the object's primary style name and updates all dependent style names.
+ * Gets all of the element's style names, as a space-separated list.
*
- * @param elem the element whose style is to be reset
- * @param style the new primary style name
- * @see #setStyleName(Element, String, boolean)
+ * @param elem the element whose style is to be retrieved
+ * @return the objects's space-separated style names
*/
- protected static void resetStyleName(Element elem, String style) {
- if (elem == null) {
- throw new RuntimeException(NULL_HANDLE_MSG);
- }
-
- // Style names cannot contain leading or trailing whitespace, and cannot
- // legally be empty.
- style = style.trim();
- if (style.length() == 0) {
- throw new IllegalArgumentException(EMPTY_STYLENAME_MSG);
- }
-
- ensurePrimaryStyleName(elem);
- updatePrimaryAndDependentStyleNames(elem, style);
+ protected static String getStyleName(Element elem) {
+ return DOM.getElementProperty(elem, "className");
}
/**
- * This convenience method adds or removes a secondary style name to the
- * primary style name for a given element. Set {@link #setStyleName(String)}
- * for a description of how primary and secondary style names are used.
+ * Gets the element's primary style name.
+ *
+ * @param elem the element whose primary style name is to be retrieved
+ * @return the element's primary style name
+ */
+ protected static String getStylePrimaryName(Element elem) {
+ String fullClassName = getStyleName(elem);
+
+ // The primary style name is always the first token of the full CSS class
+ // name. There can be no leading whitespace in the class name, so it's not
+ // necessary to trim() it.
+ int spaceIdx = fullClassName.indexOf(' ');
+ if (spaceIdx >= 0) {
+ return fullClassName.substring(0, spaceIdx);
+ }
+ return fullClassName;
+ }
+
+ /**
+ * Clears all of the element's style names and sets it to the given style.
+ *
+ * @param elem the element whose style is to be modified
+ * @param styleName the new style name
+ */
+ protected static void setStyleName(Element elem, String styleName) {
+ DOM.setElementProperty(elem, "className", styleName);
+ }
+
+ /**
+ * This convenience method adds or removes a style name for a given element.
+ * This method is typically used to add and remove secondary style names, but
+ * it can be used to remove primary stylenames as well, but that is not
+ * recommended. See {@link #setStyleName(String)} for a description of how
+ * primary and secondary style names are used.
*
* @param elem the element whose style is to be modified
* @param style the secondary style name to be added or removed
@@ -141,14 +157,8 @@
}
// Get the current style string.
- String oldStyle = ensurePrimaryStyleName(elem);
- int idx;
- if (oldStyle == null) {
- idx = -1;
- oldStyle = "";
- } else {
- idx = oldStyle.indexOf(style);
- }
+ String oldStyle = getStyleName(elem);
+ int idx = oldStyle.indexOf(style);
// Calculate matching index.
while (idx != -1) {
@@ -174,72 +184,93 @@
} else {
// Don't try to remove the style if it's not there.
if (idx != -1) {
- if (idx == 0) {
- // You can't remove the base (i.e. the first) style name.
- throw new IllegalArgumentException("Cannot remove base style name");
+ // Get the leading and trailing parts, without the removed name.
+ String begin = oldStyle.substring(0, idx).trim();
+ String end = oldStyle.substring(idx + style.length()).trim();
+
+ // Some contortions to make sure we don't leave extra spaces.
+ String newClassName;
+ if (begin.length() == 0) {
+ newClassName = end;
+ } else if (end.length() == 0) {
+ newClassName = begin;
+ } else {
+ newClassName = begin + " " + end;
}
- String begin = oldStyle.substring(0, idx);
- String end = oldStyle.substring(idx + style.length());
- DOM.setElementProperty(elem, "className", begin + end);
+
+ DOM.setElementProperty(elem, "className", newClassName);
}
}
}
/**
- * Ensure that the root element has a primary style name. If one is not
- * already present, then it is assigned the default style name.
+ * Sets the element's primary style name and updates all dependent style
+ * names.
*
- * @return the primary style name
+ * @param elem the element whose style is to be reset
+ * @param style the new primary style name
+ * @see #setStyleName(Element, String, boolean)
*/
- private static String ensurePrimaryStyleName(Element elem) {
- String className = DOM.getElementProperty(elem, "className").trim();
-
- if ("".equals(className)) {
- className = STYLE_EMPTY;
- DOM.setElementProperty(elem, "className", className);
+ protected static void setStylePrimaryName(Element elem, String style) {
+ if (elem == null) {
+ throw new RuntimeException(NULL_HANDLE_MSG);
}
-
- return className;
+
+ // Style names cannot contain leading or trailing whitespace, and cannot
+ // legally be empty.
+ style = style.trim();
+ if (style.length() == 0) {
+ throw new IllegalArgumentException(EMPTY_STYLENAME_MSG);
+ }
+
+ updatePrimaryAndDependentStyleNames(elem, style);
}
/**
* Replaces all instances of the primary style name with newPrimaryStyleName.
*/
- private static native void updatePrimaryAndDependentStyleNames(Element elem, String newStyle) /*-{
- var className = elem.className;
-
- var spaceIdx = className.indexOf(' ');
- if (spaceIdx >= 0) {
- // Get the old base style name from the beginning of the className.
- var oldStyle = className.substring(0, spaceIdx);
-
- // Replace oldStyle with newStyle. We have to do this by hand because
- // there is no String.replaceAll() and String.replace() takes a regex,
- // which we can't guarantee is safe on arbitrary class names.
- var newClassName = '', curIdx = 0;
- while (true) {
- var idx = className.indexOf(oldStyle, curIdx);
- if (idx == -1) {
- newClassName += className.substring(curIdx);
- break;
- }
-
- newClassName += className.substring(curIdx, idx);
- newClassName += newStyle;
- curIdx = idx + oldStyle.length;
- }
-
- elem.className = newClassName;
- } else {
- // There was no space, and therefore only one class name, which we can
- // simply clobber.
- elem.className = newStyle;
+ private static native void updatePrimaryAndDependentStyleNames(Element elem,
+ String newPrimaryStyle) /*-{
+ var classes = elem.className.split(/\s+/);
+ if (!classes) {
+ return;
}
+
+ var oldPrimaryStyle = classes[0];
+ var oldPrimaryStyleLen = oldPrimaryStyle.length;
+
+ classes[0] = newPrimaryStyle;
+ for (var i = 1, n = classes.length; i < n; i++) {
+ var name = classes[i];
+ if (name.length > oldPrimaryStyleLen
+ && name.charAt(oldPrimaryStyleLen) == '-'
+ && name.indexOf(oldPrimaryStyle) == 0) {
+ classes[i] = newPrimaryStyle + name.substring(oldPrimaryStyleLen);
+ }
+ }
+ elem.className = classes.join(" ");
}-*/;
private Element element;
/**
+ * Adds a dependent style name by specifying the style name's suffix. The
+ * actual form of the style name that is added is:
+ *
+ * <pre class="code">
+ * getStylePrimaryName() + '-' + styleSuffix
+ * </pre>
+ *
+ * @param styleSuffix the suffix of the dependent style to be added.
+ * @see #setStylePrimaryName(String)
+ * @see #removeStyleDependentName(String)
+ * @see #addStyleName(String)
+ */
+ public void addStyleDependentName(String styleSuffix) {
+ addStyleName(getStylePrimaryName() + '-' + styleSuffix);
+ }
+
+ /**
* Adds a secondary or dependent style name to this object. A secondary style
* name is an additional style name that is, in HTML/CSS terms, included as a
* space-separated token in the value of the CSS <code>class</code>
@@ -248,10 +279,11 @@
* <p>
* The most important use for this method is to add a special kind of
* secondary style name called a <i>dependent style name</i>. To add a
- * dependent style name, prefix the 'style' argument with the result of
- * {@link #getStyleName()}. For example, suppose the primary style name is
- * <code>gwt-TextBox</code>. If the following method is called as
- * <code>obj.setReadOnly(true)</code>:
+ * dependent style name, use {@link #setStyleDependentName(String)}, which
+ * will prefix the 'style' argument with the result of
+ * {@link #getStylePrimaryName()} (followed by a '-'). For example, suppose
+ * the primary style name is <code>gwt-TextBox</code>. If the following
+ * method is called as <code>obj.setReadOnly(true)</code>:
* </p>
*
* <pre class="code">
@@ -259,12 +291,12 @@
* isReadOnlyMode = readOnly;
*
* // Create a dependent style name.
- * String readOnlyStyle = getStyleName() + "-readonly";
+ * String readOnlyStyle = "readonly";
*
* if (readOnly) {
- * addStyleName(readOnlyStyle);
+ * addStyleDependentName(readOnlyStyle);
* } else {
- * removeStyleName(readOnlyStyle);
+ * removeStyleDependentName(readOnlyStyle);
* }
* }</pre>
*
@@ -280,7 +312,8 @@
* }
*
* // This rule is based on a dependent style name that is only active
- * // when the widget has called addStyleName(getStyleName() + "-readonly").
+ * // when the widget has called addStyleName(getStylePrimaryName() +
+ * // "-readonly").
* .gwt-TextBox-readonly {
* background-color: lightgrey;
* border: none;
@@ -292,11 +325,11 @@
* if the primary style name changed due to the following call:
* </p>
*
- * <pre class="code">setStyleName("my-TextThingy");</pre>
+ * <pre class="code">setStylePrimaryName("my-TextThingy");</pre>
*
* <p>
- * then the object would be re-associated with style rules below rather than
- * those above:
+ * then the object would be re-associated with following style rules, removing
+ * those that were shown above.
* </p>
*
* <pre class="code">
@@ -372,6 +405,18 @@
}
/**
+ * Gets all of the object's style names, as a space-separated list. If you
+ * wish to retrieve only the primary style name, call
+ * {@link #getStylePrimaryName()}.
+ *
+ * @return the objects's space-separated style names
+ * @see #getStylePrimaryName()
+ */
+ public String getStyleName() {
+ return getStyleName(getStyleElement());
+ }
+
+ /**
* Gets the primary style name associated with the object.
*
* @return the object's primary style name
@@ -379,17 +424,8 @@
* @see #addStyleName(String)
* @see #removeStyleName(String)
*/
- public String getStyleName() {
- String fullClassName = ensurePrimaryStyleName(getStyleElement());
-
- // The base style name is always the first token of the full CSS class
- // name. There can be no leading whitespace in the class name, so it's not
- // necessary to trim() it.
- int spaceIdx = fullClassName.indexOf(' ');
- if (spaceIdx >= 0) {
- return fullClassName.substring(0, spaceIdx);
- }
- return fullClassName;
+ public String getStylePrimaryName() {
+ return getStylePrimaryName(getStyleElement());
}
/**
@@ -412,7 +448,21 @@
}
/**
- * Removes a secondary style name.
+ * Removes a dependent style name by specifying the style name's suffix.
+ *
+ * @param styleSuffix the suffix of the dependent style to be removed
+ * @see #setStylePrimaryName(Element, String)
+ * @see #addStyleDependentName(String)
+ * @see #addStyleName(String)
+ */
+ public void removeStyleDependentName(String styleSuffix) {
+ removeStyleName(getStylePrimaryName() + '-' + styleSuffix);
+ }
+
+ /**
+ * Removes a style name. This method is typically used to remove secondary
+ * style names, but it can be used to remove primary stylenames as well. That
+ * use is not recommended.
*
* @param style the secondary style name to be removed
* @see #addStyleName(String)
@@ -430,8 +480,7 @@
public void setHeight(String height) {
// This exists to deal with an inconsistency in IE's implementation where
// it won't accept negative numbers in length measurements
- assert extractLengthValue(height.trim().toLowerCase()) >= 0 :
- "CSS heights should not be negative";
+ assert extractLengthValue(height.trim().toLowerCase()) >= 0 : "CSS heights should not be negative";
DOM.setStyleAttribute(element, "height", height);
}
@@ -464,14 +513,26 @@
}
/**
+ * Clears all of the object's style names and sets it to the given style. You
+ * should normally use {@link #setStylePrimaryName(String)} unless you wish to
+ * explicitly remove all existing styles.
+ *
+ * @param style the new style name
+ * @see #setStylePrimaryName(String)
+ */
+ public void setStyleName(String style) {
+ setStyleName(getStyleElement(), style);
+ }
+
+ /**
* Sets the object's primary style name and updates all dependent style names.
*
* @param style the new primary style name
* @see #addStyleName(String)
* @see #removeStyleName(String)
*/
- public void setStyleName(String style) {
- resetStyleName(getStyleElement(), style);
+ public void setStylePrimaryName(String style) {
+ setStylePrimaryName(getStyleElement(), style);
}
/**
@@ -507,8 +568,7 @@
public void setWidth(String width) {
// This exists to deal with an inconsistency in IE's implementation where
// it won't accept negative numbers in length measurements
- assert extractLengthValue(width.trim().toLowerCase()) >= 0 :
- "CSS widths should not be negative";
+ assert extractLengthValue(width.trim().toLowerCase()) >= 0 : "CSS widths should not be negative";
DOM.setStyleAttribute(element, "width", width);
}
@@ -580,10 +640,6 @@
}
this.element = elem;
-
- // We do not actually force the creation of a primary style name here.
- // Instead, we do it lazily -- when it is aboslutely required --
- // in getStyleName(), addStyleName(), and removeStyleName().
}
/**
@@ -602,7 +658,7 @@
return parseFloat(s);
}
}-*/;
-
+
private native void replaceNode(Element node, Element newNode) /*-{
var p = node.parentNode;
if (!p) {
diff --git a/user/src/com/google/gwt/user/client/ui/impl/AbstractItemPickerImpl.java b/user/src/com/google/gwt/user/client/ui/impl/AbstractItemPickerImpl.java
index 0386dc7..049eae6 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/AbstractItemPickerImpl.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/AbstractItemPickerImpl.java
@@ -76,7 +76,7 @@
}
}
- private static final String STYLENAME_DEPENDENT_SELECTED = "-selected";
+ private static final String STYLENAME_DEPENDENT_SELECTED = "selected";
private static final String STYLENAME_PRIMARY_ITEM = "item";
final Element body;
@@ -210,13 +210,13 @@
// Remove "selected" style from the item.
if (selectedItem != null) {
- selectedItem.removeStyleName(selectedItem.getStyleName() + STYLENAME_DEPENDENT_SELECTED);
+ selectedItem.removeStyleDependentName(STYLENAME_DEPENDENT_SELECTED);
}
// Add the "selected" style to the item.
selectedItem = item;
if (selectedItem != null) {
- selectedItem.addStyleName(selectedItem.getStyleName() + STYLENAME_DEPENDENT_SELECTED);
+ selectedItem.addStyleDependentName(STYLENAME_DEPENDENT_SELECTED);
}
}
diff --git a/user/test/com/google/gwt/user/client/ui/CustomButtonTest.java b/user/test/com/google/gwt/user/client/ui/CustomButtonTest.java
index c016748..5593cfa 100644
--- a/user/test/com/google/gwt/user/client/ui/CustomButtonTest.java
+++ b/user/test/com/google/gwt/user/client/ui/CustomButtonTest.java
@@ -41,7 +41,7 @@
ToggleButton b = new ToggleButton("up", "down");
b.setStyleName("random");
b.setDown(true);
- assertEquals(b.getStyleName(), "random");
+ assertEquals(b.getStylePrimaryName(), "random");
Map faces = new HashMap();
faces.put("downDisabled", b.getDownDisabledFace());
@@ -56,8 +56,8 @@
Map.Entry entry = (Entry) entries.next();
Face f = (Face) entry.getValue();
b.setCurrentFace(f);
- assertEquals("random random-" + f.getName(), DOM.getElementProperty(
- b.getElement(), "className").trim());
+ assertEquals("random", b.getStylePrimaryName());
+ assertTrue(b.getStyleName().indexOf("random-" + f.getName()) != -1);
}
entries = faces.entrySet().iterator();
@@ -154,5 +154,4 @@
assertFalse(b.isDown());
assertFalse(b.isEnabled());
}
-
}
diff --git a/user/test/com/google/gwt/user/client/ui/GridTest.java b/user/test/com/google/gwt/user/client/ui/GridTest.java
index 41d02ad..44ed1f1 100644
--- a/user/test/com/google/gwt/user/client/ui/GridTest.java
+++ b/user/test/com/google/gwt/user/client/ui/GridTest.java
@@ -65,16 +65,16 @@
columns.addStyleName(0, "a");
assertEquals("base a", columns.getStyleName(0));
columns.addStyleName(0, "b");
- assertEquals("base a b", getNormalizedStyleName(columns, 0));
+ assertEquals("base a b", columns.getStyleName(0));
columns.addStyleName(0, "c");
- assertEquals("base a b c", getNormalizedStyleName(columns, 0));
+ assertEquals("base a b c", columns.getStyleName(0));
// Remove first.
columns.removeStyleName(0, "a");
- assertEquals("base b c", getNormalizedStyleName(columns, 0));
+ assertEquals("base b c", columns.getStyleName(0));
// Remove last.
columns.removeStyleName(0, "c");
- assertEquals("base b", getNormalizedStyleName(columns, 0));
+ assertEquals("base b", columns.getStyleName(0));
// Only one column should be created.
Element e = DOM.getChild(r.getElement(), 0);
@@ -119,9 +119,4 @@
assertEquals(3, r.getRowCount());
assertEquals(2, r.getColumnCount());
}
-
- private String getNormalizedStyleName(Grid.ColumnFormatter formatter,
- int index) {
- return formatter.getStyleName(index).replaceAll(" ", " ").trim();
- }
}
diff --git a/user/test/com/google/gwt/user/client/ui/ListBoxTest.java b/user/test/com/google/gwt/user/client/ui/ListBoxTest.java
index ced0ac0..c68c69a 100644
--- a/user/test/com/google/gwt/user/client/ui/ListBoxTest.java
+++ b/user/test/com/google/gwt/user/client/ui/ListBoxTest.java
@@ -16,7 +16,6 @@
package com.google.gwt.user.client.ui;
import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.user.client.DOM;
/**
* Tests {@link ListBox}. Needs many, many more tests.
@@ -67,26 +66,21 @@
public void testSetStyleNames() {
ListBox box = new ListBox();
- try {
- box.removeStyleName("gwt-ListBox");
- fail("Should have thrown illegal argument exception");
- } catch (IllegalArgumentException e) {
- }
// Check subset problems.
box.addStyleName("superset");
box.addStyleName("super");
- assertEquals("gwt-ListBox superset super", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox superset super", box.getStyleName());
// Remove a style that doesn't exist.
box.removeStyleName("sup");
- assertEquals("gwt-ListBox superset super", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox superset super", box.getStyleName());
box.removeStyleName("super");
- assertEquals("gwt-ListBox superset", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox superset", box.getStyleName());
box.addStyleName("two styles");
- assertEquals("gwt-ListBox superset two styles", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox superset two styles", box.getStyleName());
box.removeStyleName("superset");
- assertEquals("gwt-ListBox two styles", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox two styles", box.getStyleName());
box.removeStyleName("two styles");
try {
box.addStyleName("");
@@ -97,7 +91,7 @@
box.addStyleName("superset");
box.addStyleName("two");
box.addStyleName("styles");
- assertEquals("gwt-ListBox superset two styles", getNormalizedStyleName(box));
+ assertEquals("gwt-ListBox superset two styles", box.getStyleName());
}
public void testText() {
@@ -164,9 +158,4 @@
assertEquals("item text", box.getItemText(1));
}
}
-
- private String getNormalizedStyleName(ListBox box) {
- return DOM.getElementProperty(box.getElement(), "className").replaceAll(" ", " ").trim();
- }
-
}
diff --git a/user/test/com/google/gwt/user/client/ui/UIObjectTest.java b/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
index f6f4c7e..86ad0d6 100644
--- a/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
+++ b/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
@@ -23,59 +23,26 @@
*/
public class UIObjectTest extends GWTTestCase {
- public String getModuleName() {
- return "com.google.gwt.user.User";
- }
-
static class MyObject extends UIObject {
MyObject() {
setElement(DOM.createDiv());
}
}
- public void testEmpty() {
- MyObject o = new MyObject();
-
- assertEquals("gwt-nostyle", o.getStyleName());
- doStuff(o);
- assertEquals("gwt-nostyle", o.getStyleName());
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
}
- public void testNormal() {
- // Test the basic set/get case.
+ public void testAccidentalPrimary() {
MyObject o = new MyObject();
-
- o.setStyleName("baseStyle");
-
- assertEquals("baseStyle", o.getStyleName());
- doStuff(o);
- assertEquals("baseStyle", o.getStyleName());
- }
-
- public void testAddStyleBeforeSet() {
- MyObject o = new MyObject();
-
- // Test that adding a style name before calling setStyleName() causes the
- // gwt-nostyle class to get added.
- o.addStyleName("userStyle");
- assertStartsWithClass(o, "gwt-nostyle");
- assertContainsClass(o, "userStyle");
- o.removeStyleName("userStyle");
- assertDoesNotContainClass(o, "userStyle");
-
- // getStyleName() should still be "gwt-nostyle".
- assertEquals("gwt-nostyle", o.getStyleName());
-
- doStuff(o);
-
- assertStartsWithClass(o, "gwt-nostyle");
- assertEquals("gwt-nostyle", o.getStyleName());
+ o.addStyleName("accidentalPrimary");
+ assertEquals("accidentalPrimary", o.getStylePrimaryName());
}
public void testAddAndRemoveEmptyStyleName() {
MyObject o = new MyObject();
- o.setStyleName("base");
+ o.setStylePrimaryName("primary");
try {
o.addStyleName("");
fail();
@@ -104,77 +71,115 @@
// This *should* throw.
}
- assertEquals("base", o.getStyleName());
+ assertEquals("primary", o.getStylePrimaryName());
}
- public void testSetEmptyBaseStyleName() {
+ public void testNormal() {
+ // Test the basic set/get case.
+ MyObject o = new MyObject();
+ o.setStylePrimaryName("primaryStyle");
+
+ // Note: getStyleName() explicitly returns the className attribute, so it
+ // doesn't guarantee that there aren't leading or trailing spaces.
+ assertEquals("primaryStyle", o.getStyleName());
+ doDependentAndSecondaryStyleTest(o);
+ assertEquals("primaryStyle", o.getStyleName());
+ }
+
+ public void testSetEmptyPrimaryStyleName() {
MyObject o = new MyObject();
try {
- o.setStyleName("");
+ o.setStylePrimaryName("");
fail();
} catch (IllegalArgumentException e) {
// This *should* throw.
}
try {
- o.setStyleName(" ");
+ o.setStylePrimaryName(" ");
fail();
} catch (IllegalArgumentException e) {
// This *should* throw.
}
}
- public void testRemoveBaseStyleName() {
+ public void testSetStyleNameNormalization() {
MyObject o = new MyObject();
- o.setStyleName("base");
- try {
- o.removeStyleName("base");
- fail();
- } catch (IllegalArgumentException e) {
- // This *should* throw.
+ o.setStylePrimaryName(" one ");
+ o.addStyleName(" two ");
+ o.addStyleName("\tthree\t");
+
+ assertEquals("one two three", o.getStyleName());
+ }
+
+ public void testSetStylePrimaryName() {
+ MyObject o = new MyObject();
+ o.setStylePrimaryName("gwt");
+ o.addStyleDependentName("dependent");
+ o.addStyleName("i-heart-gwt");
+ o.addStyleName("i-gwt-heart");
+
+ assertTrue(containsClass(o, "gwt"));
+ assertTrue(containsClass(o, "gwt-dependent"));
+ assertTrue(containsClass(o, "i-heart-gwt"));
+ assertTrue(containsClass(o, "i-gwt-heart"));
+
+ o.setStylePrimaryName("awt");
+
+ assertPrimaryStyleNameEquals(o, "awt");
+ assertTrue(containsClass(o, "awt-dependent"));
+ assertFalse(containsClass(o, "gwt-dependent"));
+ assertTrue(containsClass(o, "i-heart-gwt"));
+ assertTrue(containsClass(o, "i-gwt-heart"));
+ assertFalse(containsClass(o, "i-heart-awt"));
+ assertFalse(containsClass(o, "i-awt-heart"));
+ }
+
+ private void assertPrimaryStyleNameEquals(UIObject o, String className) {
+ String attr = DOM.getElementProperty(o.getElement(), "className");
+ assertTrue(attr.indexOf(className) == 0);
+ assertTrue(attr.length() == className.length()
+ || attr.charAt(className.length()) == ' ');
+ }
+
+ private boolean containsClass(UIObject o, String className) {
+ String[] classes = DOM.getElementProperty(o.getElement(), "className").split(
+ "\\s+");
+ for (int i = 0; i < classes.length; i++) {
+ if (className.equals(classes[i])) {
+ return true;
+ }
}
+ return false;
}
// doStuff() should leave MyObject's style in the same state it started in.
- private void doStuff(MyObject o) {
- // Test that the base style remains the first class, and that the dependent
- // style shows up.
- o.addStyleName(o.getStyleName() + "-dependent");
- assertContainsClass(o, o.getStyleName() + "-dependent");
+ private void doDependentAndSecondaryStyleTest(MyObject o) {
+ // Test that the primary style remains the first class, and that the
+ // dependent style shows up.
+ o.addStyleDependentName("dependent");
+ assertTrue(containsClass(o, o.getStylePrimaryName() + "-dependent"));
- String oldBaseStyle = o.getStyleName();
+ String oldPrimaryStyle = o.getStylePrimaryName();
- // Test that replacing the base style name works (and doesn't munge up the
- // user style).
- o.addStyleName("userStyle");
- o.setStyleName("newBaseStyle");
+ // Test that replacing the primary style name works (and doesn't munge up
+ // the secondary style).
+ o.addStyleName("secondaryStyle");
+ o.setStylePrimaryName("newPrimaryStyle");
- assertEquals("newBaseStyle", o.getStyleName());
- assertStartsWithClass(o, "newBaseStyle");
- assertContainsClass(o, "newBaseStyle-dependent");
- assertContainsClass(o, "userStyle");
- assertDoesNotContainClass(o, oldBaseStyle);
- assertDoesNotContainClass(o, oldBaseStyle + "-dependent");
+ assertEquals("newPrimaryStyle", o.getStylePrimaryName());
+ assertPrimaryStyleNameEquals(o, "newPrimaryStyle");
+ assertTrue(containsClass(o, "newPrimaryStyle-dependent"));
+ assertTrue(containsClass(o, "secondaryStyle"));
+ assertFalse(containsClass(o, oldPrimaryStyle));
+ assertFalse(containsClass(o, oldPrimaryStyle + "-dependent"));
// Clean up & return.
- o.setStyleName(oldBaseStyle);
- o.removeStyleName(oldBaseStyle + "-dependent");
- o.removeStyleName("userStyle");
- }
-
- private void assertContainsClass(UIObject o, String className) {
- String attr = DOM.getElementProperty(o.getElement(), "className");
- assertTrue(attr.indexOf(className) != -1);
- }
-
- private void assertDoesNotContainClass(UIObject o, String className) {
- String attr = DOM.getElementProperty(o.getElement(), "className");
- assertTrue(attr.indexOf(className) == -1);
- }
-
- private void assertStartsWithClass(UIObject o, String className) {
- String attr = DOM.getElementProperty(o.getElement(), "className");
- assertTrue(attr.indexOf(className) == 0);
+ o.setStylePrimaryName(oldPrimaryStyle);
+ o.removeStyleDependentName("dependent");
+ o.removeStyleName("secondaryStyle");
+ assertFalse(containsClass(o, o.getStylePrimaryName() + "-dependent"));
+ assertFalse(containsClass(o, "secondaryStyle"));
}
}