</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skipTests>false</skipTests>
- <additionalClasspathElements>
- <additionalClasspathElement>
- ${project.build.sourceDirectory}
- </additionalClasspathElement>
- <additionalClasspathElement>
- ${project.build.testSourceDirectory}
- </additionalClasspathElement>
- </additionalClasspathElements>
- <!-- Needed to run gwt-Tests -->
- <useManifestOnlyJar>false</useManifestOnlyJar>
- <!-- Necessary to run tests with return the same getModuleName-->
- <forkMode>always</forkMode>
- <!-- This makes emma:emma fail -->
- <!-- <useSystemClassLoader>true</useSystemClassLoader> -->
- <parallel>both</parallel>
- <threadCount>6</threadCount>
- <systemProperties>
- <property>
- <name>gwt.args</name>
- <value>-out target/www-junit</value>
- <name>gwt.noserver</name>
- <value>true</value>
- </property>
- </systemProperties>
- </configuration>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <additionalClasspathElements>
+ <additionalClasspathElement>${basedir}/src/main/java</additionalClasspathElement>
+ <additionalClasspathElement>${basedir}/src/test/java</additionalClasspathElement>
+ </additionalClasspathElements>
+ <!-- <useManifestOnlyJar>false</useManifestOnlyJar> -->
+ <!-- <forkMode>always</forkMode> -->
+ <useSystemClassLoader>false</useSystemClassLoader>
+ </configuration>
</plugin>
<plugin>
<groupId>org.riedelcastro</groupId>
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
+import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.BodyElement;
import com.google.gwt.dom.client.ButtonElement;
import com.google.gwt.query.client.js.JsMap;
import com.google.gwt.query.client.js.JsNamedArray;
import com.google.gwt.query.client.js.JsNodeArray;
+import com.google.gwt.query.client.js.JsObjectArray;
import com.google.gwt.query.client.js.JsRegexp;
import com.google.gwt.query.client.js.JsUtils;
import com.google.gwt.query.client.plugins.Effects;
import com.google.gwt.query.client.plugins.Events;
import com.google.gwt.query.client.plugins.Plugin;
import com.google.gwt.query.client.plugins.Widgets;
+import com.google.gwt.query.client.plugins.ajax.Ajax;
+import com.google.gwt.query.client.plugins.ajax.Ajax.Settings;
import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
import com.google.gwt.query.client.plugins.events.EventsListener;
import com.google.gwt.user.client.DOM;
LazyGQuery<T> andSelf();
/**
+ *
* The animate() method allows you to create animation effects on any numeric
* Attribute, CSS property, or color CSS property.
*
* Example:
*
* <pre class="code">
- * //move the element from its original position to the position top:500px and left:500px for 400ms.
- * //use a swing easing function for the transition
- * $("#foo").animate(Properties.create("{top:'500px',left:'500px'}"), 400, Easing.SWING);
- * // Change the width and border attributes of a table
- * $("table").animate(Properties.create("{$width: '500', $border: '10'}"), 400, Easing.LINEAR);
+ * //move the element from its original position to left:500px for 500ms
+ * $("#foo").animate("left:'500'");
+ * // Change the width attribute of a table
+ * $("table").animate("$width:'500'"), 400, Easing.LINEAR);
* </pre>
*
* In addition to numeric values, each property can take the strings 'show',
* Example:
*
* <pre class="code">
- * //move the element from its original position to 500px to the left and 5OOpx down for 400ms.
- * //use a swing easing function for the transition
- * $("#foo").animate(Properties.create("{top:'+=500px',left:'+=500px'}"), 400, Easing.SWING);
+ * //move the element from its original position to 500px to the left for 500ms and
+ * // change the background color of the element at the end of the animation
+ * $("#foo").animate("left:'+=500'", new Function(){
+ *
+ * public void f(Element e){
+ * $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED);
+ * }
+ *
+ * });
* </pre>
*
+ * The duration of the animation is 500ms.
+ *
* For color css properties, values can be specified via hexadecimal or rgb or
* literal values.
*
* Example:
*
* <pre class="code">
- * $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'"), 400, Easing.SWING);
+ * $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'");
* </pre>
*
- * @param stringOrProperties a String or a {@link Properties} object containing css properties to animate.
+ * @param prop the property to animate : "cssName:'value'"
* @param funcs an array of {@link Function} called once the animation is
* complete
- * @param duration the duration in milliseconds of the animation
- * @param easing the easing function to use for the transition
*/
- LazyGQuery<T> animate(Object stringOrProperties, int duration, Easing easing, Function... funcs);
+ LazyGQuery<T> animate(Object stringOrProperties, Function... funcs);
/**
- *
* The animate() method allows you to create animation effects on any numeric
* Attribute, CSS property, or color CSS property.
*
* Example:
*
* <pre class="code">
- * //move the element from its original position to left:500px for 500ms
- * $("#foo").animate("left:'500'");
- * // Change the width attribute of a table
- * $("table").animate("$width:'500'"), 400, Easing.LINEAR);
+ * //move the element from its original position to the position top:500px and left:500px for 400ms.
+ * //use a swing easing function for the transition
+ * $("#foo").animate(Properties.create("{top:'500px',left:'500px'}"), 400, Easing.SWING);
+ * // Change the width and border attributes of a table
+ * $("table").animate(Properties.create("{$width: '500', $border: '10'}"), 400, Easing.LINEAR);
* </pre>
*
* In addition to numeric values, each property can take the strings 'show',
* Example:
*
* <pre class="code">
- * //move the element from its original position to 500px to the left for 500ms and
- * // change the background color of the element at the end of the animation
- * $("#foo").animate("left:'+=500'", new Function(){
- *
- * public void f(Element e){
- * $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED);
- * }
- *
- * });
+ * //move the element from its original position to 500px to the left and 5OOpx down for 400ms.
+ * //use a swing easing function for the transition
+ * $("#foo").animate(Properties.create("{top:'+=500px',left:'+=500px'}"), 400, Easing.SWING);
* </pre>
*
- * The duration of the animation is 500ms.
- *
* For color css properties, values can be specified via hexadecimal or rgb or
* literal values.
*
* Example:
*
* <pre class="code">
- * $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'");
+ * $("#foo").animate("backgroundColor:'red', color:'#ffffff', borderColor:'rgb(129, 0, 70)'"), 400, Easing.SWING);
* </pre>
*
- * @param prop the property to animate : "cssName:'value'"
+ * @param stringOrProperties a String or a {@link Properties} object containing css properties to animate.
* @param funcs an array of {@link Function} called once the animation is
* complete
+ * @param duration the duration in milliseconds of the animation
+ * @param easing the easing function to use for the transition
*/
- LazyGQuery<T> animate(Object stringOrProperties, Function... funcs);
+ LazyGQuery<T> animate(Object stringOrProperties, int duration, Easing easing, Function... funcs);
/**
* The animate() method allows you to create animation effects on any numeric
*/
LazyGQuery<T> closest(String selector);
+ /**
+ * Get the first ancestor element that matches the selector (for each matched
+ * element), beginning at the current element and progressing up through the
+ * DOM tree until reach the <code>context</code> node.
+ *
+ * If no context is passed in then the context of the gQuery object will be
+ * used instead.
+ *
+ */
+ LazyGQuery<T> closest(String selector, Node context);
+
/**
* Returns a {@link Map} object as key a selector and as value the list of
* ancestor elements matching this selectors, beginning at the first matched
*/
JsNamedArray<NodeList<Element>> closest(String[] selectors, Node context);
- /**
- * Get the first ancestor element that matches the selector (for each matched
- * element), beginning at the current element and progressing up through the
- * DOM tree until reach the <code>context</code> node.
- *
- * If no context is passed in then the context of the gQuery object will be
- * used instead.
- *
- */
- LazyGQuery<T> closest(String selector, Node context);
-
/**
* Filter the set of elements to those that contain the specified text.
*/
/**
* Attach <code>handlers</code> to one or more events for all elements that
* match the <code>selector</code>, now or in the future, based on a specific
- * set of root elements.
+ * set of root elements.
*
* Example:
*
* <pre>
- * $("table").delegate("td", "click", new Function(){
+ * $("table").delegate("td", Event.ONCLICK, new Function(){
* public void f(Element e){
* $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
* }
* <pre>
* $("table").each(new Function(){
* public void f(Element table){
- * $("td", table).live("click", new Function(){
+ * $("td", table).live(Event.ONCLICK, new Function(){
* public void f(Element e){
* $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
* }
*
* </pre>
*
- * You can pass attach the handlers to many events by specifying a String with espaced event type.
+ * You can attach the handlers to many events by using the '|' operator
* ex:
* <pre>
- * $("div.main").delegate(".subMain", "click dblclick", new Function(){...});
- * </pre>
+ * $("div.main").delegate(".subMain", Event.ONCLICK | Event.ONDBLCLICK, new Function(){...});
* </pre>
*/
- LazyGQuery<T> delegate(String selector, String eventType, Function... handlers);
+ LazyGQuery<T> delegate(String selector, int eventbits, Function... handlers);
/**
- * Attach <code>handlers</code> to one or more events for all elements that
- * match the <code>selector</code>, now or in the future, based on a specific
- * set of root elements.
- *
+ * Attach <code>handlers</code> to one or more events for all elements that match the <code>selector</code>,
+ * now or in the future, based on a specific set of root elements.
+ * The <code>data</code> parameter allows us
+ * to pass data to the handler.
+ *
* Example:
- *
* <pre>
* $("table").delegate("td", "click", new Function(){
* public void f(Element e){
* }
* });
* </pre>
- *
- * This code above add an handler on click event on all cell (the existing
- * oneand the future cell) of all table. This code is equivalent to :
- *
+ * This code above add an handler on click event on all cell (the existing oneand the future cell) of all table.
+ * This code is equivalent to :
* <pre>
* $("table").each(new Function(){
* public void f(Element table){
* }
* });
*
- * You can pass attach the handlers to many events by specifying a String with espaced event type.
+ * </pre>
+ *
+ * You can pass attach the handlers to many events by using the '|' operator
* ex:
* <pre>
- * $("div.main").delegate(".subMain", "click dblclick", new Function(){...});
- * </pre>
+ * $("div.main").delegate(".subMain", Event.ONCLICK | Event.ONDBLCLICK, new Function(){...});
* </pre>
*/
- LazyGQuery<T> delegate(String selector, String eventType, Object data, Function... handlers);
+ LazyGQuery<T> delegate(String selector, int eventbits, Object data, Function... handlers);
/**
* Attach <code>handlers</code> to one or more events for all elements that
* match the <code>selector</code>, now or in the future, based on a specific
- * set of root elements.
+ * set of root elements.
*
* Example:
*
* <pre>
- * $("table").delegate("td", Event.ONCLICK, new Function(){
+ * $("table").delegate("td", "click", new Function(){
* public void f(Element e){
* $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
* }
* <pre>
* $("table").each(new Function(){
* public void f(Element table){
- * $("td", table).live(Event.ONCLICK, new Function(){
+ * $("td", table).live("click", new Function(){
* public void f(Element e){
* $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
* }
*
* </pre>
*
- * You can attach the handlers to many events by using the '|' operator
+ * You can pass attach the handlers to many events by specifying a String with espaced event type.
* ex:
* <pre>
- * $("div.main").delegate(".subMain", Event.ONCLICK | Event.ONDBLCLICK, new Function(){...});
+ * $("div.main").delegate(".subMain", "click dblclick", new Function(){...});
+ * </pre>
* </pre>
*/
- LazyGQuery<T> delegate(String selector, int eventbits, Function... handlers);
+ LazyGQuery<T> delegate(String selector, String eventType, Function... handlers);
/**
- * Attach <code>handlers</code> to one or more events for all elements that match the <code>selector</code>,
- * now or in the future, based on a specific set of root elements.
- * The <code>data</code> parameter allows us
- * to pass data to the handler.
- *
+ * Attach <code>handlers</code> to one or more events for all elements that
+ * match the <code>selector</code>, now or in the future, based on a specific
+ * set of root elements.
+ *
* Example:
+ *
* <pre>
* $("table").delegate("td", "click", new Function(){
* public void f(Element e){
* }
* });
* </pre>
- * This code above add an handler on click event on all cell (the existing oneand the future cell) of all table.
- * This code is equivalent to :
+ *
+ * This code above add an handler on click event on all cell (the existing
+ * oneand the future cell) of all table. This code is equivalent to :
+ *
* <pre>
* $("table").each(new Function(){
* public void f(Element table){
* }
* });
*
- * </pre>
- *
- * You can pass attach the handlers to many events by using the '|' operator
+ * You can pass attach the handlers to many events by specifying a String with espaced event type.
* ex:
* <pre>
- * $("div.main").delegate(".subMain", Event.ONCLICK | Event.ONDBLCLICK, new Function(){...});
+ * $("div.main").delegate(".subMain", "click dblclick", new Function(){...});
+ * </pre>
* </pre>
*/
- LazyGQuery<T> delegate(String selector, int eventbits, Object data, Function... handlers);
+ LazyGQuery<T> delegate(String selector, String eventType, Object data, Function... handlers);
/**
* Execute the next function on the Effects queue for the matched elements.
/**
* Remove an event handlers previously attached using
- * {@link #live(String, Function)} In order for this method to function
+ * {@link #live(int, Function)} In order for this method to function
* correctly, the selector used with it must match exactly the selector
- * initially used with {@link #live(String, Function)}
+ * initially used with {@link #live(int, Function)}
*/
- LazyGQuery<T> die(String eventName);
+ LazyGQuery<T> die(int eventbits);
/**
* Remove an event handlers previously attached using
- * {@link #live(int, Function)} In order for this method to function
+ * {@link #live(String, Function)} In order for this method to function
* correctly, the selector used with it must match exactly the selector
- * initially used with {@link #live(int, Function)}
+ * initially used with {@link #live(String, Function)}
*/
- LazyGQuery<T> die(int eventbits);
+ LazyGQuery<T> die(String eventName);
/**
* Run one or more Functions over each element of the GQuery. You have to
/**
* Reduce the set of matched elements to those that have a descendant
- * that matches the selector.
+ * that matches the Element.
*/
- LazyGQuery<T> has(String selector);
+ LazyGQuery<T> has(Element elem);
/**
* Reduce the set of matched elements to those that have a descendant
- * that matches the Element.
+ * that matches the selector.
*/
- LazyGQuery<T> has(Element elem);
+ LazyGQuery<T> has(String selector);
/**
* Returns true any of the specified classes are present on any of the matched
*/
boolean isEmpty();
+ /**
+ * Return true if the first element is visible.isVisible
+ */
+ boolean isVisible();
+
/**
* Bind a set of functions to the keydown event of each matched element. Or
* trigger the event if no functions are provided.
*/
int length();
+ /**
+ * Attach a handler for this event to all elements which match the current
+ * selector, now and in the future.
+ */
+ LazyGQuery<T> live(int eventbits, Function... funcs);
+
+ /**
+ * Attach a handler for this event to all elements which match the current
+ * selector, now and in the future.
+ */
+ LazyGQuery<T> live(int eventbits, Object data, Function... funcs);
+
/**
* <p>
* Attach a handler for this event to all elements which match the current
*/
LazyGQuery<T> live(String eventName, Function... funcs);
- /**
- * Attach a handler for this event to all elements which match the current
- * selector, now and in the future.
- */
- LazyGQuery<T> live(int eventbits, Function... funcs);
-
- /**
- * Attach a handler for this event to all elements which match the current
- * selector, now and in the future.
- */
- LazyGQuery<T> live(int eventbits, Object data, Function... funcs);
-
/**
* <p>
* Attach a handler for this event to all elements which match the current
LazyGQuery<T> live(String eventName, Object data, Function... funcs);
/**
- * Bind a function to the load event of each matched element.
+ * Load data from the server and place the returned HTML into the matched element.
+ *
+ * The url allows us to specify a portion of the remote document to be inserted.
+ * This is achieved with a special syntax for the url parameter.
+ * If one or more space characters are included in the string, the portion of
+ * the string following the first space is assumed to be a GQuery selector that
+ * determines the content to be loaded.
+ *
*/
- LazyGQuery<T> load(Function f);
+ LazyGQuery<T> load(String url);
+
+ /**
+ * Load data from the server and place the returned HTML into the matched element.
+ *
+ * The url allows us to specify a portion of the remote document to be inserted.
+ * This is achieved with a special syntax for the url parameter.
+ * If one or more space characters are included in the string, the portion of
+ * the string following the first space is assumed to be a GQuery selector that
+ * determines the content to be loaded.
+ *
+ */
+ LazyGQuery<T> load(String url, Properties data, Function onSuccess);
/**
* Reduce the set of matched elements to all elements before a given position.
*/
int queue();
- /**
- * Show the number of functions in the queued named as queueName to be
- * executed on the first matched element.
- */
- int queue(String queueName);
-
/**
* Put a set of {@link Function} at the end of the Effects queue.
*
*/
LazyGQuery<T> queue(Function... f);
+ /**
+ * Show the number of functions in the queued named as queueName to be
+ * executed on the first matched element.
+ */
+ int queue(String queueName);
+
/**
* Put a set of {@link Function} at the end of a queue.
*
LazyGQuery<T> resize(Function... f);
/**
- * Save a set of Css properties of every matched element.
+ * Bind an event handler to the "resize" JavaScript event, or trigger that event on an element.
*/
- void restoreCssAttrs(String... cssProps);
+ LazyGQuery<T> resize(Function f);
/**
- * Bind an event handler to the "resize" JavaScript event, or trigger that event on an element.
+ * Save a set of Css properties of every matched element.
*/
- LazyGQuery<T> resize(Function f);
+ void restoreCssAttrs(String... cssProps);
/**
* Restore a set of previously saved Css properties in every matched element.
LazyGQuery<T> submit(Function... funcs);
/**
- * Return the text contained in the first matched element.
+ * Return the concatened text contained in the matched elements.
*/
String text();
LazyGQuery<T> toggleClass(String clz, boolean addOrRemove);
/**
- * Returns the computed left position of the first element matched.
+ * Returns the computed top position of the first element matched.
*/
int top();
*/
LazyGQuery<T> unbind(int eventbits);
+ /**
+ * Removes all events that match the eventList.
+ */
+ LazyGQuery<T> unbind(String eventList);
+
/**
* Remove all event delegation that have been bound using
* {@link #delegate(String, int, Function...)} {@link #live(int, Function...)} methods
* Undelegate is a way of removing event handlers that have been bound using
* {@link #delegate(String, int, Function...)} method
*/
- LazyGQuery<T> undelegate(String selector, String eventName);
+ LazyGQuery<T> undelegate(String selector, int eventBit);
/**
* Undelegate is a way of removing event handlers that have been bound using
* {@link #delegate(String, int, Function...)} method
*/
- LazyGQuery<T> undelegate(String selector, int eventBit);
+ LazyGQuery<T> undelegate(String selector, String eventName);
/**
* Remove all duplicate elements from an array of elements. Note that this
*/
String[] vals();
- /**
- * Return true if the first element is visible.isVisible
- */
- boolean isVisible();
-
/**
* Return the first non null attached widget from the matched elements or null
* if there isn't any.
import com.google.gwt.query.client.js.JsObjectArray;\r
import com.google.gwt.query.client.js.JsRegexp;\r
import com.google.gwt.query.client.js.JsUtils;\r
+import com.google.gwt.regexp.shared.RegExp;\r
\r
/**\r
* Runtime selector engine implementation which translates selectors to XPath\r
}\r
}\r
};\r
+ \r
+ /**\r
+ * A replacer which works in both sides. Right now gquery JsRegexp is faster\r
+ * than gwt shared RegExp and does not uses HashSet\r
+ */\r
+ public static final Replacer replacerGwt = new Replacer() {\r
+ public String replaceAll(String s, String r, Object o) {\r
+ RegExp p = RegExp.compile(r, "g");\r
+ if (o instanceof ReplaceCallback) {\r
+ ReplaceCallback callback = (ReplaceCallback) o;\r
+ com.google.gwt.regexp.shared.MatchResult a = null;\r
+ while ((a = p.exec(s)) != null) {\r
+ ArrayList<String> args = new ArrayList<String>();\r
+ for (int i = 0; i < a.getGroupCount(); i++) {\r
+ args.add(a.getGroup(i));\r
+ }\r
+ String f = callback.foundMatch(args);\r
+ s = s.replace(a.getGroup(0), f);\r
+ p = RegExp.compile(r, "g");\r
+ }\r
+ return s;\r
+ } else {\r
+ return p.replace(s, o.toString());\r
+ }\r
+ }\r
+ };\r
\r
public SelectorEngineCssToXPath() {\r
instance = this;\r
return Properties.create();
}
}
+
+ public static native boolean isDefaultPrevented(JavaScriptObject e)/*-{
+ return e.defaultPrevented || e.returnValue === false || e.getPreventDefault && e.getPreventDefault() ? true : false;
+ }-*/;
+
}
if ((eventbits | Event.ONMOUSEWHEEL) == Event.ONMOUSEWHEEL)
dispatchEvent(document.createMouseEvent("mousewheel", true, true, 0, 0,
0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, null));
- if (eventbits == EventsListener.ONSUBMIT)
- triggerHtmlEvent("submit");
+ if (eventbits == EventsListener.ONSUBMIT) {
+ Event evt = document.createHtmlEvent("submit", true, true).cast();
+ dispatchEvent(evt, new Function() {
+ public native void f(Element e) /*-{
+ e.submit();
+ }-*/;
+ });
+ }
if (eventbits == EventsListener.ONRESIZE)
triggerHtmlEvent("resize");
return this;
}
-
+
/**
* Trigger a html event in all matched elements.
*
* @param htmlEvent An string representing the html event desired
+ * @functions a set of function to run if the event is not canceled.
*/
- public Events triggerHtmlEvent(String htmlEvent) {
- dispatchEvent(document.createHtmlEvent(htmlEvent, true, true));
+ public Events triggerHtmlEvent(String htmlEvent, Function...functions) {
+ dispatchEvent(document.createHtmlEvent(htmlEvent, true, true), functions);
return this;
}
}
return this;
}
-
- private void dispatchEvent(NativeEvent evt) {
+
+ private void dispatchEvent(NativeEvent evt, Function...funcs) {
for (Element e : elements()) {
if (isEventCapable(e)){
e.dispatchEvent(evt);
+ if (!JsUtils.isDefaultPrevented(evt)){
+ for (Function f: funcs) {
+ f.setEvent(Event.as(evt));
+ f.f(e);
+ }
+ }
}
}
}
}
return this;
}
-
-
}
import com.google.gwt.dom.client.Node;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.js.JsUtils;
import com.google.gwt.query.client.plugins.events.EventsListener;
import com.google.gwt.user.client.Event;
import com.google.gwt.query.client.LazyBase;
* Trigger a html event in all matched elements.
*
* @param htmlEvent An string representing the html event desired
+ * @functions a set of function to run if the event is not canceled.
*/
- LazyEvents<T> triggerHtmlEvent(String htmlEvent);
+ LazyEvents<T> triggerHtmlEvent(String htmlEvent, Function...functions);
/**
* Removes all handlers, that matches the events bits passed, from each
import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;\r
import com.google.gwt.query.client.impl.SelectorEngineCssToXPath.ReplaceCallback;\r
import com.google.gwt.query.client.impl.SelectorEngineCssToXPath.Replacer;\r
-import com.google.gwt.regexp.shared.RegExp;\r
import com.google.gwt.user.rebind.SourceWriter;\r
\r
/**\r
/**\r
* The replacer implementation for the JVM.\r
*/\r
- public static final Replacer replacerJvm = new Replacer() {\r
+ public static final Replacer replacer = new Replacer() {\r
public String replaceAll(String s, String r, Object o) {\r
Pattern p = Pattern.compile(r);\r
if (o instanceof ReplaceCallback) {\r
}\r
};\r
\r
- /**\r
- * A replacer which works in both sides. Right now gquery JsRegexp is faster\r
- * than gwt shared RegExp and does not uses HashSet\r
- */\r
- public static final Replacer replacerGwt = new Replacer() {\r
- public String replaceAll(String s, String r, Object o) {\r
- RegExp p = RegExp.compile(r, "g");\r
- if (o instanceof ReplaceCallback) {\r
- ReplaceCallback callback = (ReplaceCallback) o;\r
- com.google.gwt.regexp.shared.MatchResult a = null;\r
- while ((a = p.exec(s)) != null) {\r
- ArrayList<String> args = new ArrayList<String>();\r
- for (int i = 0; i < a.getGroupCount(); i++) {\r
- args.add(a.getGroup(i));\r
- }\r
- String f = callback.foundMatch(args);\r
- s = s.replace(a.getGroup(0), f);\r
- p = RegExp.compile(r, "g");\r
- }\r
- return s;\r
- } else {\r
- return p.replace(s, o.toString());\r
- }\r
- }\r
- };\r
- \r
- public static final Replacer replacer = replacerGwt;\r
-\r
private SelectorEngineCssToXPath engine = new SelectorEngineCssToXPath(\r
replacer);\r
\r
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.builders.JsonBuilder;
-import com.google.gwt.query.client.builders.Name;
-import com.google.gwt.query.client.builders.XmlBuilder;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test class for testing ajax stuff.
- */
-public class GQueryAjaxTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("core-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- interface JsonExample extends JsonBuilder {
- int getA();
- JsonExample getB();
- @Name("u")
- String getUrl();
- long getD();
- Boolean getZ();
- String[] getT();
- JsonExample setT(String[] strings);
- JsonExample setZ(Boolean b);
- JsonExample setD(long l);
- }
-
- public void testJsonBuilder() {
- String json = "[{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}]";
- JsonExample c = GWT.create(JsonExample.class);
- assertEquals(0, c.getA());
- c.parse(json, true);
- assertEquals(1, c.getA());
- assertNotNull(c.getB());
- assertEquals(2, c.getB().getA());
- assertEquals(3, c.getB().getB().getA());
- assertTrue(c.getZ());
- assertEquals("hola", c.getT()[0]);
- assertEquals("adios", c.getT()[1]);
- assertEquals("url", c.getUrl());
- c.setT(new String[]{"foo", "bar"})
- .setZ(false).setD(1234);
- assertFalse(c.getZ());
- assertEquals("foo", c.getT()[0]);
- assertEquals("bar", c.getT()[1]);
- assertEquals(1234l, c.getD());
-
- }
-
- interface XmlExample extends XmlBuilder {
- String getA();
- Boolean getB();
- @Name("c")
- int getNumber();
-
- XmlExample[] getX();
- @Name("x")
- XmlExample getFirstX();
-
- XmlExample setA(String s);
- @Name("c")
- XmlExample setNumber(int i);
- }
-
- public void testXmlBuilder() {
- String xml = "<a a='ra' b='true' c='-1.48'><x a='xa1'/> <x a='xa2'/> text</a>";
- XmlExample x = GWT.create(XmlExample.class);
- x.parse(xml);
- assertTrue(x.getB());
- assertEquals("ra", x.getA());
- assertEquals(-1, x.getNumber());
- assertEquals("xa2", x.getX()[1].getA());
- assertEquals("xa1", x.getFirstX().getA());
- x.setA("X").setNumber(1234);
- assertEquals("X", x.getA());
- assertEquals(1234, x.getNumber());
- }
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+
+import static com.google.gwt.query.client.GQuery.$;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.builders.JsonBuilder;
+import com.google.gwt.query.client.builders.Name;
+import com.google.gwt.query.client.builders.XmlBuilder;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing ajax stuff.
+ */
+public class GQueryAjaxTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("core-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ interface JsonExample extends JsonBuilder {
+ int getA();
+ JsonExample getB();
+ @Name("u")
+ String getUrl();
+ long getD();
+ Boolean getZ();
+ String[] getT();
+ JsonExample setT(String[] strings);
+ JsonExample setZ(Boolean b);
+ JsonExample setD(long l);
+ }
+
+ public void testJsonBuilder() {
+ String json = "[{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}]";
+ JsonExample c = GWT.create(JsonExample.class);
+ assertEquals(0, c.getA());
+ c.parse(json, true);
+ assertEquals(1, c.getA());
+ assertNotNull(c.getB());
+ assertEquals(2, c.getB().getA());
+ assertEquals(3, c.getB().getB().getA());
+ assertTrue(c.getZ());
+ assertEquals("hola", c.getT()[0]);
+ assertEquals("adios", c.getT()[1]);
+ assertEquals("url", c.getUrl());
+ c.setT(new String[]{"foo", "bar"})
+ .setZ(false).setD(1234);
+ assertFalse(c.getZ());
+ assertEquals("foo", c.getT()[0]);
+ assertEquals("bar", c.getT()[1]);
+ assertEquals(1234l, c.getD());
+
+ }
+
+ interface XmlExample extends XmlBuilder {
+ String getA();
+ Boolean getB();
+ @Name("c")
+ int getNumber();
+
+ XmlExample[] getX();
+ @Name("x")
+ XmlExample getFirstX();
+
+ XmlExample setA(String s);
+ @Name("c")
+ XmlExample setNumber(int i);
+ }
+
+ public void testXmlBuilder() {
+ String xml = "<a a='ra' b='true' c='-1.48'><x a='xa1'/> <x a='xa2'/> text</a>";
+ XmlExample x = GWT.create(XmlExample.class);
+ x.parse(xml);
+ assertTrue(x.getB());
+ assertEquals("ra", x.getA());
+ assertEquals(-1, x.getNumber());
+ assertEquals("xa2", x.getX()[1].getA());
+ assertEquals("xa1", x.getFirstX().getA());
+ x.setA("X").setNumber(1234);
+ assertEquals("X", x.getA());
+ assertEquals(1234, x.getNumber());
+ }
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-import static com.google.gwt.query.client.GQuery.$$;
-import static com.google.gwt.query.client.GQuery.document;
-
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.InputElement;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.css.CSS;
-import com.google.gwt.query.client.css.RGBColor;
-import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;
-import com.google.gwt.query.client.impl.SelectorEngineImpl;
-import com.google.gwt.query.client.impl.SelectorEngineSizzle;
-import com.google.gwt.query.client.js.JsNamedArray;
-import com.google.gwt.query.client.js.JsNodeArray;
-import com.google.gwt.query.client.js.JsUtils;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.TextArea;
-import com.google.gwt.user.client.ui.Widget;
-
-import junit.framework.Assert;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Test class for testing gwtquery-core api.
- */
-public class GQueryCoreTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- protected static void assertHtmlEquals(Object expected, Object actual) {
- assertEquals(iExplorerFixHtml(expected), iExplorerFixHtml(actual));
- }
-
- protected static String iExplorerFixHtml(Object s) {
- // IE shows all tags upper-case
- // IE adds \r \n
- // IE does not put quotes to some attributes
- // Investigate: IE in method find puts the attribute $h="4"
- // Investigate: IE in method filter adds the attrib added="null"
- return s.toString().trim().toLowerCase().replaceAll("[\r\n]", "").replaceAll(
- " ([\\w]+)=[\"']([^\"']+)[\"']", " $1=$2").replaceAll(
- "\\s+\\$h=\"[^\"]+\"", "").replaceAll(" added=[^ >]+", "");
- }
-
- int done = 0;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null || DOM.getElementById("core-tst") == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("core-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- public void testAttributeMethods() {
-
- $(e).html("<p class=\"a1\">Content</p>");
- GQuery gq = $("p", e);
-
- // attr()
- gq.attr($$("attr1: 'a', attr2: 'b'"));
- assertEquals("a", gq.attr("attr1"));
- assertEquals("b", gq.attr("attr2"));
-
- gq.attr("attr3", new Function() {
- public String f(Element e, int i) {
- return e.getInnerText();
- }
- });
- assertEquals("Content", gq.attr("attr3"));
-
- assertEquals("a1", gq.attr("class"));
- gq.attr("class", "b1 b2");
-
- // hasClass()
- assertTrue(gq.hasClass("b1"));
- assertTrue(gq.hasClass("b2"));
-
- // addClass()
- gq.addClass("c1", "c2");
- assertTrue(gq.hasClass("b1"));
- assertTrue(gq.hasClass("b2"));
- assertTrue(gq.hasClass("c1"));
- assertTrue(gq.hasClass("c2"));
-
- // removeClass()
- gq.removeClass("c2", "c1");
- assertTrue(gq.hasClass("b1"));
- assertTrue(gq.hasClass("b2"));
- assertFalse(gq.hasClass("c1"));
- assertFalse(gq.hasClass("c2"));
-
- // toggleClass()
- gq.toggleClass("b2");
- assertTrue(gq.hasClass("b1"));
- assertFalse(gq.hasClass("b2"));
- gq.toggleClass("b2");
- assertTrue(gq.hasClass("b1"));
- assertTrue(gq.hasClass("b2"));
- gq.toggleClass("b2", true);
- assertTrue(gq.hasClass("b2"));
- gq.toggleClass("b2", false);
- assertFalse(gq.hasClass("b2"));
-
- // css()
- String content = "<p style='color:red;'>Test Paragraph.</p>";
- $(e).html(content);
- assertEquals("red", $("p", e).css("color"));
- $("p", e).css("font-weight", "bold");
- assertEquals("bold", $("p", e).css("font-weight"));
-
- // css() properties
- $(e).html("<p>Test Paragraph.</p>");
- $("p", e).css(
- Properties.create("color: 'red', 'font-weight': 'bold', background: 'blue'"));
- assertEquals("red", $("p", e).css("color"));
- assertEquals("bold", $("p", e).css("font-weight"));
- assertEquals("blue", $("p", e).css("background-color", false));
-
- // css() camelize and uppercase
- $(e).html("<p>Test Paragraph.</p>");
- $("p", e).css(Properties.create("COLOR: 'red', 'FONT-WEIGHT': 'bold'"));
- assertEquals("red", $("p", e).css("color", false));
- assertEquals("", $("p", e).css("background"));
- }
-
- public void testCapitalLetters() {
- $(e).html("<div id='testImageDisplay' class='whatEver'>Content</div>");
- assertEquals(1, $("#testImageDisplay").size());
- // Commented because IE is case insensitive
- // assertEquals(0, $("#testimagedisplay").size());
- assertEquals(1, $(".whatEver").size());
- assertEquals(0, $(".whatever").size());
- }
-
- public void testCleanMethod() {
- $(e).html("").append($("<tr/>"));
- assertHtmlEquals("<tr></tr>", $(e).html());
-
- $(e).html("").append($("<td/>"));
- assertHtmlEquals("<td></td>", $(e).html());
-
- $(e).html("").append($("<th/>"));
- assertHtmlEquals("<th></th>", $(e).html());
- }
-
- public void testDomManip() {
- String content = "<span class='branchA'><span class='target'>branchA target</span></span>"
- + "<span class='branchB'><span class='target'>branchB target</span></span>";
-
- $(e).html("");
- $(e).append(content);
- assertEquals(4, $("span", e).size());
- assertEquals(2, $("span.target", e).size());
- assertHtmlEquals(content, $(e).html());
-
- $(e).html("<span>a</span><span>b</span>");
- $("span").append("<div>c</div>");
- assertHtmlEquals("<span>a<div>c</div></span><span>b<div>c</div></span>", $(
- e).html());
- }
-
- public void testEach() {
- $(e).html("<p>Content 1</p><p>Content 2</p><p>Content 3</p>");
- $("p", e).each(new Function() {
- public void f(Element e) {
- $(e).text(".");
- }
- });
- assertHtmlEquals("<p>.</p><p>.</p><p>.</p>", $("p", e));
- $("p", e).each(new Function() {
- public String f(Element e, int i) {
- $(e).text("" + i);
- return "";
- }
- });
- assertHtmlEquals("<p>0</p><p>1</p><p>2</p>", $("p", e));
- }
-
- public void testIFrameManipulation() {
- $(e).html("<iframe name='miframe' id='miframe' src=\"javascript:''\">");
- // FF has to call empty to open and close the document before
- // accessing the recently created iframe content
- Document d = $("#miframe").contents().empty().get(0).cast();
- assertNotNull(d);
- assertNotNull(d.getBody());
- assertEquals(1, $("#miframe").contents().size());
- assertEquals(1, $("#miframe").contents().find("body").size());
- assertEquals(0, $("#miframe").contents().find("body > h1").size());
- $("#miframe").contents().find("body").append("<h1>Test</h1>");
- assertEquals(1, $("#miframe").contents().find("body > h1").size());
- assertEquals(1, $(d).find("h1").size());
- }
-
- public void testInnerMethods() {
- String txt = "<p>I would like to say: </p>";
-
- // Check that setHTML and getHTML work as GQuery html()
- testPanel.setHTML(txt);
- assertHtmlEquals(txt, testPanel.getHTML());
- assertHtmlEquals(txt, $(e).html());
- assertHtmlEquals(txt, $("#core-tst").html());
- $(e).html("");
- assertHtmlEquals("", $(e).html());
- $(e).html(txt);
- assertHtmlEquals(txt, $(e).html());
-
- // toString()
- assertHtmlEquals(txt, $("p", e));
-
- // remove()
- $("p", e).remove();
- assertHtmlEquals("", $(e).html());
-
- // text()
- String expected = "I would like to say: I would like to say:";
- $(e).html(txt + txt);
- assertHtmlEquals(expected, $("p", e).text());
-
- // empty()
- expected = "<p></p><p></p>";
- $("p", e).empty();
- assertHtmlEquals(expected, $(e).html());
- }
-
- public void testInputValueMethods() {
- // imput text
- $(e).html("<input type='text'/>");
- GQuery gq = $("input", e);
- assertEquals("", gq.val());
- gq.val("some value");
- assertEquals("some value", gq.val());
-
- // select
- $(e).html(
- "<select name='n'><option value='v1'>1</option><option value='v2' selected='selected'>2</option></select>");
- gq = $("select", e);
- assertEquals("v2", gq.val());
- gq.val("v1");
- assertEquals("v1", gq.val());
-
- // select multiple
- $(e).html(
- "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2'>2</option><option value='v3'>3</option></select>");
- gq = $("select", e);
- assertNull(gq.vals());
- assertNull(gq.val());
-
- $(e).html(
- "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2' selected='selected'>2</option><option value='v3'>3</option></select>");
- gq = $("select", e);
- assertEquals(1, gq.vals().length);
- assertEquals("v2", gq.val());
- gq.val("v1", "v3", "invalid");
- assertEquals(2, gq.vals().length);
- assertEquals("v1", gq.vals()[0]);
- assertEquals("v3", gq.vals()[1]);
- // FIXME: fix in IE
- // gq.val("v1");
- // assertEquals(1, gq.vals().length);
- // assertEquals("v1", gq.val());
-
- // input radio
- $(e).html(
- "<input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input>");
- gq = $("input", e);
- assertEquals("v1", gq.val());
- assertEquals("v2", $("input:checked", e).val());
- gq.val(new String[]{"v1"});
- assertEquals("v1", $("input:checked", e).val());
- gq.val(new String[]{"v2"});
- assertEquals("v2", $("input:checked", e).val());
-
- // input checkbox
- $(e).html(
- "<input type='checkbox' name='n1' value='v1'>1</input><input type='checkbox' name='n2' value='v2' checked='checked'>2</input>");
- gq = $("input", e);
- assertEquals("v1", gq.val());
- assertEquals("v2", $("input:checked", e).val());
- gq.val(new String[]{"v1"});
- assertEquals("v1", $("input:checked", e).val());
- }
-
- public void testIssue23() {
- $(e).html(
- "<table><tr><td><input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input></td><td><button>Click</button></tr><td></table>");
- $("button").click(new Function() {
- public boolean f(Event ev) {
- done = 0;
- $("table > tbody > tr > td > input:checked", e).each(new Function() {
- public void f(Element e) {
- done++;
- }
- });
- assertEquals(1, done);
- return true;
- }
- });
- $("button").click();
- }
-
- public void testModifyMethods() {
- String pTxt = "<p>I would like to say: </p>";
- String bTxt = "<b>Hello</b>";
-
- // append()
- String expected = "<p>I would like to say: <b>Hello</b></p>";
- $(e).html(pTxt);
- $("p", e).append(bTxt);
- assertHtmlEquals(expected, $(e).html());
-
- $(e).html(pTxt);
- $("p", e).append($(bTxt).get(0));
- assertHtmlEquals(expected, $(e).html());
-
- // appendTo()
- expected = "<p>I would like to say: <b>Hello</b></p>";
- $(e).html(bTxt + pTxt);
- GQuery g = $("b", e).appendTo($("p", e));
- assertHtmlEquals(expected, $(e).html());
- assertHtmlEquals("<b>Hello</b>", g.toString());
- // document is a valid node, actually it is substituted by body
- g.appendTo(document);
- expected = "<p>I would like to say: </p>";
- assertHtmlEquals(expected, $(e).html());
- g.remove();
- // Check that the new elements are returned and can be modified
- $("<div id='mid'>Hello</div>").appendTo(e).css("color", "white");
- assertEquals("white", $("#mid").css("color"));
-
- // prepend()
- expected = "<p><b>Hello</b>I would like to say: </p>";
- $(e).html(pTxt);
- $("p", e).prepend(bTxt);
- assertHtmlEquals(expected, $(e).html());
-
- // prependTo()
- expected = "<p><b>Hello</b>I would like to say: </p>";
- $(e).html(bTxt + pTxt);
- $("b", e).prependTo($("p", e));
- assertHtmlEquals(expected, $(e).html());
- // Check that the new elements are returned and can be modified
- $("<div id='mid'>Hello</div>").prependTo(e).css("color", "yellow");
- assertEquals("yellow", $("#mid").css("color"));
-
- // prependTo()
- expected = "<b>Hello</b><p><b>Hello</b>I would like to say: </p>";
- $(e).html(bTxt + pTxt);
- $("b", e).clone().prependTo($("p", e));
- assertHtmlEquals(expected, $(e).html());
-
- // before()
- expected = "<b>Hello</b><p>I would like to say: </p>";
- $(e).html(pTxt);
- $("p", e).before(bTxt);
- assertHtmlEquals(expected, $(e).html());
-
- // before()
- expected = "<b>Hello</b><p>I would like to say: </p>";
- $(e).html(pTxt + bTxt);
- $("p", e).before($("b", e));
- assertHtmlEquals(expected, $(e).html());
-
- // before()
- expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
- $(e).html(pTxt + bTxt);
- $("p", e).before($("b", e).clone());
- assertHtmlEquals(expected, $(e).html());
-
- // insertBefore()
- expected = "<b>Hello</b><p>I would like to say: </p>";
- $(e).html(pTxt + bTxt);
- $("b", e).insertBefore($("p", e));
- assertHtmlEquals(expected, $(e).html());
-
- // insertBefore()
- expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
- $(e).html(pTxt + bTxt);
- $("b", e).clone().insertBefore($("p", e));
- assertHtmlEquals(expected, $(e).html());
-
- // after()
- expected = "<p>I would like to say: </p><b>Hello</b>";
- $(e).html(pTxt);
- $("p", e).after(bTxt);
- assertHtmlEquals(expected, testPanel.getHTML());
-
- // after()
- expected = "<p>I would like to say: </p><b>Hello</b>";
- $(e).html(bTxt + pTxt);
- $("p", e).after($("b", e));
- assertHtmlEquals(expected, $(e).html());
-
- // after()
- expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
- $(e).html(bTxt + pTxt);
- $("p", e).after($("b", e).clone().get(0));
- assertHtmlEquals(expected, $(e).html());
-
- // The set of elements should be the same after the manipulation
- String content = "<span>s</span>";
- expected = "<p>p</p>";
- GQuery g1 = $(content);
- GQuery g2 = $(expected);
- $(e).html("").append(g1);
- assertEquals(1, g1.size());
- assertEquals(content, g1.toString());
-
- $(g1).append(g2);
- assertEquals(1, g1.size());
- assertEquals(1, g2.size());
- assertEquals(expected, g2.toString());
-
- $(g1).prepend(g2);
- assertEquals(1, g1.size());
- assertEquals(1, g2.size());
- assertEquals(expected, g2.toString());
-
- $(g1).after(g2);
- assertEquals(1, g1.size());
- assertEquals(1, g2.size());
- assertEquals(expected, g2.toString());
-
- $(g1).before(g2);
- assertEquals(1, g1.size());
- assertEquals(1, g2.size());
- assertEquals(expected, g2.toString());
- }
-
- public void testAppendTo() {
- String txt = "<h2>Greetings</h2><div class='container'><div class='inner'>Hello</div><div class='inner'>Goodbye</div></div>";
- String expected = "<h2>Greetings</h2><div class='container'><div class='inner'>Hello<p>Test</p></div><div class='inner'>Goodbye<p>Test</p></div></div>";
- $(e).html(txt);
- $("<p>Test</p>").appendTo(".inner");
- assertHtmlEquals(expected, $(e).html());
-
- expected = "<div class='container'><div class='inner'>Hello</div><div class='inner'>Goodbye</div><h2>Greetings</h2></div>";
- $(e).html(txt);
- $("h2", e).appendTo($(".container"));
- assertHtmlEquals(expected, $(e).html());
-
- expected = "<div class='container'><div class='inner'>Hello<h2>Greetings</h2></div><div class='inner'>Goodbye<h2>Greetings</h2></div><h2>Greetings</h2></div><h2>Greetings</h2>";
- $(e).html(txt);
- $("h2", e).appendTo($("div"));
- assertHtmlEquals(expected, $(e).html());
- }
-
- public void testOpacity() {
- $(e).html(
- "<p id='id1' style='opacity: 0.6; filter: alpha(opacity=60)'>Content 1</p>");
- GQuery g = $("#id1");
- assertEquals("0.6", g.css("opacity", false));
- assertEquals("0.6", g.css("opacity", true));
- g.css("opacity", "");
- assertEquals("", g.css("opacity", false));
- assertEquals("1.0", g.css("opacity", true));
- g.css("opacity", "0.4");
- assertEquals("0.4", g.css("opacity", false));
- assertEquals("0.4", g.css("opacity", true));
- }
-
- public void testPosition() {
- $(e).html(
- "<div style='top:25px; left:25px; padding:20px; position:relative;'><div id='child' style='margin:30px'>test</div></div> ");
- GQuery g = $("#child");
- assertEquals(20, g.position().left);
- assertEquals(20, g.position().top);
-
- $(e).html(
- "<div style='top:25px; left:25px; position:relative;'><div id='child' style='position:relative; top:15px; left:35px;'>test</div></div> ");
- g = $("#child");
- assertEquals(35, g.position().left);
- assertEquals(15, g.position().top);
-
- }
-
- public void testPropMethod(){
- $(e).html("<input id=\"checkBox1\" type=\"checkbox\" checked=\"checked\" /> <input id=\"checkBox2\" type=\"checkbox\" />");
-
- assertTrue($("#checkBox1",e).prop("checked"));
- assertFalse($("#checkBox2",e).prop("checked"));
-
- $("#checkBox1",e).prop("checked", false);
- $("#checkBox2",e).prop("checked", new Function() {
- @Override
- public Object f(Element e, int i) {
- return Boolean.TRUE;
- }
- });
-
- assertTrue($("#checkBox2",e).prop("checked"));
- assertFalse($("#checkBox1",e).prop("checked"));
-
- }
-
- public void testProperties() {
- Properties p = $$("border:'1px solid black'");
- assertEquals(1, p.keys().length);
- assertNotNull(p.getStr("border"));
-
- p = $$("({border:'1px solid black'})");
- assertEquals(1, p.keys().length);
- assertNotNull(p.getStr("border"));
- }
-
- public void testRelativeMethods() {
- String content = "<p><span>Hello</span>, how are you?</p>";
- String expected = "<span>Hello</span>";
-
- // find()
- $(e).html(content);
- assertHtmlEquals(expected, $("p", e).find("span"));
-
- // filter()
- content = "<p>First</p><p class=\"selected\">Hello</p><p>How are you?</p>";
- $(e).html(content);
- expected = "<p class=\"selected\">Hello</p>";
- assertHtmlEquals(expected, $("p", e).filter(".selected"));
-
- // not()
- expected = "<p>First</p><p>How are you?</p>";
- assertEquals(2, $("p", e).not(".selected").size());
- assertHtmlEquals(expected, $("p", e).not(".selected"));
- assertEquals(2, $("p", e).not($(".selected")).size());
- assertHtmlEquals(expected, $("p", e).not($(".selected")));
- assertEquals(2, $("p", e).not($(".selected").get(0)).size());
- assertHtmlEquals(expected, $("p", e).not($(".selected").get(0)));
-
- // add()
- String added = "<p>Last</p>";
- expected = content + added;
- assertEquals(4, $("p", e).add(added).size());
- assertHtmlEquals(expected, $("p", e).add(added));
-
- // parent()
- expected = content = "<div><p>Hello</p><p>Hello</p></div>";
- $(e).html(content);
- assertHtmlEquals(expected, $("p", e).parent());
-
- // parent()
- content = "<div><p>Hello</p></div><div class=\"selected\"><p>Hello Again</p></div>";
- expected = "<div class=\"selected\"><p>Hello Again</p></div>";
- $(e).html(content);
- assertHtmlEquals(expected, $("p", e).parent(".selected"));
-
- // parents()
- content = "<div><p><span>Hello</span></p><span>Hello Again</span></div>";
- $(e).html(content);
- assertEquals(2, $("span", e).size());
- assertTrue(3 < $("span", e).parents().size());
- assertEquals(1, $("span", e).parents().filter("body").size());
- $("span", e).parents().filter("body").toString().trim().toLowerCase().contains(
- content.toLowerCase());
-
- //parentsUntil()
- content = "<div id='mainDiv'><div id='subDiv1' class='subDiv'><div id='subSubDiv1'><p id='p1'>child1</p></div></div><div id='subDiv2' class='subDiv'><div id='subSubDiv2'><p id='p2'>child2</p></div></div></div>";
- $(e).html(content);
- $("p",e).parentsUntil("#mainDiv").css(CSS.COLOR.with(RGBColor.RED));
- assertEquals("red", $("#subDiv1", e).css(CSS.COLOR, false));
- assertEquals("red", $("#subSubDiv1", e).css(CSS.COLOR, false));
- assertEquals("red", $("#subDiv2", e).css(CSS.COLOR, false));
- assertEquals("red", $("#subSubDiv2", e).css(CSS.COLOR, false));
- assertEquals("", $("#mainDiv", e).css(CSS.COLOR, false));
- assertEquals("", $("#p1", e).css(CSS.COLOR, false));
- assertEquals("", $("#p2", e).css(CSS.COLOR, false));
-
- $("#p1",e).parentsUntil(".subDiv").css(CSS.COLOR.with(RGBColor.YELLOW));
- assertEquals("red", $("#subDiv1", e).css(CSS.COLOR));
- assertEquals("yellow", $("#subSubDiv1", e).css(CSS.COLOR));
-
- // is()
- content = "<form><input type=\"checkbox\"></form>";
- $(e).html(content);
- assertEquals(true, $("input[type=\"checkbox\"]", e).parent().is("form"));
-
- // is()
- content = "<form><p><input type=\"checkbox\"></p></form>";
- $(e).html(content);
- assertEquals(false, $("input[type='checkbox']", e).parent().is("form"));
-
- // next()
- content = "<p>Hello</p><p>Hello Again</p><div><span>And Again</span></div>";
- String next1 = "<p>Hello Again</p>";
- String next2 = "<div><span>And Again</span></div>";
- $(e).html(content);
- assertEquals(2, $("p", e).next().size());
- assertHtmlEquals(next1, $("p", e).next().get(0).getString());
- assertHtmlEquals(next2, $("p", e).next().get(1).getString());
-
- // next()
- content = "<p>Hello</p><p class=\"selected\">Hello Again</p><div><span>And Again</span></div>";
- expected = "<p class=\"selected\">Hello Again</p>";
- $(e).html(content);
- assertEquals(1, $("p", e).next(".selected").size());
- assertHtmlEquals(expected, $("p", e).next(".selected").get(0).getString());
-
- // nextAll()
- content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li>i5</li></ul>";
- expected = "<li>i4</li><li>i5</li>";
- $(e).html(content);
- assertEquals(2, $("li.third-item", e).nextAll().size());
- assertHtmlEquals(expected, $("li.third-item", e).nextAll());
-
- // nextUntil()
- content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
- expected = "<li>i4</li>";
- $(e).html(content);
- assertEquals(1, $("li.third-item", e).nextUntil(".five-item").size());
- assertHtmlEquals(expected, $("li.third-item", e).nextUntil(".five-item"));
-
-
- // andSelf()
- content = "<ul><li>i1</li><li>i2</li><li class=\"third-item\">i3</li><li>i4</li><li>i5</li></ul>";
- expected = "<li>i4</li><li>i5</li><li class=\"third-item\">i3</li>";
- $(e).html(content);
- assertEquals(3, $("li.third-item", e).nextAll().andSelf().size());
- assertHtmlEquals(expected, $("li.third-item", e).nextAll().andSelf());
-
- // prev()
- content = "<p>Hello</p><div><span>Hello Again</span></div><p>And Again</p>";
- expected = "<div><span>Hello Again</span></div>";
- $(e).html(content);
- assertEquals(1, $("p", e).prev().size());
- assertHtmlEquals(expected, $("p", e).prev().get(0).getString());
-
- // prev()
- content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
- expected = "<p class=\"selected\">Hello Again</p>";
- $(e).html(content);
- assertEquals(2, $("p", e).prev().size());
- assertEquals(1, $("p", e).prev(".selected").size());
- assertHtmlEquals(expected, $("p", e).prev(".selected").get(0).getString());
-
- // prevAll()
- content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
- expected = "<li>i4</li><li class='third-item'>i3</li><li>i2</li><li>i1</li>";
- $(e).html(content);
- assertEquals(4, $("li.five-item", e).prevAll().size());
- assertHtmlEquals(expected, $("li.five-item", e).prevAll());
-
-
- // prevUntil()
- content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
- expected = "<li>i4</li>";
- $(e).html(content);
- assertEquals(1, $("li.five-item", e).prevUntil(".third-item").size());
- assertHtmlEquals(expected, $("li.five-item", e).prevUntil(".third-item"));
-
- // siblings()
- content = "<p>Hello</p><div id='mdiv'><span>Hello Again</span></div><p>And Again</p>";
- next1 = "<p>Hello</p>";
- next2 = "<p>And Again</p>";
- $(e).html(content);
- assertEquals(2, $("#mdiv", e).siblings().size());
- assertHtmlEquals(next1, $("#mdiv", e).siblings().get(0).getString());
- assertHtmlEquals(next2, $("#mdiv", e).siblings().get(1).getString());
-
- // siblings()
- content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
- expected = "<p class=\"selected\">Hello Again</p>";
- $(e).html(content);
- assertEquals(1, $("p", e).siblings(".selected").size());
- assertHtmlEquals(expected,
- $("p", e).siblings(".selected").get(0).getString());
-
- // children()
- content = "<p>Hello</p><div id='mdiv'><span>Hello Again</span></div><p>And Again</p>";
- expected = "<span>Hello Again</span>";
- $(e).html(content);
- assertHtmlEquals(expected, $("#mdiv", e).children());
-
- // children()
- content = "<div id='mdiv'><span>Hello</span><p class=\"selected\">Hello Again</p><p>And Again</p></div>";
- expected = "<p class=\"selected\">Hello Again</p>";
- $(e).html(content);
- assertHtmlEquals(expected, $("#mdiv", e).children(".selected"));
-
- // contains()
- content = "<p>This is just a test.</p><p>So is this</p>";
- expected = "<p>This is just a test.</p>";
- $(e).html(content);
- assertHtmlEquals(expected, $("p", e).contains("test"));
- }
-
- public void testReplaceMethods() {
- String content = "<div><div class='inner first'>Hello</div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
-
- $(e).html(content);
- GQuery $inner = $(".inner").replaceWith("<h3>blop</h3>");
- String expectedHtml = "<div><h3>blop</h3><h3>blop</h3><h3>blop</h3></div>";
- assertEquals(expectedHtml, $(e).html());
-
- // the returned gquery object should be the original with the div elements
- assertEquals(3, $inner.filter("div.inner").length());
-
- $(e).html(content);
- // the css part below allows us to check if the objects returned by the
- // replaceAll method are the new inserted elements
- $("<h3>blop</h3>").replaceAll($(".inner")).css(CSS.COLOR.with(RGBColor.RED));
- // $(e) must content 3 h3
- assertEquals(3, $("h3", e).length());
- // the objects returned by the replaceAll method should be the 3 inserted h3
- assertEquals("red", $("h3", e).css(CSS.COLOR));
-
-
- $(e).html(content);
- $(".third").replaceWith($(".first"));
- expectedHtml = "<div><div class=\"inner second\">And</div><div class=\"inner first\">Hello</div></div>";
- assertEquals($(e).html(), expectedHtml);
-
- $(e).html(content);
- $(".first").replaceAll(".third");
- assertEquals($(e).html(), expectedHtml);
-
- }
-
- public void testShowHide() {
- $(e).html(
- "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
-
- final GQuery sectA = $("#id1");
- final GQuery sectB = $("#id2");
- final GQuery sectC = $("#id3");
-
- // hide()
- sectA.hide();
- assertEquals("none", sectA.css("display", false));
- sectB.hide();
- assertEquals("none", sectB.css("display", false));
-
- // show()
- sectA.show();
- assertEquals("inline", sectA.css("display", false));
- sectB.show();
- assertEquals("", sectB.css("display", false));
-
- // toggle()
- assertEquals("", sectC.css("display", false));
- sectC.toggle();
- assertEquals("none", sectC.css("display", false));
- sectC.toggle();
- assertEquals("block", sectC.css("display", false));
- }
-
- public void testSliceMethods() {
- String content = "<p>This is just a test.</p><p>So is this</p>";
- $(e).html(content);
-
- String expected = "<p>So is this</p>";
- assertEquals(1, $("p", e).eq(1).size());
- assertHtmlEquals(expected, $("p", e).eq(1));
-
- expected = "<p>This is just a test.</p>";
- assertEquals(1, $("p", e).lt(1).size());
- assertHtmlEquals(expected, $("p", e).lt(1));
-
- expected = "<p>So is this</p>";
- assertEquals(1, $("p", e).gt(0).size());
- assertHtmlEquals(expected, $("p", e).gt(0));
-
- assertEquals(2, $("p", e).slice(0, 2).size());
- assertEquals(2, $("p", e).slice(0, -1).size());
- assertEquals(0, $("p", e).slice(3, 2).size());
- }
-
- public void testGetEqLastFirstMethods(){
- String content = "<div id='1'>blop1</div><div id='2'>blop2</div><div id='3'>blop3</div><div id='4'>blop4</div>";
- $(e).html(content);
-
- GQuery divs =$("div",e);
- assertEquals(4, divs.size());
- assertEquals("1", divs.get(0).getId());
- assertEquals("2", divs.get(1).getId());
- assertEquals("3", divs.get(2).getId());
- assertEquals("4", divs.get(3).getId());
- assertEquals("1", divs.get(-4).getId());
- assertEquals("2", divs.get(-3).getId());
- assertEquals("3", divs.get(-2).getId());
- assertEquals("4", divs.get(-1).getId());
-
- assertEquals(1, divs.first().size());
- assertEquals("1", divs.first().get(0).getId());
-
- assertEquals(1, divs.last().size());
- assertEquals("4", divs.last().get(0).getId());
-
- assertEquals(1, divs.eq(0).size());
- assertEquals("1", divs.eq(0).get(0).getId());
- assertEquals(1, divs.eq(1).size());
- assertEquals("2", divs.eq(1).get(0).getId());
- assertEquals(1, divs.eq(2).size());
- assertEquals("3", divs.eq(2).get(0).getId());
- assertEquals(1, divs.eq(3).size());
- assertEquals("4", divs.eq(3).get(0).getId());
-
- assertEquals(1, divs.eq(-4).size());
- assertEquals("1", divs.eq(-4).get(0).getId());
- assertEquals(1, divs.eq(-3).size());
- assertEquals("2", divs.eq(-3).get(0).getId());
- assertEquals(1, divs.eq(-2).size());
- assertEquals("3", divs.eq(-2).get(0).getId());
- assertEquals(1, divs.eq(-1).size());
- assertEquals("4", divs.eq(-1).get(0).getId());
-
-
- }
-
- public void testUnique() {
- SelectorEngineImpl selSizz = new SelectorEngineSizzle();
- GQuery g = $(e).html("<div><p></p><p></p><span></span><p></p>");
- JsNodeArray a;
- a = selSizz.select("p", e).cast();
- assertEquals(3, a.getLength());
- a.addNode(a.getNode(0));
- a.addNode(a.getNode(3));
- assertEquals(5, a.getLength());
- a = g.unique(a);
- assertEquals(3, a.getLength());
- }
-
- public void testUtilsEq() {
- assertTrue(JsUtils.eq("a", "a"));
- assertTrue(JsUtils.eq(true, true));
- assertTrue(JsUtils.eq(45, 45));
- assertTrue(JsUtils.eq(45d, 45f));
- assertTrue(JsUtils.eq("", ""));
- assertTrue(JsUtils.eq(0.45, 0.45));
- assertTrue(JsUtils.eq(0.45d, 0.45d));
- assertTrue(JsUtils.eq(0.45f, 0.45f));
-
- assertFalse(JsUtils.eq("a", ""));
- assertFalse(JsUtils.eq(true, false));
- assertFalse(JsUtils.eq(45, 42));
- assertFalse(JsUtils.eq("", null));
- assertFalse(JsUtils.eq(0.45, 0.451));
-
- // assertEquals("a", GQUtils.or("a", ""));
- }
-
- public void testUtilsTruth() {
- assertTrue(JsUtils.truth("a"));
- assertTrue(JsUtils.truth(this));
- assertTrue(JsUtils.truth(45));
- assertTrue(JsUtils.truth(0.33));
- assertTrue(JsUtils.truth(45l));
- assertTrue(JsUtils.truth(45d));
- assertTrue(JsUtils.truth(45f));
- assertTrue(JsUtils.truth(0.33f));
-
- assertFalse(JsUtils.truth(0));
- assertFalse(JsUtils.truth(0l));
- assertFalse(JsUtils.truth(0d));
- assertFalse(JsUtils.truth(00.00d));
- assertFalse(JsUtils.truth(00.00f));
- assertFalse(JsUtils.truth(null));
- assertFalse(JsUtils.truth(""));
- }
-
- public void testVal_issue98() {
- $(e).html(""
- +"<input type='text' id='inputText' name='inputText' value='original' />"
- +"<textarea id='textArea' name='textArea'>original</textarea>"
- +"<button id='button' name='button'value='original'>Click</button>"
-
- +"<select id='selectSingle' name='selectSingle'>"
- +"<option value='v0'>Single0</option>"
- +"<option value='v1'>Single1</option>"
- +"<option value='v2'>Single2</option>"
- +"</select>"
-
- +"<select id='selectMultiple' name='selectMultiple' multiple='multiple'>"
- +"<option value='v0'>Multiple0</option>"
- +"<option value='v1'>Multiple1</option>"
- +"<option value='v2'>Multiple2</option>"
- +"</select><br/>"
-
- +"<input type='checkbox' name='c' value='v0'/> check0"
- +"<input type='checkbox' name='c' value='v1'/> check1"
- +"<input type='checkbox' name='c' value='v2'/> check2"
-
- +"<input type='radio' name='r' value='v0'/> radio0"
- +"<input type='radio' name='r' value='v1'/> radio1"
- +"<input type='radio' name='r' value='v2'/> radio2"
- );
-
- assertNull($().val());
- assertEquals(0, $().vals().length);
-
- assertEquals("original", $("#inputText", e).val());
- assertEquals("original", $("#textArea", e).val());
- assertEquals("original", $("#button", e).val());
- $("#inputText, #textArea, #button", e).val("newval");
- assertEquals("newval", $("#inputText", e).val());
- assertEquals("newval", $("#textArea", e).val());
- assertEquals("newval", $("#button", e).val());
-
- assertEquals("v0", $("#selectSingle", e).val());
- assertNull($("#selectMultiple", e).val());
- $("#selectSingle, #selectMultiple", e).val("v2");
- assertEquals("v2", $("#selectSingle", e).val());
- assertEquals("v2", $("#selectMultiple", e).val());
-
- assertEquals("v0", $("input[type='checkbox']", e).val());
- assertNull($("input[type='checkbox']:checked", e).val());
- // val(String) changes the value attribute, but not set it as checked
- $("input[type='checkbox']", e).eq(0).val("n0");
- assertEquals("n0", $("input[type='checkbox']", e).val());
- assertNull($("input[type='checkbox']:checked", e).val());
- // val(array) set the checked property to true if the value name matches
- $("input[type='checkbox']", e).val(new String[]{"n0"});
- assertEquals("n0", $("input[type='checkbox']", e).val());
- assertNotNull($("input[type='checkbox']:checked", e).val());
-
- assertEquals("v0", $("input[type='radio']", e).val());
- assertNull($("input[type='radio']:checked", e).val());
- $("input[type='radio']").eq(0).val("n0");
- assertEquals("n0", $("input[type='radio']", e).val());
- assertNull($("input[type='radio']:checked", e).val());
-
-// evalJQuery("$('input, select, textarea, button').val(['whatever', 'v1', 'v2'])");
- $("input, select, textarea, button").val("whatever", "v1", "v2");
-
- String joinVals = "whatever,v1,v2";
- assertEquals(joinVals, $("#inputText", e).val());
- assertEquals(joinVals, $("#textArea", e).val());
- assertEquals(joinVals, $("#button", e).val());
- assertEquals("v2", $("#selectSingle", e).val());
- assertEquals("v1", $("#selectMultiple", e).vals()[0]);
- assertEquals("v2", $("#selectMultiple", e).vals()[1]);
- assertEquals(2, $("input[type='checkbox']:checked", e).size());
- assertEquals("v1", $("input[type='checkbox']:checked", e).eq(0).val());
- assertEquals("v2", $("input[type='checkbox']:checked", e).eq(1).val());
- assertEquals(1, $("input[type='radio']:checked", e).size());
- assertEquals("v2", $("input[type='radio']:checked", e).val());
- }
-
-
- public void testAttr_Issue97() {
- $(e).html("<input type='checkbox' id='cb' name='cb' value='1' />");
- assertNull($("#cb:checked", e).val());
-
- $("#cb", e).attr("checked", "checked");
- assertEquals(1, $("#cb:checked", e).length());
- assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
- assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
- assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
-
- $("#cb", e).removeAttr("checked");
- assertEquals(0, $("#cb:checked", e).length());
- assertEquals(false, InputElement.as($("#cb", e).get(0)).isChecked());
- assertEquals("", $("#cb", e).get(0).getAttribute("checked"));
- assertEquals(false, $("#cb", e).get(0).getPropertyBoolean("checked"));
-
- $("#cb", e).attr("checked", true);
- assertEquals(1, $("#cb:checked", e).length());
- assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
- assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
- assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
-
- $("#cb", e).attr("checked", false);
- assertEquals(0, $("#cb:checked", e).length());
- assertEquals(false, InputElement.as($("#cb", e).get(0)).isChecked());
- assertEquals("", $("#cb", e).get(0).getAttribute("checked"));
- assertEquals(false, $("#cb", e).get(0).getPropertyBoolean("checked"));
-
- $("#cb", e).attr("checked", "");
- assertEquals(1, $("#cb:checked", e).length());
- assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
- assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
- assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
-
- GQuery gq = $("<div></div>test<!-- a comment-->");
- gq.attr("class", "test1");
-
- assertEquals("test1", gq.get(0).getClassName());
- assertEquals("test1", gq.attr("class"));
- assertNull(gq.get(0).getPropertyString("class"));
-
- gq.removeAttr("class");
- assertEquals("", gq.get(0).getClassName());
- assertEquals("", gq.attr("class"));
-
- //test on value
- $("#cb", e).attr("value", "mail");
- assertEquals("mail", InputElement.as($("#cb", e).get(0)).getValue());
- assertEquals("mail", $("#cb", e).get(0).getAttribute("value"));
-
- $("#cb", e).removeAttr("value");
- assertEquals("", InputElement.as($("#cb", e).get(0)).getValue());
- assertEquals("", $("#cb", e).get(0).getAttribute("value"));
-
- try{
- $("#cb", e).attr("type", "hidden");
- fail("Cannnot change a type of an element already attached to the dom");
- }catch (Exception e){}
-
- gq = $("<input type='text' value='blop'></input>");
- gq.attr("type", "radio");
- assertEquals("radio", InputElement.as(gq.get(0)).getType());
- assertEquals("blop", InputElement.as(gq.get(0)).getValue());
-
-
-
- gq.attr(Properties.create("{class:'test2', disabled:true}"));
- InputElement ie = InputElement.as(gq.get(0));
-
- assertEquals("test2", ie.getClassName());
- assertEquals(true, ie.isDisabled());
- assertEquals("disabled", ie.getAttribute("disabled"));
-
- }
-
- public void testWidthHeight() {
- $(e).html(
- "<div style='border: 1px solid red; padding: 10px; margin:10px; width: 100px; height: 100px'>Content 1</div>");
- GQuery g = $("div", e);
- assertEquals(100, g.width());
- assertEquals(100, g.height());
- assertEquals(120, g.innerWidth());
- assertEquals(120, g.innerHeight());
- assertEquals(100d, g.cur("width", false));
- assertEquals(100d, g.cur("height", false));
- assertEquals(100d, g.cur("width", true));
- assertEquals(100d, g.cur("height", true));
- assertEquals("100px", g.css("width"));
- assertEquals("100px", g.css("height"));
- assertEquals("100px", g.get(0).getStyle().getProperty("width"));
- assertEquals("100px", g.get(0).getStyle().getProperty("height"));
- assertEquals(122, g.outerHeight());
- assertEquals(122, g.outerWidth());
- assertEquals(142, g.outerHeight(true));
- assertEquals(142, g.outerWidth(true));
-
- }
-
- public void testWrapMethod() {
- String content = "<p>Test Paragraph.</p>";
- String wrapper = "<div id=\"content\">Content</div>";
-
- String expected = "<div id=\"content\">Content<p>Test Paragraph.</p></div>";
- $(e).html(content);
-
- $("p", e).wrap(wrapper);
- assertHtmlEquals(expected, $(e).html());
-
- $(e).html(content + wrapper);
- expected = "<b><p>Test Paragraph.</p></b><b><div id=\"content\">Content</div></b>";
- $("*", e).wrap("<b></b>");
- assertHtmlEquals(expected, $(e).html());
- }
-
-
- public void testFilterBody() {
- GQuery myNewElement = $("<div>my new div</div>");
- boolean isAttachedToTheDOM = myNewElement.parents().filter("body").size() > 0;
- assertEquals(false, isAttachedToTheDOM);
-
- myNewElement.appendTo(document);
- isAttachedToTheDOM = myNewElement.parents().filter("body").size() > 0;
- assertEquals(true, isAttachedToTheDOM);
- }
-
- public void testFilterMethod(){
- // first test filter on element attached to the DOM
- String content = "<div class='outer'><div class='inner first'>Hello <span>blop</span></div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
-
- $(e).html(content);
-
- assertEquals(5, $("*", e).length());
- assertEquals(4, $("*", e).filter("div").length());
- assertEquals(1, $("*", e).filter("div.outer").length());
- assertEquals(3, $("*", e).filter("div.inner").length());
- assertEquals(1, $("*", e).filter("span").length());
-
- GQuery $html = $("<div>div1</div><div>div2</div><div>div3</div><span>span1</span>");
- assertEquals(3, $html.filter("div").length());
- assertEquals(1, $html.filter("span").length());
-
- JsNodeArray array = JsNodeArray.create();
- for (int i = 0 ; i < 3; i++){
- array.addNode(DOM.createDiv());
- }
- assertEquals(3, $(array).filter("div").length());
-
-
- String content2 = "<div><div class='inner first'>Hello</div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
- $(e).html(content2);
- //the inner object contains the 3 div that are detached from the dom
- GQuery $inner = $(".inner").replaceWith("<h3>blop</h3>");
- assertEquals(3, $inner.filter("div").length());
- }
-
- public void testGQueryWidgets() {
- final Button b1 = new Button("click-me");
- RootPanel.get().add(b1);
-
- GQuery g = $(b1);
- Button b2 = g.widget();
- assertEquals(b1, b2);
-
- b2 = new Button("click-me");
- RootPanel.get().add(b2);
- b2.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- $(b1).css("color", "red");
- }
- });
-
- (b2).click();
- assertEquals("red", $(b1).css("color"));
-
- $("<button>Click-me</button>").appendTo(document);
- assertEquals(3, $("button").size());
- assertEquals(2, $("button").widgets(Button.class).size());
- assertEquals(2, $($("button").widgets(Button.class)).size());
-
- assertEquals(2, $(new Label(""), new TextArea()).size());
- }
-
- public void testGQueryWidgetManipulation() {
-
- String content = "<div class='outer'></div>";
- $(e).html(content);
- Button b = new Button("b");
- RootPanel.get().add(b);
- assertTrue(b.isAttached());
- $("button").remove();
- assertFalse(b.isAttached());
-
- RootPanel.get().add(b);
- assertTrue(b.isAttached());
- $(e).append($(b));
- assertTrue(b.isAttached());
- $(e).empty();
- // FIXME: assertFalse(b.isAttached());
-
- }
-
- public void testGQueryMap() {
- String content = "<p id='1'/><p/><p id='2'/><p id='4'/>";
- $(e).html(content);
-
- List<String> s = $("p", e).map(new Function() {
- public Object f(Element e, int i) {
- return null;
- }
- });
- assertNotNull(s);
- assertEquals(0, s.size());
-
- s = $("p", e).map(new Function() {
- public Object f(Element e, int i) {
- String id = $(e).attr("id");
- return id.isEmpty() ? null : id;
- }
- });
- assertEquals(3, s.size());
- assertEquals("1", s.get(0));
- assertEquals("2", s.get(1));
- assertEquals("4", s.get(2));
-
- List<Element> a = $("p", e).map(new Function() {
- public Object f(Element e, int i) {
- String id = $(e).attr("id");
- return id.isEmpty() ? null : e;
- }
- });
- assertEquals(3, a.size());
- assertEquals(3, $(a).size());
-
- }
-
- public void testHtmlSnippet(){
-
- GQuery gq = $("<div>blop</div><p>test</p><span>test</span>");
- assertEquals(3, gq.size());
- assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
- assertEquals("P", gq.get(1).getTagName().toUpperCase());
- assertEquals("SPAN", gq.get(2).getTagName().toUpperCase());
-
- //xhtml tag
- gq = $("<div/>");
- assertEquals(1, gq.size());
- assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
-
- gq = $("<a/>");
- assertEquals(1, gq.size());
- assertEquals("A", gq.get(0).getTagName().toUpperCase());
-
- gq = $("<div>");
- assertEquals(1, gq.size());
- assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
-
- //issue 81 : trailing spaces
- gq = $(" <div>blop</div><p>test</p><span>test</span> ");
- assertEquals(3, gq.size());
- assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
- assertEquals("P", gq.get(1).getTagName().toUpperCase());
- assertEquals("SPAN", gq.get(2).getTagName().toUpperCase());
-
- //wrapping
- gq = $("<tr>blop</tr><tr>test</tr>");
- assertEquals(2, gq.size());
- assertEquals("TR", gq.get(0).getTagName().toUpperCase());
- assertEquals("TR", gq.get(1).getTagName().toUpperCase());
- //same in uppercase
- gq = $("<TR>blop</TR><tr>test</tr>");
- assertEquals(2, gq.size());
- assertEquals("TR", gq.get(0).getTagName().toUpperCase());
- assertEquals("TR", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<td>blop</td><td>test</td>");
- assertEquals(2, gq.size());
- assertEquals("TD", gq.get(0).getTagName().toUpperCase());
- assertEquals("TD", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<th>blop</th><th>test</th>");
- assertEquals(2, gq.size());
- assertEquals("TH", gq.get(0).getTagName().toUpperCase());
- assertEquals("TH", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<col/><col/>");
- assertEquals(2, gq.size());
- assertEquals("COL", gq.get(0).getTagName().toUpperCase());
- assertEquals("COL", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<area/><area/>");
- assertEquals(2, gq.size());
- assertEquals("AREA", gq.get(0).getTagName().toUpperCase());
- assertEquals("AREA", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<option>blop</option><option>test</option>");
- assertEquals(2, gq.size());
- assertEquals("OPTION", gq.get(0).getTagName().toUpperCase());
- assertEquals("OPTION", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<legend>blop</legend><legend>test</legend>");
- assertEquals(2, gq.size());
- assertEquals("LEGEND", gq.get(0).getTagName().toUpperCase());
- assertEquals("LEGEND", gq.get(1).getTagName().toUpperCase());
-
- gq = $("<thead>blop</thead><thead>test</thead>");
- assertEquals(2, gq.size());
- assertEquals("THEAD", gq.get(0).getTagName().toUpperCase());
- assertEquals("THEAD", gq.get(1).getTagName().toUpperCase());
-
- //issue
- gq = $("<select name=\"modificator\"><option value=\"work\" selected=\"selected"
- +"\">Work</option><option value=\"work_fax\" >Work fax</option><option "
- +"value=\"home\" >Home</option><option value=\"other\" >Other</"
- +"option><option value=\"home_fax\" >Home fax</option><option value=\"main\" >Main</option></select>");
-
- assertEquals(1, gq.size());
-
- assertEquals("SELECT", gq.get(0).getTagName().toUpperCase());
- assertEquals(6, gq.get(0).getChildCount());
-
-
- }
-
-
- public void testNulls() {
- Assert.assertEquals(0, $((Node) null).size());
- Assert.assertEquals(0, $((Element) null).size());
- Assert.assertEquals(0, $((String) null).size());
- Assert.assertNull($((String) null).get(0));
- Assert.assertNull($((String) null).get(-1));
- Assert.assertEquals(0, $((String) null).eq(0).size());
- }
-
- public void testRemoveMethod(){
- String html = "<div id='parent'>parent<div id='child'>child</div></div>";
- $(e).html(html);
-
- Function failCallback = new Function(){
- @Override
- public void f() {
- fail("Event binding not removed");
- }
- };
-
- Element parent = $("#parent", e).get(0);
- Element child = $("#child", e).get(0);
-
- $("#child", e).data("key", "child");
- $("#child", e).click(failCallback);
- $("#parent", e).data("key", "parent");
- $("#parent", e).click(failCallback);
-
- $("#parent", e).remove();
-
- //child and the parent was removed
- assertEquals(0,$("#child", e).length());
- assertEquals(0,$("#parent", e).length());
-
- assertNull($(child).data("key"));
- assertNull($(parent).data("key"));
- //if failCallback is always binded, test fails...
- $(child).click();
- $(parent).click();
-
-
-
- }
-
- public void testRemoveMethodWithFilter(){
- String html = "<div id='parent'>parent<div id='child'>child</div></div>";
- $(e).html(html);
-
- Function failCallback = new Function(){
- @Override
- public void f() {
- fail("Event binding not removed");
- }
- };
-
- Function noFailCallback = new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
- }
- };
-
- Element parent = $("#parent", e).get(0);
- Element child = $("#child", e).get(0);
-
- $("#child", e).data("key", "child");
- $("#child", e).click(failCallback);
- $("#parent", e).data("key", "parent");
- $("#parent", e).click(noFailCallback);
-
- $("div", e).remove("#child");
-
- //child was removed but not the parent
- assertEquals(0,$("#child", e).length());
- assertEquals(1,$("#parent", e).length());
-
- assertNull($(child).data("key"));
- assertEquals("parent",$(parent).data("key"));
-
- //if failCallback is always binded, test fails...
- $(child).click();
-
-
- $(parent).click();
- assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR, false));
- }
-
- public void testDetachMethod(){
- String html = "<div id='parent'>parent<div id='child'>child</div></div>";
- $(e).html(html);
-
- Function noFailCallback = new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
- }
- };
-
- Element parent = $("#parent", e).get(0);
- Element child = $("#child", e).get(0);
-
- $("#child", e).data("key", "child");
- $("#child", e).click(noFailCallback);
- $("#parent", e).data("key", "parent");
- $("#parent", e).click(noFailCallback);
-
- GQuery $parent = $("#parent", e).detach();
-
- //test parent an child well detached
- assertEquals(0,$("#parent", e).length());
- assertEquals(0,$("#child", e).length());
- //test that data was not cleaned
- assertEquals("child",$(child).data("key"));
- assertEquals("parent",$(parent).data("key"));
-
- $(e).append($parent);
-
- assertEquals(1,$("#parent", e).length());
- assertEquals(1,$("#child", e).length());
- assertEquals("child",$("#child", e).data("key"));
- assertEquals("parent",$("#parent", e).data("key"));
-
- $("#child", e).click();
- assertEquals("red", $(child).css(CSS.BACKGROUND_COLOR, false));
- $("#parent", e).click();
- assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR, false));
- }
-
- public void testDetachMethodWithFilter(){
- String html = "<div id='parent'>parent<div id='child'>child</div></div>";
- $(e).html(html);
-
- Function noFailCallback = new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
- }
- };
-
- Element parent = $("#parent", e).get(0);
- Element child = $("#child", e).get(0);
-
- $("#child", e).data("key", "child");
- $("#child", e).click(noFailCallback);
- $("#parent", e).data("key", "parent");
- $("#parent", e).click(noFailCallback);
-
- $("div", e).detach("#child");
-
- //child was removed but not the parent
- assertEquals(0,$("#child", e).length());
- assertEquals(1,$("#parent", e).length());
-
- //data must always exist
- assertEquals("child", $(child).data("key"));
- assertEquals("parent",$(parent).data("key"));
-
- $(e).append($(child));
-
- assertEquals(1,$("#child", e).length());
- assertEquals(1,$("#parent", e).length());
-
- $(child).click();
- assertEquals("red", $("#child", e).css(CSS.BACKGROUND_COLOR, false));
-
- $(parent).click();
- assertEquals("red", $("#parent", e).css(CSS.BACKGROUND_COLOR, false));
- }
-
- public void testUnwrapMethod(){
- String html = "<div class='parent'><div class='child'>child1</div><span>other child</span></div><div class='parent'><div class='child'>child2</div></div><div class='parent'><div class='child'>child3</div></div>";
- $(e).html(html);
-
- assertEquals(3, $(".parent", e).length());
- assertEquals(3, $(".child", e).length());
-
- $(".child",e).unwrap();
-
- assertEquals(0, $(".parent",e).length());
- assertEquals(3, $(".child",e).length());
-
- String expectedHtml = "<div class=\"child\">child1</div><span>other child</span><div class=\"child\">child2</div><div class=\"child\">child3</div>";
-
- assertEquals(expectedHtml, $(e).html());
-
- }
-
- public void testClosestMethod(){
- String html = "<div><p><div id='firstDiv'><p id='firstP'><span><input id='firstInput' type='text'></input></span></p></div></p></div>";
- $(e).html(html);
-
- GQuery closeP = $("input", e).closest("p,div");
-
- assertEquals(1, closeP.length());
- assertEquals("firstP", closeP.get(0).getId());
-
- GQuery closeDiv = $("input", e).closest("div");
-
- assertEquals(1, closeDiv.length());
- assertEquals("firstDiv", closeDiv.get(0).getId());
-
- GQuery closeInput = $("input", e).closest("input");
-
- assertEquals(1, closeInput.length());
- assertEquals("firstInput", closeInput.get(0).getId());
-
- GQuery closeUnknown = $("input", e).closest("h1");
-
- assertEquals(0, closeUnknown.length());
-
- GQuery closePWithContext = $("input", e).closest("p,div",$("#firstDiv",e).get(0));
-
- assertEquals(1, closePWithContext.length());
- assertEquals("firstP", closePWithContext.get(0).getId());
-
- GQuery closeDivWithContext = $("input", e).closest("div",$("#firstP",e).get(0));
-
- assertEquals(0, closeDivWithContext.length());
-
- }
-
- public void testClosestMethodWithArrayOfString(){
-
- String html = "<div id='mainDiv'><div id='subDiv' class='test'><div id='subSubDiv'><p id='mainP'><span id='testSpan' class='test'><input id='firstInput' type='text'></input></span></p></div></div></div>";
- $(e).html(html);
-
- JsNamedArray<NodeList<Element>> close = $("input", e).closest(new String[]{"p","div", ".test", "#unknown"});
-
- assertEquals(3, close.length());
-
- assertNotNull(close.get("p"));
- assertEquals(1,close.get("p").getLength());
- assertEquals("mainP", close.get("p").getItem(0).getId());
-
- assertNotNull(close.get("div"));
- assertEquals(3,close.get("div").getLength());
- assertEquals("subSubDiv", close.get("div").getItem(0).getId());
- assertEquals("subDiv", close.get("div").getItem(1).getId());
- assertEquals("mainDiv", close.get("div").getItem(2).getId());
-
- assertNotNull(close.get(".test"));
- assertEquals(2,close.get(".test").getLength());
- assertEquals("testSpan", close.get(".test").getItem(0).getId());
- assertEquals("subDiv", close.get(".test").getItem(1).getId());
-
- assertNull(close.get("#unknown"));
-
- }
-
- public void testMap() {
- String html = "<div class='d' id='6'></div>" +
- "<span class='s' id='5'></span>" +
- "<p class='p' id='4'></p>" +
- "<em class='d' id='3'></em>" +
- "<b class='s' id='2'></b>" +
- "<i class='p' id='1'></i>" +
- "<strong></strong>";
- $(e).html(html);
-
- GQuery c = $(e).children();
- assertEquals(7, c.size());
-
- // A list of lists containing tag,class,id, remove elements without id
- List<List<String>> m = $(e).children().map(new Function() {
- public List<String> f(Element e, int i) {
- // map does not add to the list null elements
- if ($(e).attr("id").isEmpty() || $(e).attr("class").isEmpty()) {
- return null;
- }
- List<String> attrs = new ArrayList<String>();
- attrs.add(e.getTagName());
- attrs.add($(e).attr("class"));
- attrs.add($(e).attr("id"));
- return attrs;
- }
- });
- assertEquals(6, m.size());
-
- // Sort the list by id
- assertEquals("div", m.get(0).get(0).toLowerCase());
- assertEquals("i", m.get(5).get(0).toLowerCase());
- Collections.sort(m, new Comparator<List<String>>() {
- public int compare(List<String> o1, List<String> o2) {
- return o1.get(2).compareTo(o2.get(2));
- }
- });
- assertEquals("div", m.get(5).get(0).toLowerCase());
- assertEquals("i", m.get(0).get(0).toLowerCase());
- }
-
- public void testWindowSize() {
- GQuery w = $(GQuery.window);
- assertTrue(w.width() > 0);
- assertTrue(w.height() > 0);
- }
-
- public void testFunction() {
- $(e).html("<div id=fid>0</div>");
- GQuery g = $("#fid", e);
- assertEquals("0", g.text());
-
- // EACH
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.user.client.Element e) {
- $(e).text("U");
- }
- });
- assertEquals("U", g.text());
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.dom.client.Element e) {
- $(e).text("D");
- }
- });
- assertEquals("D", g.text());
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.user.client.Element e, int idx) {
- $(e).text("U" + idx);
- return "";
- }
- });
- assertEquals("U0", g.text());
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.user.client.Element e, int idx) {
- $(e).text("D" + idx);
- return "";
- }
- });
- assertEquals("D0", g.text());
-
- // EVENTS
- g.unbind(Event.ONCLICK).click(new Function(){
- @Override
- public void f(com.google.gwt.user.client.Element e) {
- $(e).text("U");
- }
- }).click();
- assertEquals("U", g.text());
- g.unbind(Event.ONCLICK).click(new Function(){
- @Override
- public void f(com.google.gwt.dom.client.Element e) {
- $(this).text("D");
- }
- }).click();
- assertEquals("D", g.text());
- g.unbind(Event.ONCLICK).click(new Function(){
- @Override
- public boolean f(Event e) {
- $(this).text("E");
- return false;
- }
- }).click();
- assertEquals("E", g.text());
- g.unbind(Event.ONCLICK).bind(Event.ONCLICK, "D", new Function(){
- @Override
- public boolean f(Event e, Object o) {
- $(e).text("E" + o);
- return false;
- }
- }).click();
- assertEquals("ED", g.text());
-
- // ELEMENTS AND WIDGETS
- Label label = new Label("1");
- RootPanel.get().add(label);
- g = $("#fid, .gwt-Label");
- assertEquals(2, g.size());
-
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.user.client.Element e) {
- $(e).text("U");
- }
- });
- assertEquals("UU", g.text());
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.dom.client.Element e) {
- $(e).text("D");
- }
- });
- assertEquals("DD", g.text());
-
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.user.client.Element e) {
- $(e).text("U");
- }
- @Override
- public void f(Widget w) {
- $(w).text("W");
- }
- });
- assertEquals("UW", g.text());
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.dom.client.Element e) {
- $(e).text("D");
- }
- @Override
- public void f(Widget w) {
- $(w).text("W");
- }
- });
- assertEquals("DW", g.text());
-
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.user.client.Element e, int idx) {
- $(e).text("U" + idx);
- return "";
- }
- });
- assertEquals("U0U1", g.text());
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.user.client.Element e, int idx) {
- $(e).text("D" + idx);
- return "";
- }
- });
- assertEquals("D0D1", g.text());
-
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.user.client.Element e, int idx) {
- $(e).text("U" + idx);
- return "";
- }
- @Override
- public Object f(Widget w, int idx) {
- $(w).text("W" + idx);
- return "";
- }
- });
- assertEquals("U0U1", g.text());
- g.each(new Function() {
- @Override
- public Object f(com.google.gwt.dom.client.Element e, int idx) {
- $(e).text("D" + idx);
- return "";
- }
- @Override
- public Object f(Widget w, int idx) {
- $(w).text("W" + idx);
- return "";
- }
- });
- assertEquals("D0D1", g.text());
-
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.user.client.Element e) {
- $(e).text("U");
- }
- @Override
- public Object f(Widget w, int idx) {
- $(w).text("W" + idx);
- return "";
- }
- });
- assertEquals("UW1", g.text());
- g.each(new Function() {
- @Override
- public void f(com.google.gwt.dom.client.Element e) {
- $(e).text("D");
- }
- @Override
- public Object f(Widget w, int idx) {
- $(w).text("W" + idx);
- return "";
- }
- });
- assertEquals("DW1", g.text());
-
- label.removeFromParent();
- }
-
- public void testXpathSelector() {
- $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A Text</td><td width=50%>B</td></tr></table>");
- SelectorEngineCssToXPath s = new SelectorEngineCssToXPath();
- for (String selector : Arrays.asList("td[width]", "table > tr > td", "*[width!='440']")) {
- String xselector = s.css2Xpath(selector);
- assertEquals($(selector).size(), $(xselector).size());
- }
- }
-
- public void testIssue81(){
- GQuery test = $(" <div>blop</div><!-- comment --> <p>test2</p> ");
- test.addClass("test");
- test.removeClass("test");
- }
-
- public void testHas() {
- $(e).html("<ul>"
- +"<li>list item 1</li>"
- +"<li id='l2'>list item 2"
- +" <ul>"
- +" <li>list item 2-a</li>"
- +" <li>list item 2-b</li>"
- +" </ul>"
- +"</li>"
- +"<li id='l3'>list item 3 <span>span</span>"
- +"</li>"
- +"<li>list item 4</li>"
- +"</ul>");
- assertEquals("", $("#l2").css("background-color", false));
- $("li", e).has("ul").css("background-color", "red");
- assertEquals("red", $("#l2").css("background-color", false));
-
- Element span = $("span", e).get(0);
- assertEquals("l3", $("li", e).has(span).id());
- }
-
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.$$;
+import static com.google.gwt.query.client.GQuery.document;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.css.CSS;
+import com.google.gwt.query.client.css.RGBColor;
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;
+import com.google.gwt.query.client.impl.SelectorEngineImpl;
+import com.google.gwt.query.client.impl.SelectorEngineSizzle;
+import com.google.gwt.query.client.js.JsNamedArray;
+import com.google.gwt.query.client.js.JsNodeArray;
+import com.google.gwt.query.client.js.JsUtils;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.TextArea;
+import com.google.gwt.user.client.ui.Widget;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Test class for testing gwtquery-core api.
+ */
+public class GQueryCoreTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ protected static void assertHtmlEquals(Object expected, Object actual) {
+ assertEquals(iExplorerFixHtml(expected), iExplorerFixHtml(actual));
+ }
+
+ protected static String iExplorerFixHtml(Object s) {
+ // IE shows all tags upper-case
+ // IE adds \r \n
+ // IE does not put quotes to some attributes
+ // Investigate: IE in method find puts the attribute $h="4"
+ // Investigate: IE in method filter adds the attrib added="null"
+ return s.toString().trim().toLowerCase().replaceAll("[\r\n]", "").replaceAll(
+ " ([\\w]+)=[\"']([^\"']+)[\"']", " $1=$2").replaceAll(
+ "\\s+\\$h=\"[^\"]+\"", "").replaceAll(" added=[^ >]+", "");
+ }
+
+ int done = 0;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null || DOM.getElementById("core-tst") == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("core-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ public void testAttributeMethods() {
+
+ $(e).html("<p class=\"a1\">Content</p>");
+ GQuery gq = $("p", e);
+
+ // attr()
+ gq.attr($$("attr1: 'a', attr2: 'b'"));
+ assertEquals("a", gq.attr("attr1"));
+ assertEquals("b", gq.attr("attr2"));
+
+ gq.attr("attr3", new Function() {
+ public String f(Element e, int i) {
+ return e.getInnerText();
+ }
+ });
+ assertEquals("Content", gq.attr("attr3"));
+
+ assertEquals("a1", gq.attr("class"));
+ gq.attr("class", "b1 b2");
+
+ // hasClass()
+ assertTrue(gq.hasClass("b1"));
+ assertTrue(gq.hasClass("b2"));
+
+ // addClass()
+ gq.addClass("c1", "c2");
+ assertTrue(gq.hasClass("b1"));
+ assertTrue(gq.hasClass("b2"));
+ assertTrue(gq.hasClass("c1"));
+ assertTrue(gq.hasClass("c2"));
+
+ // removeClass()
+ gq.removeClass("c2", "c1");
+ assertTrue(gq.hasClass("b1"));
+ assertTrue(gq.hasClass("b2"));
+ assertFalse(gq.hasClass("c1"));
+ assertFalse(gq.hasClass("c2"));
+
+ // toggleClass()
+ gq.toggleClass("b2");
+ assertTrue(gq.hasClass("b1"));
+ assertFalse(gq.hasClass("b2"));
+ gq.toggleClass("b2");
+ assertTrue(gq.hasClass("b1"));
+ assertTrue(gq.hasClass("b2"));
+ gq.toggleClass("b2", true);
+ assertTrue(gq.hasClass("b2"));
+ gq.toggleClass("b2", false);
+ assertFalse(gq.hasClass("b2"));
+
+ // css()
+ String content = "<p style='color:red;'>Test Paragraph.</p>";
+ $(e).html(content);
+ assertEquals("red", $("p", e).css("color"));
+ $("p", e).css("font-weight", "bold");
+ assertEquals("bold", $("p", e).css("font-weight"));
+
+ // css() properties
+ $(e).html("<p>Test Paragraph.</p>");
+ $("p", e).css(
+ Properties.create("color: 'red', 'font-weight': 'bold', background: 'blue'"));
+ assertEquals("red", $("p", e).css("color"));
+ assertEquals("bold", $("p", e).css("font-weight"));
+ assertEquals("blue", $("p", e).css("background-color", false));
+
+ // css() camelize and uppercase
+ $(e).html("<p>Test Paragraph.</p>");
+ $("p", e).css(Properties.create("COLOR: 'red', 'FONT-WEIGHT': 'bold'"));
+ assertEquals("red", $("p", e).css("color", false));
+ assertEquals("", $("p", e).css("background"));
+ }
+
+ public void testCapitalLetters() {
+ $(e).html("<div id='testImageDisplay' class='whatEver'>Content</div>");
+ assertEquals(1, $("#testImageDisplay").size());
+ // Commented because IE is case insensitive
+ // assertEquals(0, $("#testimagedisplay").size());
+ assertEquals(1, $(".whatEver").size());
+ assertEquals(0, $(".whatever").size());
+ }
+
+ public void testCleanMethod() {
+ $(e).html("").append($("<tr/>"));
+ assertHtmlEquals("<tr></tr>", $(e).html());
+
+ $(e).html("").append($("<td/>"));
+ assertHtmlEquals("<td></td>", $(e).html());
+
+ $(e).html("").append($("<th/>"));
+ assertHtmlEquals("<th></th>", $(e).html());
+ }
+
+ public void testDomManip() {
+ String content = "<span class='branchA'><span class='target'>branchA target</span></span>"
+ + "<span class='branchB'><span class='target'>branchB target</span></span>";
+
+ $(e).html("");
+ $(e).append(content);
+ assertEquals(4, $("span", e).size());
+ assertEquals(2, $("span.target", e).size());
+ assertHtmlEquals(content, $(e).html());
+
+ $(e).html("<span>a</span><span>b</span>");
+ $("span").append("<div>c</div>");
+ assertHtmlEquals("<span>a<div>c</div></span><span>b<div>c</div></span>", $(
+ e).html());
+ }
+
+ public void testEach() {
+ $(e).html("<p>Content 1</p><p>Content 2</p><p>Content 3</p>");
+ $("p", e).each(new Function() {
+ public void f(Element e) {
+ $(e).text(".");
+ }
+ });
+ assertHtmlEquals("<p>.</p><p>.</p><p>.</p>", $("p", e));
+ $("p", e).each(new Function() {
+ public String f(Element e, int i) {
+ $(e).text("" + i);
+ return "";
+ }
+ });
+ assertHtmlEquals("<p>0</p><p>1</p><p>2</p>", $("p", e));
+ }
+
+ public void testIFrameManipulation() {
+ $(e).html("<iframe name='miframe' id='miframe' src=\"javascript:''\">");
+ // FF has to call empty to open and close the document before
+ // accessing the recently created iframe content
+ Document d = $("#miframe").contents().empty().get(0).cast();
+ assertNotNull(d);
+ assertNotNull(d.getBody());
+ assertEquals(1, $("#miframe").contents().size());
+ assertEquals(1, $("#miframe").contents().find("body").size());
+ assertEquals(0, $("#miframe").contents().find("body > h1").size());
+ $("#miframe").contents().find("body").append("<h1>Test</h1>");
+ assertEquals(1, $("#miframe").contents().find("body > h1").size());
+ assertEquals(1, $(d).find("h1").size());
+ }
+
+ public void testInnerMethods() {
+ String txt = "<p>I would like to say: </p>";
+
+ // Check that setHTML and getHTML work as GQuery html()
+ testPanel.setHTML(txt);
+ assertHtmlEquals(txt, testPanel.getHTML());
+ assertHtmlEquals(txt, $(e).html());
+ assertHtmlEquals(txt, $("#core-tst").html());
+ $(e).html("");
+ assertHtmlEquals("", $(e).html());
+ $(e).html(txt);
+ assertHtmlEquals(txt, $(e).html());
+
+ // toString()
+ assertHtmlEquals(txt, $("p", e));
+
+ // remove()
+ $("p", e).remove();
+ assertHtmlEquals("", $(e).html());
+
+ // text()
+ String expected = "I would like to say: I would like to say:";
+ $(e).html(txt + txt);
+ assertHtmlEquals(expected, $("p", e).text());
+
+ // empty()
+ expected = "<p></p><p></p>";
+ $("p", e).empty();
+ assertHtmlEquals(expected, $(e).html());
+ }
+
+ public void testInputValueMethods() {
+ // imput text
+ $(e).html("<input type='text'/>");
+ GQuery gq = $("input", e);
+ assertEquals("", gq.val());
+ gq.val("some value");
+ assertEquals("some value", gq.val());
+
+ // select
+ $(e).html(
+ "<select name='n'><option value='v1'>1</option><option value='v2' selected='selected'>2</option></select>");
+ gq = $("select", e);
+ assertEquals("v2", gq.val());
+ gq.val("v1");
+ assertEquals("v1", gq.val());
+
+ // select multiple
+ $(e).html(
+ "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2'>2</option><option value='v3'>3</option></select>");
+ gq = $("select", e);
+ assertNull(gq.vals());
+ assertNull(gq.val());
+
+ $(e).html(
+ "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2' selected='selected'>2</option><option value='v3'>3</option></select>");
+ gq = $("select", e);
+ assertEquals(1, gq.vals().length);
+ assertEquals("v2", gq.val());
+ gq.val("v1", "v3", "invalid");
+ assertEquals(2, gq.vals().length);
+ assertEquals("v1", gq.vals()[0]);
+ assertEquals("v3", gq.vals()[1]);
+ // FIXME: fix in IE
+ // gq.val("v1");
+ // assertEquals(1, gq.vals().length);
+ // assertEquals("v1", gq.val());
+
+ // input radio
+ $(e).html(
+ "<input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input>");
+ gq = $("input", e);
+ assertEquals("v1", gq.val());
+ assertEquals("v2", $("input:checked", e).val());
+ gq.val(new String[]{"v1"});
+ assertEquals("v1", $("input:checked", e).val());
+ gq.val(new String[]{"v2"});
+ assertEquals("v2", $("input:checked", e).val());
+
+ // input checkbox
+ $(e).html(
+ "<input type='checkbox' name='n1' value='v1'>1</input><input type='checkbox' name='n2' value='v2' checked='checked'>2</input>");
+ gq = $("input", e);
+ assertEquals("v1", gq.val());
+ assertEquals("v2", $("input:checked", e).val());
+ gq.val(new String[]{"v1"});
+ assertEquals("v1", $("input:checked", e).val());
+ }
+
+ public void testIssue23() {
+ $(e).html(
+ "<table><tr><td><input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input></td><td><button>Click</button></tr><td></table>");
+ $("button").click(new Function() {
+ public boolean f(Event ev) {
+ done = 0;
+ $("table > tbody > tr > td > input:checked", e).each(new Function() {
+ public void f(Element e) {
+ done++;
+ }
+ });
+ assertEquals(1, done);
+ return true;
+ }
+ });
+ $("button").click();
+ }
+
+ public void testModifyMethods() {
+ String pTxt = "<p>I would like to say: </p>";
+ String bTxt = "<b>Hello</b>";
+
+ // append()
+ String expected = "<p>I would like to say: <b>Hello</b></p>";
+ $(e).html(pTxt);
+ $("p", e).append(bTxt);
+ assertHtmlEquals(expected, $(e).html());
+
+ $(e).html(pTxt);
+ $("p", e).append($(bTxt).get(0));
+ assertHtmlEquals(expected, $(e).html());
+
+ // appendTo()
+ expected = "<p>I would like to say: <b>Hello</b></p>";
+ $(e).html(bTxt + pTxt);
+ GQuery g = $("b", e).appendTo($("p", e));
+ assertHtmlEquals(expected, $(e).html());
+ assertHtmlEquals("<b>Hello</b>", g.toString());
+ // document is a valid node, actually it is substituted by body
+ g.appendTo(document);
+ expected = "<p>I would like to say: </p>";
+ assertHtmlEquals(expected, $(e).html());
+ g.remove();
+ // Check that the new elements are returned and can be modified
+ $("<div id='mid'>Hello</div>").appendTo(e).css("color", "white");
+ assertEquals("white", $("#mid").css("color"));
+
+ // prepend()
+ expected = "<p><b>Hello</b>I would like to say: </p>";
+ $(e).html(pTxt);
+ $("p", e).prepend(bTxt);
+ assertHtmlEquals(expected, $(e).html());
+
+ // prependTo()
+ expected = "<p><b>Hello</b>I would like to say: </p>";
+ $(e).html(bTxt + pTxt);
+ $("b", e).prependTo($("p", e));
+ assertHtmlEquals(expected, $(e).html());
+ // Check that the new elements are returned and can be modified
+ $("<div id='mid'>Hello</div>").prependTo(e).css("color", "yellow");
+ assertEquals("yellow", $("#mid").css("color"));
+
+ // prependTo()
+ expected = "<b>Hello</b><p><b>Hello</b>I would like to say: </p>";
+ $(e).html(bTxt + pTxt);
+ $("b", e).clone().prependTo($("p", e));
+ assertHtmlEquals(expected, $(e).html());
+
+ // before()
+ expected = "<b>Hello</b><p>I would like to say: </p>";
+ $(e).html(pTxt);
+ $("p", e).before(bTxt);
+ assertHtmlEquals(expected, $(e).html());
+
+ // before()
+ expected = "<b>Hello</b><p>I would like to say: </p>";
+ $(e).html(pTxt + bTxt);
+ $("p", e).before($("b", e));
+ assertHtmlEquals(expected, $(e).html());
+
+ // before()
+ expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+ $(e).html(pTxt + bTxt);
+ $("p", e).before($("b", e).clone());
+ assertHtmlEquals(expected, $(e).html());
+
+ // insertBefore()
+ expected = "<b>Hello</b><p>I would like to say: </p>";
+ $(e).html(pTxt + bTxt);
+ $("b", e).insertBefore($("p", e));
+ assertHtmlEquals(expected, $(e).html());
+
+ // insertBefore()
+ expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+ $(e).html(pTxt + bTxt);
+ $("b", e).clone().insertBefore($("p", e));
+ assertHtmlEquals(expected, $(e).html());
+
+ // after()
+ expected = "<p>I would like to say: </p><b>Hello</b>";
+ $(e).html(pTxt);
+ $("p", e).after(bTxt);
+ assertHtmlEquals(expected, testPanel.getHTML());
+
+ // after()
+ expected = "<p>I would like to say: </p><b>Hello</b>";
+ $(e).html(bTxt + pTxt);
+ $("p", e).after($("b", e));
+ assertHtmlEquals(expected, $(e).html());
+
+ // after()
+ expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+ $(e).html(bTxt + pTxt);
+ $("p", e).after($("b", e).clone().get(0));
+ assertHtmlEquals(expected, $(e).html());
+
+ // The set of elements should be the same after the manipulation
+ String content = "<span>s</span>";
+ expected = "<p>p</p>";
+ GQuery g1 = $(content);
+ GQuery g2 = $(expected);
+ $(e).html("").append(g1);
+ assertEquals(1, g1.size());
+ assertEquals(content, g1.toString());
+
+ $(g1).append(g2);
+ assertEquals(1, g1.size());
+ assertEquals(1, g2.size());
+ assertEquals(expected, g2.toString());
+
+ $(g1).prepend(g2);
+ assertEquals(1, g1.size());
+ assertEquals(1, g2.size());
+ assertEquals(expected, g2.toString());
+
+ $(g1).after(g2);
+ assertEquals(1, g1.size());
+ assertEquals(1, g2.size());
+ assertEquals(expected, g2.toString());
+
+ $(g1).before(g2);
+ assertEquals(1, g1.size());
+ assertEquals(1, g2.size());
+ assertEquals(expected, g2.toString());
+ }
+
+ public void testAppendTo() {
+ String txt = "<h2>Greetings</h2><div class='container'><div class='inner'>Hello</div><div class='inner'>Goodbye</div></div>";
+ String expected = "<h2>Greetings</h2><div class='container'><div class='inner'>Hello<p>Test</p></div><div class='inner'>Goodbye<p>Test</p></div></div>";
+ $(e).html(txt);
+ $("<p>Test</p>").appendTo(".inner");
+ assertHtmlEquals(expected, $(e).html());
+
+ expected = "<div class='container'><div class='inner'>Hello</div><div class='inner'>Goodbye</div><h2>Greetings</h2></div>";
+ $(e).html(txt);
+ $("h2", e).appendTo($(".container"));
+ assertHtmlEquals(expected, $(e).html());
+
+ expected = "<div class='container'><div class='inner'>Hello<h2>Greetings</h2></div><div class='inner'>Goodbye<h2>Greetings</h2></div><h2>Greetings</h2></div><h2>Greetings</h2>";
+ $(e).html(txt);
+ $("h2", e).appendTo($("div"));
+ assertHtmlEquals(expected, $(e).html());
+ }
+
+ public void testOpacity() {
+ $(e).html(
+ "<p id='id1' style='opacity: 0.6; filter: alpha(opacity=60)'>Content 1</p>");
+ GQuery g = $("#id1");
+ assertEquals("0.6", g.css("opacity", false));
+ assertEquals("0.6", g.css("opacity", true));
+ g.css("opacity", "");
+ assertEquals("", g.css("opacity", false));
+ assertEquals("1.0", g.css("opacity", true));
+ g.css("opacity", "0.4");
+ assertEquals("0.4", g.css("opacity", false));
+ assertEquals("0.4", g.css("opacity", true));
+ }
+
+ public void testPosition() {
+ $(e).html(
+ "<div style='top:25px; left:25px; padding:20px; position:relative;'><div id='child' style='margin:30px'>test</div></div> ");
+ GQuery g = $("#child");
+ assertEquals(20, g.position().left);
+ assertEquals(20, g.position().top);
+
+ $(e).html(
+ "<div style='top:25px; left:25px; position:relative;'><div id='child' style='position:relative; top:15px; left:35px;'>test</div></div> ");
+ g = $("#child");
+ assertEquals(35, g.position().left);
+ assertEquals(15, g.position().top);
+
+ }
+
+ public void testPropMethod(){
+ $(e).html("<input id=\"checkBox1\" type=\"checkbox\" checked=\"checked\" /> <input id=\"checkBox2\" type=\"checkbox\" />");
+
+ assertTrue($("#checkBox1",e).prop("checked"));
+ assertFalse($("#checkBox2",e).prop("checked"));
+
+ $("#checkBox1",e).prop("checked", false);
+ $("#checkBox2",e).prop("checked", new Function() {
+ @Override
+ public Object f(Element e, int i) {
+ return Boolean.TRUE;
+ }
+ });
+
+ assertTrue($("#checkBox2",e).prop("checked"));
+ assertFalse($("#checkBox1",e).prop("checked"));
+
+ }
+
+ public void testProperties() {
+ Properties p = $$("border:'1px solid black'");
+ assertEquals(1, p.keys().length);
+ assertNotNull(p.getStr("border"));
+
+ p = $$("({border:'1px solid black'})");
+ assertEquals(1, p.keys().length);
+ assertNotNull(p.getStr("border"));
+ }
+
+ public void testRelativeMethods() {
+ String content = "<p><span>Hello</span>, how are you?</p>";
+ String expected = "<span>Hello</span>";
+
+ // find()
+ $(e).html(content);
+ assertHtmlEquals(expected, $("p", e).find("span"));
+
+ // filter()
+ content = "<p>First</p><p class=\"selected\">Hello</p><p>How are you?</p>";
+ $(e).html(content);
+ expected = "<p class=\"selected\">Hello</p>";
+ assertHtmlEquals(expected, $("p", e).filter(".selected"));
+
+ // not()
+ expected = "<p>First</p><p>How are you?</p>";
+ assertEquals(2, $("p", e).not(".selected").size());
+ assertHtmlEquals(expected, $("p", e).not(".selected"));
+ assertEquals(2, $("p", e).not($(".selected")).size());
+ assertHtmlEquals(expected, $("p", e).not($(".selected")));
+ assertEquals(2, $("p", e).not($(".selected").get(0)).size());
+ assertHtmlEquals(expected, $("p", e).not($(".selected").get(0)));
+
+ // add()
+ String added = "<p>Last</p>";
+ expected = content + added;
+ assertEquals(4, $("p", e).add(added).size());
+ assertHtmlEquals(expected, $("p", e).add(added));
+
+ // parent()
+ expected = content = "<div><p>Hello</p><p>Hello</p></div>";
+ $(e).html(content);
+ assertHtmlEquals(expected, $("p", e).parent());
+
+ // parent()
+ content = "<div><p>Hello</p></div><div class=\"selected\"><p>Hello Again</p></div>";
+ expected = "<div class=\"selected\"><p>Hello Again</p></div>";
+ $(e).html(content);
+ assertHtmlEquals(expected, $("p", e).parent(".selected"));
+
+ // parents()
+ content = "<div><p><span>Hello</span></p><span>Hello Again</span></div>";
+ $(e).html(content);
+ assertEquals(2, $("span", e).size());
+ assertTrue(3 < $("span", e).parents().size());
+ assertEquals(1, $("span", e).parents().filter("body").size());
+ $("span", e).parents().filter("body").toString().trim().toLowerCase().contains(
+ content.toLowerCase());
+
+ //parentsUntil()
+ content = "<div id='mainDiv'><div id='subDiv1' class='subDiv'><div id='subSubDiv1'><p id='p1'>child1</p></div></div><div id='subDiv2' class='subDiv'><div id='subSubDiv2'><p id='p2'>child2</p></div></div></div>";
+ $(e).html(content);
+ $("p",e).parentsUntil("#mainDiv").css(CSS.COLOR.with(RGBColor.RED));
+ assertEquals("red", $("#subDiv1", e).css(CSS.COLOR, false));
+ assertEquals("red", $("#subSubDiv1", e).css(CSS.COLOR, false));
+ assertEquals("red", $("#subDiv2", e).css(CSS.COLOR, false));
+ assertEquals("red", $("#subSubDiv2", e).css(CSS.COLOR, false));
+ assertEquals("", $("#mainDiv", e).css(CSS.COLOR, false));
+ assertEquals("", $("#p1", e).css(CSS.COLOR, false));
+ assertEquals("", $("#p2", e).css(CSS.COLOR, false));
+
+ $("#p1",e).parentsUntil(".subDiv").css(CSS.COLOR.with(RGBColor.YELLOW));
+ assertEquals("red", $("#subDiv1", e).css(CSS.COLOR));
+ assertEquals("yellow", $("#subSubDiv1", e).css(CSS.COLOR));
+
+ // is()
+ content = "<form><input type=\"checkbox\"></form>";
+ $(e).html(content);
+ assertEquals(true, $("input[type=\"checkbox\"]", e).parent().is("form"));
+
+ // is()
+ content = "<form><p><input type=\"checkbox\"></p></form>";
+ $(e).html(content);
+ assertEquals(false, $("input[type='checkbox']", e).parent().is("form"));
+
+ // next()
+ content = "<p>Hello</p><p>Hello Again</p><div><span>And Again</span></div>";
+ String next1 = "<p>Hello Again</p>";
+ String next2 = "<div><span>And Again</span></div>";
+ $(e).html(content);
+ assertEquals(2, $("p", e).next().size());
+ assertHtmlEquals(next1, $("p", e).next().get(0).getString());
+ assertHtmlEquals(next2, $("p", e).next().get(1).getString());
+
+ // next()
+ content = "<p>Hello</p><p class=\"selected\">Hello Again</p><div><span>And Again</span></div>";
+ expected = "<p class=\"selected\">Hello Again</p>";
+ $(e).html(content);
+ assertEquals(1, $("p", e).next(".selected").size());
+ assertHtmlEquals(expected, $("p", e).next(".selected").get(0).getString());
+
+ // nextAll()
+ content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li>i5</li></ul>";
+ expected = "<li>i4</li><li>i5</li>";
+ $(e).html(content);
+ assertEquals(2, $("li.third-item", e).nextAll().size());
+ assertHtmlEquals(expected, $("li.third-item", e).nextAll());
+
+ // nextUntil()
+ content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
+ expected = "<li>i4</li>";
+ $(e).html(content);
+ assertEquals(1, $("li.third-item", e).nextUntil(".five-item").size());
+ assertHtmlEquals(expected, $("li.third-item", e).nextUntil(".five-item"));
+
+
+ // andSelf()
+ content = "<ul><li>i1</li><li>i2</li><li class=\"third-item\">i3</li><li>i4</li><li>i5</li></ul>";
+ expected = "<li>i4</li><li>i5</li><li class=\"third-item\">i3</li>";
+ $(e).html(content);
+ assertEquals(3, $("li.third-item", e).nextAll().andSelf().size());
+ assertHtmlEquals(expected, $("li.third-item", e).nextAll().andSelf());
+
+ // prev()
+ content = "<p>Hello</p><div><span>Hello Again</span></div><p>And Again</p>";
+ expected = "<div><span>Hello Again</span></div>";
+ $(e).html(content);
+ assertEquals(1, $("p", e).prev().size());
+ assertHtmlEquals(expected, $("p", e).prev().get(0).getString());
+
+ // prev()
+ content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
+ expected = "<p class=\"selected\">Hello Again</p>";
+ $(e).html(content);
+ assertEquals(2, $("p", e).prev().size());
+ assertEquals(1, $("p", e).prev(".selected").size());
+ assertHtmlEquals(expected, $("p", e).prev(".selected").get(0).getString());
+
+ // prevAll()
+ content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
+ expected = "<li>i4</li><li class='third-item'>i3</li><li>i2</li><li>i1</li>";
+ $(e).html(content);
+ assertEquals(4, $("li.five-item", e).prevAll().size());
+ assertHtmlEquals(expected, $("li.five-item", e).prevAll());
+
+
+ // prevUntil()
+ content = "<ul><li>i1</li><li>i2</li><li class='third-item'>i3</li><li>i4</li><li class='five-item'>i5</li></ul>";
+ expected = "<li>i4</li>";
+ $(e).html(content);
+ assertEquals(1, $("li.five-item", e).prevUntil(".third-item").size());
+ assertHtmlEquals(expected, $("li.five-item", e).prevUntil(".third-item"));
+
+ // siblings()
+ content = "<p>Hello</p><div id='mdiv'><span>Hello Again</span></div><p>And Again</p>";
+ next1 = "<p>Hello</p>";
+ next2 = "<p>And Again</p>";
+ $(e).html(content);
+ assertEquals(2, $("#mdiv", e).siblings().size());
+ assertHtmlEquals(next1, $("#mdiv", e).siblings().get(0).getString());
+ assertHtmlEquals(next2, $("#mdiv", e).siblings().get(1).getString());
+
+ // siblings()
+ content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
+ expected = "<p class=\"selected\">Hello Again</p>";
+ $(e).html(content);
+ assertEquals(1, $("p", e).siblings(".selected").size());
+ assertHtmlEquals(expected,
+ $("p", e).siblings(".selected").get(0).getString());
+
+ // children()
+ content = "<p>Hello</p><div id='mdiv'><span>Hello Again</span></div><p>And Again</p>";
+ expected = "<span>Hello Again</span>";
+ $(e).html(content);
+ assertHtmlEquals(expected, $("#mdiv", e).children());
+
+ // children()
+ content = "<div id='mdiv'><span>Hello</span><p class=\"selected\">Hello Again</p><p>And Again</p></div>";
+ expected = "<p class=\"selected\">Hello Again</p>";
+ $(e).html(content);
+ assertHtmlEquals(expected, $("#mdiv", e).children(".selected"));
+
+ // contains()
+ content = "<p>This is just a test.</p><p>So is this</p>";
+ expected = "<p>This is just a test.</p>";
+ $(e).html(content);
+ assertHtmlEquals(expected, $("p", e).contains("test"));
+ }
+
+ public void testReplaceMethods() {
+ String content = "<div><div class='inner first'>Hello</div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
+
+ $(e).html(content);
+ GQuery $inner = $(".inner").replaceWith("<h3>blop</h3>");
+ String expectedHtml = "<div><h3>blop</h3><h3>blop</h3><h3>blop</h3></div>";
+ assertEquals(expectedHtml, $(e).html());
+
+ // the returned gquery object should be the original with the div elements
+ assertEquals(3, $inner.filter("div.inner").length());
+
+ $(e).html(content);
+ // the css part below allows us to check if the objects returned by the
+ // replaceAll method are the new inserted elements
+ $("<h3>blop</h3>").replaceAll($(".inner")).css(CSS.COLOR.with(RGBColor.RED));
+ // $(e) must content 3 h3
+ assertEquals(3, $("h3", e).length());
+ // the objects returned by the replaceAll method should be the 3 inserted h3
+ assertEquals("red", $("h3", e).css(CSS.COLOR));
+
+
+ $(e).html(content);
+ $(".third").replaceWith($(".first"));
+ expectedHtml = "<div><div class=\"inner second\">And</div><div class=\"inner first\">Hello</div></div>";
+ assertEquals($(e).html(), expectedHtml);
+
+ $(e).html(content);
+ $(".first").replaceAll(".third");
+ assertEquals($(e).html(), expectedHtml);
+
+ }
+
+ public void testShowHide() {
+ $(e).html(
+ "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
+
+ final GQuery sectA = $("#id1");
+ final GQuery sectB = $("#id2");
+ final GQuery sectC = $("#id3");
+
+ // hide()
+ sectA.hide();
+ assertEquals("none", sectA.css("display", false));
+ sectB.hide();
+ assertEquals("none", sectB.css("display", false));
+
+ // show()
+ sectA.show();
+ assertEquals("inline", sectA.css("display", false));
+ sectB.show();
+ assertEquals("", sectB.css("display", false));
+
+ // toggle()
+ assertEquals("", sectC.css("display", false));
+ sectC.toggle();
+ assertEquals("none", sectC.css("display", false));
+ sectC.toggle();
+ assertEquals("block", sectC.css("display", false));
+ }
+
+ public void testSliceMethods() {
+ String content = "<p>This is just a test.</p><p>So is this</p>";
+ $(e).html(content);
+
+ String expected = "<p>So is this</p>";
+ assertEquals(1, $("p", e).eq(1).size());
+ assertHtmlEquals(expected, $("p", e).eq(1));
+
+ expected = "<p>This is just a test.</p>";
+ assertEquals(1, $("p", e).lt(1).size());
+ assertHtmlEquals(expected, $("p", e).lt(1));
+
+ expected = "<p>So is this</p>";
+ assertEquals(1, $("p", e).gt(0).size());
+ assertHtmlEquals(expected, $("p", e).gt(0));
+
+ assertEquals(2, $("p", e).slice(0, 2).size());
+ assertEquals(2, $("p", e).slice(0, -1).size());
+ assertEquals(0, $("p", e).slice(3, 2).size());
+ }
+
+ public void testGetEqLastFirstMethods(){
+ String content = "<div id='1'>blop1</div><div id='2'>blop2</div><div id='3'>blop3</div><div id='4'>blop4</div>";
+ $(e).html(content);
+
+ GQuery divs =$("div",e);
+ assertEquals(4, divs.size());
+ assertEquals("1", divs.get(0).getId());
+ assertEquals("2", divs.get(1).getId());
+ assertEquals("3", divs.get(2).getId());
+ assertEquals("4", divs.get(3).getId());
+ assertEquals("1", divs.get(-4).getId());
+ assertEquals("2", divs.get(-3).getId());
+ assertEquals("3", divs.get(-2).getId());
+ assertEquals("4", divs.get(-1).getId());
+
+ assertEquals(1, divs.first().size());
+ assertEquals("1", divs.first().get(0).getId());
+
+ assertEquals(1, divs.last().size());
+ assertEquals("4", divs.last().get(0).getId());
+
+ assertEquals(1, divs.eq(0).size());
+ assertEquals("1", divs.eq(0).get(0).getId());
+ assertEquals(1, divs.eq(1).size());
+ assertEquals("2", divs.eq(1).get(0).getId());
+ assertEquals(1, divs.eq(2).size());
+ assertEquals("3", divs.eq(2).get(0).getId());
+ assertEquals(1, divs.eq(3).size());
+ assertEquals("4", divs.eq(3).get(0).getId());
+
+ assertEquals(1, divs.eq(-4).size());
+ assertEquals("1", divs.eq(-4).get(0).getId());
+ assertEquals(1, divs.eq(-3).size());
+ assertEquals("2", divs.eq(-3).get(0).getId());
+ assertEquals(1, divs.eq(-2).size());
+ assertEquals("3", divs.eq(-2).get(0).getId());
+ assertEquals(1, divs.eq(-1).size());
+ assertEquals("4", divs.eq(-1).get(0).getId());
+
+
+ }
+
+ public void testUnique() {
+ SelectorEngineImpl selSizz = new SelectorEngineSizzle();
+ GQuery g = $(e).html("<div><p></p><p></p><span></span><p></p>");
+ JsNodeArray a;
+ a = selSizz.select("p", e).cast();
+ assertEquals(3, a.getLength());
+ a.addNode(a.getNode(0));
+ a.addNode(a.getNode(3));
+ assertEquals(5, a.getLength());
+ a = g.unique(a);
+ assertEquals(3, a.getLength());
+ }
+
+ public void testUtilsEq() {
+ assertTrue(JsUtils.eq("a", "a"));
+ assertTrue(JsUtils.eq(true, true));
+ assertTrue(JsUtils.eq(45, 45));
+ assertTrue(JsUtils.eq(45d, 45f));
+ assertTrue(JsUtils.eq("", ""));
+ assertTrue(JsUtils.eq(0.45, 0.45));
+ assertTrue(JsUtils.eq(0.45d, 0.45d));
+ assertTrue(JsUtils.eq(0.45f, 0.45f));
+
+ assertFalse(JsUtils.eq("a", ""));
+ assertFalse(JsUtils.eq(true, false));
+ assertFalse(JsUtils.eq(45, 42));
+ assertFalse(JsUtils.eq("", null));
+ assertFalse(JsUtils.eq(0.45, 0.451));
+
+ // assertEquals("a", GQUtils.or("a", ""));
+ }
+
+ public void testUtilsTruth() {
+ assertTrue(JsUtils.truth("a"));
+ assertTrue(JsUtils.truth(this));
+ assertTrue(JsUtils.truth(45));
+ assertTrue(JsUtils.truth(0.33));
+ assertTrue(JsUtils.truth(45l));
+ assertTrue(JsUtils.truth(45d));
+ assertTrue(JsUtils.truth(45f));
+ assertTrue(JsUtils.truth(0.33f));
+
+ assertFalse(JsUtils.truth(0));
+ assertFalse(JsUtils.truth(0l));
+ assertFalse(JsUtils.truth(0d));
+ assertFalse(JsUtils.truth(00.00d));
+ assertFalse(JsUtils.truth(00.00f));
+ assertFalse(JsUtils.truth(null));
+ assertFalse(JsUtils.truth(""));
+ }
+
+ public void testVal_issue98() {
+ $(e).html(""
+ +"<input type='text' id='inputText' name='inputText' value='original' />"
+ +"<textarea id='textArea' name='textArea'>original</textarea>"
+ +"<button id='button' name='button'value='original'>Click</button>"
+
+ +"<select id='selectSingle' name='selectSingle'>"
+ +"<option value='v0'>Single0</option>"
+ +"<option value='v1'>Single1</option>"
+ +"<option value='v2'>Single2</option>"
+ +"</select>"
+
+ +"<select id='selectMultiple' name='selectMultiple' multiple='multiple'>"
+ +"<option value='v0'>Multiple0</option>"
+ +"<option value='v1'>Multiple1</option>"
+ +"<option value='v2'>Multiple2</option>"
+ +"</select><br/>"
+
+ +"<input type='checkbox' name='c' value='v0'/> check0"
+ +"<input type='checkbox' name='c' value='v1'/> check1"
+ +"<input type='checkbox' name='c' value='v2'/> check2"
+
+ +"<input type='radio' name='r' value='v0'/> radio0"
+ +"<input type='radio' name='r' value='v1'/> radio1"
+ +"<input type='radio' name='r' value='v2'/> radio2"
+ );
+
+ assertNull($().val());
+ assertEquals(0, $().vals().length);
+
+ assertEquals("original", $("#inputText", e).val());
+ assertEquals("original", $("#textArea", e).val());
+ assertEquals("original", $("#button", e).val());
+ $("#inputText, #textArea, #button", e).val("newval");
+ assertEquals("newval", $("#inputText", e).val());
+ assertEquals("newval", $("#textArea", e).val());
+ assertEquals("newval", $("#button", e).val());
+
+ assertEquals("v0", $("#selectSingle", e).val());
+ assertNull($("#selectMultiple", e).val());
+ $("#selectSingle, #selectMultiple", e).val("v2");
+ assertEquals("v2", $("#selectSingle", e).val());
+ assertEquals("v2", $("#selectMultiple", e).val());
+
+ assertEquals("v0", $("input[type='checkbox']", e).val());
+ assertNull($("input[type='checkbox']:checked", e).val());
+ // val(String) changes the value attribute, but not set it as checked
+ $("input[type='checkbox']", e).eq(0).val("n0");
+ assertEquals("n0", $("input[type='checkbox']", e).val());
+ assertNull($("input[type='checkbox']:checked", e).val());
+ // val(array) set the checked property to true if the value name matches
+ $("input[type='checkbox']", e).val(new String[]{"n0"});
+ assertEquals("n0", $("input[type='checkbox']", e).val());
+ assertNotNull($("input[type='checkbox']:checked", e).val());
+
+ assertEquals("v0", $("input[type='radio']", e).val());
+ assertNull($("input[type='radio']:checked", e).val());
+ $("input[type='radio']").eq(0).val("n0");
+ assertEquals("n0", $("input[type='radio']", e).val());
+ assertNull($("input[type='radio']:checked", e).val());
+
+// evalJQuery("$('input, select, textarea, button').val(['whatever', 'v1', 'v2'])");
+ $("input, select, textarea, button").val("whatever", "v1", "v2");
+
+ String joinVals = "whatever,v1,v2";
+ assertEquals(joinVals, $("#inputText", e).val());
+ assertEquals(joinVals, $("#textArea", e).val());
+ assertEquals(joinVals, $("#button", e).val());
+ assertEquals("v2", $("#selectSingle", e).val());
+ assertEquals("v1", $("#selectMultiple", e).vals()[0]);
+ assertEquals("v2", $("#selectMultiple", e).vals()[1]);
+ assertEquals(2, $("input[type='checkbox']:checked", e).size());
+ assertEquals("v1", $("input[type='checkbox']:checked", e).eq(0).val());
+ assertEquals("v2", $("input[type='checkbox']:checked", e).eq(1).val());
+ assertEquals(1, $("input[type='radio']:checked", e).size());
+ assertEquals("v2", $("input[type='radio']:checked", e).val());
+ }
+
+
+ public void testAttr_Issue97() {
+ $(e).html("<input type='checkbox' id='cb' name='cb' value='1' />");
+ assertNull($("#cb:checked", e).val());
+
+ $("#cb", e).attr("checked", "checked");
+ assertEquals(1, $("#cb:checked", e).length());
+ assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
+ assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
+ assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
+
+ $("#cb", e).removeAttr("checked");
+ assertEquals(0, $("#cb:checked", e).length());
+ assertEquals(false, InputElement.as($("#cb", e).get(0)).isChecked());
+ assertEquals("", $("#cb", e).get(0).getAttribute("checked"));
+ assertEquals(false, $("#cb", e).get(0).getPropertyBoolean("checked"));
+
+ $("#cb", e).attr("checked", true);
+ assertEquals(1, $("#cb:checked", e).length());
+ assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
+ assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
+ assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
+
+ $("#cb", e).attr("checked", false);
+ assertEquals(0, $("#cb:checked", e).length());
+ assertEquals(false, InputElement.as($("#cb", e).get(0)).isChecked());
+ assertEquals("", $("#cb", e).get(0).getAttribute("checked"));
+ assertEquals(false, $("#cb", e).get(0).getPropertyBoolean("checked"));
+
+ $("#cb", e).attr("checked", "");
+ assertEquals(1, $("#cb:checked", e).length());
+ assertEquals(true, InputElement.as($("#cb", e).get(0)).isChecked());
+ assertEquals("checked", $("#cb", e).get(0).getAttribute("checked"));
+ assertEquals(true, $("#cb", e).get(0).getPropertyBoolean("checked"));
+
+ GQuery gq = $("<div></div>test<!-- a comment-->");
+ gq.attr("class", "test1");
+
+ assertEquals("test1", gq.get(0).getClassName());
+ assertEquals("test1", gq.attr("class"));
+ assertNull(gq.get(0).getPropertyString("class"));
+
+ gq.removeAttr("class");
+ assertEquals("", gq.get(0).getClassName());
+ assertEquals("", gq.attr("class"));
+
+ //test on value
+ $("#cb", e).attr("value", "mail");
+ assertEquals("mail", InputElement.as($("#cb", e).get(0)).getValue());
+ assertEquals("mail", $("#cb", e).get(0).getAttribute("value"));
+
+ $("#cb", e).removeAttr("value");
+ assertEquals("", InputElement.as($("#cb", e).get(0)).getValue());
+ assertEquals("", $("#cb", e).get(0).getAttribute("value"));
+
+ try{
+ $("#cb", e).attr("type", "hidden");
+ fail("Cannnot change a type of an element already attached to the dom");
+ }catch (Exception e){}
+
+ gq = $("<input type='text' value='blop'></input>");
+ gq.attr("type", "radio");
+ assertEquals("radio", InputElement.as(gq.get(0)).getType());
+ assertEquals("blop", InputElement.as(gq.get(0)).getValue());
+
+
+
+ gq.attr(Properties.create("{class:'test2', disabled:true}"));
+ InputElement ie = InputElement.as(gq.get(0));
+
+ assertEquals("test2", ie.getClassName());
+ assertEquals(true, ie.isDisabled());
+ assertEquals("disabled", ie.getAttribute("disabled"));
+
+ }
+
+ public void testWidthHeight() {
+ $(e).html(
+ "<div style='border: 1px solid red; padding: 10px; margin:10px; width: 100px; height: 100px'>Content 1</div>");
+ GQuery g = $("div", e);
+ assertEquals(100, g.width());
+ assertEquals(100, g.height());
+ assertEquals(120, g.innerWidth());
+ assertEquals(120, g.innerHeight());
+ assertEquals(100d, g.cur("width", false));
+ assertEquals(100d, g.cur("height", false));
+ assertEquals(100d, g.cur("width", true));
+ assertEquals(100d, g.cur("height", true));
+ assertEquals("100px", g.css("width"));
+ assertEquals("100px", g.css("height"));
+ assertEquals("100px", g.get(0).getStyle().getProperty("width"));
+ assertEquals("100px", g.get(0).getStyle().getProperty("height"));
+ assertEquals(122, g.outerHeight());
+ assertEquals(122, g.outerWidth());
+ assertEquals(142, g.outerHeight(true));
+ assertEquals(142, g.outerWidth(true));
+
+ }
+
+ public void testWrapMethod() {
+ String content = "<p>Test Paragraph.</p>";
+ String wrapper = "<div id=\"content\">Content</div>";
+
+ String expected = "<div id=\"content\">Content<p>Test Paragraph.</p></div>";
+ $(e).html(content);
+
+ $("p", e).wrap(wrapper);
+ assertHtmlEquals(expected, $(e).html());
+
+ $(e).html(content + wrapper);
+ expected = "<b><p>Test Paragraph.</p></b><b><div id=\"content\">Content</div></b>";
+ $("*", e).wrap("<b></b>");
+ assertHtmlEquals(expected, $(e).html());
+ }
+
+
+ public void testFilterBody() {
+ GQuery myNewElement = $("<div>my new div</div>");
+ boolean isAttachedToTheDOM = myNewElement.parents().filter("body").size() > 0;
+ assertEquals(false, isAttachedToTheDOM);
+
+ myNewElement.appendTo(document);
+ isAttachedToTheDOM = myNewElement.parents().filter("body").size() > 0;
+ assertEquals(true, isAttachedToTheDOM);
+ }
+
+ public void testFilterMethod(){
+ // first test filter on element attached to the DOM
+ String content = "<div class='outer'><div class='inner first'>Hello <span>blop</span></div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
+
+ $(e).html(content);
+
+ assertEquals(5, $("*", e).length());
+ assertEquals(4, $("*", e).filter("div").length());
+ assertEquals(1, $("*", e).filter("div.outer").length());
+ assertEquals(3, $("*", e).filter("div.inner").length());
+ assertEquals(1, $("*", e).filter("span").length());
+
+ GQuery $html = $("<div>div1</div><div>div2</div><div>div3</div><span>span1</span>");
+ assertEquals(3, $html.filter("div").length());
+ assertEquals(1, $html.filter("span").length());
+
+ JsNodeArray array = JsNodeArray.create();
+ for (int i = 0 ; i < 3; i++){
+ array.addNode(DOM.createDiv());
+ }
+ assertEquals(3, $(array).filter("div").length());
+
+
+ String content2 = "<div><div class='inner first'>Hello</div><div class='inner second'>And</div><div class='inner third'>Goodbye</div></div>";
+ $(e).html(content2);
+ //the inner object contains the 3 div that are detached from the dom
+ GQuery $inner = $(".inner").replaceWith("<h3>blop</h3>");
+ assertEquals(3, $inner.filter("div").length());
+ }
+
+ public void testGQueryWidgets() {
+ final Button b1 = new Button("click-me");
+ RootPanel.get().add(b1);
+
+ GQuery g = $(b1);
+ Button b2 = g.widget();
+ assertEquals(b1, b2);
+
+ b2 = new Button("click-me");
+ RootPanel.get().add(b2);
+ b2.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ $(b1).css("color", "red");
+ }
+ });
+
+ (b2).click();
+ assertEquals("red", $(b1).css("color"));
+
+ $("<button>Click-me</button>").appendTo(document);
+ assertEquals(3, $("button").size());
+ assertEquals(2, $("button").widgets(Button.class).size());
+ assertEquals(2, $($("button").widgets(Button.class)).size());
+
+ assertEquals(2, $(new Label(""), new TextArea()).size());
+ }
+
+ public void testGQueryWidgetManipulation() {
+
+ String content = "<div class='outer'></div>";
+ $(e).html(content);
+ Button b = new Button("b");
+ RootPanel.get().add(b);
+ assertTrue(b.isAttached());
+ $("button").remove();
+ assertFalse(b.isAttached());
+
+ RootPanel.get().add(b);
+ assertTrue(b.isAttached());
+ $(e).append($(b));
+ assertTrue(b.isAttached());
+ $(e).empty();
+ // FIXME: assertFalse(b.isAttached());
+
+ }
+
+ public void testGQueryMap() {
+ String content = "<p id='1'/><p/><p id='2'/><p id='4'/>";
+ $(e).html(content);
+
+ List<String> s = $("p", e).map(new Function() {
+ public Object f(Element e, int i) {
+ return null;
+ }
+ });
+ assertNotNull(s);
+ assertEquals(0, s.size());
+
+ s = $("p", e).map(new Function() {
+ public Object f(Element e, int i) {
+ String id = $(e).attr("id");
+ return id.isEmpty() ? null : id;
+ }
+ });
+ assertEquals(3, s.size());
+ assertEquals("1", s.get(0));
+ assertEquals("2", s.get(1));
+ assertEquals("4", s.get(2));
+
+ List<Element> a = $("p", e).map(new Function() {
+ public Object f(Element e, int i) {
+ String id = $(e).attr("id");
+ return id.isEmpty() ? null : e;
+ }
+ });
+ assertEquals(3, a.size());
+ assertEquals(3, $(a).size());
+
+ }
+
+ public void testHtmlSnippet(){
+
+ GQuery gq = $("<div>blop</div><p>test</p><span>test</span>");
+ assertEquals(3, gq.size());
+ assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
+ assertEquals("P", gq.get(1).getTagName().toUpperCase());
+ assertEquals("SPAN", gq.get(2).getTagName().toUpperCase());
+
+ //xhtml tag
+ gq = $("<div/>");
+ assertEquals(1, gq.size());
+ assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
+
+ gq = $("<a/>");
+ assertEquals(1, gq.size());
+ assertEquals("A", gq.get(0).getTagName().toUpperCase());
+
+ gq = $("<div>");
+ assertEquals(1, gq.size());
+ assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
+
+ //issue 81 : trailing spaces
+ gq = $(" <div>blop</div><p>test</p><span>test</span> ");
+ assertEquals(3, gq.size());
+ assertEquals("DIV", gq.get(0).getTagName().toUpperCase());
+ assertEquals("P", gq.get(1).getTagName().toUpperCase());
+ assertEquals("SPAN", gq.get(2).getTagName().toUpperCase());
+
+ //wrapping
+ gq = $("<tr>blop</tr><tr>test</tr>");
+ assertEquals(2, gq.size());
+ assertEquals("TR", gq.get(0).getTagName().toUpperCase());
+ assertEquals("TR", gq.get(1).getTagName().toUpperCase());
+ //same in uppercase
+ gq = $("<TR>blop</TR><tr>test</tr>");
+ assertEquals(2, gq.size());
+ assertEquals("TR", gq.get(0).getTagName().toUpperCase());
+ assertEquals("TR", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<td>blop</td><td>test</td>");
+ assertEquals(2, gq.size());
+ assertEquals("TD", gq.get(0).getTagName().toUpperCase());
+ assertEquals("TD", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<th>blop</th><th>test</th>");
+ assertEquals(2, gq.size());
+ assertEquals("TH", gq.get(0).getTagName().toUpperCase());
+ assertEquals("TH", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<col/><col/>");
+ assertEquals(2, gq.size());
+ assertEquals("COL", gq.get(0).getTagName().toUpperCase());
+ assertEquals("COL", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<area/><area/>");
+ assertEquals(2, gq.size());
+ assertEquals("AREA", gq.get(0).getTagName().toUpperCase());
+ assertEquals("AREA", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<option>blop</option><option>test</option>");
+ assertEquals(2, gq.size());
+ assertEquals("OPTION", gq.get(0).getTagName().toUpperCase());
+ assertEquals("OPTION", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<legend>blop</legend><legend>test</legend>");
+ assertEquals(2, gq.size());
+ assertEquals("LEGEND", gq.get(0).getTagName().toUpperCase());
+ assertEquals("LEGEND", gq.get(1).getTagName().toUpperCase());
+
+ gq = $("<thead>blop</thead><thead>test</thead>");
+ assertEquals(2, gq.size());
+ assertEquals("THEAD", gq.get(0).getTagName().toUpperCase());
+ assertEquals("THEAD", gq.get(1).getTagName().toUpperCase());
+
+ //issue
+ gq = $("<select name=\"modificator\"><option value=\"work\" selected=\"selected"
+ +"\">Work</option><option value=\"work_fax\" >Work fax</option><option "
+ +"value=\"home\" >Home</option><option value=\"other\" >Other</"
+ +"option><option value=\"home_fax\" >Home fax</option><option value=\"main\" >Main</option></select>");
+
+ assertEquals(1, gq.size());
+
+ assertEquals("SELECT", gq.get(0).getTagName().toUpperCase());
+ assertEquals(6, gq.get(0).getChildCount());
+
+
+ }
+
+
+ public void testNulls() {
+ Assert.assertEquals(0, $((Node) null).size());
+ Assert.assertEquals(0, $((Element) null).size());
+ Assert.assertEquals(0, $((String) null).size());
+ Assert.assertNull($((String) null).get(0));
+ Assert.assertNull($((String) null).get(-1));
+ Assert.assertEquals(0, $((String) null).eq(0).size());
+ }
+
+ public void testRemoveMethod(){
+ String html = "<div id='parent'>parent<div id='child'>child</div></div>";
+ $(e).html(html);
+
+ Function failCallback = new Function(){
+ @Override
+ public void f() {
+ fail("Event binding not removed");
+ }
+ };
+
+ Element parent = $("#parent", e).get(0);
+ Element child = $("#child", e).get(0);
+
+ $("#child", e).data("key", "child");
+ $("#child", e).click(failCallback);
+ $("#parent", e).data("key", "parent");
+ $("#parent", e).click(failCallback);
+
+ $("#parent", e).remove();
+
+ //child and the parent was removed
+ assertEquals(0,$("#child", e).length());
+ assertEquals(0,$("#parent", e).length());
+
+ assertNull($(child).data("key"));
+ assertNull($(parent).data("key"));
+ //if failCallback is always binded, test fails...
+ $(child).click();
+ $(parent).click();
+
+
+
+ }
+
+ public void testRemoveMethodWithFilter(){
+ String html = "<div id='parent'>parent<div id='child'>child</div></div>";
+ $(e).html(html);
+
+ Function failCallback = new Function(){
+ @Override
+ public void f() {
+ fail("Event binding not removed");
+ }
+ };
+
+ Function noFailCallback = new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
+ }
+ };
+
+ Element parent = $("#parent", e).get(0);
+ Element child = $("#child", e).get(0);
+
+ $("#child", e).data("key", "child");
+ $("#child", e).click(failCallback);
+ $("#parent", e).data("key", "parent");
+ $("#parent", e).click(noFailCallback);
+
+ $("div", e).remove("#child");
+
+ //child was removed but not the parent
+ assertEquals(0,$("#child", e).length());
+ assertEquals(1,$("#parent", e).length());
+
+ assertNull($(child).data("key"));
+ assertEquals("parent",$(parent).data("key"));
+
+ //if failCallback is always binded, test fails...
+ $(child).click();
+
+
+ $(parent).click();
+ assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR, false));
+ }
+
+ public void testDetachMethod(){
+ String html = "<div id='parent'>parent<div id='child'>child</div></div>";
+ $(e).html(html);
+
+ Function noFailCallback = new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
+ }
+ };
+
+ Element parent = $("#parent", e).get(0);
+ Element child = $("#child", e).get(0);
+
+ $("#child", e).data("key", "child");
+ $("#child", e).click(noFailCallback);
+ $("#parent", e).data("key", "parent");
+ $("#parent", e).click(noFailCallback);
+
+ GQuery $parent = $("#parent", e).detach();
+
+ //test parent an child well detached
+ assertEquals(0,$("#parent", e).length());
+ assertEquals(0,$("#child", e).length());
+ //test that data was not cleaned
+ assertEquals("child",$(child).data("key"));
+ assertEquals("parent",$(parent).data("key"));
+
+ $(e).append($parent);
+
+ assertEquals(1,$("#parent", e).length());
+ assertEquals(1,$("#child", e).length());
+ assertEquals("child",$("#child", e).data("key"));
+ assertEquals("parent",$("#parent", e).data("key"));
+
+ $("#child", e).click();
+ assertEquals("red", $(child).css(CSS.BACKGROUND_COLOR, false));
+ $("#parent", e).click();
+ assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR, false));
+ }
+
+ public void testDetachMethodWithFilter(){
+ String html = "<div id='parent'>parent<div id='child'>child</div></div>";
+ $(e).html(html);
+
+ Function noFailCallback = new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED));
+ }
+ };
+
+ Element parent = $("#parent", e).get(0);
+ Element child = $("#child", e).get(0);
+
+ $("#child", e).data("key", "child");
+ $("#child", e).click(noFailCallback);
+ $("#parent", e).data("key", "parent");
+ $("#parent", e).click(noFailCallback);
+
+ $("div", e).detach("#child");
+
+ //child was removed but not the parent
+ assertEquals(0,$("#child", e).length());
+ assertEquals(1,$("#parent", e).length());
+
+ //data must always exist
+ assertEquals("child", $(child).data("key"));
+ assertEquals("parent",$(parent).data("key"));
+
+ $(e).append($(child));
+
+ assertEquals(1,$("#child", e).length());
+ assertEquals(1,$("#parent", e).length());
+
+ $(child).click();
+ assertEquals("red", $("#child", e).css(CSS.BACKGROUND_COLOR, false));
+
+ $(parent).click();
+ assertEquals("red", $("#parent", e).css(CSS.BACKGROUND_COLOR, false));
+ }
+
+ public void testUnwrapMethod(){
+ String html = "<div class='parent'><div class='child'>child1</div><span>other child</span></div><div class='parent'><div class='child'>child2</div></div><div class='parent'><div class='child'>child3</div></div>";
+ $(e).html(html);
+
+ assertEquals(3, $(".parent", e).length());
+ assertEquals(3, $(".child", e).length());
+
+ $(".child",e).unwrap();
+
+ assertEquals(0, $(".parent",e).length());
+ assertEquals(3, $(".child",e).length());
+
+ String expectedHtml = "<div class=\"child\">child1</div><span>other child</span><div class=\"child\">child2</div><div class=\"child\">child3</div>";
+
+ assertEquals(expectedHtml, $(e).html());
+
+ }
+
+ public void testClosestMethod(){
+ String html = "<div><p><div id='firstDiv'><p id='firstP'><span><input id='firstInput' type='text'></input></span></p></div></p></div>";
+ $(e).html(html);
+
+ GQuery closeP = $("input", e).closest("p,div");
+
+ assertEquals(1, closeP.length());
+ assertEquals("firstP", closeP.get(0).getId());
+
+ GQuery closeDiv = $("input", e).closest("div");
+
+ assertEquals(1, closeDiv.length());
+ assertEquals("firstDiv", closeDiv.get(0).getId());
+
+ GQuery closeInput = $("input", e).closest("input");
+
+ assertEquals(1, closeInput.length());
+ assertEquals("firstInput", closeInput.get(0).getId());
+
+ GQuery closeUnknown = $("input", e).closest("h1");
+
+ assertEquals(0, closeUnknown.length());
+
+ GQuery closePWithContext = $("input", e).closest("p,div",$("#firstDiv",e).get(0));
+
+ assertEquals(1, closePWithContext.length());
+ assertEquals("firstP", closePWithContext.get(0).getId());
+
+ GQuery closeDivWithContext = $("input", e).closest("div",$("#firstP",e).get(0));
+
+ assertEquals(0, closeDivWithContext.length());
+
+ }
+
+ public void testClosestMethodWithArrayOfString(){
+
+ String html = "<div id='mainDiv'><div id='subDiv' class='test'><div id='subSubDiv'><p id='mainP'><span id='testSpan' class='test'><input id='firstInput' type='text'></input></span></p></div></div></div>";
+ $(e).html(html);
+
+ JsNamedArray<NodeList<Element>> close = $("input", e).closest(new String[]{"p","div", ".test", "#unknown"});
+
+ assertEquals(3, close.length());
+
+ assertNotNull(close.get("p"));
+ assertEquals(1,close.get("p").getLength());
+ assertEquals("mainP", close.get("p").getItem(0).getId());
+
+ assertNotNull(close.get("div"));
+ assertEquals(3,close.get("div").getLength());
+ assertEquals("subSubDiv", close.get("div").getItem(0).getId());
+ assertEquals("subDiv", close.get("div").getItem(1).getId());
+ assertEquals("mainDiv", close.get("div").getItem(2).getId());
+
+ assertNotNull(close.get(".test"));
+ assertEquals(2,close.get(".test").getLength());
+ assertEquals("testSpan", close.get(".test").getItem(0).getId());
+ assertEquals("subDiv", close.get(".test").getItem(1).getId());
+
+ assertNull(close.get("#unknown"));
+
+ }
+
+ public void testMap() {
+ String html = "<div class='d' id='6'></div>" +
+ "<span class='s' id='5'></span>" +
+ "<p class='p' id='4'></p>" +
+ "<em class='d' id='3'></em>" +
+ "<b class='s' id='2'></b>" +
+ "<i class='p' id='1'></i>" +
+ "<strong></strong>";
+ $(e).html(html);
+
+ GQuery c = $(e).children();
+ assertEquals(7, c.size());
+
+ // A list of lists containing tag,class,id, remove elements without id
+ List<List<String>> m = $(e).children().map(new Function() {
+ public List<String> f(Element e, int i) {
+ // map does not add to the list null elements
+ if ($(e).attr("id").isEmpty() || $(e).attr("class").isEmpty()) {
+ return null;
+ }
+ List<String> attrs = new ArrayList<String>();
+ attrs.add(e.getTagName());
+ attrs.add($(e).attr("class"));
+ attrs.add($(e).attr("id"));
+ return attrs;
+ }
+ });
+ assertEquals(6, m.size());
+
+ // Sort the list by id
+ assertEquals("div", m.get(0).get(0).toLowerCase());
+ assertEquals("i", m.get(5).get(0).toLowerCase());
+ Collections.sort(m, new Comparator<List<String>>() {
+ public int compare(List<String> o1, List<String> o2) {
+ return o1.get(2).compareTo(o2.get(2));
+ }
+ });
+ assertEquals("div", m.get(5).get(0).toLowerCase());
+ assertEquals("i", m.get(0).get(0).toLowerCase());
+ }
+
+ public void testWindowSize() {
+ GQuery w = $(GQuery.window);
+ assertTrue(w.width() > 0);
+ assertTrue(w.height() > 0);
+ }
+
+ public void testFunction() {
+ $(e).html("<div id=fid>0</div>");
+ GQuery g = $("#fid", e);
+ assertEquals("0", g.text());
+
+ // EACH
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.user.client.Element e) {
+ $(e).text("U");
+ }
+ });
+ assertEquals("U", g.text());
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.dom.client.Element e) {
+ $(e).text("D");
+ }
+ });
+ assertEquals("D", g.text());
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.user.client.Element e, int idx) {
+ $(e).text("U" + idx);
+ return "";
+ }
+ });
+ assertEquals("U0", g.text());
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.user.client.Element e, int idx) {
+ $(e).text("D" + idx);
+ return "";
+ }
+ });
+ assertEquals("D0", g.text());
+
+ // EVENTS
+ g.unbind(Event.ONCLICK).click(new Function(){
+ @Override
+ public void f(com.google.gwt.user.client.Element e) {
+ $(e).text("U");
+ }
+ }).click();
+ assertEquals("U", g.text());
+ g.unbind(Event.ONCLICK).click(new Function(){
+ @Override
+ public void f(com.google.gwt.dom.client.Element e) {
+ $(this).text("D");
+ }
+ }).click();
+ assertEquals("D", g.text());
+ g.unbind(Event.ONCLICK).click(new Function(){
+ @Override
+ public boolean f(Event e) {
+ $(this).text("E");
+ return false;
+ }
+ }).click();
+ assertEquals("E", g.text());
+ g.unbind(Event.ONCLICK).bind(Event.ONCLICK, "D", new Function(){
+ @Override
+ public boolean f(Event e, Object o) {
+ $(e).text("E" + o);
+ return false;
+ }
+ }).click();
+ assertEquals("ED", g.text());
+
+ // ELEMENTS AND WIDGETS
+ Label label = new Label("1");
+ RootPanel.get().add(label);
+ g = $("#fid, .gwt-Label");
+ assertEquals(2, g.size());
+
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.user.client.Element e) {
+ $(e).text("U");
+ }
+ });
+ assertEquals("UU", g.text());
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.dom.client.Element e) {
+ $(e).text("D");
+ }
+ });
+ assertEquals("DD", g.text());
+
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.user.client.Element e) {
+ $(e).text("U");
+ }
+ @Override
+ public void f(Widget w) {
+ $(w).text("W");
+ }
+ });
+ assertEquals("UW", g.text());
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.dom.client.Element e) {
+ $(e).text("D");
+ }
+ @Override
+ public void f(Widget w) {
+ $(w).text("W");
+ }
+ });
+ assertEquals("DW", g.text());
+
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.user.client.Element e, int idx) {
+ $(e).text("U" + idx);
+ return "";
+ }
+ });
+ assertEquals("U0U1", g.text());
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.user.client.Element e, int idx) {
+ $(e).text("D" + idx);
+ return "";
+ }
+ });
+ assertEquals("D0D1", g.text());
+
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.user.client.Element e, int idx) {
+ $(e).text("U" + idx);
+ return "";
+ }
+ @Override
+ public Object f(Widget w, int idx) {
+ $(w).text("W" + idx);
+ return "";
+ }
+ });
+ assertEquals("U0U1", g.text());
+ g.each(new Function() {
+ @Override
+ public Object f(com.google.gwt.dom.client.Element e, int idx) {
+ $(e).text("D" + idx);
+ return "";
+ }
+ @Override
+ public Object f(Widget w, int idx) {
+ $(w).text("W" + idx);
+ return "";
+ }
+ });
+ assertEquals("D0D1", g.text());
+
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.user.client.Element e) {
+ $(e).text("U");
+ }
+ @Override
+ public Object f(Widget w, int idx) {
+ $(w).text("W" + idx);
+ return "";
+ }
+ });
+ assertEquals("UW1", g.text());
+ g.each(new Function() {
+ @Override
+ public void f(com.google.gwt.dom.client.Element e) {
+ $(e).text("D");
+ }
+ @Override
+ public Object f(Widget w, int idx) {
+ $(w).text("W" + idx);
+ return "";
+ }
+ });
+ assertEquals("DW1", g.text());
+
+ label.removeFromParent();
+ }
+
+ public void testXpathSelector() {
+ $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A Text</td><td width=50%>B</td></tr></table>");
+ SelectorEngineCssToXPath s = new SelectorEngineCssToXPath();
+ for (String selector : Arrays.asList("td[width]", "table > tr > td", "*[width!='440']")) {
+ String xselector = s.css2Xpath(selector);
+ assertEquals($(selector).size(), $(xselector).size());
+ }
+ }
+
+ public void testIssue81(){
+ GQuery test = $(" <div>blop</div><!-- comment --> <p>test2</p> ");
+ test.addClass("test");
+ test.removeClass("test");
+ }
+
+ public void testHas() {
+ $(e).html("<ul>"
+ +"<li>list item 1</li>"
+ +"<li id='l2'>list item 2"
+ +" <ul>"
+ +" <li>list item 2-a</li>"
+ +" <li>list item 2-b</li>"
+ +" </ul>"
+ +"</li>"
+ +"<li id='l3'>list item 3 <span>span</span>"
+ +"</li>"
+ +"<li>list item 4</li>"
+ +"</ul>");
+ assertEquals("", $("#l2").css("background-color", false));
+ $("li", e).has("ul").css("background-color", "red");
+ assertEquals("red", $("#l2").css("background-color", false));
+
+ Element span = $("span", e).get(0);
+ assertEquals("l3", $("li", e).has(span).id());
+ }
+
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.Style.Cursor;
-import com.google.gwt.dom.client.Style.Display;
-import com.google.gwt.dom.client.Style.FontStyle;
-import com.google.gwt.dom.client.Style.ListStyleType;
-import com.google.gwt.dom.client.Style.Overflow;
-import com.google.gwt.dom.client.Style.Position;
-import com.google.gwt.dom.client.Style.TextDecoration;
-import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.dom.client.Style.VerticalAlign;
-import com.google.gwt.dom.client.Style.Visibility;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.css.BackgroundAttachmentProperty.BackgroundAttachment;
-import com.google.gwt.query.client.css.BackgroundPositionProperty.BackgroundPosition;
-import com.google.gwt.query.client.css.BackgroundRepeatProperty.BackgroundRepeat;
-import com.google.gwt.query.client.css.BorderCollapseProperty.BorderCollapse;
-import com.google.gwt.query.client.css.BorderSpacingProperty.BorderSpacing;
-import com.google.gwt.query.client.css.BorderStyleProperty.BorderStyle;
-import com.google.gwt.query.client.css.BorderWidthProperty.BorderWidth;
-import com.google.gwt.query.client.css.CSS;
-import com.google.gwt.query.client.css.CaptionSideProperty.CaptionSide;
-import com.google.gwt.query.client.css.ClearProperty.Clear;
-import com.google.gwt.query.client.css.ClipProperty.Shape;
-import com.google.gwt.query.client.css.EmptyCellsProperty;
-import com.google.gwt.query.client.css.FontSizeProperty.FontSize;
-import com.google.gwt.query.client.css.FontVariantProperty.FontVariant;
-import com.google.gwt.query.client.css.Length;
-import com.google.gwt.query.client.css.ListStylePositionProperty.ListStylePosition;
-import com.google.gwt.query.client.css.RGBColor;
-import com.google.gwt.query.client.css.TextAlignProperty.TextAlign;
-import com.google.gwt.query.client.css.TextTransformProperty.TextTransform;
-import com.google.gwt.query.client.css.UnicodeBidiProperty.UnicodeBidi;
-import com.google.gwt.query.client.css.UriValue;
-import com.google.gwt.dom.client.Style.Float;
-
-import com.google.gwt.query.client.css.WhiteSpaceProperty.WhiteSpace;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test class for testing css part.
- */
-public class GQueryCssTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("core-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- public void testBackgroundAttachmentProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(
- CSS.BACKGROUND_ATTACHMENT.with(BackgroundAttachment.FIXED));
-
- assertEquals("fixed", $("#test").css("backgroundAttachment"));
- assertEquals("fixed", $("#test").css(CSS.BACKGROUND_ATTACHMENT));
-
- $("#test").css(
- CSS.BACKGROUND_ATTACHMENT.with(BackgroundAttachment.SCROLL));
-
- assertEquals("scroll", $("#test").css("backgroundAttachment"));
- assertEquals("scroll", $("#test").css(CSS.BACKGROUND_ATTACHMENT));
-
- }
-
- public void testBackgroundColorProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.AQUA));
-
- assertEquals("aqua", $("#test").css("backgroundColor", false));
- assertEquals("aqua", $("#test").css(CSS.BACKGROUND_COLOR, false));
-
- $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.rgb("#112233")));
-
- assertEquals("#112233", $("#test").css("backgroundColor", false));
- assertEquals("#112233", $("#test").css(CSS.BACKGROUND_COLOR, false));
-
- $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.rgb(35, 45, 55)));
- assertEquals("rgb(35,45,55)", $("#test").css("backgroundColor", false));
- assertEquals("rgb(35,45,55)", $("#test").css(CSS.BACKGROUND_COLOR, false));
-
- }
-
- public void testBackgroundImageProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BACKGROUND_IMAGE.with(UriValue.url("image.jpg")));
-
- assertEquals("url('image.jpg')", $("#test").css("backgroundImage"));
- assertEquals("url('image.jpg')", $("#test").css(CSS.BACKGROUND_IMAGE));
- }
-
- public void testBackgroundPositionProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER));
- assertEquals("center", $("#test").css("backgroundPosition"));
- assertEquals("center", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_CENTER));
- assertEquals("center center", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_TOP));
- assertEquals("center top", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_BOTTOM));
- assertEquals("center bottom", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT));
- assertEquals("left", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_TOP));
- assertEquals("left top", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_CENTER));
- assertEquals("left center", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_BOTTOM));
- assertEquals("left bottom", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT));
- assertEquals("right", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_TOP));
- assertEquals("right top", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_CENTER));
- assertEquals("right center", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_BOTTOM));
- assertEquals("right bottom", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.position(12, 12,
- Unit.PX)));
- assertEquals("12px 12px", $("#test").css(CSS.BACKGROUND_POSITION));
-
- $("#test").css(
- CSS.BACKGROUND_POSITION.with(BackgroundPosition.position(12, 12,
- Unit.PCT)));
- assertEquals("12% 12%", $("#test").css(CSS.BACKGROUND_POSITION));
-
- }
-
- public void testBackgroundProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(
- CSS.BACKGROUND.with(RGBColor.TRANSPARENT, UriValue.url("back.jpg"),
- BackgroundRepeat.NO_REPEAT, BackgroundAttachment.SCROLL,
- BackgroundPosition.CENTER));
- assertEquals("transparent url('back.jpg') no-repeat scroll center", $(
- "#test").css("background"));
- assertEquals("transparent url('back.jpg') no-repeat scroll center", $(
- "#test").css(CSS.BACKGROUND));
-
- }
-
- public void testBackgroundRepeatProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BACKGROUND_REPEAT.with(BackgroundRepeat.REPEAT_X));
-
- assertEquals("repeat-x", $("#test").css("backgroundRepeat"));
- assertEquals("repeat-x", $("#test").css(CSS.BACKGROUND_REPEAT));
- }
-
- public void testBorderCollapseProperty() {
-
- $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
-
- $("#test").css(CSS.BORDER_COLLAPSE.with(BorderCollapse.COLLAPSE));
-
- assertEquals("collapse", $("#test").css("borderCollapse"));
- assertEquals("collapse", $("#test").css(CSS.BORDER_COLLAPSE));
-
- $("#test").css(CSS.BORDER_COLLAPSE.with(BorderCollapse.SEPARATE));
-
- assertEquals("separate", $("#test").css("borderCollapse"));
- assertEquals("separate", $("#test").css(CSS.BORDER_COLLAPSE));
- }
-
- public void testCaptionSideProperty() {
-
- $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
-
- $("#test").css(CSS.CAPTION_SIDE.with(CaptionSide.BOTTOM));
- assertEquals("bottom", $("#test").css("captionSide"));
- assertEquals("bottom", $("#test").css(CSS.CAPTION_SIDE));
-
- }
-
- public void testEmptyCellsProperty() {
-
- $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
-
- $("#test").css(CSS.EMPTY_CELLS.with(EmptyCellsProperty.EmptyCells.HIDE));
- assertEquals("hide", $("#test").css("emptyCells"));
- assertEquals("hide", $("#test").css(CSS.EMPTY_CELLS));
-
- }
-
- public void testBorderSpacingProperty() {
-
- $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
-
- $("#test").css(CSS.BORDER_SPACING.with(new BorderSpacing(Length.px(15))));
-
- assertEquals("15px 15px", $("#test").css("borderSpacing"));
- assertEquals("15px 15px", $("#test").css(CSS.BORDER_SPACING));
-
- $("#test").css(
- CSS.BORDER_SPACING.with(new BorderSpacing(Length.px(10), Length.em(20))));
-
- assertEquals("10px 20em", $("#test").css("borderSpacing"));
- assertEquals("10px 20em", $("#test").css(CSS.BORDER_SPACING));
- }
-
- public void testBorderColorProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BORDER_COLOR.with(RGBColor.AQUA));
- assertEquals("aqua", $("#test").css("borderColor"));
- assertEquals("aqua", $("#test").css(CSS.BORDER_COLOR));
-
- $("#test").css(CSS.BORDER_BOTTOM_COLOR.with(RGBColor.BLACK));
- assertEquals("black", $("#test").css("borderBottomColor"));
- assertEquals("black", $("#test").css(CSS.BORDER_BOTTOM_COLOR));
-
- $("#test").css(CSS.BORDER_TOP_COLOR.with(RGBColor.FUSCHIA));
- assertEquals("fuschia", $("#test").css("borderTopColor"));
- assertEquals("fuschia", $("#test").css(CSS.BORDER_TOP_COLOR));
-
- $("#test").css(CSS.BORDER_LEFT_COLOR.with(RGBColor.GRAY));
- assertEquals("gray", $("#test").css("borderLeftColor"));
- assertEquals("gray", $("#test").css(CSS.BORDER_LEFT_COLOR));
-
- $("#test").css(CSS.BORDER_RIGHT_COLOR.with(RGBColor.WHITE));
- assertEquals("white", $("#test").css("borderRightColor"));
- assertEquals("white", $("#test").css(CSS.BORDER_RIGHT_COLOR));
-
- }
-
- public void testBorderProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(
- CSS.BORDER.with(BorderWidth.THICK, BorderStyle.DASHED, RGBColor.BLACK));
- assertEquals("thick dashed black", $("#test").css("border"));
- assertEquals("thick dashed black", $("#test").css(CSS.BORDER));
-
- $("#test").css(
- CSS.BORDER.with(Length.px(15), BorderStyle.SOLID, RGBColor.rgb("#000000")));
- assertEquals("15px solid #000000", $("#test").css("border"));
- assertEquals("15px solid #000000", $("#test").css(CSS.BORDER));
-
- $("#test").css(
- CSS.BORDER_TOP.with(BorderWidth.MEDIUM, BorderStyle.SOLID, RGBColor.GRAY));
- assertEquals("medium solid gray", $("#test").css("borderTop"));
- assertEquals("medium solid gray", $("#test").css(CSS.BORDER_TOP));
-
- $("#test").css(
- CSS.BORDER_BOTTOM.with(BorderWidth.THIN, BorderStyle.DOUBLE,
- RGBColor.FUSCHIA));
- assertEquals("thin double fuschia", $("#test").css("borderBottom"));
- assertEquals("thin double fuschia", $("#test").css(CSS.BORDER_BOTTOM));
-
- $("#test").css(
- CSS.BORDER_LEFT.with(BorderWidth.THIN, BorderStyle.SOLID, RGBColor.BLACK));
- assertEquals("thin solid black", $("#test").css("borderLeft"));
- assertEquals("thin solid black", $("#test").css(CSS.BORDER_LEFT));
-
- $("#test").css(
- CSS.BORDER_RIGHT.with(BorderWidth.MEDIUM, BorderStyle.DASHED, RGBColor.GRAY));
- assertEquals("medium dashed gray", $("#test").css("borderRight"));
- assertEquals("medium dashed gray", $("#test").css(CSS.BORDER_RIGHT));
-
- }
-
- public void testBorderStyleProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BORDER_STYLE.with(BorderStyle.DOTTED));
- assertEquals("dotted", $("#test").css("borderStyle"));
- assertEquals("dotted", $("#test").css(CSS.BORDER_STYLE));
-
- $("#test").css(CSS.BORDER_BOTTOM_STYLE.with(BorderStyle.DASHED));
- assertEquals("dashed", $("#test").css("borderBottomStyle"));
- assertEquals("dashed", $("#test").css(CSS.BORDER_BOTTOM_STYLE));
-
- $("#test").css(CSS.BORDER_TOP_STYLE.with(BorderStyle.DOUBLE));
- assertEquals("double", $("#test").css("borderTopStyle"));
- assertEquals("double", $("#test").css(CSS.BORDER_TOP_STYLE));
-
- $("#test").css(CSS.BORDER_LEFT_STYLE.with(BorderStyle.HIDDEN));
- assertEquals("hidden", $("#test").css("borderLeftStyle"));
- assertEquals("hidden", $("#test").css(CSS.BORDER_LEFT_STYLE));
-
- $("#test").css(CSS.BORDER_RIGHT_STYLE.with(BorderStyle.SOLID));
- assertEquals("solid", $("#test").css("borderRightStyle"));
- assertEquals("solid", $("#test").css(CSS.BORDER_RIGHT_STYLE));
-
- }
-
- public void testBorderWidthProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.BORDER_WIDTH.with(BorderWidth.MEDIUM));
- assertEquals("medium", $("#test").css("borderWidth"));
- assertEquals("medium", $("#test").css(CSS.BORDER_WIDTH));
-
- $("#test").css(CSS.BORDER_WIDTH.with(Length.px(15)));
- assertEquals("15px", $("#test").css(CSS.BORDER_WIDTH));
-
- $("#test").css(CSS.BORDER_WIDTH.with(Length.px(20)));
- assertEquals("20px", $("#test").css(CSS.BORDER_WIDTH));
-
- $("#test").css(CSS.BORDER_WIDTH.with(Length.mm(20)));
- assertEquals("20mm", $("#test").css(CSS.BORDER_WIDTH));
-
- $("#test").css(CSS.BORDER_BOTTOM_WIDTH.with(BorderWidth.THICK));
- assertEquals("thick", $("#test").css("borderBottomWidth", false));
- assertEquals("thick", $("#test").css(CSS.BORDER_BOTTOM_WIDTH, false));
-
- $("#test").css(CSS.BORDER_TOP_WIDTH.with(BorderWidth.THIN));
- assertEquals("thin", $("#test").css("borderTopWidth", false));
- assertEquals("thin", $("#test").css(CSS.BORDER_TOP_WIDTH, false));
-
- $("#test").css(CSS.BORDER_LEFT_WIDTH.with(BorderWidth.THIN));
- assertEquals("thin", $("#test").css("borderLeftWidth", false));
- assertEquals("thin", $("#test").css(CSS.BORDER_LEFT_WIDTH, false));
-
- $("#test").css(CSS.BORDER_RIGHT_WIDTH.with(BorderWidth.THICK));
- assertEquals("thick", $("#test").css("borderRightWidth", false));
- assertEquals("thick", $("#test").css(CSS.BORDER_RIGHT_WIDTH, false));
-
- }
-
- public void testClearProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.CLEAR.with(Clear.BOTH));
- assertEquals("both", $("#test").css("clear"));
- assertEquals("both", $("#test").css(CSS.CLEAR));
-
- $("#test").css(CSS.CLEAR.with(Clear.LEFT));
- assertEquals("left", $("#test").css(CSS.CLEAR));
-
- $("#test").css(CSS.CLEAR.with(Clear.RIGHT));
- assertEquals("right", $("#test").css(CSS.CLEAR));
-
- $("#test").css(CSS.CLEAR.with(Clear.NONE));
- assertEquals("none", $("#test").css(CSS.CLEAR));
-
- }
-
- public void testClipProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.CLIP.with(Shape.rect(0, 10, 10, 0)));
- assertEquals("rect(0px,10px,10px,0px)", $("#test").css("clip"));
- assertEquals("rect(0px,10px,10px,0px)", $("#test").css(CSS.CLIP));
- }
-
- public void testColorProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.COLOR.with(RGBColor.AQUA));
-
- assertEquals("aqua", $("#test").css("color"));
- assertEquals("aqua", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.rgb("#112233")));
-
- assertEquals("#112233", $("#test").css("color"));
- assertEquals("#112233", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.rgb(35, 45, 55)));
- assertEquals("rgb(35,45,55)", $("#test").css("color"));
- assertEquals("rgb(35,45,55)", $("#test").css(CSS.COLOR));
-
- }
-
- public void testColorValue() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.COLOR.with(RGBColor.AQUA));
- assertEquals("aqua", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.BLACK));
- assertEquals("black", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.BLUE));
- assertEquals("blue", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.FUSCHIA));
- assertEquals("fuschia", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.GRAY));
- assertEquals("gray", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.GREY));
- assertEquals("grey", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.GREEN));
- assertEquals("green", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.LIME));
- assertEquals("lime", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.MAROON));
- assertEquals("maroon", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.NAVY));
- assertEquals("navy", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.OLIVE));
- assertEquals("olive", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.ORANGE));
- assertEquals("orange", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.PURPLE));
- assertEquals("purple", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.RED));
- assertEquals("red", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.SILVER));
- assertEquals("silver", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.TEAL));
- assertEquals("teal", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.TRANSPARENT));
- assertEquals("transparent", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.WHITE));
- assertEquals("white", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.YELLOW));
- assertEquals("yellow", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.rgb("#112233")));
- assertEquals("#112233", $("#test").css(CSS.COLOR));
-
- $("#test").css(CSS.COLOR.with(RGBColor.rgb(35, 45, 55)));
- assertEquals("rgb(35,45,55)", $("#test").css(CSS.COLOR));
-
- }
-
- public void testCursorProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.CURSOR.with(Cursor.WAIT));
-
- assertEquals("wait", $("#test").css("cursor"));
- assertEquals("wait", $("#test").css(CSS.CURSOR));
-
- }
-
- public void testDisplayProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.DISPLAY.with(Display.INLINE));
-
- assertEquals("inline", $("#test").css("display"));
- assertEquals("inline", $("#test").css(CSS.DISPLAY));
-
- }
-
- public void testEdgePositionProperty() {
-
- $(e).html("<div id='test'>Content</div><");
-
- $("#test").css(CSS.LEFT.with(Length.px(10)));
- assertEquals("10px", $("#test").css("left"));
- assertEquals("10px", $("#test").css(CSS.LEFT));
-
- $("#test").css(CSS.TOP.with(Length.px(15)));
- assertEquals("15px", $("#test").css("top"));
- assertEquals("15px", $("#test").css(CSS.TOP));
-
- $("#test").css(CSS.RIGHT.with(Length.px(0)));
- assertEquals("0px", $("#test").css("right"));
- assertEquals("0px", $("#test").css(CSS.RIGHT));
-
- $("#test").css(CSS.BOTTOM.with(Length.px(20)));
- assertEquals("20px", $("#test").css("bottom"));
- assertEquals("20px", $("#test").css(CSS.BOTTOM));
-
- }
-
- public void testFloatProperty() {
-
- $(e).html("<div><div id='test'>Content</div></div>");
- $("#test").css(CSS.FLOAT.with(Float.LEFT));
-
- assertEquals("left", $("#test").css("float"));
- assertEquals("left", $("#test").css(CSS.FLOAT));
-
- }
-
- public void testFontSizeProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.LARGER));
- assertEquals("larger", $("#test").css("fontSize"));
- assertEquals("larger", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.LARGE));
- assertEquals("large", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.MEDIUM));
- assertEquals("medium", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.SMALL));
- assertEquals("small", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.SMALLER));
- assertEquals("smaller", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.X_LARGE));
- assertEquals("x-large", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.X_SMALL));
- assertEquals("x-small", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.XX_LARGE));
- assertEquals("xx-large", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(FontSize.XX_SMALL));
- assertEquals("xx-small", $("#test").css(CSS.FONT_SIZE));
-
- $("#test").css(CSS.FONT_SIZE.with(Length.px(16)));
- assertEquals("16px", $("#test").css(CSS.FONT_SIZE));
- }
-
- public void testFontStyleProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.FONT_STYLE.with(FontStyle.ITALIC));
- assertEquals("italic", $("#test").css("fontStyle"));
- assertEquals("italic", $("#test").css(CSS.FONT_STYLE));
-
- }
-
- public void testFontVariantProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.FONT_VARIANT.with(FontVariant.SMALL_CAPS));
- assertEquals("small-caps", $("#test").css("fontVariant"));
- assertEquals("small-caps", $("#test").css(CSS.FONT_VARIANT));
-
- }
-
- public void testHeightProperties() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.HEIGHT.with(Length.px(10)));
-
- assertEquals("10px", $("#test").css("height"));
- assertEquals("10px", $("#test").css(CSS.HEIGHT));
-
- $("#test").css(CSS.MAX_HEIGHT.with(Length.px(15)));
-
- assertEquals("15px", $("#test").css("maxHeight"));
- assertEquals("15px", $("#test").css(CSS.MAX_HEIGHT));
-
- $("#test").css(CSS.MIN_HEIGHT.with(Length.px(5)));
-
- assertEquals("5px", $("#test").css("minHeight"));
- assertEquals("5px", $("#test").css(CSS.MIN_HEIGHT));
- }
-
- public void testLengthValue() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.HEIGHT.with(Length.px(10)));
- assertEquals("10px", $("#test").css(CSS.HEIGHT));
-
- $("#test").css(CSS.HEIGHT.with(Length.cm(10)));
- assertEquals("10cm", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.em(10)));
- assertEquals("10em", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.ex(10)));
- assertEquals("10ex", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.in(10)));
- assertEquals("10in", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.mm(10)));
- assertEquals("10mm", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pc(10)));
- assertEquals("10pc", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pct(10)));
- assertEquals("10%", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pt(10)));
- assertEquals("10pt", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.px(10.1)));
- assertEquals("10.1px", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.cm(10.1)));
- assertEquals("10.1cm", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.em(10.1)));
- assertEquals("10.1em", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.ex(10.1)));
- assertEquals("10.1ex", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.in(10.1)));
- assertEquals("10.1in", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.mm(10.1)));
- assertEquals("10.1mm", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pc(10.1)));
- assertEquals("10.1pc", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pct(10.1)));
- assertEquals("10.1%", $("#test").css(CSS.HEIGHT, false));
-
- $("#test").css(CSS.HEIGHT.with(Length.pt(10.1)));
- assertEquals("10.1pt", $("#test").css(CSS.HEIGHT, false));
-
- }
-
- public void testLetterSpacingProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.LETTER_SPACING.with(Length.px(15)));
- assertEquals("15px", $("#test").css("letterSpacing"));
- assertEquals("15px", $("#test").css(CSS.LETTER_SPACING));
-
- }
-
- public void testLineHeightProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.LINE_HEIGHT.with(Length.px(15)));
- assertEquals("15px", $("#test").css("lineHeight"));
- assertEquals("15px", $("#test").css(CSS.LINE_HEIGHT));
-
- $("#test").css(CSS.LINE_HEIGHT.with(2));
- assertEquals("2", $("#test").css("lineHeight"));
- assertEquals("2", $("#test").css(CSS.LINE_HEIGHT));
-
- $("#test").css(CSS.LINE_HEIGHT.with(2.5));
- assertEquals("2.5", $("#test").css("lineHeight"));
- assertEquals("2.5", $("#test").css(CSS.LINE_HEIGHT));
-
- }
-
- public void testListStyleImageProperty() {
-
- $(e).html("<ul id='test'><li>Content</li></ul>");
-
- $("#test").css(CSS.LIST_STYLE_IMAGE.with(UriValue.url("arrow.jpg")));
- assertEquals("url('arrow.jpg')", $("#test").css("listStyleImage"));
- assertEquals("url('arrow.jpg')", $("#test").css(CSS.LIST_STYLE_IMAGE));
-
- }
-
- public void testListStylePositionProperty() {
-
- $(e).html("<ul id='test'><li>Content</li></ul>");
-
- $("#test").css(CSS.LIST_STYLE_POSITION.with(ListStylePosition.INSIDE));
- assertEquals("inside", $("#test").css("listStylePosition"));
- assertEquals("inside", $("#test").css(CSS.LIST_STYLE_POSITION));
-
- $("#test").css(CSS.LIST_STYLE_POSITION.with(ListStylePosition.OUTSIDE));
- assertEquals("outside", $("#test").css("listStylePosition"));
- assertEquals("outside", $("#test").css(CSS.LIST_STYLE_POSITION));
-
- }
-
- public void testListStyleProperty() {
-
- $(e).html("<ul id='test'><li>Content</li></ul>");
-
- $("#test").css(
- CSS.LIST_STYLE.with(ListStyleType.DISC, ListStylePosition.OUTSIDE,
- null));
- assertEquals("disc outside", $("#test").css("listStyle"));
- assertEquals("disc outside", $("#test").css(CSS.LIST_STYLE));
-
- $("#test").css(
- CSS.LIST_STYLE.with(ListStyleType.DISC, null, UriValue.url("square.jpg")));
- assertEquals("disc url('square.jpg')", $("#test").css("listStyle"));
- assertEquals("disc url('square.jpg')", $("#test").css(CSS.LIST_STYLE));
-
- $("#test").css(
- CSS.LIST_STYLE.with(null, ListStylePosition.OUTSIDE, UriValue.url("square.jpg")));
- assertEquals("outside url('square.jpg')", $("#test").css("listStyle"));
- assertEquals("outside url('square.jpg')", $("#test").css(CSS.LIST_STYLE));
-
- }
-
- public void testListStyleTypeProperty() {
-
- $(e).html("<ul id='test'><li>Content</li></ul>");
-
- $("#test").css(CSS.LIST_STYLE_TYPE.with(ListStyleType.DISC));
- assertEquals("disc", $("#test").css("listStyleType"));
- assertEquals("disc", $("#test").css(CSS.LIST_STYLE_TYPE));
-
- }
-
- public void testMarginProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.MARGIN.with(Length.px(10), Length.px(20)));
-
- assertEquals("10px 20px", $("#test").css("margin"));
- assertEquals("10px 20px", $("#test").css(CSS.MARGIN));
-
- $("#test").css(CSS.MARGIN.with(Length.px(10), Length.px(20), Length.px(30)));
-
- assertEquals("10px 20px 30px", $("#test").css("margin"));
- assertEquals("10px 20px 30px", $("#test").css(CSS.MARGIN));
-
- $("#test").css(CSS.MARGIN.with(Length.px(10)));
-
- assertEquals("10px", $("#test").css("margin"));
- assertEquals("10px", $("#test").css(CSS.MARGIN));
-
- $("#test").css(
- CSS.MARGIN.with(Length.px(10), Length.px(20), Length.px(30),
- Length.px(40)));
-
- assertEquals("10px 20px 30px 40px", $("#test").css("margin"));
- assertEquals("10px 20px 30px 40px", $("#test").css(CSS.MARGIN));
-
- $("#test").css(CSS.MARGIN_TOP.with(Length.px(20)));
-
- assertEquals("20px", $("#test").css("marginTop"));
- assertEquals("20px", $("#test").css(CSS.MARGIN_TOP));
-
- $("#test").css(CSS.MARGIN_BOTTOM.with(Length.px(30)));
-
- assertEquals("30px", $("#test").css("marginBottom"));
- assertEquals("30px", $("#test").css(CSS.MARGIN_BOTTOM));
-
- $("#test").css(CSS.MARGIN_LEFT.with(Length.px(40)));
-
- assertEquals("40px", $("#test").css("marginLeft"));
- assertEquals("40px", $("#test").css(CSS.MARGIN_LEFT));
-
- $("#test").css(CSS.MARGIN_RIGHT.with(Length.px(50)));
-
- assertEquals("50px", $("#test").css("marginRight"));
- assertEquals("50px", $("#test").css(CSS.MARGIN_RIGHT));
- }
-
- public void testOutlineProperty() {
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.OUTLINE_WIDTH.with(Length.px(10)));
- assertEquals("10px", $("#test").css("outlineWidth"));
- assertEquals("10px", $("#test").css(CSS.OUTLINE_WIDTH));
-
- $("#test").css(CSS.OUTLINE_WIDTH.with(BorderWidth.MEDIUM));
- assertEquals("medium", $("#test").css("outlineWidth"));
- assertEquals("medium", $("#test").css(CSS.OUTLINE_WIDTH));
-
- $("#test").css(CSS.OUTLINE_COLOR.with(RGBColor.GRAY));
- assertEquals("gray", $("#test").css("outlineColor"));
- assertEquals("gray", $("#test").css(CSS.OUTLINE_COLOR));
-
- $("#test").css(CSS.OUTLINE_STYLE.with(BorderStyle.DOTTED));
- assertEquals("dotted", $("#test").css("outlineStyle"));
- assertEquals("dotted", $("#test").css(CSS.OUTLINE_STYLE));
-
- $("#test").css(
- CSS.OUTLINE.with(RGBColor.BLACK, BorderStyle.DASHED, BorderWidth.MEDIUM));
- assertEquals("black dashed medium", $("#test").css("outline"));
- assertEquals("black dashed medium", $("#test").css(CSS.OUTLINE));
-
- $("#test").css(
- CSS.OUTLINE.with(RGBColor.AQUA, BorderStyle.DOUBLE, Length.px(15)));
- assertEquals("aqua double 15px", $("#test").css("outline"));
- assertEquals("aqua double 15px", $("#test").css(CSS.OUTLINE));
-
- }
-
- public void testOverflowProperty() {
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.OVERFLOW.with(Overflow.HIDDEN));
- assertEquals("hidden", $("#test").css("overflow"));
- assertEquals("hidden", $("#test").css(CSS.OVERFLOW));
-
- $("#test").css(CSS.OVERFLOW.with(Overflow.SCROLL));
- assertEquals("scroll", $("#test").css("overflow"));
- assertEquals("scroll", $("#test").css(CSS.OVERFLOW));
-
- $("#test").css(CSS.OVERFLOW.with(Overflow.VISIBLE));
- assertEquals("visible", $("#test").css("overflow"));
- assertEquals("visible", $("#test").css(CSS.OVERFLOW));
-
- }
-
- public void testPaddingProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.PADDING.with(Length.px(10)));
-
- assertEquals("10px", $("#test").css("padding"));
- assertEquals("10px", $("#test").css(CSS.PADDING));
-
- $("#test").css(
- CSS.PADDING.with(Length.px(10), Length.px(20)));
-
- assertEquals("10px 20px", $("#test").css("padding"));
- assertEquals("10px 20px", $("#test").css(CSS.PADDING));
-
- $("#test").css(
- CSS.PADDING.with(Length.px(10), Length.px(20), Length.px(30)));
-
- assertEquals("10px 20px 30px", $("#test").css("padding"));
- assertEquals("10px 20px 30px", $("#test").css(CSS.PADDING));
-
- $("#test").css(
- CSS.PADDING.with(Length.px(10), Length.px(20), Length.px(30),
- Length.px(40)));
-
- assertEquals("10px 20px 30px 40px", $("#test").css("padding"));
- assertEquals("10px 20px 30px 40px", $("#test").css(CSS.PADDING));
-
- $("#test").css(CSS.PADDING_TOP.with(Length.px(20)));
-
- assertEquals("20px", $("#test").css("paddingTop"));
- assertEquals("20px", $("#test").css(CSS.PADDING_TOP));
-
- $("#test").css(CSS.PADDING_BOTTOM.with(Length.px(30)));
-
- assertEquals("30px", $("#test").css("paddingBottom"));
- assertEquals("30px", $("#test").css(CSS.PADDING_BOTTOM));
-
- $("#test").css(CSS.PADDING_LEFT.with(Length.px(40)));
-
- assertEquals("40px", $("#test").css("paddingLeft"));
- assertEquals("40px", $("#test").css(CSS.PADDING_LEFT));
-
- $("#test").css(CSS.PADDING_RIGHT.with(Length.px(50)));
-
- assertEquals("50px", $("#test").css("paddingRight"));
- assertEquals("50px", $("#test").css(CSS.PADDING_RIGHT));
- }
-
- public void testPositionProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.POSITION.with(Position.ABSOLUTE));
- assertEquals("absolute", $("#test").css("position"));
- assertEquals("absolute", $("#test").css(CSS.POSITION));
-
- $("#test").css(CSS.POSITION.with(Position.FIXED));
- assertEquals("fixed", $("#test").css("position"));
- assertEquals("fixed", $("#test").css(CSS.POSITION));
-
- $("#test").css(CSS.POSITION.with(Position.RELATIVE));
- assertEquals("relative", $("#test").css("position"));
- assertEquals("relative", $("#test").css(CSS.POSITION));
-
- $("#test").css(CSS.POSITION.with(Position.STATIC));
- assertEquals("static", $("#test").css("position"));
- assertEquals("static", $("#test").css(CSS.POSITION));
-
- }
-
- public void testTextAlignProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.CENTER));
- assertEquals("center", $("#test").css("textAlign"));
- assertEquals("center", $("#test").css(CSS.TEXT_ALIGN));
-
- $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.JUSTIFY));
- assertEquals("justify", $("#test").css("textAlign"));
- assertEquals("justify", $("#test").css(CSS.TEXT_ALIGN));
-
- $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.LEFT));
- assertEquals("left", $("#test").css("textAlign"));
- assertEquals("left", $("#test").css(CSS.TEXT_ALIGN));
-
- $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.RIGHT));
- assertEquals("right", $("#test").css("textAlign"));
- assertEquals("right", $("#test").css(CSS.TEXT_ALIGN));
-
- }
-
- public void testTextDecorationProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.TEXT_DECORATION.with(TextDecoration.LINE_THROUGH));
- assertEquals("line-through", $("#test").css("textDecoration"));
- assertEquals("line-through", $("#test").css(CSS.TEXT_DECORATION));
-
- }
-
- public void testTextIdentProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.TEXT_IDENT.with(Length.px(15)));
- assertEquals("15px", $("#test").css("textIdent", false));
- assertEquals("15px", $("#test").css(CSS.TEXT_IDENT, false));
-
- }
-
- public void testTextTransformProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.UPPERCASE));
- assertEquals("uppercase", $("#test").css("textTransform", false));
- assertEquals("uppercase", $("#test").css(CSS.TEXT_TRANSFORM, false));
-
- $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.LOWERCASE));
- assertEquals("lowercase", $("#test").css("textTransform", false));
-
- $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.CAPITALIZE));
- assertEquals("capitalize", $("#test").css("textTransform", false));
- }
-
- public void testUnicodeBidiProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.BIDI_OVERRIDE));
- assertEquals("bidi-override", $("#test").css("unicode-bidi"));
- assertEquals("bidi-override", $("#test").css(CSS.UNICODE_BIDI));
-
- $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.EMBED));
- assertEquals("embed", $("#test").css(CSS.UNICODE_BIDI));
-
- $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.NORMAL));
- assertEquals("normal", $("#test").css(CSS.UNICODE_BIDI));
- }
-
- public void testVerticalAlignProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(Length.px(120)));
- assertEquals("120px", $("#test").css("verticalAlign"));
- assertEquals("120px", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.BASELINE));
- assertEquals("baseline", $("#test").css("verticalAlign"));
- assertEquals("baseline", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.BOTTOM));
- assertEquals("bottom", $("#test").css("verticalAlign"));
- assertEquals("bottom", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.MIDDLE));
- assertEquals("middle", $("#test").css("verticalAlign"));
- assertEquals("middle", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.SUB));
- assertEquals("sub", $("#test").css("verticalAlign"));
- assertEquals("sub", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.SUPER));
- assertEquals("super", $("#test").css("verticalAlign"));
- assertEquals("super", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TEXT_BOTTOM));
- assertEquals("text-bottom", $("#test").css("verticalAlign"));
- assertEquals("text-bottom", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TEXT_TOP));
- assertEquals("text-top", $("#test").css("verticalAlign"));
- assertEquals("text-top", $("#test").css(CSS.VERTICAL_ALIGN));
-
- $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TOP));
- assertEquals("top", $("#test").css("verticalAlign"));
- assertEquals("top", $("#test").css(CSS.VERTICAL_ALIGN));
-
- }
-
- public void testVisibilityProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.VISIBILITY.with(Visibility.HIDDEN));
- assertEquals("hidden", $("#test").css("visibility"));
- assertEquals("hidden", $("#test").css(CSS.VISIBILITY));
-
- $("#test").css(CSS.VISIBILITY.with(Visibility.VISIBLE));
- assertEquals("visible", $("#test").css("visibility"));
- assertEquals("visible", $("#test").css(CSS.VISIBILITY));
-
- }
-
- public void testWhiteSpaceProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.NORMAL));
- assertEquals("normal", $("#test").css("whiteSpace"));
- assertEquals("normal", $("#test").css(CSS.WHITE_SPACE));
-
- $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.NOWRAP));
- assertEquals("nowrap", $("#test").css(CSS.WHITE_SPACE));
-
- $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE));
- assertEquals("pre", $("#test").css(CSS.WHITE_SPACE));
-
- $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE_LINE));
- assertEquals("pre-line", $("#test").css(CSS.WHITE_SPACE));
-
- $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE_WRAP));
- assertEquals("pre-wrap", $("#test").css(CSS.WHITE_SPACE));
-
- }
-
- public void testWidthProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.WIDTH.with(Length.px(20)));
- assertEquals("20px", $("#test").css("width"));
- assertEquals("20px", $("#test").css(CSS.WIDTH));
-
- $("#test").css(CSS.MIN_WIDTH.with(Length.px(10)));
- assertEquals("10px", $("#test").css("minWidth"));
- assertEquals("10px", $("#test").css(CSS.MIN_WIDTH));
-
- $("#test").css(CSS.MAX_WIDTH.with(Length.px(30)));
- assertEquals("30px", $("#test").css("maxWidth"));
- assertEquals("30px", $("#test").css(CSS.MAX_WIDTH));
-
- }
-
- public void testWordSpacingProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.WORD_SPACING.with(Length.pt(2)));
- assertEquals("2pt", $("#test").css("wordSpacing"));
- assertEquals("2pt", $("#test").css(CSS.WORD_SPACING));
-
- }
-
- public void testZIndexProperty() {
-
- $(e).html("<div id='test'>Content</div>");
-
- $("#test").css(CSS.ZINDEX.with(1000));
- assertEquals("1000", $("#test").css("zIndex"));
- assertEquals("1000", $("#test").css(CSS.ZINDEX));
-
- $("#test").css(CSS.ZINDEX.with(new Integer(200)));
- assertEquals("200", $("#test").css("zIndex"));
- assertEquals("200", $("#test").css(CSS.ZINDEX));
-
- $("#test").css(CSS.ZINDEX.with(null));
- assertEquals("0", $("#test").css("zIndex"));
- assertEquals("0", $("#test").css(CSS.ZINDEX));
-
- }
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Cursor;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.FontStyle;
+import com.google.gwt.dom.client.Style.ListStyleType;
+import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.TextDecoration;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Style.VerticalAlign;
+import com.google.gwt.dom.client.Style.Visibility;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.css.BackgroundAttachmentProperty.BackgroundAttachment;
+import com.google.gwt.query.client.css.BackgroundPositionProperty.BackgroundPosition;
+import com.google.gwt.query.client.css.BackgroundRepeatProperty.BackgroundRepeat;
+import com.google.gwt.query.client.css.BorderCollapseProperty.BorderCollapse;
+import com.google.gwt.query.client.css.BorderSpacingProperty.BorderSpacing;
+import com.google.gwt.query.client.css.BorderStyleProperty.BorderStyle;
+import com.google.gwt.query.client.css.BorderWidthProperty.BorderWidth;
+import com.google.gwt.query.client.css.CSS;
+import com.google.gwt.query.client.css.CaptionSideProperty.CaptionSide;
+import com.google.gwt.query.client.css.ClearProperty.Clear;
+import com.google.gwt.query.client.css.ClipProperty.Shape;
+import com.google.gwt.query.client.css.EmptyCellsProperty;
+import com.google.gwt.query.client.css.FontSizeProperty.FontSize;
+import com.google.gwt.query.client.css.FontVariantProperty.FontVariant;
+import com.google.gwt.query.client.css.Length;
+import com.google.gwt.query.client.css.ListStylePositionProperty.ListStylePosition;
+import com.google.gwt.query.client.css.RGBColor;
+import com.google.gwt.query.client.css.TextAlignProperty.TextAlign;
+import com.google.gwt.query.client.css.TextTransformProperty.TextTransform;
+import com.google.gwt.query.client.css.UnicodeBidiProperty.UnicodeBidi;
+import com.google.gwt.query.client.css.UriValue;
+import com.google.gwt.dom.client.Style.Float;
+
+import com.google.gwt.query.client.css.WhiteSpaceProperty.WhiteSpace;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing css part.
+ */
+public class GQueryCssTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("core-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ public void testBackgroundAttachmentProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(
+ CSS.BACKGROUND_ATTACHMENT.with(BackgroundAttachment.FIXED));
+
+ assertEquals("fixed", $("#test").css("backgroundAttachment"));
+ assertEquals("fixed", $("#test").css(CSS.BACKGROUND_ATTACHMENT));
+
+ $("#test").css(
+ CSS.BACKGROUND_ATTACHMENT.with(BackgroundAttachment.SCROLL));
+
+ assertEquals("scroll", $("#test").css("backgroundAttachment"));
+ assertEquals("scroll", $("#test").css(CSS.BACKGROUND_ATTACHMENT));
+
+ }
+
+ public void testBackgroundColorProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.AQUA));
+
+ assertEquals("aqua", $("#test").css("backgroundColor", false));
+ assertEquals("aqua", $("#test").css(CSS.BACKGROUND_COLOR, false));
+
+ $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.rgb("#112233")));
+
+ assertEquals("#112233", $("#test").css("backgroundColor", false));
+ assertEquals("#112233", $("#test").css(CSS.BACKGROUND_COLOR, false));
+
+ $("#test").css(CSS.BACKGROUND_COLOR.with(RGBColor.rgb(35, 45, 55)));
+ assertEquals("rgb(35,45,55)", $("#test").css("backgroundColor", false));
+ assertEquals("rgb(35,45,55)", $("#test").css(CSS.BACKGROUND_COLOR, false));
+
+ }
+
+ public void testBackgroundImageProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BACKGROUND_IMAGE.with(UriValue.url("image.jpg")));
+
+ assertEquals("url('image.jpg')", $("#test").css("backgroundImage"));
+ assertEquals("url('image.jpg')", $("#test").css(CSS.BACKGROUND_IMAGE));
+ }
+
+ public void testBackgroundPositionProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER));
+ assertEquals("center", $("#test").css("backgroundPosition"));
+ assertEquals("center", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_CENTER));
+ assertEquals("center center", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_TOP));
+ assertEquals("center top", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.CENTER_BOTTOM));
+ assertEquals("center bottom", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT));
+ assertEquals("left", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_TOP));
+ assertEquals("left top", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_CENTER));
+ assertEquals("left center", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.LEFT_BOTTOM));
+ assertEquals("left bottom", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT));
+ assertEquals("right", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_TOP));
+ assertEquals("right top", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_CENTER));
+ assertEquals("right center", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.RIGHT_BOTTOM));
+ assertEquals("right bottom", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.position(12, 12,
+ Unit.PX)));
+ assertEquals("12px 12px", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ $("#test").css(
+ CSS.BACKGROUND_POSITION.with(BackgroundPosition.position(12, 12,
+ Unit.PCT)));
+ assertEquals("12% 12%", $("#test").css(CSS.BACKGROUND_POSITION));
+
+ }
+
+ public void testBackgroundProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(
+ CSS.BACKGROUND.with(RGBColor.TRANSPARENT, UriValue.url("back.jpg"),
+ BackgroundRepeat.NO_REPEAT, BackgroundAttachment.SCROLL,
+ BackgroundPosition.CENTER));
+ assertEquals("transparent url('back.jpg') no-repeat scroll center", $(
+ "#test").css("background"));
+ assertEquals("transparent url('back.jpg') no-repeat scroll center", $(
+ "#test").css(CSS.BACKGROUND));
+
+ }
+
+ public void testBackgroundRepeatProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BACKGROUND_REPEAT.with(BackgroundRepeat.REPEAT_X));
+
+ assertEquals("repeat-x", $("#test").css("backgroundRepeat"));
+ assertEquals("repeat-x", $("#test").css(CSS.BACKGROUND_REPEAT));
+ }
+
+ public void testBorderCollapseProperty() {
+
+ $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
+
+ $("#test").css(CSS.BORDER_COLLAPSE.with(BorderCollapse.COLLAPSE));
+
+ assertEquals("collapse", $("#test").css("borderCollapse"));
+ assertEquals("collapse", $("#test").css(CSS.BORDER_COLLAPSE));
+
+ $("#test").css(CSS.BORDER_COLLAPSE.with(BorderCollapse.SEPARATE));
+
+ assertEquals("separate", $("#test").css("borderCollapse"));
+ assertEquals("separate", $("#test").css(CSS.BORDER_COLLAPSE));
+ }
+
+ public void testCaptionSideProperty() {
+
+ $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
+
+ $("#test").css(CSS.CAPTION_SIDE.with(CaptionSide.BOTTOM));
+ assertEquals("bottom", $("#test").css("captionSide"));
+ assertEquals("bottom", $("#test").css(CSS.CAPTION_SIDE));
+
+ }
+
+ public void testEmptyCellsProperty() {
+
+ $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
+
+ $("#test").css(CSS.EMPTY_CELLS.with(EmptyCellsProperty.EmptyCells.HIDE));
+ assertEquals("hide", $("#test").css("emptyCells"));
+ assertEquals("hide", $("#test").css(CSS.EMPTY_CELLS));
+
+ }
+
+ public void testBorderSpacingProperty() {
+
+ $(e).html("<table id='test'><tr><td>Content<td></tr></table>");
+
+ $("#test").css(CSS.BORDER_SPACING.with(new BorderSpacing(Length.px(15))));
+
+ assertEquals("15px 15px", $("#test").css("borderSpacing"));
+ assertEquals("15px 15px", $("#test").css(CSS.BORDER_SPACING));
+
+ $("#test").css(
+ CSS.BORDER_SPACING.with(new BorderSpacing(Length.px(10), Length.em(20))));
+
+ assertEquals("10px 20em", $("#test").css("borderSpacing"));
+ assertEquals("10px 20em", $("#test").css(CSS.BORDER_SPACING));
+ }
+
+ public void testBorderColorProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BORDER_COLOR.with(RGBColor.AQUA));
+ assertEquals("aqua", $("#test").css("borderColor"));
+ assertEquals("aqua", $("#test").css(CSS.BORDER_COLOR));
+
+ $("#test").css(CSS.BORDER_BOTTOM_COLOR.with(RGBColor.BLACK));
+ assertEquals("black", $("#test").css("borderBottomColor"));
+ assertEquals("black", $("#test").css(CSS.BORDER_BOTTOM_COLOR));
+
+ $("#test").css(CSS.BORDER_TOP_COLOR.with(RGBColor.FUSCHIA));
+ assertEquals("fuschia", $("#test").css("borderTopColor"));
+ assertEquals("fuschia", $("#test").css(CSS.BORDER_TOP_COLOR));
+
+ $("#test").css(CSS.BORDER_LEFT_COLOR.with(RGBColor.GRAY));
+ assertEquals("gray", $("#test").css("borderLeftColor"));
+ assertEquals("gray", $("#test").css(CSS.BORDER_LEFT_COLOR));
+
+ $("#test").css(CSS.BORDER_RIGHT_COLOR.with(RGBColor.WHITE));
+ assertEquals("white", $("#test").css("borderRightColor"));
+ assertEquals("white", $("#test").css(CSS.BORDER_RIGHT_COLOR));
+
+ }
+
+ public void testBorderProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(
+ CSS.BORDER.with(BorderWidth.THICK, BorderStyle.DASHED, RGBColor.BLACK));
+ assertEquals("thick dashed black", $("#test").css("border"));
+ assertEquals("thick dashed black", $("#test").css(CSS.BORDER));
+
+ $("#test").css(
+ CSS.BORDER.with(Length.px(15), BorderStyle.SOLID, RGBColor.rgb("#000000")));
+ assertEquals("15px solid #000000", $("#test").css("border"));
+ assertEquals("15px solid #000000", $("#test").css(CSS.BORDER));
+
+ $("#test").css(
+ CSS.BORDER_TOP.with(BorderWidth.MEDIUM, BorderStyle.SOLID, RGBColor.GRAY));
+ assertEquals("medium solid gray", $("#test").css("borderTop"));
+ assertEquals("medium solid gray", $("#test").css(CSS.BORDER_TOP));
+
+ $("#test").css(
+ CSS.BORDER_BOTTOM.with(BorderWidth.THIN, BorderStyle.DOUBLE,
+ RGBColor.FUSCHIA));
+ assertEquals("thin double fuschia", $("#test").css("borderBottom"));
+ assertEquals("thin double fuschia", $("#test").css(CSS.BORDER_BOTTOM));
+
+ $("#test").css(
+ CSS.BORDER_LEFT.with(BorderWidth.THIN, BorderStyle.SOLID, RGBColor.BLACK));
+ assertEquals("thin solid black", $("#test").css("borderLeft"));
+ assertEquals("thin solid black", $("#test").css(CSS.BORDER_LEFT));
+
+ $("#test").css(
+ CSS.BORDER_RIGHT.with(BorderWidth.MEDIUM, BorderStyle.DASHED, RGBColor.GRAY));
+ assertEquals("medium dashed gray", $("#test").css("borderRight"));
+ assertEquals("medium dashed gray", $("#test").css(CSS.BORDER_RIGHT));
+
+ }
+
+ public void testBorderStyleProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BORDER_STYLE.with(BorderStyle.DOTTED));
+ assertEquals("dotted", $("#test").css("borderStyle"));
+ assertEquals("dotted", $("#test").css(CSS.BORDER_STYLE));
+
+ $("#test").css(CSS.BORDER_BOTTOM_STYLE.with(BorderStyle.DASHED));
+ assertEquals("dashed", $("#test").css("borderBottomStyle"));
+ assertEquals("dashed", $("#test").css(CSS.BORDER_BOTTOM_STYLE));
+
+ $("#test").css(CSS.BORDER_TOP_STYLE.with(BorderStyle.DOUBLE));
+ assertEquals("double", $("#test").css("borderTopStyle"));
+ assertEquals("double", $("#test").css(CSS.BORDER_TOP_STYLE));
+
+ $("#test").css(CSS.BORDER_LEFT_STYLE.with(BorderStyle.HIDDEN));
+ assertEquals("hidden", $("#test").css("borderLeftStyle"));
+ assertEquals("hidden", $("#test").css(CSS.BORDER_LEFT_STYLE));
+
+ $("#test").css(CSS.BORDER_RIGHT_STYLE.with(BorderStyle.SOLID));
+ assertEquals("solid", $("#test").css("borderRightStyle"));
+ assertEquals("solid", $("#test").css(CSS.BORDER_RIGHT_STYLE));
+
+ }
+
+ public void testBorderWidthProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.BORDER_WIDTH.with(BorderWidth.MEDIUM));
+ assertEquals("medium", $("#test").css("borderWidth"));
+ assertEquals("medium", $("#test").css(CSS.BORDER_WIDTH));
+
+ $("#test").css(CSS.BORDER_WIDTH.with(Length.px(15)));
+ assertEquals("15px", $("#test").css(CSS.BORDER_WIDTH));
+
+ $("#test").css(CSS.BORDER_WIDTH.with(Length.px(20)));
+ assertEquals("20px", $("#test").css(CSS.BORDER_WIDTH));
+
+ $("#test").css(CSS.BORDER_WIDTH.with(Length.mm(20)));
+ assertEquals("20mm", $("#test").css(CSS.BORDER_WIDTH));
+
+ $("#test").css(CSS.BORDER_BOTTOM_WIDTH.with(BorderWidth.THICK));
+ assertEquals("thick", $("#test").css("borderBottomWidth", false));
+ assertEquals("thick", $("#test").css(CSS.BORDER_BOTTOM_WIDTH, false));
+
+ $("#test").css(CSS.BORDER_TOP_WIDTH.with(BorderWidth.THIN));
+ assertEquals("thin", $("#test").css("borderTopWidth", false));
+ assertEquals("thin", $("#test").css(CSS.BORDER_TOP_WIDTH, false));
+
+ $("#test").css(CSS.BORDER_LEFT_WIDTH.with(BorderWidth.THIN));
+ assertEquals("thin", $("#test").css("borderLeftWidth", false));
+ assertEquals("thin", $("#test").css(CSS.BORDER_LEFT_WIDTH, false));
+
+ $("#test").css(CSS.BORDER_RIGHT_WIDTH.with(BorderWidth.THICK));
+ assertEquals("thick", $("#test").css("borderRightWidth", false));
+ assertEquals("thick", $("#test").css(CSS.BORDER_RIGHT_WIDTH, false));
+
+ }
+
+ public void testClearProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.CLEAR.with(Clear.BOTH));
+ assertEquals("both", $("#test").css("clear"));
+ assertEquals("both", $("#test").css(CSS.CLEAR));
+
+ $("#test").css(CSS.CLEAR.with(Clear.LEFT));
+ assertEquals("left", $("#test").css(CSS.CLEAR));
+
+ $("#test").css(CSS.CLEAR.with(Clear.RIGHT));
+ assertEquals("right", $("#test").css(CSS.CLEAR));
+
+ $("#test").css(CSS.CLEAR.with(Clear.NONE));
+ assertEquals("none", $("#test").css(CSS.CLEAR));
+
+ }
+
+ public void testClipProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.CLIP.with(Shape.rect(0, 10, 10, 0)));
+ assertEquals("rect(0px,10px,10px,0px)", $("#test").css("clip"));
+ assertEquals("rect(0px,10px,10px,0px)", $("#test").css(CSS.CLIP));
+ }
+
+ public void testColorProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.COLOR.with(RGBColor.AQUA));
+
+ assertEquals("aqua", $("#test").css("color"));
+ assertEquals("aqua", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.rgb("#112233")));
+
+ assertEquals("#112233", $("#test").css("color"));
+ assertEquals("#112233", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.rgb(35, 45, 55)));
+ assertEquals("rgb(35,45,55)", $("#test").css("color"));
+ assertEquals("rgb(35,45,55)", $("#test").css(CSS.COLOR));
+
+ }
+
+ public void testColorValue() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.COLOR.with(RGBColor.AQUA));
+ assertEquals("aqua", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.BLACK));
+ assertEquals("black", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.BLUE));
+ assertEquals("blue", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.FUSCHIA));
+ assertEquals("fuschia", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.GRAY));
+ assertEquals("gray", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.GREY));
+ assertEquals("grey", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.GREEN));
+ assertEquals("green", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.LIME));
+ assertEquals("lime", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.MAROON));
+ assertEquals("maroon", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.NAVY));
+ assertEquals("navy", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.OLIVE));
+ assertEquals("olive", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.ORANGE));
+ assertEquals("orange", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.PURPLE));
+ assertEquals("purple", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.RED));
+ assertEquals("red", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.SILVER));
+ assertEquals("silver", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.TEAL));
+ assertEquals("teal", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.TRANSPARENT));
+ assertEquals("transparent", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.WHITE));
+ assertEquals("white", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.YELLOW));
+ assertEquals("yellow", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.rgb("#112233")));
+ assertEquals("#112233", $("#test").css(CSS.COLOR));
+
+ $("#test").css(CSS.COLOR.with(RGBColor.rgb(35, 45, 55)));
+ assertEquals("rgb(35,45,55)", $("#test").css(CSS.COLOR));
+
+ }
+
+ public void testCursorProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.CURSOR.with(Cursor.WAIT));
+
+ assertEquals("wait", $("#test").css("cursor"));
+ assertEquals("wait", $("#test").css(CSS.CURSOR));
+
+ }
+
+ public void testDisplayProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.DISPLAY.with(Display.INLINE));
+
+ assertEquals("inline", $("#test").css("display"));
+ assertEquals("inline", $("#test").css(CSS.DISPLAY));
+
+ }
+
+ public void testEdgePositionProperty() {
+
+ $(e).html("<div id='test'>Content</div><");
+
+ $("#test").css(CSS.LEFT.with(Length.px(10)));
+ assertEquals("10px", $("#test").css("left"));
+ assertEquals("10px", $("#test").css(CSS.LEFT));
+
+ $("#test").css(CSS.TOP.with(Length.px(15)));
+ assertEquals("15px", $("#test").css("top"));
+ assertEquals("15px", $("#test").css(CSS.TOP));
+
+ $("#test").css(CSS.RIGHT.with(Length.px(0)));
+ assertEquals("0px", $("#test").css("right"));
+ assertEquals("0px", $("#test").css(CSS.RIGHT));
+
+ $("#test").css(CSS.BOTTOM.with(Length.px(20)));
+ assertEquals("20px", $("#test").css("bottom"));
+ assertEquals("20px", $("#test").css(CSS.BOTTOM));
+
+ }
+
+ public void testFloatProperty() {
+
+ $(e).html("<div><div id='test'>Content</div></div>");
+ $("#test").css(CSS.FLOAT.with(Float.LEFT));
+
+ assertEquals("left", $("#test").css("float"));
+ assertEquals("left", $("#test").css(CSS.FLOAT));
+
+ }
+
+ public void testFontSizeProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.LARGER));
+ assertEquals("larger", $("#test").css("fontSize"));
+ assertEquals("larger", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.LARGE));
+ assertEquals("large", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.MEDIUM));
+ assertEquals("medium", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.SMALL));
+ assertEquals("small", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.SMALLER));
+ assertEquals("smaller", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.X_LARGE));
+ assertEquals("x-large", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.X_SMALL));
+ assertEquals("x-small", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.XX_LARGE));
+ assertEquals("xx-large", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(FontSize.XX_SMALL));
+ assertEquals("xx-small", $("#test").css(CSS.FONT_SIZE));
+
+ $("#test").css(CSS.FONT_SIZE.with(Length.px(16)));
+ assertEquals("16px", $("#test").css(CSS.FONT_SIZE));
+ }
+
+ public void testFontStyleProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.FONT_STYLE.with(FontStyle.ITALIC));
+ assertEquals("italic", $("#test").css("fontStyle"));
+ assertEquals("italic", $("#test").css(CSS.FONT_STYLE));
+
+ }
+
+ public void testFontVariantProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.FONT_VARIANT.with(FontVariant.SMALL_CAPS));
+ assertEquals("small-caps", $("#test").css("fontVariant"));
+ assertEquals("small-caps", $("#test").css(CSS.FONT_VARIANT));
+
+ }
+
+ public void testHeightProperties() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.HEIGHT.with(Length.px(10)));
+
+ assertEquals("10px", $("#test").css("height"));
+ assertEquals("10px", $("#test").css(CSS.HEIGHT));
+
+ $("#test").css(CSS.MAX_HEIGHT.with(Length.px(15)));
+
+ assertEquals("15px", $("#test").css("maxHeight"));
+ assertEquals("15px", $("#test").css(CSS.MAX_HEIGHT));
+
+ $("#test").css(CSS.MIN_HEIGHT.with(Length.px(5)));
+
+ assertEquals("5px", $("#test").css("minHeight"));
+ assertEquals("5px", $("#test").css(CSS.MIN_HEIGHT));
+ }
+
+ public void testLengthValue() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.HEIGHT.with(Length.px(10)));
+ assertEquals("10px", $("#test").css(CSS.HEIGHT));
+
+ $("#test").css(CSS.HEIGHT.with(Length.cm(10)));
+ assertEquals("10cm", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.em(10)));
+ assertEquals("10em", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.ex(10)));
+ assertEquals("10ex", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.in(10)));
+ assertEquals("10in", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.mm(10)));
+ assertEquals("10mm", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pc(10)));
+ assertEquals("10pc", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pct(10)));
+ assertEquals("10%", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pt(10)));
+ assertEquals("10pt", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.px(10.1)));
+ assertEquals("10.1px", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.cm(10.1)));
+ assertEquals("10.1cm", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.em(10.1)));
+ assertEquals("10.1em", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.ex(10.1)));
+ assertEquals("10.1ex", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.in(10.1)));
+ assertEquals("10.1in", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.mm(10.1)));
+ assertEquals("10.1mm", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pc(10.1)));
+ assertEquals("10.1pc", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pct(10.1)));
+ assertEquals("10.1%", $("#test").css(CSS.HEIGHT, false));
+
+ $("#test").css(CSS.HEIGHT.with(Length.pt(10.1)));
+ assertEquals("10.1pt", $("#test").css(CSS.HEIGHT, false));
+
+ }
+
+ public void testLetterSpacingProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.LETTER_SPACING.with(Length.px(15)));
+ assertEquals("15px", $("#test").css("letterSpacing"));
+ assertEquals("15px", $("#test").css(CSS.LETTER_SPACING));
+
+ }
+
+ public void testLineHeightProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.LINE_HEIGHT.with(Length.px(15)));
+ assertEquals("15px", $("#test").css("lineHeight"));
+ assertEquals("15px", $("#test").css(CSS.LINE_HEIGHT));
+
+ $("#test").css(CSS.LINE_HEIGHT.with(2));
+ assertEquals("2", $("#test").css("lineHeight"));
+ assertEquals("2", $("#test").css(CSS.LINE_HEIGHT));
+
+ $("#test").css(CSS.LINE_HEIGHT.with(2.5));
+ assertEquals("2.5", $("#test").css("lineHeight"));
+ assertEquals("2.5", $("#test").css(CSS.LINE_HEIGHT));
+
+ }
+
+ public void testListStyleImageProperty() {
+
+ $(e).html("<ul id='test'><li>Content</li></ul>");
+
+ $("#test").css(CSS.LIST_STYLE_IMAGE.with(UriValue.url("arrow.jpg")));
+ assertEquals("url('arrow.jpg')", $("#test").css("listStyleImage"));
+ assertEquals("url('arrow.jpg')", $("#test").css(CSS.LIST_STYLE_IMAGE));
+
+ }
+
+ public void testListStylePositionProperty() {
+
+ $(e).html("<ul id='test'><li>Content</li></ul>");
+
+ $("#test").css(CSS.LIST_STYLE_POSITION.with(ListStylePosition.INSIDE));
+ assertEquals("inside", $("#test").css("listStylePosition"));
+ assertEquals("inside", $("#test").css(CSS.LIST_STYLE_POSITION));
+
+ $("#test").css(CSS.LIST_STYLE_POSITION.with(ListStylePosition.OUTSIDE));
+ assertEquals("outside", $("#test").css("listStylePosition"));
+ assertEquals("outside", $("#test").css(CSS.LIST_STYLE_POSITION));
+
+ }
+
+ public void testListStyleProperty() {
+
+ $(e).html("<ul id='test'><li>Content</li></ul>");
+
+ $("#test").css(
+ CSS.LIST_STYLE.with(ListStyleType.DISC, ListStylePosition.OUTSIDE,
+ null));
+ assertEquals("disc outside", $("#test").css("listStyle"));
+ assertEquals("disc outside", $("#test").css(CSS.LIST_STYLE));
+
+ $("#test").css(
+ CSS.LIST_STYLE.with(ListStyleType.DISC, null, UriValue.url("square.jpg")));
+ assertEquals("disc url('square.jpg')", $("#test").css("listStyle"));
+ assertEquals("disc url('square.jpg')", $("#test").css(CSS.LIST_STYLE));
+
+ $("#test").css(
+ CSS.LIST_STYLE.with(null, ListStylePosition.OUTSIDE, UriValue.url("square.jpg")));
+ assertEquals("outside url('square.jpg')", $("#test").css("listStyle"));
+ assertEquals("outside url('square.jpg')", $("#test").css(CSS.LIST_STYLE));
+
+ }
+
+ public void testListStyleTypeProperty() {
+
+ $(e).html("<ul id='test'><li>Content</li></ul>");
+
+ $("#test").css(CSS.LIST_STYLE_TYPE.with(ListStyleType.DISC));
+ assertEquals("disc", $("#test").css("listStyleType"));
+ assertEquals("disc", $("#test").css(CSS.LIST_STYLE_TYPE));
+
+ }
+
+ public void testMarginProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.MARGIN.with(Length.px(10), Length.px(20)));
+
+ assertEquals("10px 20px", $("#test").css("margin"));
+ assertEquals("10px 20px", $("#test").css(CSS.MARGIN));
+
+ $("#test").css(CSS.MARGIN.with(Length.px(10), Length.px(20), Length.px(30)));
+
+ assertEquals("10px 20px 30px", $("#test").css("margin"));
+ assertEquals("10px 20px 30px", $("#test").css(CSS.MARGIN));
+
+ $("#test").css(CSS.MARGIN.with(Length.px(10)));
+
+ assertEquals("10px", $("#test").css("margin"));
+ assertEquals("10px", $("#test").css(CSS.MARGIN));
+
+ $("#test").css(
+ CSS.MARGIN.with(Length.px(10), Length.px(20), Length.px(30),
+ Length.px(40)));
+
+ assertEquals("10px 20px 30px 40px", $("#test").css("margin"));
+ assertEquals("10px 20px 30px 40px", $("#test").css(CSS.MARGIN));
+
+ $("#test").css(CSS.MARGIN_TOP.with(Length.px(20)));
+
+ assertEquals("20px", $("#test").css("marginTop"));
+ assertEquals("20px", $("#test").css(CSS.MARGIN_TOP));
+
+ $("#test").css(CSS.MARGIN_BOTTOM.with(Length.px(30)));
+
+ assertEquals("30px", $("#test").css("marginBottom"));
+ assertEquals("30px", $("#test").css(CSS.MARGIN_BOTTOM));
+
+ $("#test").css(CSS.MARGIN_LEFT.with(Length.px(40)));
+
+ assertEquals("40px", $("#test").css("marginLeft"));
+ assertEquals("40px", $("#test").css(CSS.MARGIN_LEFT));
+
+ $("#test").css(CSS.MARGIN_RIGHT.with(Length.px(50)));
+
+ assertEquals("50px", $("#test").css("marginRight"));
+ assertEquals("50px", $("#test").css(CSS.MARGIN_RIGHT));
+ }
+
+ public void testOutlineProperty() {
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.OUTLINE_WIDTH.with(Length.px(10)));
+ assertEquals("10px", $("#test").css("outlineWidth"));
+ assertEquals("10px", $("#test").css(CSS.OUTLINE_WIDTH));
+
+ $("#test").css(CSS.OUTLINE_WIDTH.with(BorderWidth.MEDIUM));
+ assertEquals("medium", $("#test").css("outlineWidth"));
+ assertEquals("medium", $("#test").css(CSS.OUTLINE_WIDTH));
+
+ $("#test").css(CSS.OUTLINE_COLOR.with(RGBColor.GRAY));
+ assertEquals("gray", $("#test").css("outlineColor"));
+ assertEquals("gray", $("#test").css(CSS.OUTLINE_COLOR));
+
+ $("#test").css(CSS.OUTLINE_STYLE.with(BorderStyle.DOTTED));
+ assertEquals("dotted", $("#test").css("outlineStyle"));
+ assertEquals("dotted", $("#test").css(CSS.OUTLINE_STYLE));
+
+ $("#test").css(
+ CSS.OUTLINE.with(RGBColor.BLACK, BorderStyle.DASHED, BorderWidth.MEDIUM));
+ assertEquals("black dashed medium", $("#test").css("outline"));
+ assertEquals("black dashed medium", $("#test").css(CSS.OUTLINE));
+
+ $("#test").css(
+ CSS.OUTLINE.with(RGBColor.AQUA, BorderStyle.DOUBLE, Length.px(15)));
+ assertEquals("aqua double 15px", $("#test").css("outline"));
+ assertEquals("aqua double 15px", $("#test").css(CSS.OUTLINE));
+
+ }
+
+ public void testOverflowProperty() {
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.OVERFLOW.with(Overflow.HIDDEN));
+ assertEquals("hidden", $("#test").css("overflow"));
+ assertEquals("hidden", $("#test").css(CSS.OVERFLOW));
+
+ $("#test").css(CSS.OVERFLOW.with(Overflow.SCROLL));
+ assertEquals("scroll", $("#test").css("overflow"));
+ assertEquals("scroll", $("#test").css(CSS.OVERFLOW));
+
+ $("#test").css(CSS.OVERFLOW.with(Overflow.VISIBLE));
+ assertEquals("visible", $("#test").css("overflow"));
+ assertEquals("visible", $("#test").css(CSS.OVERFLOW));
+
+ }
+
+ public void testPaddingProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.PADDING.with(Length.px(10)));
+
+ assertEquals("10px", $("#test").css("padding"));
+ assertEquals("10px", $("#test").css(CSS.PADDING));
+
+ $("#test").css(
+ CSS.PADDING.with(Length.px(10), Length.px(20)));
+
+ assertEquals("10px 20px", $("#test").css("padding"));
+ assertEquals("10px 20px", $("#test").css(CSS.PADDING));
+
+ $("#test").css(
+ CSS.PADDING.with(Length.px(10), Length.px(20), Length.px(30)));
+
+ assertEquals("10px 20px 30px", $("#test").css("padding"));
+ assertEquals("10px 20px 30px", $("#test").css(CSS.PADDING));
+
+ $("#test").css(
+ CSS.PADDING.with(Length.px(10), Length.px(20), Length.px(30),
+ Length.px(40)));
+
+ assertEquals("10px 20px 30px 40px", $("#test").css("padding"));
+ assertEquals("10px 20px 30px 40px", $("#test").css(CSS.PADDING));
+
+ $("#test").css(CSS.PADDING_TOP.with(Length.px(20)));
+
+ assertEquals("20px", $("#test").css("paddingTop"));
+ assertEquals("20px", $("#test").css(CSS.PADDING_TOP));
+
+ $("#test").css(CSS.PADDING_BOTTOM.with(Length.px(30)));
+
+ assertEquals("30px", $("#test").css("paddingBottom"));
+ assertEquals("30px", $("#test").css(CSS.PADDING_BOTTOM));
+
+ $("#test").css(CSS.PADDING_LEFT.with(Length.px(40)));
+
+ assertEquals("40px", $("#test").css("paddingLeft"));
+ assertEquals("40px", $("#test").css(CSS.PADDING_LEFT));
+
+ $("#test").css(CSS.PADDING_RIGHT.with(Length.px(50)));
+
+ assertEquals("50px", $("#test").css("paddingRight"));
+ assertEquals("50px", $("#test").css(CSS.PADDING_RIGHT));
+ }
+
+ public void testPositionProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.POSITION.with(Position.ABSOLUTE));
+ assertEquals("absolute", $("#test").css("position"));
+ assertEquals("absolute", $("#test").css(CSS.POSITION));
+
+ $("#test").css(CSS.POSITION.with(Position.FIXED));
+ assertEquals("fixed", $("#test").css("position"));
+ assertEquals("fixed", $("#test").css(CSS.POSITION));
+
+ $("#test").css(CSS.POSITION.with(Position.RELATIVE));
+ assertEquals("relative", $("#test").css("position"));
+ assertEquals("relative", $("#test").css(CSS.POSITION));
+
+ $("#test").css(CSS.POSITION.with(Position.STATIC));
+ assertEquals("static", $("#test").css("position"));
+ assertEquals("static", $("#test").css(CSS.POSITION));
+
+ }
+
+ public void testTextAlignProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.CENTER));
+ assertEquals("center", $("#test").css("textAlign"));
+ assertEquals("center", $("#test").css(CSS.TEXT_ALIGN));
+
+ $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.JUSTIFY));
+ assertEquals("justify", $("#test").css("textAlign"));
+ assertEquals("justify", $("#test").css(CSS.TEXT_ALIGN));
+
+ $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.LEFT));
+ assertEquals("left", $("#test").css("textAlign"));
+ assertEquals("left", $("#test").css(CSS.TEXT_ALIGN));
+
+ $("#test").css(CSS.TEXT_ALIGN.with(TextAlign.RIGHT));
+ assertEquals("right", $("#test").css("textAlign"));
+ assertEquals("right", $("#test").css(CSS.TEXT_ALIGN));
+
+ }
+
+ public void testTextDecorationProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.TEXT_DECORATION.with(TextDecoration.LINE_THROUGH));
+ assertEquals("line-through", $("#test").css("textDecoration"));
+ assertEquals("line-through", $("#test").css(CSS.TEXT_DECORATION));
+
+ }
+
+ public void testTextIdentProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.TEXT_IDENT.with(Length.px(15)));
+ assertEquals("15px", $("#test").css("textIdent", false));
+ assertEquals("15px", $("#test").css(CSS.TEXT_IDENT, false));
+
+ }
+
+ public void testTextTransformProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.UPPERCASE));
+ assertEquals("uppercase", $("#test").css("textTransform", false));
+ assertEquals("uppercase", $("#test").css(CSS.TEXT_TRANSFORM, false));
+
+ $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.LOWERCASE));
+ assertEquals("lowercase", $("#test").css("textTransform", false));
+
+ $("#test").css(CSS.TEXT_TRANSFORM.with(TextTransform.CAPITALIZE));
+ assertEquals("capitalize", $("#test").css("textTransform", false));
+ }
+
+ public void testUnicodeBidiProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.BIDI_OVERRIDE));
+ assertEquals("bidi-override", $("#test").css("unicode-bidi"));
+ assertEquals("bidi-override", $("#test").css(CSS.UNICODE_BIDI));
+
+ $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.EMBED));
+ assertEquals("embed", $("#test").css(CSS.UNICODE_BIDI));
+
+ $("#test").css(CSS.UNICODE_BIDI.with(UnicodeBidi.NORMAL));
+ assertEquals("normal", $("#test").css(CSS.UNICODE_BIDI));
+ }
+
+ public void testVerticalAlignProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(Length.px(120)));
+ assertEquals("120px", $("#test").css("verticalAlign"));
+ assertEquals("120px", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.BASELINE));
+ assertEquals("baseline", $("#test").css("verticalAlign"));
+ assertEquals("baseline", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.BOTTOM));
+ assertEquals("bottom", $("#test").css("verticalAlign"));
+ assertEquals("bottom", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.MIDDLE));
+ assertEquals("middle", $("#test").css("verticalAlign"));
+ assertEquals("middle", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.SUB));
+ assertEquals("sub", $("#test").css("verticalAlign"));
+ assertEquals("sub", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.SUPER));
+ assertEquals("super", $("#test").css("verticalAlign"));
+ assertEquals("super", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TEXT_BOTTOM));
+ assertEquals("text-bottom", $("#test").css("verticalAlign"));
+ assertEquals("text-bottom", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TEXT_TOP));
+ assertEquals("text-top", $("#test").css("verticalAlign"));
+ assertEquals("text-top", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ $("#test").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.TOP));
+ assertEquals("top", $("#test").css("verticalAlign"));
+ assertEquals("top", $("#test").css(CSS.VERTICAL_ALIGN));
+
+ }
+
+ public void testVisibilityProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.VISIBILITY.with(Visibility.HIDDEN));
+ assertEquals("hidden", $("#test").css("visibility"));
+ assertEquals("hidden", $("#test").css(CSS.VISIBILITY));
+
+ $("#test").css(CSS.VISIBILITY.with(Visibility.VISIBLE));
+ assertEquals("visible", $("#test").css("visibility"));
+ assertEquals("visible", $("#test").css(CSS.VISIBILITY));
+
+ }
+
+ public void testWhiteSpaceProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.NORMAL));
+ assertEquals("normal", $("#test").css("whiteSpace"));
+ assertEquals("normal", $("#test").css(CSS.WHITE_SPACE));
+
+ $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.NOWRAP));
+ assertEquals("nowrap", $("#test").css(CSS.WHITE_SPACE));
+
+ $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE));
+ assertEquals("pre", $("#test").css(CSS.WHITE_SPACE));
+
+ $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE_LINE));
+ assertEquals("pre-line", $("#test").css(CSS.WHITE_SPACE));
+
+ $("#test").css(CSS.WHITE_SPACE.with(WhiteSpace.PRE_WRAP));
+ assertEquals("pre-wrap", $("#test").css(CSS.WHITE_SPACE));
+
+ }
+
+ public void testWidthProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.WIDTH.with(Length.px(20)));
+ assertEquals("20px", $("#test").css("width"));
+ assertEquals("20px", $("#test").css(CSS.WIDTH));
+
+ $("#test").css(CSS.MIN_WIDTH.with(Length.px(10)));
+ assertEquals("10px", $("#test").css("minWidth"));
+ assertEquals("10px", $("#test").css(CSS.MIN_WIDTH));
+
+ $("#test").css(CSS.MAX_WIDTH.with(Length.px(30)));
+ assertEquals("30px", $("#test").css("maxWidth"));
+ assertEquals("30px", $("#test").css(CSS.MAX_WIDTH));
+
+ }
+
+ public void testWordSpacingProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.WORD_SPACING.with(Length.pt(2)));
+ assertEquals("2pt", $("#test").css("wordSpacing"));
+ assertEquals("2pt", $("#test").css(CSS.WORD_SPACING));
+
+ }
+
+ public void testZIndexProperty() {
+
+ $(e).html("<div id='test'>Content</div>");
+
+ $("#test").css(CSS.ZINDEX.with(1000));
+ assertEquals("1000", $("#test").css("zIndex"));
+ assertEquals("1000", $("#test").css(CSS.ZINDEX));
+
+ $("#test").css(CSS.ZINDEX.with(new Integer(200)));
+ assertEquals("200", $("#test").css("zIndex"));
+ assertEquals("200", $("#test").css(CSS.ZINDEX));
+
+ $("#test").css(CSS.ZINDEX.with(null));
+ assertEquals("0", $("#test").css("zIndex"));
+ assertEquals("0", $("#test").css(CSS.ZINDEX));
+
+ }
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-import static com.google.gwt.query.client.GQuery.$$;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.GQuery.Offset;
-import com.google.gwt.query.client.plugins.Effects;
-import com.google.gwt.query.client.plugins.effects.Fx.ColorFx;
-import com.google.gwt.query.client.plugins.effects.PropertiesAnimation;
-import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test class for testing gwtquery effects plugin api.
- */
-public class GQueryEffectsTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("effects-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- public void testClipAnimation() {
- $(e).html("<p id='idtest'>Content 1</p></p>");
-
- final GQuery g = $("#idtest");
- final int duration = 1000;
-
- // Clip effect places a relative div in the position of the original element
- // So check that there is not any div.
- GQuery back = $("div", e);
- assertEquals(0, back.size());
-
- g.as(Effects.Effects).clipDisappear(duration);
-
- // Check that the back div has been created
- back = $("div", e);
- assertEquals(1, back.size());
-
- // Configure the max duration for this test
- delayTestFinish(duration * 2);
-
- // each timer calls the next one
- //final Timer timer1 = new Timer() {
- //public void run() {
- // Check that the back div has been removed
- //GQuery back = $("div", e);
- //assertEquals(0, back.size());
- // Check that the attribute clip has been removed
- //assertEquals("", g.css("clip"));
- //finishTest();
- //}
- //};
- final Timer timer2 = new Timer() {
- public void run() {
- // Check that the attribute clip has been set
- assertTrue(g.css("clip").matches("rect\\(\\d+px[, ]+\\d+px[, ]+\\d+px[, ]+\\d+px\\)"));
- finishTest();
- //timer1.schedule(duration/2 + 1);
- }
- };
-
- // Start the first timer
- timer2.schedule(duration/2);
- }
-
- public void testEffectsShouldBeQueued() {
- $(e).html("<p id='idtest'>Content 1</p></p>");
-
- final GQuery g = $("#idtest").css("position", "absolute");
- final Offset o = g.offset();
-
- final int duration = 1000;
- g.as(Effects.Effects).
- animate($$("left: '+=100'"), duration, Easing.LINEAR).
- animate($$("top: '+=100'"), duration, Easing.LINEAR).
- animate($$("left: '-=100'"), duration, Easing.LINEAR).
- animate($$("top: '-=100'"), duration, Easing.LINEAR);
-
- // Configure the max duration for this test
- delayTestFinish(duration * 4);
-
- // each timer calls the next one
- final Timer timer1 = new Timer() {
- public void run() {
- assertPosition(g, o.add(0, 99), o.add(0, 1));
- // Last timer should finish the test
- finishTest();
- }
- };
- final Timer timer2 = new Timer() {
- public void run() {
- assertPosition(g, o.add(99, 100), o.add(1, 100));
- timer1.schedule(duration);
- }
- };
- final Timer timer3 = new Timer() {
- public void run() {
- assertPosition(g, o.add(100, 1), o.add(100, 99));
- timer2.schedule(duration);
- }
- };
- final Timer timer4 = new Timer() {
- public void run() {
- assertPosition(g, o.add(1, 0), o.add(99, 0));
- timer3.schedule(duration);
- }
- };
- // Start the first timer
- timer4.schedule(duration/2);
- }
-
- public void testFade() {
- $(e)
- .html(
- "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
-
- final GQuery sectA = $("#id1");
- final GQuery sectB = $("#id2");
-
- // fadeIn() & fadeOut() are tested with delayed assertions
- sectA.hide();
- sectA.fadeIn(2000);
- sectB.fadeOut(2000);
-
- // Configure the max duration for this test
- // If the test exceeds the timeout without calling finishTest() it will fail
- delayTestFinish(2500);
-
- // Delayed assertions at different intervals
- Timer timerShortTime = new Timer() {
- public void run() {
- double o = Double.valueOf(sectA.css("opacity", false));
- assertTrue(
- "'sectA' opacity must be in the interval 0-0.5 but is: " + o, o > 0
- && o < 0.5);
- o = Double.valueOf(sectB.css("opacity", false));
- assertTrue(
- "'sectB' opacity must be in the interval 0.5-1 but is: " + o,
- o > 0.5 && o < 1);
- }
- };
- Timer timerMidTime = new Timer() {
- public void run() {
- assertEquals("inline", sectA.css("display", false));
- assertEquals("", sectB.css("display", false));
- double o = Double.valueOf(sectA.css("opacity", false));
- assertTrue(
- "'sectA' opacity must be in the interval 0.5-1 but is: " + o,
- o > 0.5 && o < 1);
- o = Double.valueOf(sectB.css("opacity", false));
- assertTrue(
- "'sectB' opacity must be in the interval 0-0.5 but is: " + o, o > 0
- && o < 0.5);
- }
- };
- Timer timerLongTime = new Timer() {
- public void run() {
- assertEquals("inline", sectA.css("display", false));
- assertEquals("none", sectB.css("display", false));
- // Last delayed assertion has to stop the test to avoid a timeout
- // failure
- finishTest();
- }
- };
-
- // schedule the delayed assertions
- timerShortTime.schedule(200);
- timerMidTime.schedule(1200);
- timerLongTime.schedule(2200);
- }
-
- public void testPropertiesAnimationComputeEffects() {
- $(e)
- .html(
- "<div id='parent' style='background-color: yellow; width: 100px; height: 200px; top:130px; position: absolute; left: 130px'><p id='child' style='background-color: pink; width: 100px; height: 100px; position: absolute; padding: 5px; margin: 0px'>Content 1</p></div>");
- GQuery g = $("#child");
- Properties prop1;
-
- assertEquals("cssprop=marginTop value=-110px start=0 end=-110 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "-110px",
- false).toString());
- assertEquals("cssprop=marginLeft value=-110px start=0 end=-110 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "-110px",
- false).toString());
- assertEquals("cssprop=top value=50% start=0 end=50 unit=%",
- PropertiesAnimation.computeFxProp(g.get(0), "top", "50%", false)
- .toString());
- assertEquals("cssprop=left value=50% start=0 end=50 unit=%",
- PropertiesAnimation.computeFxProp(g.get(0), "left", "50%", false)
- .toString());
- assertEquals("cssprop=width value=174px start=100 end=174 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "width", "174px", false)
- .toString());
- assertEquals("cssprop=height value=174px start=100 end=174 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "height", "174px", false)
- .toString());
- assertEquals("cssprop=padding value=20px start=5 end=20 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "padding", "20px", false)
- .toString());
-
- prop1 = GQuery.$$("marginTop: '-110px', marginLeft: '-110px', top: '50%', left: '50%', width: '174px', height: '174px', padding: '20px'");
- PropertiesAnimation an = new PropertiesAnimation(Easing.SWING, g.get(0), prop1);
- an.onStart();
- an.onComplete();
-
- assertEquals("cssprop=marginTop value=0 start=-110 end=0 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "0", false)
- .toString());
- assertEquals("cssprop=marginLeft value=0 start=-110 end=0 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "0", false)
- .toString());
- assertEquals("cssprop=top value=0% start=50 end=0 unit=%", PropertiesAnimation
- .computeFxProp(g.get(0), "top", "0%", false).toString());
- assertEquals("cssprop=left value=0% start=50 end=0 unit=%",
- PropertiesAnimation.computeFxProp(g.get(0), "left", "0%", false)
- .toString());
- assertEquals("cssprop=width value=100px start=174 end=100 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "width", "100px", false)
- .toString());
- assertEquals("cssprop=height value=100px start=174 end=100 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "height", "100px", false)
- .toString());
- assertEquals("cssprop=padding value=5px start=20 end=5 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "padding", "5px", false)
- .toString());
-
- prop1 = GQuery.$$("marginTop: '0', marginLeft: '0', top: '0%', left: '0%', width: '100px', height: '100px', padding: '5px'");
- an = new PropertiesAnimation(Easing.SWING, g.get(0), prop1);
- an.onStart();
- an.onComplete();
-
- assertEquals("cssprop=marginTop value=-110px start=0 end=-110 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "-110px",
- false).toString());
- assertEquals("cssprop=marginLeft value=-110px start=0 end=-110 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "-110px",
- false).toString());
- assertEquals("cssprop=top value=50% start=0 end=50 unit=%",
- PropertiesAnimation.computeFxProp(g.get(0), "top", "50%", false)
- .toString());
- assertEquals("cssprop=left value=50% start=0 end=50 unit=%",
- PropertiesAnimation.computeFxProp(g.get(0), "left", "50%", false)
- .toString());
- assertEquals("cssprop=width value=174px start=100 end=174 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "width", "174px", false)
- .toString());
- assertEquals("cssprop=height value=174px start=100 end=174 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "height", "174px", false)
- .toString());
- assertEquals("cssprop=padding value=20px start=5 end=20 unit=px",
- PropertiesAnimation.computeFxProp(g.get(0), "padding", "20px", false)
- .toString());
- }
-
- public void testColorEffectParsing(){
- String html = "<div id='test' style='color: #112233'>Test</div>";
- $(e).html(html);
-
- ColorFx effect = (ColorFx) PropertiesAnimation.computeFxProp($("#test",e).get(0), "color", "#ffffff", false);
- assertEquals(17, effect.getStartColor()[0]); //#11
- assertEquals(34, effect.getStartColor()[1]); //#22
- assertEquals(51, effect.getStartColor()[2]); //#33
-
- assertEquals(255, effect.getEndColor()[0]);
- assertEquals(255, effect.getEndColor()[1]);
- assertEquals(255, effect.getEndColor()[2]);
-
- effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "rgb(255,255,255)", false);
- assertEquals(255, effect.getEndColor()[0]);
- assertEquals(255, effect.getEndColor()[1]);
- assertEquals(255, effect.getEndColor()[2]);
-
- effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "rgb(100%, 100%, 100%)", false);
- assertEquals(255, effect.getEndColor()[0]);
- assertEquals(255, effect.getEndColor()[1]);
- assertEquals(255, effect.getEndColor()[2]);
-
- effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "white", false);
- assertEquals(255, effect.getEndColor()[0]);
- assertEquals(255, effect.getEndColor()[1]);
- assertEquals(255, effect.getEndColor()[2]);
- }
-
- private void assertPosition(GQuery g, Offset min, Offset max) {
- int a = Math.min(min.top, max.top);
- int b = Math.max(min.top, max.top);
- int v = g.offset().top;
- boolean c = a <= v && v <= b;
- String msg = "Top has the value " + v + ", but should be in the range: "
- + a + " - " + b;
- assertTrue(msg, c);
-
- a = Math.min(min.left, max.left);
- b = Math.max(min.left, max.left);
- v = g.offset().left;
- c = a <= v && v <= b;
- msg = "Left has the value " + v + ", but should be in the range: " + a
- + " - " + b;
- assertTrue(msg, c);
- }
-
- public void testAttrEffect() {
- $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A</td><td width=50%>B</td></tr></table>");
-
- final GQuery g = $("#idtest").css("position", "absolute");
- final int duration = 500;
-
- assertEquals("cssprop=$width attr=width value=+=100 start=440 end=540 unit=",
- PropertiesAnimation.computeFxProp(g.get(0), "$width", "+=100", false).toString());
-
- delayTestFinish(duration * 3);
-
- g.as(Effects.Effects).
- animate($$("$width: +=100; $border: +=4"), duration, Easing.LINEAR);
-
- final Timer timer = new Timer() {
- public void run() {
- assertEquals(540.0, Double.parseDouble(g.attr("width")));
- assertEquals(5.0, Double.parseDouble(g.attr("border")));
- finishTest();
- }
- };
- timer.schedule(duration * 2);
- }
-
- public void testStop() {
- $(e)
- .html(
- "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
-
- final GQuery sectA = $("#id1");
- final GQuery sectB = $("#id2");
- final GQuery sectC = $("#id2");
-
- sectA.hide();
- sectA.fadeIn(2000);
- sectB.fadeOut(2000).delay(500).fadeIn(1000);
- sectC.fadeOut(2000).delay(500).fadeIn(1000);
-
- // Call stop
- Timer timerMidTime = new Timer() {
- public void run() {
- sectA.stop();
- sectB.stop(true, true);
- sectC.stop(false, false);
-
- Double o = Double.valueOf(sectA.css("opacity"));
- sectA.data("opacityA", o);
- assertTrue(
- "'sectA' opacity must be in the interval 0.5-1 but is: " + o,
- o > 0.5 && o < 1);
-
- //animation should jump to the end
- assertEquals("none", sectB.css("display"));
-
- o = Double.valueOf(sectC.css("opacity"));
- sectC.data("opacityC", o);
- assertTrue(
- "'sectC' opacity must be in the interval 0-0.5 but is: " + o,
- o > 0 && o < 0.5);
- }
- };
-
-
- Timer timerLongTime = new Timer() {
- public void run() {
- Double midAOpacity = sectA.data("opacityA", Double.class);
- //animation was stopped, opacity should not change
- assertEquals(midAOpacity, Double.valueOf(sectA.css("opacity")));
- //animation was stopped and jumped to the end, the queue was cleared so no change too.
- assertEquals("none", sectB.css("display"));
-
- //fadeOut was stopped but fadeIn should continue
- Double midCOpacity = sectC.data("opacityC", Double.class);
- Double laterCOpacity = Double.valueOf(sectC.css("opacity"));
- assertTrue(laterCOpacity > midCOpacity);
- // Last delayed assertion has to stop the test to avoid a timeout
- // failure
- finishTest();
- }
- };
- // schedule timer
- timerMidTime.schedule(1200);
- // schedule timer
- timerLongTime.schedule(2200);
-
- }
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.$$;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.GQuery.Offset;
+import com.google.gwt.query.client.plugins.Effects;
+import com.google.gwt.query.client.plugins.effects.Fx.ColorFx;
+import com.google.gwt.query.client.plugins.effects.PropertiesAnimation;
+import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing gwtquery effects plugin api.
+ */
+public class GQueryEffectsTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("effects-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ public void testClipAnimation() {
+ $(e).html("<p id='idtest'>Content 1</p></p>");
+
+ final GQuery g = $("#idtest");
+ final int duration = 1000;
+
+ // Clip effect places a relative div in the position of the original element
+ // So check that there is not any div.
+ GQuery back = $("div", e);
+ assertEquals(0, back.size());
+
+ g.as(Effects.Effects).clipDisappear(duration);
+
+ // Check that the back div has been created
+ back = $("div", e);
+ assertEquals(1, back.size());
+
+ // Configure the max duration for this test
+ delayTestFinish(duration * 2);
+
+ // each timer calls the next one
+ //final Timer timer1 = new Timer() {
+ //public void run() {
+ // Check that the back div has been removed
+ //GQuery back = $("div", e);
+ //assertEquals(0, back.size());
+ // Check that the attribute clip has been removed
+ //assertEquals("", g.css("clip"));
+ //finishTest();
+ //}
+ //};
+ final Timer timer2 = new Timer() {
+ public void run() {
+ // Check that the attribute clip has been set
+ assertTrue(g.css("clip").matches("rect\\(\\d+px[, ]+\\d+px[, ]+\\d+px[, ]+\\d+px\\)"));
+ finishTest();
+ //timer1.schedule(duration/2 + 1);
+ }
+ };
+
+ // Start the first timer
+ timer2.schedule(duration/2);
+ }
+
+ public void testEffectsShouldBeQueued() {
+ $(e).html("<p id='idtest'>Content 1</p></p>");
+
+ final GQuery g = $("#idtest").css("position", "absolute");
+ final Offset o = g.offset();
+
+ final int duration = 1000;
+ g.as(Effects.Effects).
+ animate($$("left: '+=100'"), duration, Easing.LINEAR).
+ animate($$("top: '+=100'"), duration, Easing.LINEAR).
+ animate($$("left: '-=100'"), duration, Easing.LINEAR).
+ animate($$("top: '-=100'"), duration, Easing.LINEAR);
+
+ // Configure the max duration for this test
+ delayTestFinish(duration * 4);
+
+ // each timer calls the next one
+ final Timer timer1 = new Timer() {
+ public void run() {
+ assertPosition(g, o.add(0, 99), o.add(0, 1));
+ // Last timer should finish the test
+ finishTest();
+ }
+ };
+ final Timer timer2 = new Timer() {
+ public void run() {
+ assertPosition(g, o.add(99, 100), o.add(1, 100));
+ timer1.schedule(duration);
+ }
+ };
+ final Timer timer3 = new Timer() {
+ public void run() {
+ assertPosition(g, o.add(100, 1), o.add(100, 99));
+ timer2.schedule(duration);
+ }
+ };
+ final Timer timer4 = new Timer() {
+ public void run() {
+ assertPosition(g, o.add(1, 0), o.add(99, 0));
+ timer3.schedule(duration);
+ }
+ };
+ // Start the first timer
+ timer4.schedule(duration/2);
+ }
+
+ public void testFade() {
+ $(e)
+ .html(
+ "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
+
+ final GQuery sectA = $("#id1");
+ final GQuery sectB = $("#id2");
+
+ // fadeIn() & fadeOut() are tested with delayed assertions
+ sectA.hide();
+ sectA.fadeIn(2000);
+ sectB.fadeOut(2000);
+
+ // Configure the max duration for this test
+ // If the test exceeds the timeout without calling finishTest() it will fail
+ delayTestFinish(2500);
+
+ // Delayed assertions at different intervals
+ Timer timerShortTime = new Timer() {
+ public void run() {
+ double o = Double.valueOf(sectA.css("opacity", false));
+ assertTrue(
+ "'sectA' opacity must be in the interval 0-0.5 but is: " + o, o > 0
+ && o < 0.5);
+ o = Double.valueOf(sectB.css("opacity", false));
+ assertTrue(
+ "'sectB' opacity must be in the interval 0.5-1 but is: " + o,
+ o > 0.5 && o < 1);
+ }
+ };
+ Timer timerMidTime = new Timer() {
+ public void run() {
+ assertEquals("inline", sectA.css("display", false));
+ assertEquals("", sectB.css("display", false));
+ double o = Double.valueOf(sectA.css("opacity", false));
+ assertTrue(
+ "'sectA' opacity must be in the interval 0.5-1 but is: " + o,
+ o > 0.5 && o < 1);
+ o = Double.valueOf(sectB.css("opacity", false));
+ assertTrue(
+ "'sectB' opacity must be in the interval 0-0.5 but is: " + o, o > 0
+ && o < 0.5);
+ }
+ };
+ Timer timerLongTime = new Timer() {
+ public void run() {
+ assertEquals("inline", sectA.css("display", false));
+ assertEquals("none", sectB.css("display", false));
+ // Last delayed assertion has to stop the test to avoid a timeout
+ // failure
+ finishTest();
+ }
+ };
+
+ // schedule the delayed assertions
+ timerShortTime.schedule(200);
+ timerMidTime.schedule(1200);
+ timerLongTime.schedule(2200);
+ }
+
+ public void testPropertiesAnimationComputeEffects() {
+ $(e)
+ .html(
+ "<div id='parent' style='background-color: yellow; width: 100px; height: 200px; top:130px; position: absolute; left: 130px'><p id='child' style='background-color: pink; width: 100px; height: 100px; position: absolute; padding: 5px; margin: 0px'>Content 1</p></div>");
+ GQuery g = $("#child");
+ Properties prop1;
+
+ assertEquals("cssprop=marginTop value=-110px start=0 end=-110 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "-110px",
+ false).toString());
+ assertEquals("cssprop=marginLeft value=-110px start=0 end=-110 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "-110px",
+ false).toString());
+ assertEquals("cssprop=top value=50% start=0 end=50 unit=%",
+ PropertiesAnimation.computeFxProp(g.get(0), "top", "50%", false)
+ .toString());
+ assertEquals("cssprop=left value=50% start=0 end=50 unit=%",
+ PropertiesAnimation.computeFxProp(g.get(0), "left", "50%", false)
+ .toString());
+ assertEquals("cssprop=width value=174px start=100 end=174 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "width", "174px", false)
+ .toString());
+ assertEquals("cssprop=height value=174px start=100 end=174 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "height", "174px", false)
+ .toString());
+ assertEquals("cssprop=padding value=20px start=5 end=20 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "padding", "20px", false)
+ .toString());
+
+ prop1 = GQuery.$$("marginTop: '-110px', marginLeft: '-110px', top: '50%', left: '50%', width: '174px', height: '174px', padding: '20px'");
+ PropertiesAnimation an = new PropertiesAnimation(Easing.SWING, g.get(0), prop1);
+ an.onStart();
+ an.onComplete();
+
+ assertEquals("cssprop=marginTop value=0 start=-110 end=0 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "0", false)
+ .toString());
+ assertEquals("cssprop=marginLeft value=0 start=-110 end=0 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "0", false)
+ .toString());
+ assertEquals("cssprop=top value=0% start=50 end=0 unit=%", PropertiesAnimation
+ .computeFxProp(g.get(0), "top", "0%", false).toString());
+ assertEquals("cssprop=left value=0% start=50 end=0 unit=%",
+ PropertiesAnimation.computeFxProp(g.get(0), "left", "0%", false)
+ .toString());
+ assertEquals("cssprop=width value=100px start=174 end=100 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "width", "100px", false)
+ .toString());
+ assertEquals("cssprop=height value=100px start=174 end=100 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "height", "100px", false)
+ .toString());
+ assertEquals("cssprop=padding value=5px start=20 end=5 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "padding", "5px", false)
+ .toString());
+
+ prop1 = GQuery.$$("marginTop: '0', marginLeft: '0', top: '0%', left: '0%', width: '100px', height: '100px', padding: '5px'");
+ an = new PropertiesAnimation(Easing.SWING, g.get(0), prop1);
+ an.onStart();
+ an.onComplete();
+
+ assertEquals("cssprop=marginTop value=-110px start=0 end=-110 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "-110px",
+ false).toString());
+ assertEquals("cssprop=marginLeft value=-110px start=0 end=-110 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "marginLeft", "-110px",
+ false).toString());
+ assertEquals("cssprop=top value=50% start=0 end=50 unit=%",
+ PropertiesAnimation.computeFxProp(g.get(0), "top", "50%", false)
+ .toString());
+ assertEquals("cssprop=left value=50% start=0 end=50 unit=%",
+ PropertiesAnimation.computeFxProp(g.get(0), "left", "50%", false)
+ .toString());
+ assertEquals("cssprop=width value=174px start=100 end=174 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "width", "174px", false)
+ .toString());
+ assertEquals("cssprop=height value=174px start=100 end=174 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "height", "174px", false)
+ .toString());
+ assertEquals("cssprop=padding value=20px start=5 end=20 unit=px",
+ PropertiesAnimation.computeFxProp(g.get(0), "padding", "20px", false)
+ .toString());
+ }
+
+ public void testColorEffectParsing(){
+ String html = "<div id='test' style='color: #112233'>Test</div>";
+ $(e).html(html);
+
+ ColorFx effect = (ColorFx) PropertiesAnimation.computeFxProp($("#test",e).get(0), "color", "#ffffff", false);
+ assertEquals(17, effect.getStartColor()[0]); //#11
+ assertEquals(34, effect.getStartColor()[1]); //#22
+ assertEquals(51, effect.getStartColor()[2]); //#33
+
+ assertEquals(255, effect.getEndColor()[0]);
+ assertEquals(255, effect.getEndColor()[1]);
+ assertEquals(255, effect.getEndColor()[2]);
+
+ effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "rgb(255,255,255)", false);
+ assertEquals(255, effect.getEndColor()[0]);
+ assertEquals(255, effect.getEndColor()[1]);
+ assertEquals(255, effect.getEndColor()[2]);
+
+ effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "rgb(100%, 100%, 100%)", false);
+ assertEquals(255, effect.getEndColor()[0]);
+ assertEquals(255, effect.getEndColor()[1]);
+ assertEquals(255, effect.getEndColor()[2]);
+
+ effect = (ColorFx) PropertiesAnimation.computeFxProp(e, "color", "white", false);
+ assertEquals(255, effect.getEndColor()[0]);
+ assertEquals(255, effect.getEndColor()[1]);
+ assertEquals(255, effect.getEndColor()[2]);
+ }
+
+ private void assertPosition(GQuery g, Offset min, Offset max) {
+ int a = Math.min(min.top, max.top);
+ int b = Math.max(min.top, max.top);
+ int v = g.offset().top;
+ boolean c = a <= v && v <= b;
+ String msg = "Top has the value " + v + ", but should be in the range: "
+ + a + " - " + b;
+ assertTrue(msg, c);
+
+ a = Math.min(min.left, max.left);
+ b = Math.max(min.left, max.left);
+ v = g.offset().left;
+ c = a <= v && v <= b;
+ msg = "Left has the value " + v + ", but should be in the range: " + a
+ + " - " + b;
+ assertTrue(msg, c);
+ }
+
+ public void testAttrEffect() {
+ $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A</td><td width=50%>B</td></tr></table>");
+
+ final GQuery g = $("#idtest").css("position", "absolute");
+ final int duration = 500;
+
+ assertEquals("cssprop=$width attr=width value=+=100 start=440 end=540 unit=",
+ PropertiesAnimation.computeFxProp(g.get(0), "$width", "+=100", false).toString());
+
+ delayTestFinish(duration * 3);
+
+ g.as(Effects.Effects).
+ animate($$("$width: +=100; $border: +=4"), duration, Easing.LINEAR);
+
+ final Timer timer = new Timer() {
+ public void run() {
+ assertEquals(540.0, Double.parseDouble(g.attr("width")));
+ assertEquals(5.0, Double.parseDouble(g.attr("border")));
+ finishTest();
+ }
+ };
+ timer.schedule(duration * 2);
+ }
+
+ public void testStop() {
+ $(e)
+ .html(
+ "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
+
+ final GQuery sectA = $("#id1");
+ final GQuery sectB = $("#id2");
+ final GQuery sectC = $("#id2");
+
+ sectA.hide();
+ sectA.fadeIn(2000);
+ sectB.fadeOut(2000).delay(500).fadeIn(1000);
+ sectC.fadeOut(2000).delay(500).fadeIn(1000);
+
+ // Call stop
+ Timer timerMidTime = new Timer() {
+ public void run() {
+ sectA.stop();
+ sectB.stop(true, true);
+ sectC.stop(false, false);
+
+ Double o = Double.valueOf(sectA.css("opacity"));
+ sectA.data("opacityA", o);
+ assertTrue(
+ "'sectA' opacity must be in the interval 0.5-1 but is: " + o,
+ o > 0.5 && o < 1);
+
+ //animation should jump to the end
+ assertEquals("none", sectB.css("display"));
+
+ o = Double.valueOf(sectC.css("opacity"));
+ sectC.data("opacityC", o);
+ assertTrue(
+ "'sectC' opacity must be in the interval 0-0.5 but is: " + o,
+ o > 0 && o < 0.5);
+ }
+ };
+
+
+ Timer timerLongTime = new Timer() {
+ public void run() {
+ Double midAOpacity = sectA.data("opacityA", Double.class);
+ //animation was stopped, opacity should not change
+ assertEquals(midAOpacity, Double.valueOf(sectA.css("opacity")));
+ //animation was stopped and jumped to the end, the queue was cleared so no change too.
+ assertEquals("none", sectB.css("display"));
+
+ //fadeOut was stopped but fadeIn should continue
+ Double midCOpacity = sectC.data("opacityC", Double.class);
+ Double laterCOpacity = Double.valueOf(sectC.css("opacity"));
+ assertTrue(laterCOpacity > midCOpacity);
+ // Last delayed assertion has to stop the test to avoid a timeout
+ // failure
+ finishTest();
+ }
+ };
+ // schedule timer
+ timerMidTime.schedule(1200);
+ // schedule timer
+ timerLongTime.schedule(2200);
+
+ }
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-import static com.google.gwt.query.client.GQuery.document;
-import static com.google.gwt.query.client.GQuery.lazy;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.junit.DoNotRunWith;
-import com.google.gwt.junit.Platform;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.css.CSS;
-import com.google.gwt.query.client.css.Length;
-import com.google.gwt.query.client.css.RGBColor;
-import com.google.gwt.query.client.plugins.Events;
-import com.google.gwt.query.client.plugins.events.EventsListener;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test class for testing gwt events plugin api.
- */
-public class GQueryEventsTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- int testSubmitEventCont = 0;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("evnt-tst");
- } else {
- EventsListener.clean(e);
- e.setInnerHTML("");
- }
- }
-
-
-
- public void testDie() {
- $(e).html("<div id='div1'>content</div>");
- $(".clickMe", e).live("click", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".clickMe", e).live("dblclick", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.BLUE));
- }
- });
-
- $("#div1",e).addClass("clickMe");
-
- $("#div1",e).click();
- assertEquals(RGBColor.RED.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- $("#div1",e).dblclick();
- assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- //reset
- $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $(".clickMe", e).die("click");
- $("#div1",e).click();
- assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- $("#div1",e).dblclick();
- assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- //reset
- $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $(".clickMe", e).die("dblclick");
-
- $("#div1",e).dblclick();
- assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- }
-
- public void testDie2() {
- $(e).html("<div id='div1'>content</div>");
- $(".clickMe", e).live("click", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".clickMe", e).live("dblclick", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.BLUE));
- }
- });
-
- $("#div1",e).addClass("clickMe");
-
- $("#div1",e).click();
- assertEquals(RGBColor.RED.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- $("#div1",e).dblclick();
- assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- //reset
- $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $(".clickMe", e).die();
-
- $("#div1",e).click();
- assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- $("#div1",e).dblclick();
- assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
-
- }
-
- /**
- * TODO: DblClick doesn't work with HtmlUnit, investigate and report.
- */
- @DoNotRunWith({Platform.HtmlUnitBug, Platform.HtmlUnitLayout, Platform.HtmlUnitUnknown})
- public void testEventsDblClick() {
- $(e).html("<p>Content</p>");
- $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
- $("p", e).dblclick(new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.YELLOW));
- }
- });
- $("p", e).dblclick();
- assertEquals("yellow", $("p", e).css("color", false));
- }
-
- public void testEventsPlugin() {
- $(e).html("<p>Content</p>");
-
- // click
- $("p", e).click(new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.RED));
- }
- }, new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.GREEN));
- }
- });
- $("p", e, Events.Events).trigger(Event.ONCLICK);
- assertEquals("red", $("p", e).css("color", false));
- assertEquals("green", $("p", e).css("background-color", false));
-
- // unbind
- $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
- $("p", e).unbind(Event.ONCLICK);
- $("p", e).click();
- assertEquals("white", $("p", e).css("color", false));
-
- // toggle
- $("p", e).unbind(Event.ONCLICK);
- $("p", e).toggle(new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.RED));
- }
- }, new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.BLUE));
- }
- });
- $("p", e).click();
- assertEquals("red", $("p", e).css("color", false));
- $("p", e).click();
- assertEquals("blue", $("p", e).css("color", false));
-
- // one
- $("p", e).unbind(Event.ONCLICK);
- $("p", e).one(Event.ONCLICK, null, new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
- $("p", e).click();
- assertEquals("red", $("p", e).css("color", false));
- $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
- $("p", e).click();
- assertEquals("white", $("p", e).css("color", false));
-
- // hover (mouseover, mouseout)
- $("p", e).hover(new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- }, new Function() {
- public void f(Element elem) {
- $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
- }
- });
- $("p", e).trigger(Event.ONMOUSEOVER);
- assertEquals("yellow", $("p", e).css("background-color", false));
- $("p", e).trigger(Event.ONMOUSEOUT);
- assertEquals("white", $("p", e).css("background-color", false));
-
-// // focus
-// FIXME: Html 2.1.0 failing but FF do not
-// $("p", e).focus(new Function() {
-// public void f(Element elem) {
-// $(elem).css("border", "1px dotted black");
-// }
-// });
-// $("p", e).focus();
-// assertEquals("black", $("p", e).css("border-top-color", false));
-// assertEquals("dotted", $("p", e).css("border-top-style", false));
-// assertEquals("1px", $("p", e).css("border-top-width", false));
-//
-// // blur
-// $("p", e).blur(new Function() {
-// public void f(Element elem) {
-// $(elem).css("border", "");
-// }
-// });
-// $("p", e).blur();
-// assertEquals("", $("p", e).css("border", false));
-
- // key events
- $(e).html("<input type='text'/>");
- Function keyEventAction = new Function() {
- public boolean f(Event evnt) {
- GQuery gq = $(evnt);
- gq.val(gq.val() + Character.toString((char) evnt.getKeyCode()));
- return false;
- }
- };
- $("input", e).keypress(keyEventAction);
- $("input", e).keydown(keyEventAction);
- $("input", e).keyup(keyEventAction);
- $("input", e).focus();
- $("input", e).keydown('a');
- $("input", e).keypress('b');
- $("input", e).keyup('c');
- assertEquals("abc", $("input", e).val());
- }
-
- public void testLazyMethods() {
- $(e).css(CSS.COLOR.with(RGBColor.WHITE));
- assertEquals("white", $(e).css("color", false));
-
- $(e).one(Event.ONCLICK, null, lazy().css(CSS.COLOR.with(RGBColor.RED)).done());
- $(e).click();
- assertEquals("red", $(e).css("color", false));
-
- $(e).click(lazy().css(CSS.COLOR.with(RGBColor.BLACK)).done());
- $(e).click();
- assertEquals("black", $(e).css("color", false));
- }
-
- public void testLive() {
- $(e).html("<div id='div1' class='clickMe'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
- $(".clickMe", e).live("click", new Function(){
- public void f() {
- $(this).css("color", "red");
- }
- });
-
- $(e).append("<div id='div3' class='clickMe'>Content 2 <div id='div4'><span id='span2'>blop</span></div></div>");
-
- $(".clickMe", e).click();
- assertEquals("red", $("#div1", e).css("color", false));
- assertEquals("red", $("#div3", e).css("color", false));
-
- //reset
- $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
- assertEquals("black", $("div", e).css("color", false));
- assertEquals("black", $("span", e).css("color", false));
-
- $("#span1", e).click();
- assertEquals("red", $("#div1", e).css("color", false));
- assertEquals("black", $("#div3", e).css("color", false));
-
- //reset
- $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $("#span2", e).click();
- assertEquals("black", $("#div1", e).css("color", false));
- assertEquals("red", $("#div3", e).css("color", false));
-
- //reset
- $("*", e).removeClass("clickMe").css(CSS.COLOR.with(RGBColor.BLACK));
-
- $("#div2, #div4", e).addClass("clickMe");
-
- $("#span1", e).click();
- assertEquals("black", $("#div1", e).css("color", false));
- assertEquals("red", $("#div2", e).css("color", false));
- assertEquals("black", $("#div3", e).css("color", false));
- assertEquals("black", $("#div4", e).css("color", false));
-
- //reset
- $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $("#span2", e).click();
- assertEquals("black", $("#div1", e).css("color", false));
- assertEquals("black", $("#div2", e).css("color", false));
- assertEquals("black", $("#div3", e).css("color", false));
- assertEquals("red", $("#div4", e).css("color", false));
- }
-
- public void testLive2() {
-
- $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
-
- $(".clickable", e).live("click", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".clickable2", e).live("click", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.BLUE));
- }
- });
-
- $(".hover", e).live("mouseover", new Function(){
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- $("#div1", e).addClass("clickable");
- $("#div2", e).addClass("clickable2", "hover");
-
- $("#span1", e).click();
-
- assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
- assertEquals("blue", $("#div2", e).css(CSS.COLOR, false));
- //ensure taht handler related to mouseover event was not called
- assertNotSame("yellow", $("#div2", e).css(CSS.BACKGROUND_COLOR, false));
-
-
- }
-
- public void testLiveWithEventBit() {
- $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
-
- $(".clickable", e).live(Event.ONCLICK, new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $("#div1", e).addClass("clickable");
- $("#span1", e).click();
-
- assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
-
- }
-
- public void testLiveWithMultipleFunction() {
-
- $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
-
- $(".clickable", e).live("click", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- }, new Function(){
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- $("#div1", e).addClass("clickable");
-
- $("#span1", e).click();
-
- assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
- assertNotSame("yellow", $("#div1", e).css(CSS.BACKGROUND_COLOR, false));
-
-
- }
-
- public void testDelegate(){
-
- $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
-
- $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- for (Element mainDiv : $(".mainDiv",e).elements()){
- for (int i = 0; i < 3 ; i++){
- String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
- $(mainDiv).append(html);
- }
- }
-
- assertEquals(8, $(".subDiv",e).length());
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("red", $(el).css(CSS.COLOR, false));
- assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
- }
-
-
-
- }
-
- public void testUnDelegate(){
-
- $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
-
- $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- for (Element mainDiv : $(".mainDiv",e).elements()){
- for (int i = 0; i < 3 ; i++){
- String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
- $(mainDiv).append(html);
- }
- }
-
- assertEquals(8, $(".subDiv",e).length());
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("red", $(el).css(CSS.COLOR, false));
- assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
- //reset
- $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
- }
-
- $(".mainDiv", e).undelegate(".subDiv",Event.ONCLICK);
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("black", $(el).css(CSS.COLOR, false));
- assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
- //reset
- $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
- }
-
- $(".mainDiv", e).undelegate(".subDiv","mouseover");
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("black", $(el).css(CSS.COLOR, false));
- assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
- }
- }
-
- public void testUnDelegateAll(){
-
- $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
-
- $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- for (Element mainDiv : $(".mainDiv",e).elements()){
- for (int i = 0; i < 3 ; i++){
- String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
- $(mainDiv).append(html);
- }
- }
-
- assertEquals(8, $(".subDiv",e).length());
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("red", $(el).css(CSS.COLOR, false));
- assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
- //reset
- $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
- }
-
- $(".mainDiv", e).undelegate(".subDiv");
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("black", $(el).css(CSS.COLOR, false));
- assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
- }
- }
-
-public void testUnDelegateAll2(){
-
- $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
-
- $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
- @Override
- public void f(Element e) {
- $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
- }
- });
-
- for (Element mainDiv : $(".mainDiv",e).elements()){
- for (int i = 0; i < 3 ; i++){
- String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
- $(mainDiv).append(html);
- }
- }
-
- assertEquals(8, $(".subDiv",e).length());
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("red", $(el).css(CSS.COLOR, false));
- assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
- //reset
- $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
- }
-
- $(".mainDiv", e).undelegate();
-
- $("span",e).click().trigger(Event.ONMOUSEOVER);
-
- for (Element el : $(".subDiv",e).elements()){
- assertEquals("black", $(el).css(CSS.COLOR, false));
- assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
- }
- }
-
-
-
-
- public void testLiveWithMultipleEvent() {
-
- $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
-
- $(".myClass", e).live("click mouseover", new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
-
- $("#div1", e).addClass("myClass");
-
- $("#div1", e).click();
-
- assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
-
- $("#div1", e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $("#div1", e).trigger(Event.ONMOUSEOVER);
- assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
-
- $(".myClass2", e).live(Event.ONCLICK|Event.ONMOUSEDOWN, new Function(){
- public void f(Element e) {
- $(e).css(CSS.COLOR.with(RGBColor.YELLOW));
- }
- });
-
- $("#div2", e).addClass("myClass2");
-
- $("#div2", e).click();
-
- assertEquals("yellow", $("#div2", e).css(CSS.COLOR, false));
-
- $("#div2", e).css(CSS.COLOR.with(RGBColor.BLACK));
-
- $("#div2", e).trigger(Event.ONMOUSEDOWN);
- assertEquals("yellow", $("#div2", e).css(CSS.COLOR, false));
-
-
-
- }
-
-
- public void testNamedBinding() {
- $(e).html("<p>Content</p>");
-
- $("p", e, Events.Events).bind("click.first.namespace", null, new Function() {;
- public void f(Element elem) {
- $(elem).css(CSS.COLOR.with(RGBColor.RED));
- }
- });
- $("p", e, Events.Events).bind("click.second.namespace", null, new Function() {;
- public void f(Element elem) {
- $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.GREEN));
- }
- });
- $("p", e, Events.Events).bind("click", null, new Function() {;
- public void f(Element elem) {
- $(elem).css(CSS.FONT_SIZE.with(Length.px(24)));
- }
- });
- $("p", e, Events.Events).trigger(Event.ONCLICK);
- assertEquals("red", $("p", e).css("color", false));
- assertEquals("green", $("p", e).css("background-color", false));
- assertEquals(24.0d, $("p", e).cur("fontSize", true));
-
- $("p", e).css(CSS.COLOR.with(null)).css(CSS.BACKGROUND_COLOR,"").css(CSS.FONT_SIZE.with(Length.px(12)));
- assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
- assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
- assertEquals(12.0d, $("p", e).cur("fontSize", true));
-
- $("p", e, Events.Events).unbind("click.first.namespace");
- $("p", e, Events.Events).trigger(Event.ONCLICK);
- assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
- assertEquals("green", $("p", e).css("background-color", false));
- assertEquals(24.0d, $("p", e).cur("fontSize", true));
-
-
- $("p", e).css(CSS.COLOR.with(null)).css(CSS.BACKGROUND_COLOR,"").css(CSS.FONT_SIZE.with(Length.px(12)));
- assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
- assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
- assertEquals(12.0d, $("p", e).cur("fontSize", true));
-
- $("p", e, Events.Events).unbind("click");
- $("p", e, Events.Events).trigger(Event.ONCLICK);
- assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
- assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
- assertEquals(12.0d, $("p", e).cur("fontSize", true));
- }
-
- public void testRebind() {
- final GQuery b = $("<p>content</p>");
- assertEquals(1, b.size());
- assertEquals(1, b.get().getLength());
- b.click(new Function() {
- public void f(Element e){
- b.css(CSS.COLOR.with(RGBColor.RED));
- }
- });
- $(e).append(b);
- // TODO: dom manipulations some times modifies gquery nodelist,
- // we could remove the nodelist since we maintain a list of elements.
- assertEquals(1, b.size());
- assertEquals(1, b.get().getLength());
- b.click();
- assertEquals("red", $(b).css("color", false));
- }
-
- @DoNotRunWith({Platform.HtmlUnitLayout})
- public void testResizeWindowEvent() {
- GQuery w = $(GQuery.window);
-
- delayTestFinish(100);
- w.bind("resize", null, new Function() {
- public void f(Element e) {
- finishTest();
- }
- });
-
- Window.resizeTo(w.width(), w.height() + 100);
- }
-
- public void testResizeEvent() {
- $(e).html("<div id=ra></div>");
- GQuery g = $("#ra", e);
-
- delayTestFinish(100);
- g.bind("resize", null, new Function() {
- public void f(Element e) {
- finishTest();
- }
- });
-
- g.width(400);
- g.resize();
- }
-
- public void testSubmitEvent() {
- // Add a form and an iframe to the dom. The form target is the iframe
- $(e).html("<form action='whatever' target='miframe'><input type='text' value='Hello'><input type='submit' value='Go'></form><iframe name='miframe' id='miframe' src=\"javascript:''\">");
- testSubmitEventCont = 0;
-
- // Add an onsubmit function to the form returning false to cancel the action
- $("form").bind(EventsListener.ONSUBMIT, null, new Function() {
- public boolean f(Event e) {
- testSubmitEventCont++;
- return false;
- }
- });
-
- // Check that the onsubmit function is called and the iframe has not changed
- $("form").submit();
- assertEquals(1, testSubmitEventCont);
- assertFalse($("#miframe").contents().find("body").text().contains("ERROR"));
-
- // Remove the binding
- $("form").unbind(EventsListener.ONSUBMIT);
-
- // Check that on submit function is not called and the form has been
- // submitted
- $("form").submit();
- assertEquals(1, testSubmitEventCont);
- new Timer() {
- public void run() {
- // Check that the server returns an error since the action does not
- // exist
- assertTrue($("#miframe").contents().find("body").text().contains("ERROR"));
- }
- }.schedule(500);
- }
-
- /**
- * Test for issue 62
- * http://code.google.com/p/gwtquery/issues/detail?id=62
- */
- public void testTabInbexInFocusEventBinding(){
- String content="<div id='test'>test content</div>";
- $(e).html(content);
- $("#test").focus(new Function(){});
-
- assertEquals($("#test").attr("tabIndex"), "0");
-
- content="<div id='test' tabIndex='2'>test content</div>";
- $(e).html(content);
- $("#test").focus(new Function(){});
-
- assertEquals($("#test").attr("tabIndex"), "2");
- }
-
- public void testUnbindMultipleEvents() {
- String content = "<p>content</p>";
- $(e).html(content);
- $(document).bind(Event.ONMOUSEMOVE, null, new Function() {
- public void f(Element e){
- $("p").css(CSS.COLOR.with(RGBColor.RED));
- }
- });
- $(document).bind(Event.ONMOUSEUP, null, new Function(){
- public void f(Element e){
- $("p").css(CSS.COLOR.with(RGBColor.YELLOW));
- }
- });
- $(document).trigger(Event.ONMOUSEMOVE);
- assertEquals("red", $("p").css("color", false));
- $(document).trigger(Event.ONMOUSEUP);
- assertEquals("yellow", $("p").css("color", false));
- $("p").css(CSS.COLOR.with(RGBColor.BLACK));
- $(document).unbind(Event.ONMOUSEUP|Event.ONMOUSEMOVE);
- $(document).trigger(Event.ONMOUSEMOVE);
- assertEquals("black", $("p").css("color", false));
- $(document).trigger(Event.ONMOUSEUP);
- assertEquals("black", $("p").css("color", false));
- }
-
- public void testWidgetEvents() {
- final Button b = new Button("click-me");
- b.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- b.getElement().getStyle().setBackgroundColor("black");
- }
- });
- RootPanel.get().add(b);
- $(b).click(lazy().css(CSS.COLOR.with(RGBColor.RED)).done());
-
- $(b).click();
- assertEquals("red", $("button").css("color", false));
- assertEquals("black", $("button").css("background-color", false));
- RootPanel.get().remove(b);
-
- $(e).append($(b));
- $(b).css(CSS.COLOR.with(RGBColor.YELLOW), CSS.BACKGROUND_COLOR.with(RGBColor.BLUE));
- $(b).click();
- assertEquals("red", $("button").css("color", false));
- assertEquals("black", $("button").css("background-color", false));
- }
-
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.document;
+import static com.google.gwt.query.client.GQuery.lazy;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.css.CSS;
+import com.google.gwt.query.client.css.Length;
+import com.google.gwt.query.client.css.RGBColor;
+import com.google.gwt.query.client.plugins.Events;
+import com.google.gwt.query.client.plugins.events.EventsListener;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing gwt events plugin api.
+ */
+public class GQueryEventsTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ int testSubmitEventCont = 0;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("evnt-tst");
+ } else {
+ EventsListener.clean(e);
+ e.setInnerHTML("");
+ }
+ }
+
+
+
+ public void testDie() {
+ $(e).html("<div id='div1'>content</div>");
+ $(".clickMe", e).live("click", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".clickMe", e).live("dblclick", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.BLUE));
+ }
+ });
+
+ $("#div1",e).addClass("clickMe");
+
+ $("#div1",e).click();
+ assertEquals(RGBColor.RED.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ $("#div1",e).dblclick();
+ assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ //reset
+ $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $(".clickMe", e).die("click");
+ $("#div1",e).click();
+ assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ $("#div1",e).dblclick();
+ assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ //reset
+ $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $(".clickMe", e).die("dblclick");
+
+ $("#div1",e).dblclick();
+ assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ }
+
+ public void testDie2() {
+ $(e).html("<div id='div1'>content</div>");
+ $(".clickMe", e).live("click", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".clickMe", e).live("dblclick", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.BLUE));
+ }
+ });
+
+ $("#div1",e).addClass("clickMe");
+
+ $("#div1",e).click();
+ assertEquals(RGBColor.RED.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ $("#div1",e).dblclick();
+ assertEquals(RGBColor.BLUE.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ //reset
+ $("#div1",e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $(".clickMe", e).die();
+
+ $("#div1",e).click();
+ assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ $("#div1",e).dblclick();
+ assertEquals(RGBColor.BLACK.getCssName(), $("#div1", e).css(CSS.COLOR, false));
+
+ }
+
+ /**
+ * TODO: DblClick doesn't work with HtmlUnit, investigate and report.
+ */
+ @DoNotRunWith({Platform.HtmlUnitBug, Platform.HtmlUnitLayout, Platform.HtmlUnitUnknown})
+ public void testEventsDblClick() {
+ $(e).html("<p>Content</p>");
+ $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
+ $("p", e).dblclick(new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.YELLOW));
+ }
+ });
+ $("p", e).dblclick();
+ assertEquals("yellow", $("p", e).css("color", false));
+ }
+
+ public void testEventsPlugin() {
+ $(e).html("<p>Content</p>");
+
+ // click
+ $("p", e).click(new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ }, new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.GREEN));
+ }
+ });
+ $("p", e, Events.Events).trigger(Event.ONCLICK);
+ assertEquals("red", $("p", e).css("color", false));
+ assertEquals("green", $("p", e).css("background-color", false));
+
+ // unbind
+ $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
+ $("p", e).unbind(Event.ONCLICK);
+ $("p", e).click();
+ assertEquals("white", $("p", e).css("color", false));
+
+ // toggle
+ $("p", e).unbind(Event.ONCLICK);
+ $("p", e).toggle(new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ }, new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.BLUE));
+ }
+ });
+ $("p", e).click();
+ assertEquals("red", $("p", e).css("color", false));
+ $("p", e).click();
+ assertEquals("blue", $("p", e).css("color", false));
+
+ // one
+ $("p", e).unbind(Event.ONCLICK);
+ $("p", e).one(Event.ONCLICK, null, new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+ $("p", e).click();
+ assertEquals("red", $("p", e).css("color", false));
+ $("p", e).css(CSS.COLOR.with(RGBColor.WHITE));
+ $("p", e).click();
+ assertEquals("white", $("p", e).css("color", false));
+
+ // hover (mouseover, mouseout)
+ $("p", e).hover(new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ }, new Function() {
+ public void f(Element elem) {
+ $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
+ }
+ });
+ $("p", e).trigger(Event.ONMOUSEOVER);
+ assertEquals("yellow", $("p", e).css("background-color", false));
+ $("p", e).trigger(Event.ONMOUSEOUT);
+ assertEquals("white", $("p", e).css("background-color", false));
+
+// // focus
+// FIXME: Html 2.1.0 failing but FF do not
+// $("p", e).focus(new Function() {
+// public void f(Element elem) {
+// $(elem).css("border", "1px dotted black");
+// }
+// });
+// $("p", e).focus();
+// assertEquals("black", $("p", e).css("border-top-color", false));
+// assertEquals("dotted", $("p", e).css("border-top-style", false));
+// assertEquals("1px", $("p", e).css("border-top-width", false));
+//
+// // blur
+// $("p", e).blur(new Function() {
+// public void f(Element elem) {
+// $(elem).css("border", "");
+// }
+// });
+// $("p", e).blur();
+// assertEquals("", $("p", e).css("border", false));
+
+ // key events
+ $(e).html("<input type='text'/>");
+ Function keyEventAction = new Function() {
+ public boolean f(Event evnt) {
+ GQuery gq = $(evnt);
+ gq.val(gq.val() + Character.toString((char) evnt.getKeyCode()));
+ return false;
+ }
+ };
+ $("input", e).keypress(keyEventAction);
+ $("input", e).keydown(keyEventAction);
+ $("input", e).keyup(keyEventAction);
+ $("input", e).focus();
+ $("input", e).keydown('a');
+ $("input", e).keypress('b');
+ $("input", e).keyup('c');
+ assertEquals("abc", $("input", e).val());
+ }
+
+ public void testLazyMethods() {
+ $(e).css(CSS.COLOR.with(RGBColor.WHITE));
+ assertEquals("white", $(e).css("color", false));
+
+ $(e).one(Event.ONCLICK, null, lazy().css(CSS.COLOR.with(RGBColor.RED)).done());
+ $(e).click();
+ assertEquals("red", $(e).css("color", false));
+
+ $(e).click(lazy().css(CSS.COLOR.with(RGBColor.BLACK)).done());
+ $(e).click();
+ assertEquals("black", $(e).css("color", false));
+ }
+
+ public void testLive() {
+ $(e).html("<div id='div1' class='clickMe'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
+ $(".clickMe", e).live("click", new Function(){
+ public void f() {
+ $(this).css("color", "red");
+ }
+ });
+
+ $(e).append("<div id='div3' class='clickMe'>Content 2 <div id='div4'><span id='span2'>blop</span></div></div>");
+
+ $(".clickMe", e).click();
+ assertEquals("red", $("#div1", e).css("color", false));
+ assertEquals("red", $("#div3", e).css("color", false));
+
+ //reset
+ $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
+ assertEquals("black", $("div", e).css("color", false));
+ assertEquals("black", $("span", e).css("color", false));
+
+ $("#span1", e).click();
+ assertEquals("red", $("#div1", e).css("color", false));
+ assertEquals("black", $("#div3", e).css("color", false));
+
+ //reset
+ $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $("#span2", e).click();
+ assertEquals("black", $("#div1", e).css("color", false));
+ assertEquals("red", $("#div3", e).css("color", false));
+
+ //reset
+ $("*", e).removeClass("clickMe").css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $("#div2, #div4", e).addClass("clickMe");
+
+ $("#span1", e).click();
+ assertEquals("black", $("#div1", e).css("color", false));
+ assertEquals("red", $("#div2", e).css("color", false));
+ assertEquals("black", $("#div3", e).css("color", false));
+ assertEquals("black", $("#div4", e).css("color", false));
+
+ //reset
+ $("*", e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $("#span2", e).click();
+ assertEquals("black", $("#div1", e).css("color", false));
+ assertEquals("black", $("#div2", e).css("color", false));
+ assertEquals("black", $("#div3", e).css("color", false));
+ assertEquals("red", $("#div4", e).css("color", false));
+ }
+
+ public void testLive2() {
+
+ $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
+
+ $(".clickable", e).live("click", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".clickable2", e).live("click", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.BLUE));
+ }
+ });
+
+ $(".hover", e).live("mouseover", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ $("#div1", e).addClass("clickable");
+ $("#div2", e).addClass("clickable2", "hover");
+
+ $("#span1", e).click();
+
+ assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
+ assertEquals("blue", $("#div2", e).css(CSS.COLOR, false));
+ //ensure taht handler related to mouseover event was not called
+ assertNotSame("yellow", $("#div2", e).css(CSS.BACKGROUND_COLOR, false));
+
+
+ }
+
+ public void testLiveWithEventBit() {
+ $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
+
+ $(".clickable", e).live(Event.ONCLICK, new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $("#div1", e).addClass("clickable");
+ $("#span1", e).click();
+
+ assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
+
+ }
+
+ public void testLiveWithMultipleFunction() {
+
+ $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
+
+ $(".clickable", e).live("click", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ }, new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ $("#div1", e).addClass("clickable");
+
+ $("#span1", e).click();
+
+ assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
+ assertNotSame("yellow", $("#div1", e).css(CSS.BACKGROUND_COLOR, false));
+
+
+ }
+
+ public void testDelegate(){
+
+ $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
+
+ $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ for (Element mainDiv : $(".mainDiv",e).elements()){
+ for (int i = 0; i < 3 ; i++){
+ String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
+ $(mainDiv).append(html);
+ }
+ }
+
+ assertEquals(8, $(".subDiv",e).length());
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("red", $(el).css(CSS.COLOR, false));
+ assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
+ }
+
+
+
+ }
+
+ public void testUnDelegate(){
+
+ $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
+
+ $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ for (Element mainDiv : $(".mainDiv",e).elements()){
+ for (int i = 0; i < 3 ; i++){
+ String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
+ $(mainDiv).append(html);
+ }
+ }
+
+ assertEquals(8, $(".subDiv",e).length());
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("red", $(el).css(CSS.COLOR, false));
+ assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
+ //reset
+ $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
+ }
+
+ $(".mainDiv", e).undelegate(".subDiv",Event.ONCLICK);
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("black", $(el).css(CSS.COLOR, false));
+ assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
+ //reset
+ $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
+ }
+
+ $(".mainDiv", e).undelegate(".subDiv","mouseover");
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("black", $(el).css(CSS.COLOR, false));
+ assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
+ }
+ }
+
+ public void testUnDelegateAll(){
+
+ $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
+
+ $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ for (Element mainDiv : $(".mainDiv",e).elements()){
+ for (int i = 0; i < 3 ; i++){
+ String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
+ $(mainDiv).append(html);
+ }
+ }
+
+ assertEquals(8, $(".subDiv",e).length());
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("red", $(el).css(CSS.COLOR, false));
+ assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
+ //reset
+ $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
+ }
+
+ $(".mainDiv", e).undelegate(".subDiv");
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("black", $(el).css(CSS.COLOR, false));
+ assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
+ }
+ }
+
+public void testUnDelegateAll2(){
+
+ $(e).html("<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>");
+
+ $(".mainDiv",e).delegate(".subDiv", "click", new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $(".mainDiv",e).delegate(".subDiv", Event.ONMOUSEOVER, new Function(){
+ @Override
+ public void f(Element e) {
+ $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ for (Element mainDiv : $(".mainDiv",e).elements()){
+ for (int i = 0; i < 3 ; i++){
+ String html = "<div class='subDiv'>Content "+i+"<span>blop</span></div>";
+ $(mainDiv).append(html);
+ }
+ }
+
+ assertEquals(8, $(".subDiv",e).length());
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("red", $(el).css(CSS.COLOR, false));
+ assertEquals("yellow", $(el).css(CSS.BACKGROUND_COLOR, false));
+ //reset
+ $(el).css(CSS.COLOR.with(RGBColor.BLACK), CSS.BACKGROUND_COLOR.with(RGBColor.WHITE));
+ }
+
+ $(".mainDiv", e).undelegate();
+
+ $("span",e).click().trigger(Event.ONMOUSEOVER);
+
+ for (Element el : $(".subDiv",e).elements()){
+ assertEquals("black", $(el).css(CSS.COLOR, false));
+ assertEquals("white", $(el).css(CSS.BACKGROUND_COLOR, false));
+ }
+ }
+
+
+
+
+ public void testLiveWithMultipleEvent() {
+
+ $(e).html("<div id='div1'><div id='div2'>Content 1<span id='span1'> blop</span></div></div>");
+
+ $(".myClass", e).live("click mouseover", new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+
+ $("#div1", e).addClass("myClass");
+
+ $("#div1", e).click();
+
+ assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
+
+ $("#div1", e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $("#div1", e).trigger(Event.ONMOUSEOVER);
+ assertEquals("red", $("#div1", e).css(CSS.COLOR, false));
+
+ $(".myClass2", e).live(Event.ONCLICK|Event.ONMOUSEDOWN, new Function(){
+ public void f(Element e) {
+ $(e).css(CSS.COLOR.with(RGBColor.YELLOW));
+ }
+ });
+
+ $("#div2", e).addClass("myClass2");
+
+ $("#div2", e).click();
+
+ assertEquals("yellow", $("#div2", e).css(CSS.COLOR, false));
+
+ $("#div2", e).css(CSS.COLOR.with(RGBColor.BLACK));
+
+ $("#div2", e).trigger(Event.ONMOUSEDOWN);
+ assertEquals("yellow", $("#div2", e).css(CSS.COLOR, false));
+
+
+
+ }
+
+
+ public void testNamedBinding() {
+ $(e).html("<p>Content</p>");
+
+ $("p", e, Events.Events).bind("click.first.namespace", null, new Function() {;
+ public void f(Element elem) {
+ $(elem).css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+ $("p", e, Events.Events).bind("click.second.namespace", null, new Function() {;
+ public void f(Element elem) {
+ $(elem).css(CSS.BACKGROUND_COLOR.with(RGBColor.GREEN));
+ }
+ });
+ $("p", e, Events.Events).bind("click", null, new Function() {;
+ public void f(Element elem) {
+ $(elem).css(CSS.FONT_SIZE.with(Length.px(24)));
+ }
+ });
+ $("p", e, Events.Events).trigger(Event.ONCLICK);
+ assertEquals("red", $("p", e).css("color", false));
+ assertEquals("green", $("p", e).css("background-color", false));
+ assertEquals(24.0d, $("p", e).cur("fontSize", true));
+
+ $("p", e).css(CSS.COLOR.with(null)).css(CSS.BACKGROUND_COLOR,"").css(CSS.FONT_SIZE.with(Length.px(12)));
+ assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
+ assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
+ assertEquals(12.0d, $("p", e).cur("fontSize", true));
+
+ $("p", e, Events.Events).unbind("click.first.namespace");
+ $("p", e, Events.Events).trigger(Event.ONCLICK);
+ assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
+ assertEquals("green", $("p", e).css("background-color", false));
+ assertEquals(24.0d, $("p", e).cur("fontSize", true));
+
+
+ $("p", e).css(CSS.COLOR.with(null)).css(CSS.BACKGROUND_COLOR,"").css(CSS.FONT_SIZE.with(Length.px(12)));
+ assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
+ assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
+ assertEquals(12.0d, $("p", e).cur("fontSize", true));
+
+ $("p", e, Events.Events).unbind("click");
+ $("p", e, Events.Events).trigger(Event.ONCLICK);
+ assertFalse("red".equalsIgnoreCase($("p", e).css("color", false)));
+ assertFalse("green".equalsIgnoreCase($("p", e).css("background-color", false)));
+ assertEquals(12.0d, $("p", e).cur("fontSize", true));
+ }
+
+ public void testRebind() {
+ final GQuery b = $("<p>content</p>");
+ assertEquals(1, b.size());
+ assertEquals(1, b.get().getLength());
+ b.click(new Function() {
+ public void f(Element e){
+ b.css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+ $(e).append(b);
+ // TODO: dom manipulations some times modifies gquery nodelist,
+ // we could remove the nodelist since we maintain a list of elements.
+ assertEquals(1, b.size());
+ assertEquals(1, b.get().getLength());
+ b.click();
+ assertEquals("red", $(b).css("color", false));
+ }
+
+ @DoNotRunWith({Platform.HtmlUnitLayout})
+ public void testResizeWindowEvent() {
+ GQuery w = $(GQuery.window);
+
+ delayTestFinish(100);
+ w.bind("resize", null, new Function() {
+ public void f(Element e) {
+ finishTest();
+ }
+ });
+
+ Window.resizeTo(w.width(), w.height() + 100);
+ }
+
+ public void testResizeEvent() {
+ $(e).html("<div id=ra></div>");
+ GQuery g = $("#ra", e);
+
+ delayTestFinish(100);
+ g.bind("resize", null, new Function() {
+ public void f(Element e) {
+ finishTest();
+ }
+ });
+
+ g.width(400);
+ g.resize();
+ }
+
+ public void testBindUnbindSubmitEvent() {
+ // Add a form and an iframe to the dom. The form target is the iframe
+ $(e).html("<form action='whatever' target='miframe'><input type='text' value='Hello'><input type='submit' value='Go'></form><iframe name='miframe' id='miframe' src=\"javascript:''\">");
+ testSubmitEventCont = 0;
+
+ // Add an onsubmit function to the form returning false to cancel the action
+ $("form").bind(EventsListener.ONSUBMIT, null, new Function() {
+ public boolean f(Event e) {
+ testSubmitEventCont++;
+ return false;
+ }
+ });
+
+ // Check that the onsubmit function is called and the iframe has not changed
+ $("form").submit();
+ assertEquals(1, testSubmitEventCont);
+
+ // Remove the binding
+ $("form").unbind(EventsListener.ONSUBMIT);
+
+ // Check that on submit function is not called and the form has been
+ // submitted
+ $("form").submit();
+ assertEquals(1, testSubmitEventCont);
+ }
+
+ /**
+ * TODO: submit doesn't work with HtmlUnit, investigate and report.
+ * The problem is that preventDefault does not set the
+ * flag e.defaultPrevented || e.returnValue in HtmlUnit native event.
+ */
+ @DoNotRunWith({Platform.HtmlUnitLayout})
+ public void testSubmitEvent() {
+ // Add a form and an iframe to the dom. The form target is the iframe
+ $(e).html("<form action='whatever' target='miframe'><input type='text' value='Hello'><input type='submit' value='Go'></form><iframe name='miframe' id='miframe' src=\"javascript:''\">");
+ testSubmitEventCont = 0;
+
+ // Add an onsubmit function to the form returning false to cancel the action
+ $("form").bind(EventsListener.ONSUBMIT, null, new Function() {
+ public boolean f(Event e) {
+ testSubmitEventCont++;
+ return false;
+ }
+ });
+
+ // Check that the onsubmit function is called and the iframe has not changed
+ $("form").submit();
+ assertEquals(1, testSubmitEventCont);
+ assertFalse($("#miframe").contents().find("body").text().contains("ERROR"));
+
+ // Remove the binding
+ $("form").unbind(EventsListener.ONSUBMIT);
+
+ // Check that on submit function is not called and the form has been
+ // submitted
+ $("form").submit();
+ assertEquals(1, testSubmitEventCont);
+
+ delayTestFinish(1000);
+ new Timer() {
+ public void run() {
+ // Check that the server returns an error since the action does not
+ // exist
+ assertTrue($("#miframe").contents().find("body").text().contains("ERROR"));
+ finishTest();
+ }
+ }.schedule(500);
+ }
+
+ /**
+ * Test for issue 62
+ * http://code.google.com/p/gwtquery/issues/detail?id=62
+ */
+ public void testTabInbexInFocusEventBinding(){
+ String content="<div id='mtest'>test content</div>";
+ $(e).html(content);
+ $("#mtest").focus(new Function(){});
+
+ assertEquals($("#mtest").attr("tabIndex"), "0");
+
+ content="<div id='mtest' tabIndex='2'>test content</div>";
+ $(e).html(content);
+ $("#mtest").focus(new Function(){});
+
+ assertEquals($("#mtest").attr("tabIndex"), "2");
+ }
+
+ public void testUnbindMultipleEvents() {
+ String content = "<p>content</p>";
+ $(e).html(content);
+ $(document).bind(Event.ONMOUSEMOVE, null, new Function() {
+ public void f(Element e){
+ $("p").css(CSS.COLOR.with(RGBColor.RED));
+ }
+ });
+ $(document).bind(Event.ONMOUSEUP, null, new Function(){
+ public void f(Element e){
+ $("p").css(CSS.COLOR.with(RGBColor.YELLOW));
+ }
+ });
+ $(document).trigger(Event.ONMOUSEMOVE);
+ assertEquals("red", $("p").css("color", false));
+ $(document).trigger(Event.ONMOUSEUP);
+ assertEquals("yellow", $("p").css("color", false));
+ $("p").css(CSS.COLOR.with(RGBColor.BLACK));
+ $(document).unbind(Event.ONMOUSEUP|Event.ONMOUSEMOVE);
+ $(document).trigger(Event.ONMOUSEMOVE);
+ assertEquals("black", $("p").css("color", false));
+ $(document).trigger(Event.ONMOUSEUP);
+ assertEquals("black", $("p").css("color", false));
+ }
+
+ public void testWidgetEvents() {
+ final Button b = new Button("click-me");
+ b.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ b.getElement().getStyle().setBackgroundColor("black");
+ }
+ });
+ RootPanel.get().add(b);
+ $(b).click(lazy().css(CSS.COLOR.with(RGBColor.RED)).done());
+
+ $(b).click();
+ assertEquals("red", $("button").css("color", false));
+ assertEquals("black", $("button").css("background-color", false));
+ RootPanel.get().remove(b);
+
+ $(e).append($(b));
+ $(b).css(CSS.COLOR.with(RGBColor.YELLOW), CSS.BACKGROUND_COLOR.with(RGBColor.BLUE));
+ $(b).click();
+ assertEquals("red", $("button").css("color", false));
+ assertEquals("black", $("button").css("background-color", false));
+ }
+
+}
--- /dev/null
+package com.google.gwt.query.client;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import com.google.gwt.junit.tools.GWTTestSuite;
+import com.google.gwt.query.client.impl.SelectorEnginesTestGwt;
+
+/**
+ * Class to run all Gwt test in a jvm instance.
+ * It speeds up maven testing phase.
+ */
+public class GQueryGwtSuiteTest extends TestCase
+{
+ public static Test suite()
+ {
+ GWTTestSuite suite = new GWTTestSuite( "GQuery Suite" );
+ suite.addTestSuite(GQuerySelectorsTestGwt.class);
+ suite.addTestSuite(GQueryCoreTestGwt.class);
+ suite.addTestSuite(GQueryCssTestGwt.class);
+ suite.addTestSuite(GQueryEventsTestGwt.class);
+ suite.addTestSuite(GQueryEffectsTestGwt.class);
+ suite.addTestSuite(GQueryJsTestGwt.class);
+ suite.addTestSuite(GQueryWidgetsTestGwt.class);
+ suite.addTestSuite(GQueryAjaxTestGwt.class);
+ suite.addTestSuite(SelectorEnginesTestGwt.class);
+ return suite;
+ }
+
+
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.*;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.js.JsCache;
-import com.google.gwt.query.client.js.JsNodeArray;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test class for testing js classes.
- */
-public class GQueryJsTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("core-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- public void testJsCache() {
- String[] slist = new String[]{"A", "B", "C"};
-
- JsCache c = JsCache.create();
- assertTrue(c.isEmpty());
- for (int i=0; i < slist.length; i++) {
- c.put(i, slist[i]);
- }
- assertFalse(c.isEmpty());
- assertEquals(3, c.length());
- assertEquals(slist[1], c.get(1));
- for (int i=0; i < slist.length; i++) {
- c.put(slist[i], slist[i]);
- }
- assertEquals(6, c.length());
- assertEquals(slist[1], c.get(1));
- assertEquals(slist[1], c.get(slist[1]));
- c.put(1, null);
- c.put("X", "X");
- assertNull(c.get(1));
- assertEquals(slist[2], c.get(2));
- assertEquals(7, c.length());
- assertEquals(7, c.keys().length);
- assertEquals(7, c.elements().length);
-
- assertTrue(c.exists(2));
- assertFalse(c.exists(3));
- assertTrue(c.exists("X"));
- assertFalse(c.exists("V"));
-
- c.delete(2);
- c.delete("C");
- assertEquals(5, c.length());
-
- c.put(-1, "N");
- assertEquals(6, c.length());
- assertEquals("N", c.get(-1));
- }
-
- public void testChrome__gwt_ObjectId() {
- JsCache a = JsCache.create();
- assertEquals(0, a.length());
- assertEquals(0, a.keys().length);
- assertEquals(0, a.elements().length);
-
- a.put("obj", new Long(21));
- assertEquals(1, a.length());
- assertEquals(1, a.keys().length);
- assertEquals(1, a.elements().length);
-
- JsNodeArray n = JsNodeArray.create();
- assertEquals(0, n.getLength());
- assertEquals(0, n.<JsCache>cast().keys().length);
- assertEquals(0, n.elements().length);
-
- n.addNode($("<hr/>").get(0));
- assertEquals(1, n.getLength());
- assertEquals(1, n.<JsCache>cast().keys().length);
- assertEquals(1, n.elements().length);
- }
-
- public void testProperties() {
- Properties p = $$("b: 'a'; c: 1, /*gg: aadf*/d: url('https://test.com');");
- assertEquals(3, p.keys().length);
- assertEquals("url(https://test.com)", p.getStr("d"));
-
- p = $$("color: 'rgb(0, 0,139)', background: red");
- assertEquals(2, p.keys().length);
- assertEquals("rgb(0,0,139)", p.getStr("color"));
-
- p = $$("a: 1, b: 0.5, c: null, d: whatever, e: true, f: false");
- assertEquals(1, p.getInt("a"));
- assertEquals(0.5f, p.getFloat("b"));
- assertEquals("whatever", p.getStr("d"));
- assertNull(p.getStr("c"));
- assertNull(p.getStr("ccc"));
- assertTrue(p.getBoolean("e"));
- assertFalse(p.getBoolean("d"));
- assertFalse(p.getBoolean("f"));
- assertFalse(p.getBoolean("c"));
- assertTrue(p.defined("d"));
- p.remove("d");
- assertFalse(p.defined("d"));
- }
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.*;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.js.JsCache;
+import com.google.gwt.query.client.js.JsNodeArray;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing js classes.
+ */
+public class GQueryJsTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("core-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void testJsCache() {
+ String[] slist = new String[]{"A", "B", "C"};
+
+ JsCache c = JsCache.create();
+ assertTrue(c.isEmpty());
+ for (int i=0; i < slist.length; i++) {
+ c.put(i, slist[i]);
+ }
+ assertFalse(c.isEmpty());
+ assertEquals(3, c.length());
+ assertEquals(slist[1], c.get(1));
+ for (int i=0; i < slist.length; i++) {
+ c.put(slist[i], slist[i]);
+ }
+ assertEquals(6, c.length());
+ assertEquals(slist[1], c.get(1));
+ assertEquals(slist[1], c.get(slist[1]));
+ c.put(1, null);
+ c.put("X", "X");
+ assertNull(c.get(1));
+ assertEquals(slist[2], c.get(2));
+ assertEquals(7, c.length());
+ assertEquals(7, c.keys().length);
+ assertEquals(7, c.elements().length);
+
+ assertTrue(c.exists(2));
+ assertFalse(c.exists(3));
+ assertTrue(c.exists("X"));
+ assertFalse(c.exists("V"));
+
+ c.delete(2);
+ c.delete("C");
+ assertEquals(5, c.length());
+
+ c.put(-1, "N");
+ assertEquals(6, c.length());
+ assertEquals("N", c.get(-1));
+ }
+
+ public void testChrome__gwt_ObjectId() {
+ JsCache a = JsCache.create();
+ assertEquals(0, a.length());
+ assertEquals(0, a.keys().length);
+ assertEquals(0, a.elements().length);
+
+ a.put("obj", new Long(21));
+ assertEquals(1, a.length());
+ assertEquals(1, a.keys().length);
+ assertEquals(1, a.elements().length);
+
+ JsNodeArray n = JsNodeArray.create();
+ assertEquals(0, n.getLength());
+ assertEquals(0, n.<JsCache>cast().keys().length);
+ assertEquals(0, n.elements().length);
+
+ n.addNode($("<hr/>").get(0));
+ assertEquals(1, n.getLength());
+ assertEquals(1, n.<JsCache>cast().keys().length);
+ assertEquals(1, n.elements().length);
+ }
+
+ public void testProperties() {
+ Properties p = $$("b: 'a'; c: 1, /*gg: aadf*/d: url('https://test.com');");
+ assertEquals(3, p.keys().length);
+ assertEquals("url(https://test.com)", p.getStr("d"));
+
+ p = $$("color: 'rgb(0, 0,139)', background: red");
+ assertEquals(2, p.keys().length);
+ assertEquals("rgb(0,0,139)", p.getStr("color"));
+
+ p = $$("a: 1, b: 0.5, c: null, d: whatever, e: true, f: false");
+ assertEquals(1, p.getInt("a"));
+ assertEquals(0.5f, p.getFloat("b"));
+ assertEquals("whatever", p.getStr("d"));
+ assertNull(p.getStr("c"));
+ assertNull(p.getStr("ccc"));
+ assertTrue(p.getBoolean("e"));
+ assertFalse(p.getBoolean("d"));
+ assertFalse(p.getBoolean("f"));
+ assertFalse(p.getBoolean("c"));
+ assertTrue(p.defined("d"));
+ p.remove("d");
+ assertFalse(p.defined("d"));
+ }
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-import static com.google.gwt.query.client.GQuery.body;
-import static com.google.gwt.query.client.GQuery.document;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;
-import com.google.gwt.query.client.impl.SelectorEngineImpl;
-import com.google.gwt.query.client.impl.SelectorEngineNative;
-import com.google.gwt.query.client.impl.SelectorEngineSizzle;
-import com.google.gwt.query.client.impl.research.SelectorEngineJS;
-import com.google.gwt.query.client.impl.research.SelectorEngineSizzleGwt;
-import com.google.gwt.query.client.impl.research.SelectorEngineXPath;
-import com.google.gwt.query.client.js.JsUtils;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.RootPanel;
-
-/**
- * Test for selectors
- */
-public class GQuerySelectorsTest extends GWTTestCase {
-
- boolean runSlow = false;
-
- protected interface AllSelectors extends Selectors {
- @Selector("h1[id]:contains(Selectors)")
- NodeList<Element> h1IdContainsSelectors();
- @Selector("tr:first")
- NodeList<Element> trFirst();
- @Selector("tr:last")
- NodeList<Element> trLast();
- // @Selector("div[class!='madeup']")
- // NodeList<Element> divWithClassNotContainsMadeup();
- // @Selector("div, p a")
- // NodeList<Element> divCommaPA();
- @Selector("p:contains(selectors)")
- NodeList<Element> pContainsSelectors();
- @Selector("a[href][lang][class]")
- NodeList<Element> aHrefLangClass();
- @Selector("*:checked")
- NodeList<Element> allChecked();
- @Selector("body")
- NodeList<Element> body();
- @Selector("body div")
- NodeList<Element> bodyDiv();
- @Selector("div .example")
- NodeList<Element> divExample();
- @Selector("div > div")
- NodeList<Element> divGtP();
- @Selector("div:not(.example)")
- NodeList<Element> divNotExample();
- @Selector("div p")
- NodeList<Element> divP();
- @Selector("div p a")
- NodeList<Element> divPA();
- @Selector("div + p")
- NodeList<Element> divPlusP();
- @Selector("div[class^=exa][class$=mple]")
- NodeList<Element> divPrefixExaSuffixMple();
- @Selector("div #title")
- NodeList<Element> divSpaceTitle();
- @Selector("div ~ p")
- NodeList<Element> divTildeP();
- @Selector("div[class]")
- NodeList<Element> divWithClass();
- @Selector("div[class~=dialog]")
- NodeList<Element> divWithClassContainsDialog();
- @Selector("div[class*=e]")
- NodeList<Element> divWithClassContainsE();
- @Selector("div[class=example]")
- NodeList<Element> divWithClassExample();
- @Selector("div[class~=dialog]")
- NodeList<Element> divWithClassListContainsDialog();
- @Selector("div[class^=exa]")
- NodeList<Element> divWithClassPrefixExa();
- @Selector("div[class$=mple]")
- NodeList<Element> divWithClassSuffixMple();
- @Selector("p:first-child")
- NodeList<Element> firstChild();
- @Selector("h1#title")
- NodeList<Element> h1Title();
- @Selector("h1#title + em > span")
- NodeList<Element> h1TitlePlusEmGtSpan();
- @Selector("p:last-child")
- NodeList<Element> lastChild();
- @Selector(".note")
- NodeList<Element> note();
- @Selector("p:nth-child(n)")
- NodeList<Element> nthChild();
- @Selector("p:nth-child(2n)")
- NodeList<Element> nThChild2n();
- @Selector("p:nth-child(2n+1)")
- NodeList<Element> nThChild2nPlus1();
- @Selector("p:nth-child(even)")
- NodeList<Element> nThChildEven();
- @Selector("p:nth-child(odd)")
- NodeList<Element> nThChildOdd();
- @Selector("p:only-child")
- NodeList<Element> onlyChild();
- @Selector("#title")
- NodeList<Element> title();
- @Selector("#title,h1#title")
- NodeList<Element> titleAndh1Title();
- @Selector("ul .tocline2")
- NodeList<Element> ulTocline2();
- @Selector("ul.toc li.tocline2")
- NodeList<Element> ulTocLiTocLine2();
- }
-
- protected interface TestSelectors extends Selectors {
- @Selector("*:checked")
- GQuery allChecked();
- @Selector("*:checked")
- GQuery allChecked(Node n);
- @Selector(".branchA")
- GQuery branchA();
- @Selector(".branchA")
- GQuery branchA(Node n);
- @Selector(".branchA .target")
- GQuery branchAtarget();
- @Selector(".branchA .target")
- GQuery branchAtarget(Node n);
- @Selector(".branchB")
- GQuery branchB();
- @Selector(".branchB")
- GQuery branchB(Node n);
-
- @Selector("div .target")
- GQuery divTarget();
- @Selector("div .target")
- GQuery divTarget(Node n);
- @Selector(".target")
- GQuery target();
- @Selector(".target")
- GQuery target(Node n);
- }
-
- static Element e = null;
- static HTML testPanel = null;
-
- private static native boolean hasNativeSelector() /*-{
- return !!(document.querySelectorAll && /native/.test(String(document.querySelectorAll)));
- }-*/;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void gwtSetUp() {
- if (e == null) {
- testPanel = new HTML();
- RootPanel.get().add(testPanel);
- e = testPanel.getElement();
- e.setId("select-tst");
- } else {
- e.setInnerHTML("");
- }
- }
-
- public void testJQueryPseudoselectors() {
- $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A Text</td><td width=50%><a></a><p id=a></p><p id=b style='display: none'><span id=c>s</span></p></td></tr></table>");
- assertEquals(9, $("* ", e).size());
- assertEquals(1, $("p:hidden ", e).size());
- assertEquals(2, $("td:visible ", e).size());
- $(e).html("<input type='checkbox' id='cb' name='cb' value='1' /><input type='radio' id='cb' name='cb' value='1' />");
- assertEquals(1, $("input:checkbox ", e).size());
- assertEquals(1, $(":radio ", e).size());
- assertEquals(2, $("*:radio, *:checkbox", e).size());
- }
-
- public void testCompiledSelectors() {
- final AllSelectors sel = GWT.create(AllSelectors.class);
- $(e).html(getTestContent());
-
- // TODO: fix these selectors
- // sel.divWithClassNotContainsMadeup().getLength()
- // sel.divCommaPA().getLength()
-
- // assertArrayContains(sel.title().getLength(), 1);
- assertEquals(1, sel.body().getLength());
- assertArrayContains(sel.bodyDiv().getLength(), 53, 55);
- sel.setRoot(e);
- assertArrayContains(sel.trFirst().getLength(), 5);
- assertArrayContains(sel.trLast().getLength(), 5);
- assertArrayContains(sel.pContainsSelectors().getLength(), 54);
- assertArrayContains(sel.h1IdContainsSelectors().getLength(), 1);
- assertArrayContains(sel.aHrefLangClass().getLength(), 0, 1);
- assertArrayContains(sel.allChecked().getLength(), 1);
- assertArrayContains(sel.divExample().getLength(), 43);
- assertArrayContains(sel.divGtP().getLength(), 51, 52);
- assertArrayContains(sel.divNotExample().getLength(), 9, 10);
- assertArrayContains(sel.divP().getLength(), 324);
- assertArrayContains(sel.divPA().getLength(), 84);
- assertArrayContains(sel.divPlusP().getLength(), 22);
- assertArrayContains(sel.divPrefixExaSuffixMple().getLength(), 43);
- assertArrayContains(sel.divSpaceTitle().getLength(), 1);
- assertArrayContains(sel.divTildeP().getLength(), 183);
- assertArrayContains(sel.divWithClass().getLength(), 51, 52);
- assertArrayContains(sel.divWithClassContainsDialog().getLength(), 1);
- assertArrayContains(sel.divWithClassContainsE().getLength(), 50);
- assertArrayContains(sel.divWithClassExample().getLength(), 43);
- assertArrayContains(sel.divWithClassListContainsDialog().getLength(), 1);
- assertArrayContains(sel.divWithClassPrefixExa().getLength(), 43);
- assertArrayContains(sel.divWithClassSuffixMple().getLength(), 43);
- assertArrayContains(sel.firstChild().getLength(), 54);
- assertArrayContains(sel.h1Title().getLength(), 1);
- assertArrayContains(sel.h1TitlePlusEmGtSpan().getLength(), 1);
- assertArrayContains(sel.lastChild().getLength(), 19);
- assertArrayContains(sel.note().getLength(), 14);
- assertArrayContains(sel.nthChild().getLength(), 324);
- assertArrayContains(sel.nThChild2n().getLength(), 159);
- assertArrayContains(sel.nThChild2nPlus1().getLength(), 165);
- assertArrayContains(sel.nThChildEven().getLength(), 159);
- assertArrayContains(sel.nThChildOdd().getLength(), 165);
- assertArrayContains(sel.onlyChild().getLength(), 3);
- assertArrayContains(sel.titleAndh1Title().getLength(), 0, 1, 2); //FIXME
- assertArrayContains(sel.ulTocline2().getLength(), 12);
- assertArrayContains(sel.ulTocLiTocLine2().getLength(), 12);
- }
-
- public void testIssue12() {
- $(e).html("<table><tr><td><p myCustomAttr='whatever'><input disabled='disabled' type='radio' name='wantedName' value='v1'>1</input></p><input type='radio' name='n' value='v2' checked='checked'>2</input></td><td><button myCustomAttr='val'>Click</button></tr><td></table>");
- executeSelectInAllImplementations(":checked", e, 1);
- executeSelectInAllImplementations(":disabled", e, 1);
- executeSelectInAllImplementations("input:enabled", e, 1);
- executeSelectInAllImplementations("[myCustomAttr]", e, 2);
- executeSelectInAllImplementations("*[myCustomAttr]", e, 2);
- executeSelectInAllImplementations("input[name=wantedName]", e, 1);
- executeSelectInAllImplementations("input[name='wantedName']", e, 1);
- executeSelectInAllImplementations("input[name=\"wantedName\"]", e, 1);
- }
-
- public void testSelectElementsInsideContext() {
- $(e).html("<spam><p>s</p></spam>");
- GQuery q = $("spam", e);
- // TODO: in XPath engine returns 2 when it should return 1
- executeSelectInAllImplementations("*", q.get(0), 1, 2);
- }
-
- public void testSelectorEngineCssToXpath() {
- SelectorEngineImpl selEng = new SelectorEngineCssToXPath();
- executeSelectorEngineTests(selEng);
- }
-
- public void testSelectorEngineDomAssistant() {
- if (!runSlow) return;
- // This test runs very slow in chrome
- SelectorEngineImpl selEng = new SelectorEngineJS();
- executeSelectorEngineTests(selEng);
- }
-
- public void testSelectorEngineNative() {
- SelectorEngineImpl selEng = new SelectorEngineNative();
- if (hasNativeSelector()) {
- executeSelectorEngineTests(selEng);
- }
- }
-
- public void testSelectorEngineSizzle() {
- SelectorEngineImpl selEng = new SelectorEngineSizzle();
- executeSelectorEngineTests(selEng);
- }
-
- public void testSelectorEngineSizzleGwt() {
- if (!runSlow) return;
- SelectorEngineImpl selEng = new SelectorEngineSizzleGwt();
- executeSelectorEngineTests(selEng);
- }
-
- public void testSelectorEngineXpath() {
- SelectorEngineImpl selEng = new SelectorEngineXPath();
- executeSelectorEngineTests(selEng);
- }
-
- public void testSelectorsGeneratorNative() {
- $(e).html(
- "<input type='radio' name='n' value='v1'>1</input>"
- + "<input type='radio' name='n' value='v2' checked='checked'>2</input>");
-
- TestSelectors selectors = GWT.create(TestSelectors.class);
- assertEquals(1, selectors.allChecked().size());
- }
-
- public void testSelectorsInIframe() {
- $(e).html("<iframe name='miframe' id='miframe' src=\"javascript:''\">");
- Element d = $("#miframe").contents().empty().get(0);
- assertNotNull(d);
-
- $(d).html(
- "<div class='branchA'><div class='target'>branchA target</div></div>"
- + "<div class='branchB'><div class='target'>branchB target</div></div>");
-
-
- executeSelectInAllImplementations(".branchA .target", d, 1, 2); //FIXME:
- executeSelectInAllImplementations(".branchA .target", body, 0);
- executeSelectInAllImplementations("div .target", d, 2);
- executeSelectInAllImplementations("div .target", body, 0);
-
- TestSelectors selectors = GWT.create(TestSelectors.class);
- assertEquals(1, selectors.branchAtarget(d).length());
- assertEquals(0, selectors.branchAtarget().length());
- assertEquals(2, selectors.divTarget(d).length());
- assertEquals(0, selectors.divTarget().length());
-
- }
-
- public void testSelectorsWithContext() {
- $(e).append(
- "<div class='branchA'><div class='target'>branchA target</div></div>"
- + "<div class='branchB'><div class='target'>branchB target</div></div>");
-
- TestSelectors selectors = GWT.create(TestSelectors.class);
-
- assertEquals(2, selectors.target().length());
- Element branchA = selectors.branchA().get(0);
- Element branchB = selectors.branchB().get(0);
- assertNotNull(selectors.branchA().get(0));
- assertNotNull(selectors.branchB().get(0));
-
- assertEquals(2, selectors.target(body).length());
- branchA = selectors.branchA(body).get(0);
- branchB = selectors.branchB(body).get(0);
- assertNotNull(branchA);
- assertNotNull(branchB);
- assertEquals("branchA target", selectors.target(branchA).text());
- assertEquals("branchB target", selectors.target(branchB).text());
-
- selectors.setRoot(branchA);
- assertEquals(1, selectors.target().length());
- assertEquals("branchA target", selectors.target().text());
-
- selectors.setRoot(branchB);
- assertEquals(1, selectors.target().length());
- assertEquals("branchB target", selectors.target().text());
- }
-
- public void testUnique() {
- SelectorEngineImpl selSizz = new SelectorEngineSizzleGwt();
- $(e).html(getTestContent());
-
- JsArray<Element> a;
- a = selSizz.select("p", e).cast();
- int n = a.length();
- assertTrue(n > 300);
- for (int i=0; i<n; i++) {
- a.push(a.get(i));
- }
- assertEquals(n * 2 , a.length());
- a = JsUtils.unique(a);
- assertEquals(n, a.length());
- }
-
- private void assertArrayContains(Object result, Object... array) {
- assertArrayContains("", result, array);
- }
-
- private void assertArrayContains(String message, Object result, Object... array) {
- String values = "";
- boolean done = false;
- for (Object o : array) {
- values += o.toString() + " ";
- if (result.equals(o)) {
- done = true;
- }
- }
- message = message + ", value (" + result + ") not found in: " + values;
- assertTrue(message, done);
- }
-
- private void executeSelectInAllImplementations(String selector, Element elem, Object... array) {
- SelectorEngineImpl selSizz = new SelectorEngineSizzle();
- SelectorEngineImpl selSizzGwt = new SelectorEngineSizzleGwt();
- SelectorEngineImpl selJS = new SelectorEngineJS();
- SelectorEngineImpl selXpath = new SelectorEngineXPath();
- SelectorEngineImpl selC2X = new SelectorEngineCssToXPath();
- SelectorEngineImpl selNative = new SelectorEngineNative();
- assertArrayContains(selector, selSizz.select(selector, elem).getLength(), array);
- assertArrayContains(selector, selSizzGwt.select(selector, elem).getLength(), array);
- assertArrayContains(selector, selJS.select(selector, elem).getLength(), array);
- if (hasNativeSelector()) {
- assertArrayContains(selector, selNative.select(selector, elem).getLength(), array);
- }
- assertArrayContains(selector, selXpath.select(selector, elem).getLength(), array);
- assertArrayContains(selector, selC2X.select(selector, elem).getLength(), array);
- }
-
- private void executeSelectorEngineTests(SelectorEngineImpl selEng) {
- $(e).html(getTestContent());
-
- assertArrayContains(selEng.select("body", document).getLength(), 1);
- assertArrayContains(selEng.select("body div", document).getLength(), 53, 55);
-
- assertArrayContains(selEng.select("tr:first", e).getLength(), 0, 1, 5);
- assertArrayContains(selEng.select("tr:last", e).getLength(), 0, 1, 5);
- assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54);
- assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
- assertArrayContains(selEng.select("div[class!=madeup]", e).getLength(), 52, 53);
- assertArrayContains(selEng.select("div, p a", e).getLength(), 136, 137, 138);
- assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54, 55);
- assertArrayContains(selEng.select("a[href][lang][class]", e).getLength(), 1);
- assertArrayContains(selEng.select("*:checked", e).getLength(), 1);
- assertArrayContains(selEng.select("div .example", e).getLength(), 43);
- assertArrayContains(selEng.select("div > div", e).getLength(), 51, 52);
- assertArrayContains(selEng.select("div:not(.example)", e).getLength(), 9, 10);
- assertArrayContains(selEng.select("div p", e).getLength(), 324);
- assertArrayContains(selEng.select("div p a", e).getLength(), 85, 84);
- assertArrayContains(selEng.select("div + p", e).getLength(), 22);
- assertArrayContains(selEng.select("div[class^=exa][class$=mple]", e).getLength(), 43);
- assertArrayContains(selEng.select("div #title", e).getLength(), 1);
- assertArrayContains(selEng.select("div ~ p", e).getLength(), 183);
- assertArrayContains(selEng.select("div[class]", e).getLength(), 51, 52);
- assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
- assertArrayContains(selEng.select("div[class*=e]", e).getLength(), 50);
- assertArrayContains(selEng.select("div[class=example]", e).getLength(), 43);
- assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
- assertArrayContains(selEng.select("div[class^=exa]", e).getLength(), 43);
- assertArrayContains(selEng.select("div[class$=mple]", e).getLength(), 43);
- assertArrayContains(selEng.select("p:first-child", e).getLength(), 54);
- assertArrayContains(selEng.select("h1#title", e).getLength(), 1);
- assertArrayContains(selEng.select("h1#title + em > span", e).getLength(), 1);
- assertArrayContains(selEng.select("p:last-child", e).getLength(), 19, 22);
- assertArrayContains(selEng.select(".note", e).getLength(), 14);
- assertArrayContains(selEng.select("p:nth-child(n)", e).getLength(), 324);
- assertArrayContains(selEng.select("p:nth-child(2n)", e).getLength(), 159);
- assertArrayContains(selEng.select("p:nth-child(2n+1)", e).getLength(), 165);
- assertArrayContains(selEng.select("p:nth-child(even)", e).getLength(), 159);
- assertArrayContains(selEng.select("p:nth-child(odd)", e).getLength(), 165);
- assertArrayContains(selEng.select("p:only-child", e).getLength(), 3);
- assertArrayContains(selEng.select("#title", e).getLength(), 1);
- // TODO: sizze_gwt returns 2
- assertArrayContains(selEng.select("#title, h1#title", e).getLength(), 1, 2);
- assertArrayContains(selEng.select("ul.toc li.tocline2", e).getLength(), 12);
- assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
- }
-
- // This method is used to initialize a huge html String, because
- // java 1.5 has a limitation in the size of static strings.
- private String getTestContent() {
- String ret = "";
- ret += "<html><head> </head><body><div>";
- ret += " <div class='head dialog'>";
- ret += " <p><a href='http://www.w3.org/'><img alt='W3C' src='' height='48' width='72'></a></p>";
- ret += " <h1 id='title'>Selectors</h1>";
- ret += " <em><span>.</span></em>";
- ret += " <h2>W3C Working Draft 15 December 2005</h2>";
- ret += " <dl>";
- ret += " <dt>This version:</dt>";
- ret += " <dd><a href='http://www.w3.org/TR/2005/WD-css3-selectors-20051215'>";
- ret += " http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a></dd>";
- ret += " <dt>Latest version:";
- ret += " </dt><dd><a href='http://www.w3.org/TR/css3-selectors'>";
- ret += " http://www.w3.org/TR/css3-selectors</a>";
- ret += " </dd><dt>Previous version:";
- ret += " </dt><dd><a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113'>";
- ret += " http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>";
- ret += " </dd><dt><a name='editors-list'></a>Editors:";
- ret += " </dt><dd class='vcard'><span class='fn'>Daniel Glazman</span> (Invited";
- ret += " </dd>";
- ret += " <dd class='vcard'><a class='url fn' href='http://www.tantek.com/' lang='tr'>Tantek Çelik</a>";
- ret += " </dd><dd class='vcard'><a href='mailto:ian@hixie.ch' class='url fn'>Ian";
- ret += " Hickson</a> (<span class='company'><a href='http://www.google.com/'>Google</a></span>)";
- ret += " </dd><dd class='vcard'><span class='fn'>Peter Linss</span> (former";
- ret += " editor, <span class='company'><a href='http://www.netscape.com/'>Netscape/AOL</a></span>)";
- ret += " </dd><dd class='vcard'><span class='fn'>John Williams</span> (former editor, <span class='company'><a href='http://www.quark.com/'>Quark, Inc.</a></span>)";
- ret += " </dd></dl>";
- ret += " <p class='copyright'><a href='http://www.w3.org/Consortium/Legal/ipr-notice#Copyright'>";
- ret += " Copyright</a> © 2005 <a href='http://www.w3.org/'><abbr title='World Wide Web Consortium'>W3C</abbr></a><sup>®</sup>";
- ret += " (<a href='http://www.csail.mit.edu/'><abbr title='Massachusetts";
- ret += " Institute of Technology'>MIT</abbr></a>, <a href='http://www.ercim.org/'><acronym title='European Research";
- ret += " Consortium for Informatics and Mathematics'>ERCIM</acronym></a>, <a href='http://www.keio.ac.jp/'>Keio</a>), All Rights Reserved.";
- ret += " <a href='http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer'>liability</a>,";
- ret += " <a href='http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks'>trademark</a>,";
- ret += " <a href='http://www.w3.org/Consortium/Legal/copyright-documents'>document";
- ret += " use</a> rules apply.";
- ret += " </p><hr title='Separator for header'>";
- ret += " </div>";
- ret += " <h2><a name='abstract'></a>Abstract</h2>";
- ret += " <p><em>Selectors</em> are patterns that match against elements in a";
- ret += " tree. Selectors have been optimized for use with HTML and XML, and";
- ret += " are designed to be usable in performance-critical code.</p>";
- ret += " <p><acronym title='Cascading Style Sheets'>CSS</acronym> (Cascading";
- ret += " Style Sheets) is a language for describing the rendering of <acronym title='Hypertext Markup Language'>HTML</acronym> and <acronym title='Extensible Markup Language'>XML</acronym> documents on";
- ret += " screen, on paper, in speech, etc. CSS uses Selectors for binding";
- ret += " describes extensions to the selectors defined in CSS level 2. These";
- ret += " extended selectors will be used by CSS level 3.";
- ret += " </p><p>Selectors define the following function:</p>";
- ret += " <pre>expression ∗ element → boolean</pre>";
- ret += " <p>That is, given an element and a selector, this specification";
- ret += " defines whether that element matches the selector.</p>";
- ret += " <p>These expressions can also be used, for instance, to select a set";
- ret += " subtree. <acronym title='Simple Tree Transformation";
- ret += " Sheets'>STTS</acronym> (Simple Tree Transformation Sheets), a";
- ret += " language for transforming XML trees, uses this mechanism. <a href='#refsSTTS'>[STTS]</a></p>";
- ret += " <h2><a name='status'></a>Status of this document</h2>";
- ret += " <p><em>This section describes the status of this document at the";
- ret += " of this technical report can be found in the <a href='http://www.w3.org/TR/'>W3C technical reports index at";
- ret += " http://www.w3.org/TR/.</a></em></p>";
- ret += " <p>This document describes the selectors that already exist in <a href='#refsCSS1'><abbr title='CSS level 1'>CSS1</abbr></a> and <a href='#refsCSS21'><abbr title='CSS level 2'>CSS2</abbr></a>, and";
- ret += " also proposes new selectors for <abbr title='CSS level";
- ret += " 3'>CSS3</abbr> and other languages that may need them.</p>";
- ret += " <p>The CSS Working Group doesn't expect that all implementations of";
- ret += " CSS3 will have to implement all selectors. Instead, there will";
- ret += " will include all of the selectors.</p>";
- ret += " <p>This specification is a last call working draft for the the <a href='http://www.w3.org/Style/CSS/members'>CSS Working Group</a>";
- ret += " (<a href='/Style/'>Style Activity</a>). This";
- ret += " document is a revision of the <a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113/'>Candidate";
- ret += " Recommendation dated 2001 November 13</a>, and has incorporated";
- ret += " be demonstrable.</p>";
- ret += " <p>All persons are encouraged to review and implement this";
- ret += " specification and return comments to the (<a href='http://lists.w3.org/Archives/Public/www-style/'>archived</a>)";
- ret += " public mailing list <a href='http://www.w3.org/Mail/Lists.html#www-style'>www-style</a>";
- ret += " (see <a href='http://www.w3.org/Mail/Request'>instructions</a>). W3C";
- ret += " The deadline for comments is 14 January 2006.</p>";
- ret += " <p>This is still a draft document and may be updated, replaced, or";
- ret += " </p><p>This document may be available in <a href='http://www.w3.org/Style/css3-selectors-updates/translations'>translation</a>.";
- ret += " </p><div class='subtoc'>";
- ret += " <h2><a name='contents'>Table of contents</a></h2>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline2'><a href='#context'>1. Introduction</a>";
- ret += " <ul>";
- ret += " <li><a href='#dependencies'>1.1. Dependencies</a></li>";
- ret += " <li><a href='#terminology'>1.2. Terminology</a></li>";
- ret += " <li><a href='#changesFromCSS2'>1.3. Changes from CSS2</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline2'><a href='#selectors'>2. Selectors</a>";
- ret += " </li><li class='tocline2'><a href='#casesens'>3. Case sensitivity</a>";
- ret += " </li><li class='tocline2'><a href='#selector-syntax'>4. Selector syntax</a>";
- ret += " </li><li class='tocline2'><a href='#grouping'>5. Groups of selectors</a>";
- ret += " </li><li class='tocline2'><a href='#simple-selectors'>6. Simple selectors</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline3'><a href='#type-selectors'>6.1. Type";
- ret += " selectors</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline4'><a href='#typenmsp'>6.1.1. Type";
- ret += " selectors and namespaces</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline3'><a href='#universal-selector'>6.2.";
- ret += " Universal selector</a>";
- ret += " <ul>";
- ret += " <li><a href='#univnmsp'>6.2.1. Universal selector and";
- ret += " namespaces</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline3'><a href='#attribute-selectors'>6.3.";
- ret += " Attribute selectors</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline4'><a href='#attribute-representation'>6.3.1.";
- ret += " values</a>";
- ret += " </li><li><a href='#attribute-substrings'>6.3.2. Substring";
- ret += " matching attribute selectors</a>";
- ret += " </li><li class='tocline4'><a href='#attrnmsp'>6.3.3.";
- ret += " Attribute selectors and namespaces</a>";
- ret += " </li><li class='tocline4'><a href='#def-values'>6.3.4.";
- ret += " Default attribute values in DTDs</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline3'><a href='#class-html'>6.4. Class";
- ret += " selectors</a>";
- ret += " </li><li class='tocline3'><a href='#id-selectors'>6.5. ID";
- ret += " selectors</a>";
- ret += " </li><li class='tocline3'><a href='#pseudo-classes'>6.6.";
- ret += " Pseudo-classes</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline4'><a href='#dynamic-pseudos'>6.6.1.";
- ret += " Dynamic pseudo-classes</a>";
- ret += " </li><li class='tocline4'><a href='#target-pseudo'>6.6.2. The";
- ret += " :target pseudo-class</a>";
- ret += " </li><li class='tocline4'><a href='#lang-pseudo'>6.6.3. The";
- ret += " :lang() pseudo-class</a>";
- ret += " </li><li class='tocline4'><a href='#UIstates'>6.6.4. UI";
- ret += " element states pseudo-classes</a>";
- ret += " </li><li class='tocline4'><a href='#structural-pseudos'>6.6.5.";
- ret += " Structural pseudo-classes</a>";
- ret += " <ul>";
- ret += " <li><a href='#root-pseudo'>:root";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#nth-child-pseudo'>:nth-child()";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#nth-last-child-pseudo'>:nth-last-child()</a>";
- ret += " </li><li><a href='#nth-of-type-pseudo'>:nth-of-type()";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#nth-last-of-type-pseudo'>:nth-last-of-type()</a>";
- ret += " </li><li><a href='#first-child-pseudo'>:first-child";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#last-child-pseudo'>:last-child";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#first-of-type-pseudo'>:first-of-type";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#last-of-type-pseudo'>:last-of-type";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#only-child-pseudo'>:only-child";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#only-of-type-pseudo'>:only-of-type";
- ret += " pseudo-class</a>";
- ret += " </li><li><a href='#empty-pseudo'>:empty";
- ret += " pseudo-class</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline4'><a href='#negation'>6.6.7. The";
- ret += " negation pseudo-class</a></li>";
- ret += " </ul>";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li><li><a href='#pseudo-elements'>7. Pseudo-elements</a>";
- ret += " <ul>";
- ret += " <li><a href='#first-line'>7.1. The ::first-line";
- ret += " pseudo-element</a>";
- ret += " </li><li><a href='#first-letter'>7.2. The ::first-letter";
- ret += " pseudo-element</a>";
- ret += " </li><li><a href='#UIfragments'>7.3. The ::selection";
- ret += " pseudo-element</a>";
- ret += " </li><li><a href='#gen-content'>7.4. The ::before and ::after";
- ret += " pseudo-elements</a></li>";
- ret += " </ul>";
- ret += " </li><li class='tocline2'><a href='#combinators'>8. Combinators</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline3'><a href='#descendant-combinators'>8.1.";
- ret += " Descendant combinators</a>";
- ret += " </li><li class='tocline3'><a href='#child-combinators'>8.2. Child";
- ret += " combinators</a>";
- ret += " </li><li class='tocline3'><a href='#sibling-combinators'>8.3. Sibling";
- ret += " combinators</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline4'><a href='#adjacent-sibling-combinators'>8.3.1.";
- ret += " Adjacent sibling combinator</a>";
- ret += " </li><li class='tocline4'><a href='#general-sibling-combinators'>8.3.2.";
- ret += " General sibling combinator</a></li>";
- ret += " </ul>";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li><li class='tocline2'><a href='#specificity'>9. Calculating a selector's";
- ret += " specificity</a>";
- ret += " </li><li class='tocline2'><a href='#w3cselgrammar'>10. The grammar of";
- ret += " Selectors</a>";
- ret += " <ul class='toc'>";
- ret += " <li class='tocline3'><a href='#grammar'>10.1. Grammar</a>";
- ret += " </li><li class='tocline3'><a href='#lex'>10.2. Lexical scanner</a>";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li><li class='tocline2'><a href='#downlevel'>11. Namespaces and down-level";
- ret += " clients</a>";
- ret += " </li><li class='tocline2'><a href='#profiling'>12. Profiles</a>";
- ret += " </li><li><a href='#Conformance'>13. Conformance and requirements</a>";
- ret += " </li><li><a href='#Tests'>14. Tests</a>";
- ret += " </li><li><a href='#ACKS'>15. Acknowledgements</a>";
- ret += " </li><li class='tocline2'><a href='#references'>16. References</a>";
- ret += " </li></ul>";
- ret += " </div>";
- ret += " <h2><a name='context'>1. Introduction</a></h2>";
- ret += " <h3><a name='dependencies'></a>1.1. Dependencies</h3>";
- ret += " <p>Some features of this specification are specific to CSS, or have";
- ret += " specification, these have been described in terms of CSS2.1. <a href='#refsCSS21'>[CSS21]</a></p>";
- ret += " <h3><a name='terminology'></a>1.2. Terminology</h3>";
- ret += " <p>All of the text of this specification is normative except";
- ret += " non-normative.</p>";
- ret += " <h3><a name='changesFromCSS2'></a>1.3. Changes from CSS2</h3>";
- ret += " <p><em>This section is non-normative.</em></p>";
- ret += " <p>The main differences between the selectors in CSS2 and those in";
- ret += " Selectors are:";
- ret += " </p><ul>";
- ret += " <li>the list of basic definitions (selector, group of selectors,";
- ret += " of simple selectors, and the term 'simple selector' is now used for";
- ret += " </li>";
- ret += " <li>an optional namespace component is now allowed in type element";
- ret += " selectors, the universal selector and attribute selectors";
- ret += " </li>";
- ret += " <li>a <a href='#general-sibling-combinators'>new combinator</a> has been";
- ret += " </li>";
- ret += " <li>new simple selectors including substring matching attribute";
- ret += " selectors, and new pseudo-classes";
- ret += " </li>";
- ret += " <li>new pseudo-elements, and introduction of the '::' convention";
- ret += " </li>";
- ret += " <li>the grammar has been rewritten</li>";
- ret += " <li>profiles to be added to specifications integrating Selectors";
- ret += " and defining the set of selectors which is actually supported by";
- ret += " </li>";
- ret += " <li>Selectors are now a CSS3 Module and an independent";
- ret += " </li>";
- ret += " <li>the specification now has its own test suite</li>";
- ret += " </ul>";
- ret += " <h2><a name='selectors'></a>2. Selectors</h2>";
- ret += " <p><em>This section is non-normative, as it merely summarizes the";
- ret += " following sections.</em></p>";
- ret += " <p>A Selector represents a structure. This structure can be used as a";
- ret += " HTML or XML fragment corresponding to that structure.</p>";
- ret += " <p>Selectors may range from simple element names to rich contextual";
- ret += " representations.</p>";
- ret += " <p>The following table summarizes the Selector syntax:</p>";
- ret += " <table class='selectorsReview'>";
- ret += " <thead>";
- ret += " <tr>";
- ret += " <th class='pattern'>Pattern</th>";
- ret += " <th class='meaning'>Meaning</th>";
- ret += " <th class='described'>Described in section</th>";
- ret += " <th class='origin'>First defined in CSS level</th>";
- ret += " </tr>";
- ret += " </thead><tbody>";
- ret += " <tr>";
- ret += " <td class='pattern'>*</td>";
- ret += " <td class='meaning'>any element</td>";
- ret += " <td class='described'><a href='#universal-selector'>Universal";
- ret += " selector</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E</td>";
- ret += " <td class='meaning'>an element of type E</td>";
- ret += " <td class='described'><a href='#type-selectors'>Type selector</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo]</td>";
- ret += " <td class='meaning'>an E element with a 'foo' attribute</td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo='bar']</td>";
- ret += " <td class='meaning'>an E element whose 'foo' attribute value is exactly";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo~='bar']</td>";
- ret += " <td class='meaning'>an E element whose 'foo' attribute value is a list of";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo^='bar']</td>";
- ret += " <td class='meaning'>an E element whose 'foo' attribute value begins exactly";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo$='bar']</td>";
- ret += " <td class='meaning'>an E element whose 'foo' attribute value ends exactly";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[foo*='bar']</td>";
- ret += " <td class='meaning'>an E element whose 'foo' attribute value contains the";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E[hreflang|='en']</td>";
- ret += " <td class='meaning'>an E element whose 'hreflang' attribute has a";
- ret += " </td>";
- ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:root</td>";
- ret += " <td class='meaning'>an E element, root of the document</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:nth-child(n)</td>";
- ret += " <td class='meaning'>an E element, the n-th child of its parent</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:nth-last-child(n)</td>";
- ret += " <td class='meaning'>an E element, the n-th child of its parent, counting";
- ret += " </td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:nth-of-type(n)</td>";
- ret += " <td class='meaning'>an E element, the n-th sibling of its type</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:nth-last-of-type(n)</td>";
- ret += " <td class='meaning'>an E element, the n-th sibling of its type, counting";
- ret += " </td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:first-child</td>";
- ret += " <td class='meaning'>an E element, first child of its parent</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:last-child</td>";
- ret += " <td class='meaning'>an E element, last child of its parent</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:first-of-type</td>";
- ret += " <td class='meaning'>an E element, first sibling of its type</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:last-of-type</td>";
- ret += " <td class='meaning'>an E element, last sibling of its type</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:only-child</td>";
- ret += " <td class='meaning'>an E element, only child of its parent</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:only-of-type</td>";
- ret += " <td class='meaning'>an E element, only sibling of its type</td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:empty</td>";
- ret += " <td class='meaning'>an E element that has no children (including text";
- ret += " </td>";
- ret += " <td class='described'><a href='#structural-pseudos'>Structural";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:link<br>E:visited</td>";
- ret += " <td class='meaning'>an E element being the source anchor of a hyperlink of";
- ret += " </td>";
- ret += " <td class='described'><a href='#link'>The link";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:active<br>E:hover<br>E:focus</td>";
- ret += " <td class='meaning'>an E element during certain user actions</td>";
- ret += " <td class='described'><a href='#useraction-pseudos'>The user";
- ret += " action pseudo-classes</a></td>";
- ret += " <td class='origin'>1 and 2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:target</td>";
- ret += " <td class='meaning'>an E element being the target of the referring URI</td>";
- ret += " <td class='described'><a href='#target-pseudo'>The target";
- ret += " pseudo-class</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:lang(fr)</td>";
- ret += " <td class='meaning'>an element of type E in language 'fr' (the document";
- ret += " </td>";
- ret += " <td class='described'><a href='#lang-pseudo'>The :lang()";
- ret += " pseudo-class</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:enabled<br>E:disabled</td>";
- ret += " <td class='meaning'>a user interface element E which is enabled or";
- ret += " </td>";
- ret += " <td class='described'><a href='#UIstates'>The UI element states";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:checked<!--<br>E:indeterminate--></td>";
- ret += " <td class='meaning'>a user interface element E which is checked<!-- or in an";
- ret += " indeterminate state--> (for instance a radio-button or checkbox)";
- ret += " </td>";
- ret += " <td class='described'><a href='#UIstates'>The UI element states";
- ret += " pseudo-classes</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E::first-line</td>";
- ret += " <td class='meaning'>the first formatted line of an E element</td>";
- ret += " <td class='described'><a href='#first-line'>The ::first-line";
- ret += " pseudo-element</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E::first-letter</td>";
- ret += " <td class='meaning'>the first formatted letter of an E element</td>";
- ret += " <td class='described'><a href='#first-letter'>The ::first-letter";
- ret += " pseudo-element</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E::selection</td>";
- ret += " <td class='meaning'>the portion of an E element that is currently";
- ret += " </td>";
- ret += " <td class='described'><a href='#UIfragments'>The UI element";
- ret += " fragments pseudo-elements</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E::before</td>";
- ret += " <td class='meaning'>generated content before an E element</td>";
- ret += " <td class='described'><a href='#gen-content'>The ::before";
- ret += " pseudo-element</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E::after</td>";
- ret += " <td class='meaning'>generated content after an E element</td>";
- ret += " <td class='described'><a href='#gen-content'>The ::after";
- ret += " pseudo-element</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E.warning</td>";
- ret += " <td class='meaning'>an E element whose class is";
- ret += " </td>";
- ret += " <td class='described'><a href='#class-html'>Class";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E#myid</td>";
- ret += " <td class='meaning'>an E element with ID equal to 'myid'.</td>";
- ret += " <td class='described'><a href='#id-selectors'>ID";
- ret += " selectors</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E:not(s)</td>";
- ret += " <td class='meaning'>an E element that does not match simple selector s</td>";
- ret += " <td class='described'><a href='#negation'>Negation";
- ret += " pseudo-class</a></td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E F</td>";
- ret += " <td class='meaning'>an F element descendant of an E element</td>";
- ret += " <td class='described'><a href='#descendant-combinators'>Descendant";
- ret += " combinator</a></td>";
- ret += " <td class='origin'>1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E > F</td>";
- ret += " <td class='meaning'>an F element child of an E element</td>";
- ret += " <td class='described'><a href='#child-combinators'>Child";
- ret += " combinator</a></td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E + F</td>";
- ret += " <td class='meaning'>an F element immediately preceded by an E element</td>";
- ret += " <td class='described'><a href='#adjacent-sibling-combinators'>Adjacent sibling combinator</a>";
- ret += " </td>";
- ret += " <td class='origin'>2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <td class='pattern'>E ~ F</td>";
- ret += " <td class='meaning'>an F element preceded by an E element</td>";
- ret += " <td class='described'><a href='#general-sibling-combinators'>General sibling combinator</a>";
- ret += " </td>";
- ret += " <td class='origin'>3</td>";
- ret += " </tr>";
- ret += " </tbody>";
- ret += " </table>";
- ret += " <p>The meaning of each selector is derived from the table above by";
- ret += " column.</p>";
- ret += " <h2><a name='casesens'>3. Case sensitivity</a></h2>";
- ret += " <p>The case sensitivity of document language element names, attribute";
- ret += " names, and attribute values in selectors depends on the document";
- ret += " but in XML, they are case-sensitive.</p>";
- ret += " <h2><a name='selector-syntax'>4. Selector syntax</a></h2>";
- ret += " <p>A <dfn><a name='selector'>selector</a></dfn> is a chain of one";
- ret += " or more <a href='#sequence'>sequences of simple selectors</a>";
- ret += " separated by <a href='#combinators'>combinators</a>.</p>";
- ret += " <p>A <dfn><a name='sequence'>sequence of simple selectors</a></dfn>";
- ret += " is a chain of <a href='#simple-selectors-dfn'>simple selectors</a>";
- ret += " that are not separated by a <a href='#combinators'>combinator</a>. It";
- ret += " always begins with a <a href='#type-selectors'>type selector</a> or a";
- ret += " <a href='#universal-selector'>universal selector</a>. No other type";
- ret += " selector or universal selector is allowed in the sequence.</p>";
- ret += " <p>A <dfn><a name='simple-selectors-dfn'></a><a href='#simple-selectors'>simple selector</a></dfn> is either a <a href='#type-selectors'>type selector</a>, <a href='#universal-selector'>universal selector</a>, <a href='#attribute-selectors'>attribute selector</a>, <a href='#class-html'>class selector</a>, <a href='#id-selectors'>ID selector</a>, <a href='#content-selectors'>content selector</a>, or <a href='#pseudo-classes'>pseudo-class</a>. One <a href='#pseudo-elements'>pseudo-element</a> may be appended to the last";
- ret += " sequence of simple selectors.</p>";
- ret += " <p><dfn>Combinators</dfn> are: white space, 'greater-than";
- ret += " sign' (U+003E, <code>></code>), 'plus sign' (U+002B,";
- ret += " <code>+</code>) and 'tilde' (U+007E, <code>~</code>). White";
- ret += " space may appear between a combinator and the simple selectors around";
- ret += " it. <a name='whitespace'></a>Only the characters 'space' (U+0020), 'tab'";
- ret += " never part of white space.</p>";
- ret += " <p>The elements of a document tree that are represented by a selector";
- ret += " are the <dfn><a name='subject'></a>subjects of the selector</dfn>. A";
- ret += " selector consisting of a single sequence of simple selectors";
- ret += " sequence of simple selectors and a combinator to a sequence imposes";
- ret += " simple selectors.</p>";
- ret += " <p>An empty selector, containing no sequence of simple selectors and";
- ret += " no pseudo-element, is an <a href='#Conformance'>invalid";
- ret += " selector</a>.</p>";
- ret += " <h2><a name='grouping'>5. Groups of selectors</a></h2>";
- ret += " <p>When several selectors share the same declarations, they may be";
- ret += " grouped into a comma-separated list. (A comma is U+002C.)</p>";
- ret += " <div class='example'>";
- ret += " <p>CSS examples:</p>";
- ret += " <p>In this example, we condense three rules with identical";
- ret += " declarations into one. Thus,</p>";
- ret += " <pre>h1 { font-family: sans-serif }";
- ret += " h3 { font-family: sans-serif }</pre>";
- ret += " <p>is equivalent to:</p>";
- ret += " <pre>h1, h2, h3 { font-family: sans-serif }</pre>";
- ret += " </div>";
- ret += " <p><strong>Warning</strong>: the equivalence is true in this example";
- ret += " because all the selectors are valid selectors. If just one of these";
- ret += " selectors were invalid, the entire group of selectors would be";
- ret += " heading rules would be invalidated.</p>";
- ret += " <h2><a name='simple-selectors'>6. Simple selectors</a></h2>";
- ret += " <h3><a name='type-selectors'>6.1. Type selector</a></h3>";
- ret += " <p>A <dfn>type selector</dfn> is the name of a document language";
- ret += " type in the document tree.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The following selector represents an <code>h1</code> element in the";
- ret += " document tree:</p>";
- ret += " <pre>h1</pre>";
- ret += " </div>";
- ret += " <h4><a name='typenmsp'>6.1.1. Type selectors and namespaces</a></h4>";
- ret += " <p>Type selectors allow an optional namespace (<a href='#refsXMLNAMES'>[XMLNAMES]</a>) component. A namespace prefix";
- ret += " (U+007C, <code>|</code>).</p>";
- ret += " <p>The namespace component may be left empty to indicate that the";
- ret += " selector is only to represent elements with no declared namespace.</p>";
- ret += " <p>An asterisk may be used for the namespace prefix, indicating that";
- ret += " with no namespace).</p>";
- ret += " <p>Element type selectors that have no namespace component (no";
- ret += " element's namespace (equivalent to '<code>*|</code>') unless a default";
- ret += " namespace.</p>";
- ret += " <p>A type selector containing a namespace prefix that has not been";
- ret += " previously declared is an <a href='#Conformance'>invalid</a> selector.";
- ret += " language implementing Selectors. In CSS, such a mechanism is defined";
- ret += " in the General Syntax module.</p>";
- ret += " <p>In a namespace-aware client, element type selectors will only match";
- ret += " against the <a href='http://www.w3.org/TR/REC-xml-names/#NT-LocalPart'>local";
- ret += " part</a>";
- ret += " of the element's <a href='http://www.w3.org/TR/REC-xml-names/#ns-qualnames'>qualified";
- ret += " name</a>. See <a href='#downlevel'>below</a> for notes about matching";
- ret += " behaviors in down-level clients.</p>";
- ret += " <p>In summary:</p>";
- ret += " <dl>";
- ret += " <dt><code>ns|E</code></dt>";
- ret += " <dd>elements with name E in namespace ns</dd>";
- ret += " <dt><code>*|E</code></dt>";
- ret += " <dd>elements with name E in any namespace, including those without any";
- ret += " </dd>";
- ret += " <dt><code>|E</code></dt>";
- ret += " <dd>elements with name E without any declared namespace</dd>";
- ret += " <dt><code>E</code></dt>";
- ret += " <dd>if no default namespace has been specified, this is equivalent to *|E.";
- ret += " </dd>";
- ret += " </dl>";
- ret += " <div class='example'>";
- ret += " <p>CSS examples:</p>";
- ret += " <pre>@namespace foo url(http://www.example.com);";
- ret += " h1 { color: green }</pre>";
- ret += " <p>The first rule will match only <code>h1</code> elements in the";
- ret += " 'http://www.example.com' namespace.</p>";
- ret += " <p>The second rule will match all elements in the";
- ret += " 'http://www.example.com' namespace.</p>";
- ret += " <p>The third rule will match only <code>h1</code> elements without";
- ret += " any declared namespace.</p>";
- ret += " <p>The fourth rule will match <code>h1</code> elements in any";
- ret += " namespace (including those without any declared namespace).</p>";
- ret += " <p>The last rule is equivalent to the fourth rule because no default";
- ret += " namespace has been defined.</p>";
- ret += " </div>";
- ret += " <h3><a name='universal-selector'>6.2. Universal selector</a></h3>";
- ret += " <p>The <dfn>universal selector</dfn>, written 'asterisk'";
- ret += " (<code>*</code>), represents the qualified name of any element";
- ret += " specified, see <a href='#univnmsp'>Universal selector and";
- ret += " Namespaces</a> below.</p>";
- ret += " <p>If the universal selector is not the only component of a sequence";
- ret += " of simple selectors, the <code>*</code> may be omitted.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <ul>";
- ret += " <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are";
- ret += " </li>";
- ret += " <li><code>*.warning</code> and <code>.warning</code> are equivalent,";
- ret += " </li>";
- ret += " <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>";
- ret += " </ul>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note:</strong> it is recommended that the";
- ret += " <code>*</code>, representing the universal selector, not be";
- ret += " omitted.</p>";
- ret += " <h4><a name='univnmsp'>6.2.1. Universal selector and namespaces</a></h4>";
- ret += " <p>The universal selector allows an optional namespace component. It";
- ret += " is used as follows:</p>";
- ret += " <dl>";
- ret += " <dt><code>ns|*</code></dt>";
- ret += " <dd>all elements in namespace ns</dd>";
- ret += " <dt><code>*|*</code></dt>";
- ret += " <dd>all elements</dd>";
- ret += " <dt><code>|*</code></dt>";
- ret += " <dd>all elements without any declared namespace</dd>";
- ret += " <dt><code>*</code></dt>";
- ret += " <dd>if no default namespace has been specified, this is equivalent to *|*.";
- ret += " </dd>";
- ret += " </dl>";
- ret += " <p>A universal selector containing a namespace prefix that has not";
- ret += " been previously declared is an <a href='#Conformance'>invalid</a>";
- ret += " to the language implementing Selectors. In CSS, such a mechanism is";
- ret += " defined in the General Syntax module.</p>";
- ret += " <h3><a name='attribute-selectors'>6.3. Attribute selectors</a></h3>";
- ret += " <p>Selectors allow the representation of an element's attributes. When";
- ret += " attribute selectors must be considered to match an element if that";
- ret += " attribute selector.</p>";
- ret += " <h4><a name='attribute-representation'>6.3.1. Attribute presence and values";
- ret += " selectors</a></h4>";
- ret += " <p>CSS2 introduced four attribute selectors:</p>";
- ret += " <dl>";
- ret += " <dt><code>[att]</code>";
- ret += " </dt><dd>Represents an element with the <code>att</code> attribute, whatever the";
- ret += " </dd>";
- ret += " <dt><code>[att=val]</code></dt>";
- ret += " <dd>Represents an element with the <code>att</code> attribute whose value is";
- ret += " </dd>";
- ret += " <dt><code>[att~=val]</code></dt>";
- ret += " <dd>Represents an element with the <code>att</code> attribute whose value is";
- ret += " a <a href='#whitespace'>whitespace</a>-separated list of words, one";
- ret += " represent anything (since the words are <em>separated</em> by";
- ret += " </dd>";
- ret += " <dt><code>[att|=val]</code>";
- ret += " </dt><dd>Represents an element with the <code>att</code> attribute, its value";
- ret += " matches (e.g., the <code>hreflang</code> attribute on the";
- ret += " <code>link</code> element in HTML) as described in RFC 3066 (<a href='#refsRFC3066'>[RFC3066]</a>). For <code>lang</code> (or";
- ret += " <code>xml:lang</code>) language subcode matching, please see <a href='#lang-pseudo'>the <code>:lang</code> pseudo-class</a>.";
- ret += " </dd>";
- ret += " </dl>";
- ret += " <p>Attribute values must be identifiers or strings. The";
- ret += " case-sensitivity of attribute names and values in selectors depends on";
- ret += " the document language.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following attribute selector represents an <code>h1</code>";
- ret += " element that carries the <code>title</code> attribute, whatever its";
- ret += " value:</p>";
- ret += " <pre>h1[title]</pre>";
- ret += " <p>In the following example, the selector represents a";
- ret += " <code>span</code> element whose <code>class</code> attribute has";
- ret += " exactly the value 'example':</p>";
- ret += " <pre>span[class='example']</pre>";
- ret += " <p>Multiple attribute selectors can be used to represent several";
- ret += " attribute. Here, the selector represents a <code>span</code> element";
- ret += " whose <code>hello</code> attribute has exactly the value 'Cleveland'";
- ret += " and whose <code>goodbye</code> attribute has exactly the value";
- ret += " 'Columbus':</p>";
- ret += " <pre>span[hello='Cleveland'][goodbye='Columbus']</pre>";
- ret += " <p>The following selectors illustrate the differences between '='";
- ret += " 'copyright copyleft copyeditor' on a <code>rel</code> attribute. The";
- ret += " second selector will only represent an <code>a</code> element with";
- ret += " an <code>href</code> attribute having the exact value";
- ret += " 'http://www.w3.org/'.</p>";
- ret += " <pre>a[rel~='copyright']";
- ret += " a[href='http://www.w3.org/']</pre>";
- ret += " <p>The following selector represents a <code>link</code> element";
- ret += " whose <code>hreflang</code> attribute is exactly 'fr'.</p>";
- ret += " <pre>link[hreflang=fr]</pre>";
- ret += " <p>The following selector represents a <code>link</code> element for";
- ret += " which the values of the <code>hreflang</code> attribute begins with";
- ret += " 'en', including 'en', 'en-US', and 'en-cockney':</p>";
- ret += " <pre>link[hreflang|='en']</pre>";
- ret += " <p>Similarly, the following selectors represents a";
- ret += " <code>DIALOGUE</code> element whenever it has one of two different";
- ret += " values for an attribute <code>character</code>:</p>";
- ret += " <pre>DIALOGUE[character=romeo]";
- ret += " DIALOGUE[character=juliet]</pre>";
- ret += " </div>";
- ret += " <h4><a name='attribute-substrings'></a>6.3.2. Substring matching attribute";
- ret += " selectors</h4>";
- ret += " <p>Three additional attribute selectors are provided for matching";
- ret += " substrings in the value of an attribute:</p>";
- ret += " <dl>";
- ret += " <dt><code>[att^=val]</code></dt>";
- ret += " <dd>Represents an element with the <code>att</code> attribute whose value";
- ret += " </dd>";
- ret += " <dt><code>[att$=val]</code>";
- ret += " </dt><dd>Represents an element with the <code>att</code> attribute whose value";
- ret += " </dd>";
- ret += " <dt><code>[att*=val]</code>";
- ret += " </dt><dd>Represents an element with the <code>att</code> attribute whose value";
- ret += " </dd>";
- ret += " </dl>";
- ret += " <p>Attribute values must be identifiers or strings. The";
- ret += " case-sensitivity of attribute names in selectors depends on the";
- ret += " document language.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following selector represents an HTML <code>object</code>,";
- ret += " image:</p>";
- ret += " <pre>object[type^='image/']</pre>";
- ret += " <p>The following selector represents an HTML anchor <code>a</code> with an";
- ret += " <code>href</code> attribute whose value ends with '.html'.</p>";
- ret += " <pre>a[href$='.html']</pre>";
- ret += " <p>The following selector represents an HTML paragraph with a";
- ret += " <code>title</code>";
- ret += " attribute whose value contains the substring 'hello'</p>";
- ret += " <pre>p[title*='hello']</pre>";
- ret += " </div>";
- ret += " <h4><a name='attrnmsp'>6.3.3. Attribute selectors and namespaces</a></h4>";
- ret += " <p>Attribute selectors allow an optional namespace component to the";
- ret += " separator 'vertical bar' (<code>|</code>). In keeping with";
- ret += " apply to attributes, therefore attribute selectors without a namespace";
- ret += " (equivalent to '<code>|attr</code>'). An asterisk may be used for the";
- ret += " </p><p>An attribute selector with an attribute name containing a namespace";
- ret += " prefix that has not been previously declared is an <a href='#Conformance'>invalid</a> selector. The mechanism for";
- ret += " a namespace prefix is left up to the language implementing Selectors.";
- ret += " </p><div class='example'>";
- ret += " <p>CSS examples:</p>";
- ret += " <pre>@namespace foo 'http://www.example.com';";
- ret += " [att] { color: green }</pre>";
- ret += " <p>The first rule will match only elements with the attribute";
- ret += " <code>att</code> in the 'http://www.example.com' namespace with the";
- ret += " value 'val'.</p>";
- ret += " <p>The second rule will match only elements with the attribute";
- ret += " <code>att</code> regardless of the namespace of the attribute";
- ret += " (including no declared namespace).</p>";
- ret += " <p>The last two rules are equivalent and will match only elements";
- ret += " with the attribute <code>att</code> where the attribute is not";
- ret += " declared to be in a namespace.</p>";
- ret += " </div>";
- ret += " <h4><a name='def-values'>6.3.4. Default attribute values in DTDs</a></h4>";
- ret += " <p>Attribute selectors represent explicitly set attribute values in";
- ret += " selectors. Selectors should be designed so that they work even if the";
- ret += " default values are not included in the document tree.</p>";
- ret += " <p>More precisely, a UA is <em>not</em> required to read an 'external";
- ret += " subset' of the DTD but <em>is</em> required to look for default";
- ret += " attribute values in the document's 'internal subset.' (See <a href='#refsXML10'>[XML10]</a> for definitions of these subsets.)</p>";
- ret += " <p>A UA that recognizes an XML namespace <a href='#refsXMLNAMES'>[XMLNAMES]</a> is not required to use its";
- ret += " required to use its built-in knowledge of the XHTML DTD.)</p>";
- ret += " <p class='note'><strong>Note:</strong> Typically, implementations";
- ret += " choose to ignore external subsets.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>Consider an element EXAMPLE with an attribute 'notation' that has a";
- ret += " default value of 'decimal'. The DTD fragment might be</p>";
- ret += " <pre class='dtd-example'><!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'></pre>";
- ret += " <p>If the style sheet contains the rules</p>";
- ret += " <pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }";
- ret += " EXAMPLE[notation=octal] { /*... other settings...*/ }</pre>";
- ret += " <p>the first rule will not match elements whose 'notation' attribute";
- ret += " attribute selector for the default value must be dropped:</p>";
- ret += " <pre>EXAMPLE { /*... default property settings ...*/ }";
- ret += " EXAMPLE[notation=octal] { /*... other settings...*/ }</pre>";
- ret += " <p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is";
- ret += " cases' style rules.</p>";
- ret += " </div>";
- ret += " <h3><a name='class-html'>6.4. Class selectors</a></h3>";
- ret += " <p>Working with HTML, authors may use the period (U+002E,";
- ret += " <code>.</code>) notation as an alternative to the <code>~=</code>";
- ret += " notation when representing the <code>class</code> attribute. Thus, for";
- ret += " HTML, <code>div.value</code> and <code>div[class~=value]</code> have";
- ret += " 'period' (<code>.</code>).</p>";
- ret += " <p>UAs may apply selectors using the period (.) notation in XML";
- ret += " 1.0 <a href='#refsSVG'>[SVG]</a> describes the <a href='http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute'>SVG";
- ret += " 'class' attribute</a> and how a UA should interpret it, and";
- ret += " similarly MathML 1.01 <a href='#refsMATH'>[MATH]</a> describes the <a href='http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4'>MathML";
- ret += " 'class' attribute</a>.)</p>";
- ret += " <div class='example'>";
- ret += " <p>CSS examples:</p>";
- ret += " <p>We can assign style information to all elements with";
- ret += " <code>class~='pastoral'</code> as follows:</p>";
- ret += " <pre>*.pastoral { color: green } /* all elements with class~=pastoral */</pre>";
- ret += " <p>or just</p>";
- ret += " <pre>.pastoral { color: green } /* all elements with class~=pastoral */</pre>";
- ret += " <p>The following assigns style only to H1 elements with";
- ret += " <code>class~='pastoral'</code>:</p>";
- ret += " <pre>H1.pastoral { color: green } /* H1 elements with class~=pastoral */</pre>";
- ret += " <p>Given these rules, the first H1 instance below would not have";
- ret += " green text, while the second would:</p>";
- ret += " <pre><H1>Not green</H1>";
- ret += " <H1 class='pastoral'>Very green</H1></pre>";
- ret += " </div>";
- ret += " <p>To represent a subset of 'class' values, each value must be preceded";
- ret += " by a '.', in any order.</p>";
- ret += " <div class='example'>";
- ret += " <p>CSS example:</p>";
- ret += " <p>The following rule matches any P element whose 'class' attribute";
- ret += " has been assigned a list of <a href='#whitespace'>whitespace</a>-separated values that includes";
- ret += " 'pastoral' and 'marine':</p>";
- ret += " <pre>p.pastoral.marine { color: green }</pre>";
- ret += " <p>This rule matches when <code>class='pastoral blue aqua";
- ret += " marine'</code> but does not match for <code>class='pastoral";
- ret += " blue'</code>.</p>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note:</strong> Because CSS gives considerable";
- ret += " not.</p>";
- ret += " <p class='note'><strong>Note:</strong> If an element has multiple";
- ret += " this specification.</p>";
- ret += " <h3><a name='id-selectors'>6.5. ID selectors</a></h3>";
- ret += " <p>Document languages may contain attributes that are declared to be";
- ret += " applies.</p>";
- ret += " <p>An ID-typed attribute of a document language allows authors to";
- ret += " ID selectors represent an element instance based on its identifier. An";
- ret += " <code>#</code>) immediately followed by the ID value, which must be an";
- ret += " identifier.</p>";
- ret += " <p>Selectors does not specify how a UA knows the ID-typed attribute of";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following ID selector represents an <code>h1</code> element";
- ret += " whose ID-typed attribute has the value 'chapter1':</p>";
- ret += " <pre>h1#chapter1</pre>";
- ret += " <p>The following ID selector represents any element whose ID-typed";
- ret += " attribute has the value 'chapter1':</p>";
- ret += " <pre>#chapter1</pre>";
- ret += " <p>The following selector represents any element whose ID-typed";
- ret += " attribute has the value 'z98y'.</p>";
- ret += " <pre>*#z98y</pre>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note.</strong> In XML 1.0 <a href='#refsXML10'>[XML10]</a>, the information about which attribute";
- ret += " should use normal attribute selectors instead:";
- ret += " <code>[name=p371]</code> instead of <code>#p371</code>. Elements in";
- ret += " XML 1.0 documents without a DTD do not have IDs at all.</p>";
- ret += " <p>If an element has multiple ID attributes, all of them must be";
- ret += " DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>";
- ret += " <h3><a name='pseudo-classes'>6.6. Pseudo-classes</a></h3>";
- ret += " <p>The pseudo-class concept is introduced to permit selection based on";
- ret += " expressed using the other simple selectors.</p>";
- ret += " <p>A pseudo-class always consists of a 'colon'";
- ret += " (<code>:</code>) followed by the name of the pseudo-class and";
- ret += " optionally by a value between parentheses.</p>";
- ret += " <p>Pseudo-classes are allowed in all sequences of simple selectors";
- ret += " sequences of simple selectors, after the leading type selector or";
- ret += " document.</p>";
- ret += " <h4><a name='dynamic-pseudos'>6.6.1. Dynamic pseudo-classes</a></h4>";
- ret += " <p>Dynamic pseudo-classes classify elements on characteristics other";
- ret += " that cannot be deduced from the document tree.</p>";
- ret += " <p>Dynamic pseudo-classes do not appear in the document source or";
- ret += " document tree.</p>";
- ret += " <h5>The <a name='link'>link pseudo-classes: :link and :visited</a></h5>";
- ret += " <p>User agents commonly display unvisited links differently from";
- ret += " previously visited ones. Selectors";
- ret += " provides the pseudo-classes <code>:link</code> and";
- ret += " <code>:visited</code> to distinguish them:</p>";
- ret += " <ul>";
- ret += " <li>The <code>:link</code> pseudo-class applies to links that have";
- ret += " </li>";
- ret += " <li>The <code>:visited</code> pseudo-class applies once the link has";
- ret += " </li>";
- ret += " </ul>";
- ret += " <p>After some amount of time, user agents may choose to return a";
- ret += " visited link to the (unvisited) ':link' state.</p>";
- ret += " <p>The two states are mutually exclusive.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The following selector represents links carrying class";
- ret += " <code>external</code> and already visited:</p>";
- ret += " <pre>a.external:visited</pre>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note:</strong> It is possible for style sheet";
- ret += " </p><p>UAs may therefore treat all links as unvisited links, or implement";
- ret += " and unvisited links differently.</p>";
- ret += " <h5>The <a name='useraction-pseudos'>user action pseudo-classes";
- ret += " :hover, :active, and :focus</a></h5>";
- ret += " <p>Interactive user agents sometimes change the rendering in response";
- ret += " to user actions. Selectors provides";
- ret += " acting on.</p>";
- ret += " <ul>";
- ret += " <li>The <code>:hover</code> pseudo-class applies while the user";
- ret += " element. User agents not that do not support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
- ret += " media</a> do not have to support this pseudo-class. Some conforming";
- ret += " user agents that support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
- ret += " media</a> may not be able to support this pseudo-class (e.g., a pen";
- ret += " </li>";
- ret += " <li>The <code>:active</code> pseudo-class applies while an element";
- ret += " </li>";
- ret += " <li>The <code>:focus</code> pseudo-class applies while an element";
- ret += " </li>";
- ret += " </ul>";
- ret += " <p>There may be document language or implementation specific limits on";
- ret += " which elements can become <code>:active</code> or acquire";
- ret += " <code>:focus</code>.</p>";
- ret += " <p>These pseudo-classes are not mutually exclusive. An element may";
- ret += " match several pseudo-classes at the same time.</p>";
- ret += " <p>Selectors doesn't define if the parent of an element that is";
- ret += " ':active' or ':hover' is also in that state.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>a:link /* unvisited links */";
- ret += " a:active /* active links */</pre>";
- ret += " <p>An example of combining dynamic pseudo-classes:</p>";
- ret += " <pre>a:focus";
- ret += " a:focus:hover</pre>";
- ret += " <p>The last selector matches <code>a</code> elements that are in";
- ret += " the pseudo-class :focus and in the pseudo-class :hover.</p>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note:</strong> An element can be both ':visited'";
- ret += " and ':active' (or ':link' and ':active').</p>";
- ret += " <h4><a name='target-pseudo'>6.6.2. The target pseudo-class :target</a></h4>";
- ret += " <p>Some URIs refer to a location within a resource. This kind of URI";
- ret += " identifier (called the fragment identifier).</p>";
- ret += " <p>URIs with fragment identifiers link to a certain element within the";
- ret += " pointing to an anchor named <code>section_2</code> in an HTML";
- ret += " document:</p>";
- ret += " <pre>http://example.com/html/top.html#section_2</pre>";
- ret += " <p>A target element can be represented by the <code>:target</code>";
- ret += " the document has no target element.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <pre>p.note:target</pre>";
- ret += " <p>This selector represents a <code>p</code> element of class";
- ret += " <code>note</code> that is the target element of the referring";
- ret += " URI.</p>";
- ret += " </div>";
- ret += " <div class='example'>";
- ret += " <p>CSS example:</p>";
- ret += " <p>Here, the <code>:target</code> pseudo-class is used to make the";
- ret += " target element red and place an image before it, if there is one:</p>";
- ret += " <pre>*:target { color : red }";
- ret += " *:target::before { content : url(target.png) }</pre>";
- ret += " </div>";
- ret += " <h4><a name='lang-pseudo'>6.6.3. The language pseudo-class :lang</a></h4>";
- ret += " <p>If the document language specifies how the human language of an";
- ret += " element is determined, it is possible to write selectors that";
- ret += " represent an element based on its language. For example, in HTML <a href='#refsHTML4'>[HTML4]</a>, the language is determined by a";
- ret += " combination of the <code>lang</code> attribute, the <code>meta</code>";
- ret += " headers). XML uses an attribute called <code>xml:lang</code>, and";
- ret += " the language.</p>";
- ret += " <p>The pseudo-class <code>:lang(C)</code> represents an element that";
- ret += " <code>:lang()</code> selector is based solely on the identifier C";
- ret += " element's language value, in the same way as if performed by the <a href='#attribute-representation'>'|='</a> operator in attribute";
- ret += " selectors. The identifier C does not have to be a valid language";
- ret += " name.</p>";
- ret += " <p>C must not be empty. (If it is, the selector is invalid.)</p>";
- ret += " <p class='note'><strong>Note:</strong> It is recommended that";
- ret += " documents and protocols indicate language using codes from RFC 3066 <a href='#refsRFC3066'>[RFC3066]</a> or its successor, and by means of";
- ret += " 'xml:lang' attributes in the case of XML-based documents <a href='#refsXML10'>[XML10]</a>. See <a href='http://www.w3.org/International/questions/qa-lang-2or3.html'>";
- ret += " 'FAQ: Two-letter or three-letter language codes.'</a></p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The two following selectors represent an HTML document that is in";
- ret += " Belgian, French, or German. The two next selectors represent";
- ret += " <code>q</code> quotations in an arbitrary element in Belgian, French,";
- ret += " or German.</p>";
- ret += " <pre>html:lang(fr-be)";
- ret += " :lang(de) > q</pre>";
- ret += " </div>";
- ret += " <h4><a name='UIstates'>6.6.4. The UI element states pseudo-classes</a></h4>";
- ret += " <h5><a name='enableddisabled'>The :enabled and :disabled pseudo-classes</a></h5>";
- ret += " <p>The <code>:enabled</code> pseudo-class allows authors to customize";
- ret += " an enabled <code>input</code> element without also specifying what it";
- ret += " would look like when it was disabled.</p>";
- ret += " <p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the";
- ret += " element should look.</p>";
- ret += " <p>Most elements will be neither enabled nor disabled. An element is";
- ret += " presently activate it or transfer focus to it.</p>";
- ret += " <h5><a name='checked'>The :checked pseudo-class</a></h5>";
- ret += " <p>Radio and checkbox elements can be toggled by the user. Some menu";
- ret += " toggled 'on' the <code>:checked</code> pseudo-class applies. The";
- ret += " <code>:checked</code> pseudo-class initially applies to such elements";
- ret += " that have the HTML4 <code>selected</code> and <code>checked</code>";
- ret += " attributes as described in <a href='http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1'>Section";
- ret += " 17.2.1 of HTML4</a>, but of course the user can toggle 'off' such";
- ret += " elements in which case the <code>:checked</code> pseudo-class would no";
- ret += " longer apply. While the <code>:checked</code> pseudo-class is dynamic";
- ret += " on the presence of the semantic HTML4 <code>selected</code> and";
- ret += " <code>checked</code> attributes, it applies to all media.";
- ret += " </p><h5><a name='indeterminate'>The :indeterminate pseudo-class</a></h5>";
- ret += " <div class='note'>";
- ret += " <p>Radio and checkbox elements can be toggled by the user, but are";
- ret += " This can be due to an element attribute, or DOM manipulation.</p>";
- ret += " <p>A future version of this specification may introduce an";
- ret += " <code>:indeterminate</code> pseudo-class that applies to such elements.";
- ret += " <!--While the <code>:indeterminate</code> pseudo-class is dynamic in";
- ret += " the presence of an element attribute, it applies to all media.</p>";
- ret += " <p>Components of a radio-group initialized with no pre-selected choice";
- ret += " are an example of :indeterminate state.--></p>";
- ret += " </div>";
- ret += " <h4><a name='structural-pseudos'>6.6.5. Structural pseudo-classes</a></h4>";
- ret += " <p>Selectors introduces the concept of <dfn>structural";
- ret += " pseudo-classes</dfn> to permit selection based on extra information that";
- ret += " the document tree but cannot be represented by other simple selectors or";
- ret += " </p><p>Note that standalone pieces of PCDATA (text nodes in the DOM) are";
- ret += " </p><h5><a name='root-pseudo'>:root pseudo-class</a></h5>";
- ret += " <p>The <code>:root</code> pseudo-class represents an element that is";
- ret += " <code>HTML</code> element.";
- ret += " </p><h5><a name='nth-child-pseudo'>:nth-child() pseudo-class</a></h5>";
- ret += " <p>The";
- ret += " <code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>";
- ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings";
- ret += " <strong>before</strong> it in the document tree, for a given positive";
- ret += " integer or zero value of <code>n</code>, and has a parent element. In";
- ret += " other words, this matches the <var>b</var>th child of an element after";
- ret += " all the children have been split into groups of <var>a</var> elements";
- ret += " each. For example, this allows the selectors to address every other";
- ret += " of paragraph text in a cycle of four. The <var>a</var> and";
- ret += " <var>b</var> values must be zero, negative integers or positive";
- ret += " </p><p>In addition to this, <code>:nth-child()</code> can take";
- ret += " '<code>odd</code>' and '<code>even</code>' as arguments instead.";
- ret += " '<code>odd</code>' has the same signification as <code>2n+1</code>,";
- ret += " and '<code>even</code>' has the same signification as <code>2n</code>.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */";
- ret += " p:nth-child(4n+4) { color: purple; }</pre>";
- ret += " </div>";
- ret += " <p>When <var>a</var>=0, no repeating is used, so for example";
- ret += " <code>:nth-child(0n+5)</code> matches only the fifth child. When";
- ret += " <var>a</var>=0, the <var>a</var><code>n</code> part need not be";
- ret += " <code>:nth-child(<var>b</var>)</code> and the last example simplifies";
- ret += " to <code>:nth-child(5)</code>.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>foo:nth-child(0n+1) /* represents an element foo, first child of its parent element */";
- ret += " foo:nth-child(1) /* same */</pre>";
- ret += " </div>";
- ret += " <p>When <var>a</var>=1, the number may be omitted from the rule.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following selectors are therefore equivalent:</p>";
- ret += " <pre>bar:nth-child(1n+0) /* represents all bar elements, specificity (0,1,1) */";
- ret += " bar /* same but lower specificity (0,0,1) */</pre>";
- ret += " </div>";
- ret += " <p>If <var>b</var>=0, then every <var>a</var>th element is picked. In";
- ret += " such a case, the <var>b</var> part may be omitted.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */";
- ret += " tr:nth-child(2n) /* same */</pre>";
- ret += " </div>";
- ret += " <p>If both <var>a</var> and <var>b</var> are equal to zero, the";
- ret += " pseudo-class represents no element in the document tree.</p>";
- ret += " <p>The value <var>a</var> can be negative, but only the positive";
- ret += " values of <var>a</var><code>n</code>+<var>b</var>, for";
- ret += " <code>n</code>≥0, may represent an element in the document";
- ret += " tree.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <pre>html|tr:nth-child(-n+6) /* represents the 6 first rows of XHTML tables */</pre>";
- ret += " </div>";
- ret += " <p>When the value <var>b</var> is negative, the '+' character in the";
- ret += " character indicating the negative value of <var>b</var>).</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>:nth-child(10n-1) /* represents the 9th, 19th, 29th, etc, element */";
- ret += " :nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>";
- ret += " </div>";
- ret += " <h5><a name='nth-last-child-pseudo'>:nth-last-child() pseudo-class</a></h5>";
- ret += " <p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>";
- ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings";
- ret += " <strong>after</strong> it in the document tree, for a given positive";
- ret += " integer or zero value of <code>n</code>, and has a parent element. See";
- ret += " <code>:nth-child()</code> pseudo-class for the syntax of its argument.";
- ret += " It also accepts the '<code>even</code>' and '<code>odd</code>' values";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>tr:nth-last-child(-n+2) /* represents the two last rows of an HTML table */";
- ret += " counting from the last one */</pre>";
- ret += " </div>";
- ret += " <h5><a name='nth-of-type-pseudo'>:nth-of-type() pseudo-class</a></h5>";
- ret += " <p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>";
- ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
- ret += " element name <strong>before</strong> it in the document tree, for a";
- ret += " given zero or positive integer value of <code>n</code>, and has a";
- ret += " parent element. In other words, this matches the <var>b</var>th child";
- ret += " groups of a elements each. See <code>:nth-child()</code> pseudo-class";
- ret += " '<code>even</code>' and '<code>odd</code>' values.";
- ret += " </p><div class='example'>";
- ret += " <p>CSS example:</p>";
- ret += " <p>This allows an author to alternate the position of floated images:</p>";
- ret += " <pre>img:nth-of-type(2n+1) { float: right; }";
- ret += " img:nth-of-type(2n) { float: left; }</pre>";
- ret += " </div>";
- ret += " <h5><a name='nth-last-of-type-pseudo'>:nth-last-of-type() pseudo-class</a></h5>";
- ret += " <p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>";
- ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
- ret += " element name <strong>after</strong> it in the document tree, for a";
- ret += " given zero or positive integer value of <code>n</code>, and has a";
- ret += " parent element. See <code>:nth-child()</code> pseudo-class for the";
- ret += " syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>'";
- ret += " </p><div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>To represent all <code>h2</code> children of an XHTML";
- ret += " <code>body</code> except the first and last, one could use the";
- ret += " following selector:</p>";
- ret += " <pre>body > h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>";
- ret += " <p>In this case, one could also use <code>:not()</code>, although the";
- ret += " selector ends up being just as long:</p>";
- ret += " <pre>body > h2:not(:first-of-type):not(:last-of-type)</pre>";
- ret += " </div>";
- ret += " <h5><a name='first-child-pseudo'>:first-child pseudo-class</a></h5>";
- ret += " <p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code>";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following selector represents a <code>p</code> element that is";
- ret += " the first child of a <code>div</code> element:</p>";
- ret += " <pre>div > p:first-child</pre>";
- ret += " <p>This selector can represent the <code>p</code> inside the";
- ret += " <code>div</code> of the following fragment:</p>";
- ret += " <pre><p> The last P before the note.</p>";
- ret += " </div></pre>";
- ret += " but cannot represent the second <code>p</code> in the following";
- ret += " <pre><p> The last P before the note.</p>";
- ret += " </div></pre>";
- ret += " <p>The following two selectors are usually equivalent:</p>";
- ret += " <pre>* > a:first-child /* a is first child of any element */";
- ret += " a:first-child /* Same (assuming a is not the root element) */</pre>";
- ret += " </div>";
- ret += " <h5><a name='last-child-pseudo'>:last-child pseudo-class</a></h5>";
- ret += " <p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code>";
- ret += " </p><div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The following selector represents a list item <code>li</code> that";
- ret += " is the last child of an ordered list <code>ol</code>.";
- ret += " </p><pre>ol > li:last-child</pre>";
- ret += " </div>";
- ret += " <h5><a name='first-of-type-pseudo'>:first-of-type pseudo-class</a></h5>";
- ret += " <p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code>";
- ret += " </p><div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The following selector represents a definition title";
- ret += " <code>dt</code> inside a definition list <code>dl</code>, this";
- ret += " <code>dt</code> being the first of its type in the list of children of";
- ret += " its parent element.</p>";
- ret += " <pre>dl dt:first-of-type</pre>";
- ret += " <p>It is a valid description for the first two <code>dt</code>";
- ret += " elements in the following example but not for the third one:</p>";
- ret += " <pre><dl>";
- ret += " </dl></pre>";
- ret += " </div>";
- ret += " <h5><a name='last-of-type-pseudo'>:last-of-type pseudo-class</a></h5>";
- ret += " <p>Same as <code>:nth-last-of-type(1)</code>. The";
- ret += " <code>:last-of-type</code> pseudo-class represents an element that is";
- ret += " element.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The following selector represents the last data cell";
- ret += " <code>td</code> of a table row.</p>";
- ret += " <pre>tr > td:last-of-type</pre>";
- ret += " </div>";
- ret += " <h5><a name='only-child-pseudo'>:only-child pseudo-class</a></h5>";
- ret += " <p>Represents an element that has a parent element and whose parent";
- ret += " <code>:first-child:last-child</code> or";
- ret += " <code>:nth-child(1):nth-last-child(1)</code>, but with a lower";
- ret += " specificity.</p>";
- ret += " <h5><a name='only-of-type-pseudo'>:only-of-type pseudo-class</a></h5>";
- ret += " <p>Represents an element that has a parent element and whose parent";
- ret += " as <code>:first-of-type:last-of-type</code> or";
- ret += " <code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower";
- ret += " specificity.</p>";
- ret += " <h5><a name='empty-pseudo'></a>:empty pseudo-class</h5>";
- ret += " <p>The <code>:empty</code> pseudo-class represents an element that has";
- ret += " empty or not.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p><code>p:empty</code> is a valid representation of the following fragment:";
- ret += " </p>";
- ret += " <pre><p></p></pre>";
- ret += " <p><code>foo:empty</code> is not a valid representation for the";
- ret += " following fragments:</p>";
- ret += " <pre><foo>bar</foo></pre>";
- ret += " <pre><foo><bar>bla</bar></foo></pre>";
- ret += " <pre><foo>this is not <bar>:empty</bar></foo></pre>";
- ret += " </div>";
- ret += " <h4><a name='content-selectors'>6.6.6. Blank</a></h4>";
- ret += " <!-- It's the Return of Appendix H!!! Run away! -->";
- ret += " <p>This section intentionally left blank.</p>";
- ret += " <!-- (used to be :contains()) -->";
- ret += " <h4><a name='negation'></a>6.6.7. The negation pseudo-class</h4>";
- ret += " <p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a";
- ret += " functional notation taking a <a href='#simple-selectors-dfn'>simple";
- ret += " selector</a> (excluding the negation pseudo-class itself and";
- ret += " <!-- pseudo-elements are not simple selectors, so the above paragraph";
- ret += " may be a bit confusing -->";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following CSS selector matches all <code>button</code>";
- ret += " elements in an HTML document that are not disabled.</p>";
- ret += " <pre>button:not([DISABLED])</pre>";
- ret += " <p>The following selector represents all but <code>FOO</code>";
- ret += " elements.</p>";
- ret += " <pre>*:not(FOO)</pre>";
- ret += " <p>The following group of selectors represents all HTML elements";
- ret += " except links.</p>";
- ret += " <pre>html|*:not(:link):not(:visited)</pre>";
- ret += " </div>";
- ret += " <p>Default namespace declarations do not affect the argument of the";
- ret += " type selector.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>Assuming that the default namespace is bound to";
- ret += " elements that are not in that namespace:</p>";
- ret += " <pre>*|*:not(*)</pre>";
- ret += " <p>The following CSS selector matches any element being hovered,";
- ret += " rule when they <em>are</em> being hovered.</p>";
- ret += " <pre>*|*:not(:hover)</pre>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note</strong>: the :not() pseudo allows";
- ret += " useless selectors to be written. For instance <code>:not(*|*)</code>,";
- ret += " which represents no element at all, or <code>foo:not(bar)</code>,";
- ret += " which is equivalent to <code>foo</code> but with a higher";
- ret += " specificity.</p>";
- ret += " <h3><a name='pseudo-elements'>7. Pseudo-elements</a></h3>";
- ret += " <p>Pseudo-elements create abstractions about the document tree beyond";
- ret += " source document (e.g., the <code>::before</code> and";
- ret += " <code>::after</code> pseudo-elements give access to generated";
- ret += " content).</p>";
- ret += " <p>A pseudo-element is made of two colons (<code>::</code>) followed";
- ret += " by the name of the pseudo-element.</p>";
- ret += " <p>This <code>::</code> notation is introduced by the current document";
- ret += " <code>:first-line</code>, <code>:first-letter</code>,";
- ret += " <code>:before</code> and <code>:after</code>). This compatibility is";
- ret += " not allowed for the new pseudo-elements introduced in CSS level 3.</p>";
- ret += " <p>Only one pseudo-element may appear per selector, and if present it";
- ret += " must appear after the sequence of simple selectors that represents the";
- ret += " <a href='#subject'>subjects</a> of the selector. <span class='note'>A";
- ret += " pesudo-elements per selector.</span></p>";
- ret += " <h4><a name='first-line'>7.1. The ::first-line pseudo-element</a></h4>";
- ret += " <p>The <code>::first-line</code> pseudo-element describes the contents";
- ret += " </p><div class='example'>";
- ret += " <p>CSS example:</p>";
- ret += " <pre>p::first-line { text-transform: uppercase }</pre>";
- ret += " <p>The above rule means 'change the letters of the first line of every";
- ret += " paragraph to uppercase'.</p>";
- ret += " </div>";
- ret += " <p>The selector <code>p::first-line</code> does not match any real";
- ret += " agents will insert at the beginning of every paragraph.</p>";
- ret += " <p>Note that the length of the first line depends on a number of";
- ret += " an ordinary HTML paragraph such as:</p>";
- ret += " <pre> <P>This is a somewhat long HTML ";
- ret += " </pre>";
- ret += " <p>the lines of which happen to be broken as follows:";
- ret += " </p><pre> THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT";
- ret += " </pre>";
- ret += " <p>This paragraph might be 'rewritten' by user agents to include the";
- ret += " <em>fictional tag sequence</em> for <code>::first-line</code>. This";
- ret += " fictional tag sequence helps to show how properties are inherited.</p>";
- ret += " <pre> <P><b><P::first-line></b> This is a somewhat long HTML ";
- ret += " paragraph that <b></P::first-line></b> will be broken into several";
- ret += " </pre>";
- ret += " <p>If a pseudo-element breaks up a real element, the desired effect";
- ret += " with a <code>span</code> element:</p>";
- ret += " <pre> <P><b><SPAN class='test'></b> This is a somewhat long HTML";
- ret += " lines.<b></SPAN></b> The first line will be identified";
- ret += " </pre>";
- ret += " <p>the user agent could simulate start and end tags for";
- ret += " <code>span</code> when inserting the fictional tag sequence for";
- ret += " <code>::first-line</code>.";
- ret += " </p><pre> <P><P::first-line><b><SPAN class='test'></b> This is a";
- ret += " paragraph that will <b></SPAN></b></P::first-line><b><SPAN";
- ret += " class='test'></b> be";
- ret += " lines.<b></SPAN></b> The first line will be identified";
- ret += " </pre>";
- ret += " <p>In CSS, the <code>::first-line</code> pseudo-element can only be";
- ret += " or a table-cell.</p>";
- ret += " <p><a name='first-formatted-line'></a>The 'first formatted line' of an";
- ret += " line of the <code>div</code> in <code><DIV><P>This";
- ret += " line...</P></DIV></code> is the first line of the <code>p</code>";
- ret += " that both <code>p</code> and <code>div</code> are block-level).";
- ret += " </p><p>The first line of a table-cell or inline-block cannot be the first";
- ret += " formatted line of an ancestor element. Thus, in <code><DIV><P";
- ret += " etcetera</DIV></code> the first formatted line of the";
- ret += " <code>div</code> is not the line 'Hello'.";
- ret += " </p><p class='note'>Note that the first line of the <code>p</code> in this";
- ret += " fragment: <code><p><br>First...</code> doesn't contain any";
- ret += " letters (assuming the default style for <code>br</code> in HTML";
- ret += " </p><p>A UA should act as if the fictional start tags of the";
- ret += " <code>::first-line</code> pseudo-elements were nested just inside the";
- ret += " is an example. The fictional tag sequence for</p>";
- ret += " <pre> <DIV>";
- ret += " </pre>";
- ret += " <p>is</p>";
- ret += " <pre> <DIV>";
- ret += " </pre>";
- ret += " <p>The <code>::first-line</code> pseudo-element is similar to an";
- ret += " following properties apply to a <code>::first-line</code>";
- ret += " properties as well.</p>";
- ret += " <h4><a name='first-letter'>7.2. The ::first-letter pseudo-element</a></h4>";
- ret += " <p>The <code>::first-letter</code> pseudo-element represents the first";
- ret += " is 'none'; otherwise, it is similar to a floated element.</p>";
- ret += " <p>In CSS, these are the properties that apply to <code>::first-letter</code>";
- ret += " of the letter, unlike for normal elements.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>This example shows a possible rendering of an initial cap. Note";
- ret += " <code>::first-letter</code>";
- ret += " fictional start tag of the first letter is inside the <span>span</span>,";
- ret += " the font weight of the first letter is normal, not bold as the <span>span</span>:";
- ret += " </p><pre> p { line-height: 1.1 }";
- ret += " </pre>";
- ret += " <div class='figure'>";
- ret += " <p><img src='' alt='Image illustrating the ::first-letter pseudo-element'>";
- ret += " </p></div>";
- ret += " </div>";
- ret += " <div class='example'>";
- ret += " <p>The following CSS will make a drop cap initial letter span about two";
- ret += " lines:</p>";
- ret += " <pre> <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'>";
- ret += " </pre>";
- ret += " <p>This example might be formatted as follows:</p>";
- ret += " <div class='figure'>";
- ret += " <p><img src='' alt='Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements'>";
- ret += " </p>";
- ret += " </div>";
- ret += " <p>The <span class='index-inst' title='fictional tag";
- ret += " sequence'>fictional tag sequence</span> is:</p>";
- ret += " <pre> <P>";
- ret += " </pre>";
- ret += " <p>Note that the <code>::first-letter</code> pseudo-element tags abut";
- ret += " block element.</p></div>";
- ret += " <p>In order to achieve traditional drop caps formatting, user agents";
- ret += " glyph outline may be taken into account when formatting.</p>";
- ret += " <p>Punctuation (i.e, characters defined in Unicode in the 'open' (Ps),";
- ret += " be included. <a href='#refsUNICODE'>[UNICODE]</a></p>";
- ret += " <div class='figure'>";
- ret += " <p><img src='' alt='Quotes that precede the";
- ret += " first letter should be included.'></p>";
- ret += " </div>";
- ret += " <p>The <code>::first-letter</code> also applies if the first letter is";
- ret += " money.'</p>";
- ret += " <p>In CSS, the <code>::first-letter</code> pseudo-element applies to";
- ret += " elements. <span class='note'>A future version of this specification";
- ret += " types.</span></p>";
- ret += " <p>The <code>::first-letter</code> pseudo-element can be used with all";
- ret += " the element, even if that first text is in a descendant.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>The fictional tag sequence for this HTMLfragment:";
- ret += " </p><pre><div>";
- ret += " <p>The first text.</pre>";
- ret += " <p>is:";
- ret += " </p><pre><div>";
- ret += " <p><div::first-letter><p::first-letter>T</...></...>he first text.</pre>";
- ret += " </div>";
- ret += " <p>The first letter of a table-cell or inline-block cannot be the";
- ret += " first letter of an ancestor element. Thus, in <code><DIV><P";
- ret += " etcetera</DIV></code> the first letter of the <code>div</code> is";
- ret += " letter 'H'. In fact, the <code>div</code> doesn't have a first letter.";
- ret += " </p><p>The first letter must occur on the <a href='#first-formatted-line'>first formatted line.</a> For example, in";
- ret += " this fragment: <code><p><br>First...</code> the first line";
- ret += " doesn't contain any letters and <code>::first-letter</code> doesn't";
- ret += " match anything (assuming the default style for <code>br</code> in HTML";
- ret += " </p><p>In CSS, if an element is a list item ('display: list-item'), the";
- ret += " <code>::first-letter</code> applies to the first letter in the";
- ret += " <code>::first-letter</code> on list items with 'list-style-position:";
- ret += " inside'. If an element has <code>::before</code> or";
- ret += " <code>::after</code> content, the <code>::first-letter</code> applies";
- ret += " to the first letter of the element <em>including</em> that content.";
- ret += " </p><div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p>After the rule 'p::before {content: 'Note: '}', the selector";
- ret += " 'p::first-letter' matches the 'N' of 'Note'.</p>";
- ret += " </div>";
- ret += " <p>Some languages may have specific rules about how to treat certain";
- ret += " considered within the <code>::first-letter</code> pseudo-element.";
- ret += " </p><p>If the letters that would form the ::first-letter are not in the";
- ret += " same element, such as ''T' in <code><p>'<em>T...</code>, the UA";
- ret += " both elements, or simply not create a pseudo-element.</p>";
- ret += " <p>Similarly, if the first letter(s) of the block are not at the start";
- ret += " </p><div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <p><a name='overlapping-example'>The following example</a> illustrates";
- ret += " paragraph will be 'red'.</p>";
- ret += " <pre>p { color: red; font-size: 12pt }";
- ret += " <P>Some text that ends up on two lines</P></pre>";
- ret += " <p>Assuming that a line break will occur before the word 'ends', the";
- ret += " <span class='index-inst' title='fictional tag sequence'>fictional tag";
- ret += " sequence</span> for this fragment might be:</p>";
- ret += " <pre><P>";
- ret += " </P></pre>";
- ret += " <p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>";
- ret += " element. Properties set on <code>::first-line</code> are inherited by";
- ret += " <code>::first-letter</code>, but are overridden if the same property is";
- ret += " <code>::first-letter</code>.</p>";
- ret += " </div>";
- ret += " <h4><a name='UIfragments'>7.3.</a> <a name='selection'>The ::selection";
- ret += " pseudo-element</a></h4>";
- ret += " <p>The <code>::selection</code> pseudo-element applies to the portion";
- ret += " field. This pseudo-element should not be confused with the <code><a href='#checked'>:checked</a></code> pseudo-class (which used to be";
- ret += " named <code>:selected</code>)";
- ret += " </p><p>Although the <code>::selection</code> pseudo-element is dynamic in";
- ret += " <a href='#refsCSS21'>[CSS21]</a>) which was originally rendered to a";
- ret += " <code>::selection</code> state to that other medium, and have all the";
- ret += " required — UAs may omit the <code>::selection</code>";
- ret += " </p><p>These are the CSS properties that apply to <code>::selection</code>";
- ret += " <code>::selection</code> may be ignored.";
- ret += " </p><h4><a name='gen-content'>7.4. The ::before and ::after pseudo-elements</a></h4>";
- ret += " <p>The <code>::before</code> and <code>::after</code> pseudo-elements";
- ret += " content. They are explained in CSS 2.1 <a href='#refsCSS21'>[CSS21]</a>.</p>";
- ret += " <p>When the <code>::first-letter</code> and <code>::first-line</code>";
- ret += " pseudo-elements are combined with <code>::before</code> and";
- ret += " <code>::after</code>, they apply to the first letter or line of the";
- ret += " element including the inserted text.</p>";
- ret += " <h2><a name='combinators'>8. Combinators</a></h2>";
- ret += " <h3><a name='descendant-combinators'>8.1. Descendant combinator</a></h3>";
- ret += " <p>At times, authors may want selectors to describe an element that is";
- ret += " <code>EM</code> element that is contained within an <code>H1</code>";
- ret += " descendant combinator is <a href='#whitespace'>white space</a> that";
- ret += " separates two sequences of simple selectors. A selector of the form";
- ret += " '<code>A B</code>' represents an element <code>B</code> that is an";
- ret += " arbitrary descendant of some ancestor element <code>A</code>.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>For example, consider the following selector:</p>";
- ret += " <pre>h1 em</pre>";
- ret += " <p>It represents an <code>em</code> element being the descendant of";
- ret += " an <code>h1</code> element. It is a correct and valid, but partial,";
- ret += " description of the following fragment:</p>";
- ret += " <pre><h1>This <span class='myclass'>headline";
- ret += " is <em>very</em> important</span></h1></pre>";
- ret += " <p>The following selector:</p>";
- ret += " <pre>div * p</pre>";
- ret += " <p>represents a <code>p</code> element that is a grandchild or later";
- ret += " descendant of a <code>div</code> element. Note the whitespace on";
- ret += " of the P.</p>";
- ret += " <p>The following selector, which combines descendant combinators and";
- ret += " <a href='#attribute-selectors'>attribute selectors</a>, represents an";
- ret += " element that (1) has the <code>href</code> attribute set and (2) is";
- ret += " inside a <code>p</code> that is itself inside a <code>div</code>:</p>";
- ret += " <pre>div p *[href]</pre>";
- ret += " </div>";
- ret += " <h3><a name='child-combinators'>8.2. Child combinators</a></h3>";
- ret += " <p>A <dfn>child combinator</dfn> describes a childhood relationship";
- ret += " 'greater-than sign' (<code>></code>) character and";
- ret += " separates two sequences of simple selectors.";
- ret += " </p><div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following selector represents a <code>p</code> element that is";
- ret += " child of <code>body</code>:</p>";
- ret += " <pre>body > p</pre>";
- ret += " <p>The following example combines descendant combinators and child";
- ret += " combinators.</p>";
- ret += " <pre>div ol>li p</pre>";
- ret += " <!-- LEAVE THOSE SPACES OUT! see below -->";
- ret += " <p>It represents a <code>p</code> element that is a descendant of an";
- ret += " <code>li</code> element; the <code>li</code> element must be the";
- ret += " child of an <code>ol</code> element; the <code>ol</code> element must";
- ret += " be a descendant of a <code>div</code>. Notice that the optional white";
- ret += " space around the '>' combinator has been left out.</p>";
- ret += " </div>";
- ret += " <p>For information on selecting the first child of an element, please";
- ret += " see the section on the <code><a href='#structural-pseudos'>:first-child</a></code> pseudo-class";
- ret += " above.</p>";
- ret += " <h3><a name='sibling-combinators'>8.3. Sibling combinators</a></h3>";
- ret += " <p>There are two different sibling combinators: the adjacent sibling";
- ret += " considering adjacency of elements.</p>";
- ret += " <h4><a name='adjacent-sibling-combinators'>8.3.1. Adjacent sibling combinator</a>";
- ret += " </h4>";
- ret += " <p>The adjacent sibling combinator is made of the 'plus";
- ret += " sign' (U+002B, <code>+</code>) character that separates two";
- ret += " sequences of simple selectors. The elements represented by the two";
- ret += " represented by the second one.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <p>The following selector represents a <code>p</code> element";
- ret += " immediately following a <code>math</code> element:</p>";
- ret += " <pre>math + p</pre>";
- ret += " <p>The following selector is conceptually similar to the one in the";
- ret += " adds a constraint to the <code>h1</code> element, that it must have";
- ret += " <code>class='opener'</code>:</p>";
- ret += " <pre>h1.opener + h2</pre>";
- ret += " </div>";
- ret += " <h4><a name='general-sibling-combinators'>8.3.2. General sibling combinator</a>";
- ret += " </h4>";
- ret += " <p>The general sibling combinator is made of the 'tilde'";
- ret += " (U+007E, <code>~</code>) character that separates two sequences of";
- ret += " simple selectors. The elements represented by the two sequences share";
- ret += " represented by the second one.</p>";
- ret += " <div class='example'>";
- ret += " <p>Example:</p>";
- ret += " <pre>h1 ~ pre</pre>";
- ret += " <p>represents a <code>pre</code> element following an <code>h1</code>. It";
- ret += " is a correct and valid, but partial, description of:</p>";
- ret += " <pre><h1>Definition of the function a</h1>";
- ret += " <pre>function a(x) = 12x/13.5</pre></pre>";
- ret += " </div>";
- ret += " <h2><a name='specificity'>9. Calculating a selector's specificity</a></h2>";
- ret += " <p>A selector's specificity is calculated as follows:</p>";
- ret += " <ul>";
- ret += " <li>count the number of ID selectors in the selector (= a)</li>";
- ret += " <li>count the number of class selectors, attributes selectors, and";
- ret += " </li>";
- ret += " <li>count the number of element names in the selector (= c)</li>";
- ret += " <li>ignore pseudo-elements</li>";
- ret += " </ul>";
- ret += " <p>Selectors inside <a href='#negation'>the negation pseudo-class</a>";
- ret += " a pseudo-class.</p>";
- ret += " <p>Concatenating the three numbers a-b-c (in a number system with a";
- ret += " large base) gives the specificity.</p>";
- ret += " <div class='example'>";
- ret += " <p>Examples:</p>";
- ret += " <pre>* /* a=0 b=0 c=0 -> specificity = 0 */";
- ret += " </pre>";
- ret += " </div>";
- ret += " <p class='note'><strong>Note:</strong> the specificity of the styles";
- ret += " specified in an HTML <code>style</code> attribute is described in CSS";
- ret += " 2.1. <a href='#refsCSS21'>[CSS21]</a>.</p>";
- ret += " <h2><a name='w3cselgrammar'>10. The grammar of Selectors</a></h2>";
- ret += " <h3><a name='grammar'>10.1. Grammar</a></h3>";
- ret += " <p>The grammar below defines the syntax of Selectors. It is globally";
- ret += " shorthand notations beyond Yacc (see <a href='#refsYACC'>[YACC]</a>)";
- ret += " are used:</p>";
- ret += " <ul>";
- ret += " <li><b>*</b>: 0 or more";
- ret += " </li><li><b>+</b>: 1 or more";
- ret += " </li><li><b>?</b>: 0 or 1";
- ret += " </li><li><b>|</b>: separates alternatives";
- ret += " </li><li><b>[ ]</b>: grouping</li>";
- ret += " </ul>";
- ret += " <p>The productions are:</p>";
- ret += " <pre>selectors_group";
- ret += " ;</pre>";
- ret += " <h3><a name='lex'>10.2. Lexical scanner</a></h3>";
- ret += " <p>The following is the <a name='x3'>tokenizer</a>, written in Flex (see";
- ret += " <a href='#refsFLEX'>[FLEX]</a>) notation. The tokenizer is";
- ret += " case-insensitive.</p>";
- ret += " <p>The two occurrences of '\377' represent the highest character";
- ret += " possible code point in Unicode/ISO-10646. <a href='#refsUNICODE'>[UNICODE]</a></p>";
- ret += " <pre>%option case-insensitive";
- ret += " . return *yytext;</pre>";
- ret += " <h2><a name='downlevel'>11. Namespaces and down-level clients</a></h2>";
- ret += " <p>An important issue is the interaction of CSS selectors with XML";
- ret += " to construct a CSS style sheet which will properly match selectors in";
- ret += " is possible to construct a style sheet in which selectors would match";
- ret += " elements and attributes correctly.</p>";
- ret += " <p>It should be noted that a down-level CSS client will (if it";
- ret += " <code>@namespace</code> at-rules, as well as all style rules that make";
- ret += " use of namespace qualified element type or attribute selectors. The";
- ret += " than possibly match them incorrectly.</p>";
- ret += " <p>The use of default namespaces in CSS makes it possible to write";
- ret += " element type selectors that will function in both namespace aware CSS";
- ret += " down-level clients may incorrectly match selectors against XML";
- ret += " elements in other namespaces.</p>";
- ret += " <p>The following are scenarios and examples in which it is possible to";
- ret += " that do not implement this proposal.</p>";
- ret += " <ol>";
- ret += " <li>";
- ret += " <p>The XML document does not use namespaces.</p>";
- ret += " <ul>";
- ret += " <li>In this case, it is obviously not necessary to declare or use";
- ret += " attribute selectors will function adequately in a down-level";
- ret += " </li>";
- ret += " <li>In a CSS namespace aware client, the default behavior of";
- ret += " element selectors matching without regard to namespace will";
- ret += " present. However, the use of specific element type selectors";
- ret += " match only elements that have no namespace ('<code>|name</code>')";
- ret += " will guarantee that selectors will match only XML elements that";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li>";
- ret += " <li>";
- ret += " <p>The XML document defines a single, default namespace used";
- ret += " names.</p>";
- ret += " <ul>";
- ret += " <li>In this case, a down-level client will function as if";
- ret += " element type and attribute selectors will match against all";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li>";
- ret += " <li>";
- ret += " <p>The XML document does <b>not</b> use a default namespace, all";
- ret += " to the same URI).</p>";
- ret += " <ul>";
- ret += " <li>In this case, the down-level client will view and match";
- ret += " element type and attribute selectors based on their fully";
- ret += " qualified name, not the local part as outlined in the <a href='#typenmsp'>Type selectors and Namespaces</a>";
- ret += " selectors may be declared using an escaped colon";
- ret += " '<code>\\:</code>'";
- ret += " '<code>html\\:h1</code>' will match";
- ret += " <code><html:h1></code>. Selectors using the qualified name";
- ret += " </li>";
- ret += " <li>Note that selectors declared in this fashion will";
- ret += " <em>only</em> match in down-level clients. A CSS namespace aware";
- ret += " client will match element type and attribute selectors based on";
- ret += " the name's local part. Selectors declared with the fully";
- ret += " </li>";
- ret += " </ul>";
- ret += " </li>";
- ret += " </ol>";
- ret += " <p>In other scenarios: when the namespace prefixes used in the XML are";
- ret += " <em>different</em> namespace URIs within the same document, or in";
- ret += " a CSS and XML namespace aware client.</p>";
- ret += " <h2><a name='profiling'>12. Profiles</a></h2>";
- ret += " <p>Each specification using Selectors must define the subset of W3C";
- ret += " Selectors it allows and excludes, and describe the local meaning of";
- ret += " all the components of that subset.</p>";
- ret += " <p>Non normative examples:";
- ret += " </p><div class='profile'>";
- ret += " <table class='tprofile'>";
- ret += " <tbody>";
- ret += " <tr>";
- ret += " <th class='title' colspan='2'>Selectors profile</th>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Specification</th>";
- ret += " <td>CSS level 1</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Accepts</th>";
- ret += " <td>type selectors<br>class selectors<br>ID selectors<br>:link,";
- ret += " :visited and :active pseudo-classes<br>descendant combinator";
- ret += " <br>::first-line and ::first-letter pseudo-elements";
- ret += " </td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Excludes</th>";
- ret += " <td>";
- ret += " <p>universal selector<br>attribute selectors<br>:hover and";
- ret += " pseudo-classes<br>:target pseudo-class<br>:lang()";
- ret += " pseudo-class<br>all UI";
- ret += " element states pseudo-classes<br>all structural";
- ret += " pseudo-classes<br>negation pseudo-class<br>all";
- ret += " UI element fragments pseudo-elements<br>::before and ::after";
- ret += " pseudo-elements<br>child combinators<br>sibling combinators";
- ret += " </p><p>namespaces</p></td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Extra constraints</th>";
- ret += " <td>only one class selector allowed per sequence of simple";
- ret += " selectors";
- ret += " </td>";
- ret += " </tr>";
- ret += " </tbody>";
- ret += " </table>";
- ret += " <br><br>";
- ret += " <table class='tprofile'>";
- ret += " <tbody>";
- ret += " <tr>";
- ret += " <th class='title' colspan='2'>Selectors profile</th>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Specification</th>";
- ret += " <td>CSS level 2</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Accepts</th>";
- ret += " <td>type selectors<br>universal selector<br>attribute presence and";
- ret += " values selectors<br>class selectors<br>ID selectors<br>:link,";
- ret += " <br>descendant combinator<br>child combinator<br>adjacent";
- ret += " combinator<br>::first-line and ::first-letter";
- ret += " pseudo-elements<br>::before";
- ret += " </td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Excludes</th>";
- ret += " <td>";
- ret += " <p>content selectors<br>substring matching attribute";
- ret += " selectors<br>:target pseudo-classes<br>all UI element";
- ret += " states pseudo-classes<br>all structural pseudo-classes other";
- ret += " than :first-child<br>negation pseudo-class<br>all UI element";
- ret += " fragments pseudo-elements<br>general sibling combinators";
- ret += " </p><p>namespaces</p></td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Extra constraints</th>";
- ret += " <td>more than one class selector per sequence of simple selectors";
- ret += " </td>";
- ret += " </tr>";
- ret += " </tbody>";
- ret += " </table>";
- ret += " <p>In CSS, selectors express pattern matching rules that determine which";
- ret += " </p><p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>";
- ret += " with attribute <code>name</code> set inside a section 1 header";
- ret += " <code>h1</code>:";
- ret += " </p><pre>h1 a[name]</pre>";
- ret += " <p>All CSS declarations attached to such a selector are applied to elements";
- ret += " matching it.</p></div>";
- ret += " <div class='profile'>";
- ret += " <table class='tprofile'>";
- ret += " <tbody>";
- ret += " <tr>";
- ret += " <th class='title' colspan='2'>Selectors profile</th>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Specification</th>";
- ret += " <td>STTS 3</td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Accepts</th>";
- ret += " <td>";
- ret += " <p>type selectors<br>universal selectors<br>attribute";
- ret += " selectors<br>class";
- ret += " selectors<br>ID selectors<br>all structural";
- ret += " pseudo-classes<br>";
- ret += " </p><p>namespaces</p></td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Excludes</th>";
- ret += " <td>non-accepted pseudo-classes<br>pseudo-elements<br></td>";
- ret += " </tr>";
- ret += " <tr>";
- ret += " <th>Extra constraints</th>";
- ret += " <td>some selectors and combinators are not allowed in fragment";
- ret += " </td>";
- ret += " </tr>";
- ret += " </tbody>";
- ret += " </table>";
- ret += " <p>Selectors can be used in STTS 3 in two different";
- ret += " </p><ol>";
- ret += " <li>a selection mechanism equivalent to CSS selection mechanism:";
- ret += " </li><li>fragment descriptions that appear on the right side of declarations.";
- ret += " </li>";
- ret += " </ol>";
- ret += " </div>";
- ret += " <h2><a name='Conformance'></a>13. Conformance and requirements</h2>";
- ret += " <p>This section defines conformance with the present specification only.";
- ret += " </p><p>The inability of a user agent to implement part of this specification due to";
- ret += " </p><p>All specifications reusing Selectors must contain a <a href='#profiling'>Profile</a> listing the";
- ret += " subset of Selectors it accepts or excludes, and describing the constraints";
- ret += " </p><p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a";
- ret += " </p><p>User agents must observe the rules for handling parsing errors:";
- ret += " </p><ul>";
- ret += " <li>a simple selector containing an undeclared namespace prefix is invalid";
- ret += " </li>";
- ret += " <li>a selector containing an invalid simple selector, an invalid combinator";
- ret += " </li>";
- ret += " <li>a group of selectors containing an invalid selector is invalid.</li>";
- ret += " </ul>";
- ret += " <p>Specifications reusing Selectors must define how to handle parsing";
- ret += " used is dropped.)</p>";
- ret += " <!-- Apparently all these references are out of date:";
- ret += " <p>Implementations of this specification must behave as";
- ret += " 'recipients of text data' as defined by <a href='#refsCWWW'>[CWWW]</a>";
- ret += " when parsing selectors and attempting matches. (In particular,";
- ret += " <a href='#refsCWWW'>[CWWW]</a> and <a";
- ret += " href='#refsUNICODE'>[UNICODE]</a> and apply to implementations of this";
- ret += " specification.</p>-->";
- ret += " <h2><a name='Tests'></a>14. Tests</h2>";
- ret += " <p>This specification has <a href='http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/'>a test";
- ret += " suite</a> allowing user agents to verify their basic conformance to";
- ret += " and does not cover all possible combined cases of Selectors.</p>";
- ret += " <h2><a name='ACKS'></a>15. Acknowledgements</h2>";
- ret += " <p>The CSS working group would like to thank everyone who has sent";
- ret += " comments on this specification over the years.</p>";
- ret += " <p>The working group would like to extend special thanks to Donna";
- ret += " the final editorial review.</p>";
- ret += " <h2><a name='references'>16. References</a></h2>";
- ret += " <dl class='refs'>";
- ret += " <dt>[CSS1]";
- ret += " </dt><dd><a name='refsCSS1'></a> Bert Bos, Håkon Wium Lie; '<cite>Cascading";
- ret += " Style Sheets, level 1</cite>', W3C Recommendation, 17 Dec 1996, revised";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/REC-CSS1'>http://www.w3.org/TR/REC-CSS1</a></code>)";
- ret += " </dd><dt>[CSS21]";
- ret += " </dt><dd><a name='refsCSS21'></a> Bert Bos, Tantek Çelik, Ian Hickson, Håkon";
- ret += " Wium Lie, editors; '<cite>Cascading Style Sheets, level 2 revision";
- ret += " 1</cite>', W3C Working Draft, 13 June 2005";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/CSS21'>http://www.w3.org/TR/CSS21</a></code>)";
- ret += " </dd><dt>[CWWW]";
- ret += " </dt><dd><a name='refsCWWW'></a> Martin J. Dürst, François Yergeau,";
- ret += " Misha Wolf, Asmus Freytag, Tex Texin, editors; '<cite>Character Model";
- ret += " for the World Wide Web</cite>', W3C Recommendation, 15 February 2005";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/charmod/'>http://www.w3.org/TR/charmod/</a></code>)";
- ret += " </dd><dt>[FLEX]";
- ret += " </dt><dd><a name='refsFLEX'></a> '<cite>Flex: The Lexical Scanner";
- ret += " Generator</cite>', Version 2.3.7, ISBN 1882114213";
- ret += " </dd><dt>[HTML4]";
- ret += " </dt><dd><a name='refsHTML4'></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs,";
- ret += " editors; '<cite>HTML 4.01 Specification</cite>', W3C Recommendation, 24";
- ret += " </dd><dd>";
- ret += " (<a href='http://www.w3.org/TR/html4/'><code>http://www.w3.org/TR/html4/</code></a>)";
- ret += " </dd><dt>[MATH]";
- ret += " </dt><dd><a name='refsMATH'></a> Patrick Ion, Robert Miner, editors; '<cite>Mathematical";
- ret += " Markup Language (MathML) 1.01</cite>', W3C Recommendation, revision of 7";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/REC-MathML/'>http://www.w3.org/TR/REC-MathML/</a></code>)";
- ret += " </dd><dt>[RFC3066]";
- ret += " </dt><dd><a name='refsRFC3066'></a> H. Alvestrand; '<cite>Tags for the";
- ret += " Identification of Languages</cite>', Request for Comments 3066, January";
- ret += " </dd><dd>(<a href='http://www.ietf.org/rfc/rfc3066.txt'><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)";
- ret += " </dd><dt>[STTS]";
- ret += " </dt><dd><a name='refsSTTS'></a> Daniel Glazman; '<cite>Simple Tree Transformation";
- ret += " Sheets 3</cite>', Electricité de France, submission to the W3C,";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/NOTE-STTS3'>http://www.w3.org/TR/NOTE-STTS3</a></code>)";
- ret += " </dd><dt>[SVG]";
- ret += " </dt><dd><a name='refsSVG'></a> Jon Ferraiolo, 藤沢 淳, Dean";
- ret += " Jackson, editors; '<cite>Scalable Vector Graphics (SVG) 1.1";
- ret += " Specification</cite>', W3C Recommendation, 14 January 2003";
- ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/SVG/'>http://www.w3.org/TR/SVG/</a></code>)";
- ret += " </dd><dt>[UNICODE]</dt>";
- ret += " <dd><a name='refsUNICODE'></a> <cite><a href='http://www.unicode.org/versions/Unicode4.1.0/'>The Unicode";
- ret += " Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA,";
- ret += " Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href='http://www.unicode.org/versions/Unicode4.0.1/'>Unicode";
- ret += " 4.0.1</a> and <a href='http://www.unicode.org/versions/Unicode4.1.0/'>Unicode";
- ret += " 4.1.0</a>.";
- ret += " </dd><dd>(<code><a href='http://www.unicode.org/versions/'>http://www.unicode.org/versions/</a></code>)";
- ret += " </dd>";
- ret += " <dt>[XML10]";
- ret += " </dt><dd><a name='refsXML10'></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen,";
- ret += " Eve Maler, François Yergeau, editors; '<cite>Extensible Markup";
- ret += " Language (XML) 1.0 (Third Edition)</cite>', W3C Recommendation, 4";
- ret += " </dd><dd>(<a href='http://www.w3.org/TR/REC-xml/'><code>http://www.w3.org/TR/REC-xml/</code></a>)";
- ret += " </dd><dt>[XMLNAMES]";
- ret += " </dt><dd><a name='refsXMLNAMES'></a> Tim Bray, Dave Hollander, Andrew Layman,";
- ret += " editors; '<cite>Namespaces in XML</cite>', W3C Recommendation, 14";
- ret += " </dd><dd>(<a href='http://www.w3.org/TR/REC-xml-names/'><code>http://www.w3.org/TR/REC-xml-names/</code></a>)";
- ret += " </dd><dt>[YACC]";
- ret += " </dt><dd><a name='refsYACC'></a> S. C. Johnson; '<cite>YACC — Yet another";
- ret += " compiler compiler</cite>', Technical Report, Murray Hill, 1975";
- ret += " </dd></dl>'; </div>";
- ret += " <input name='n' value='v1' type='radio'>1";
- ret += " <input name='n' value='v2' checked='checked' type='radio'>2";
- ret += "</body></html>";
- return ret;
- }
-
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.body;
+import static com.google.gwt.query.client.GQuery.document;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;
+import com.google.gwt.query.client.impl.SelectorEngineImpl;
+import com.google.gwt.query.client.impl.SelectorEngineNative;
+import com.google.gwt.query.client.impl.SelectorEngineSizzle;
+import com.google.gwt.query.client.impl.research.SelectorEngineJS;
+import com.google.gwt.query.client.impl.research.SelectorEngineSizzleGwt;
+import com.google.gwt.query.client.impl.research.SelectorEngineXPath;
+import com.google.gwt.query.client.js.JsUtils;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test for selectors
+ */
+public class GQuerySelectorsTestGwt extends GWTTestCase {
+
+ boolean runSlow = false;
+
+ protected interface AllSelectors extends Selectors {
+ @Selector("h1[id]:contains(Selectors)")
+ NodeList<Element> h1IdContainsSelectors();
+ @Selector("tr:first")
+ NodeList<Element> trFirst();
+ @Selector("tr:last")
+ NodeList<Element> trLast();
+ // @Selector("div[class!='madeup']")
+ // NodeList<Element> divWithClassNotContainsMadeup();
+ // @Selector("div, p a")
+ // NodeList<Element> divCommaPA();
+ @Selector("p:contains(selectors)")
+ NodeList<Element> pContainsSelectors();
+ @Selector("a[href][lang][class]")
+ NodeList<Element> aHrefLangClass();
+ @Selector("*:checked")
+ NodeList<Element> allChecked();
+ @Selector("body")
+ NodeList<Element> body();
+ @Selector("body div")
+ NodeList<Element> bodyDiv();
+ @Selector("div .example")
+ NodeList<Element> divExample();
+ @Selector("div > div")
+ NodeList<Element> divGtP();
+ @Selector("div:not(.example)")
+ NodeList<Element> divNotExample();
+ @Selector("div p")
+ NodeList<Element> divP();
+ @Selector("div p a")
+ NodeList<Element> divPA();
+ @Selector("div + p")
+ NodeList<Element> divPlusP();
+ @Selector("div[class^=exa][class$=mple]")
+ NodeList<Element> divPrefixExaSuffixMple();
+ @Selector("div #title")
+ NodeList<Element> divSpaceTitle();
+ @Selector("div ~ p")
+ NodeList<Element> divTildeP();
+ @Selector("div[class]")
+ NodeList<Element> divWithClass();
+ @Selector("div[class~=dialog]")
+ NodeList<Element> divWithClassContainsDialog();
+ @Selector("div[class*=e]")
+ NodeList<Element> divWithClassContainsE();
+ @Selector("div[class=example]")
+ NodeList<Element> divWithClassExample();
+ @Selector("div[class~=dialog]")
+ NodeList<Element> divWithClassListContainsDialog();
+ @Selector("div[class^=exa]")
+ NodeList<Element> divWithClassPrefixExa();
+ @Selector("div[class$=mple]")
+ NodeList<Element> divWithClassSuffixMple();
+ @Selector("p:first-child")
+ NodeList<Element> firstChild();
+ @Selector("h1#title")
+ NodeList<Element> h1Title();
+ @Selector("h1#title + em > span")
+ NodeList<Element> h1TitlePlusEmGtSpan();
+ @Selector("p:last-child")
+ NodeList<Element> lastChild();
+ @Selector(".note")
+ NodeList<Element> note();
+ @Selector("p:nth-child(n)")
+ NodeList<Element> nthChild();
+ @Selector("p:nth-child(2n)")
+ NodeList<Element> nThChild2n();
+ @Selector("p:nth-child(2n+1)")
+ NodeList<Element> nThChild2nPlus1();
+ @Selector("p:nth-child(even)")
+ NodeList<Element> nThChildEven();
+ @Selector("p:nth-child(odd)")
+ NodeList<Element> nThChildOdd();
+ @Selector("p:only-child")
+ NodeList<Element> onlyChild();
+ @Selector("#title")
+ NodeList<Element> title();
+ @Selector("#title,h1#title")
+ NodeList<Element> titleAndh1Title();
+ @Selector("ul .tocline2")
+ NodeList<Element> ulTocline2();
+ @Selector("ul.toc li.tocline2")
+ NodeList<Element> ulTocLiTocLine2();
+ }
+
+ protected interface TestSelectors extends Selectors {
+ @Selector("*:checked")
+ GQuery allChecked();
+ @Selector("*:checked")
+ GQuery allChecked(Node n);
+ @Selector(".branchA")
+ GQuery branchA();
+ @Selector(".branchA")
+ GQuery branchA(Node n);
+ @Selector(".branchA .target")
+ GQuery branchAtarget();
+ @Selector(".branchA .target")
+ GQuery branchAtarget(Node n);
+ @Selector(".branchB")
+ GQuery branchB();
+ @Selector(".branchB")
+ GQuery branchB(Node n);
+
+ @Selector("div .target")
+ GQuery divTarget();
+ @Selector("div .target")
+ GQuery divTarget(Node n);
+ @Selector(".target")
+ GQuery target();
+ @Selector(".target")
+ GQuery target(Node n);
+ }
+
+ static Element e = null;
+ static HTML testPanel = null;
+
+ private static native boolean hasNativeSelector() /*-{
+ return !!(document.querySelectorAll && /native/.test(String(document.querySelectorAll)));
+ }-*/;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void gwtTearDown() {
+ $(e).remove();
+ e = null;
+ }
+
+ public void gwtSetUp() {
+ if (e == null) {
+ testPanel = new HTML();
+ RootPanel.get().add(testPanel);
+ e = testPanel.getElement();
+ e.setId("select-tst");
+ } else {
+ e.setInnerHTML("");
+ }
+ }
+
+ public void testJQueryPseudoselectors() {
+ $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A Text</td><td width=50%><a></a><p id=a></p><p id=b style='display: none'><span id=c>s</span></p></td></tr></table>");
+ assertEquals(9, $("* ", e).size());
+ assertEquals(1, $("p:hidden ", e).size());
+ assertEquals(2, $("td:visible ", e).size());
+ $(e).html("<input type='checkbox' id='cb' name='cb' value='1' /><input type='radio' id='cb' name='cb' value='1' />");
+ assertEquals(1, $("input:checkbox ", e).size());
+ assertEquals(1, $(":radio ", e).size());
+ assertEquals(2, $("*:radio, *:checkbox", e).size());
+ }
+
+ public void testCompiledSelectors() {
+ final AllSelectors sel = GWT.create(AllSelectors.class);
+ $(e).html(getTestContent());
+
+ // TODO: fix these selectors
+ // sel.divWithClassNotContainsMadeup().getLength()
+ // sel.divCommaPA().getLength()
+
+ // assertArrayContains(sel.title().getLength(), 1);
+ assertEquals(1, sel.body().getLength());
+ assertArrayContains(sel.bodyDiv().getLength(), 53, 55);
+ sel.setRoot(e);
+ assertArrayContains(sel.trFirst().getLength(), 5);
+ assertArrayContains(sel.trLast().getLength(), 5);
+ assertArrayContains(sel.pContainsSelectors().getLength(), 54);
+ assertArrayContains(sel.h1IdContainsSelectors().getLength(), 1);
+ assertArrayContains(sel.aHrefLangClass().getLength(), 0, 1);
+ assertArrayContains(sel.allChecked().getLength(), 1);
+ assertArrayContains(sel.divExample().getLength(), 43);
+ assertArrayContains(sel.divGtP().getLength(), 51, 52);
+ assertArrayContains(sel.divNotExample().getLength(), 9, 10);
+ assertArrayContains(sel.divP().getLength(), 324);
+ assertArrayContains(sel.divPA().getLength(), 84);
+ assertArrayContains(sel.divPlusP().getLength(), 22);
+ assertArrayContains(sel.divPrefixExaSuffixMple().getLength(), 43);
+ assertArrayContains(sel.divSpaceTitle().getLength(), 1);
+ assertArrayContains(sel.divTildeP().getLength(), 183);
+ assertArrayContains(sel.divWithClass().getLength(), 51, 52);
+ assertArrayContains(sel.divWithClassContainsDialog().getLength(), 1);
+ assertArrayContains(sel.divWithClassContainsE().getLength(), 50);
+ assertArrayContains(sel.divWithClassExample().getLength(), 43);
+ assertArrayContains(sel.divWithClassListContainsDialog().getLength(), 1);
+ assertArrayContains(sel.divWithClassPrefixExa().getLength(), 43);
+ assertArrayContains(sel.divWithClassSuffixMple().getLength(), 43);
+ assertArrayContains(sel.firstChild().getLength(), 54);
+ assertArrayContains(sel.h1Title().getLength(), 1);
+ assertArrayContains(sel.h1TitlePlusEmGtSpan().getLength(), 1);
+ assertArrayContains(sel.lastChild().getLength(), 19);
+ assertArrayContains(sel.note().getLength(), 14);
+ assertArrayContains(sel.nthChild().getLength(), 324);
+ assertArrayContains(sel.nThChild2n().getLength(), 159);
+ assertArrayContains(sel.nThChild2nPlus1().getLength(), 165);
+ assertArrayContains(sel.nThChildEven().getLength(), 159);
+ assertArrayContains(sel.nThChildOdd().getLength(), 165);
+ assertArrayContains(sel.onlyChild().getLength(), 3);
+ assertArrayContains(sel.titleAndh1Title().getLength(), 0, 1, 2); //FIXME
+ assertArrayContains(sel.ulTocline2().getLength(), 12);
+ assertArrayContains(sel.ulTocLiTocLine2().getLength(), 12);
+ }
+
+ public void testIssue12() {
+ $(e).html("<table><tr><td><p myCustomAttr='whatever'><input disabled='disabled' type='radio' name='wantedName' value='v1'>1</input></p><input type='radio' name='n' value='v2' checked='checked'>2</input></td><td><button myCustomAttr='val'>Click</button></tr><td></table>");
+ executeSelectInAllImplementations(":checked", e, 1);
+ executeSelectInAllImplementations(":disabled", e, 1);
+ executeSelectInAllImplementations("input:enabled", e, 1);
+ executeSelectInAllImplementations("[myCustomAttr]", e, 2);
+ executeSelectInAllImplementations("*[myCustomAttr]", e, 2);
+ executeSelectInAllImplementations("input[name=wantedName]", e, 1);
+ executeSelectInAllImplementations("input[name='wantedName']", e, 1);
+ executeSelectInAllImplementations("input[name=\"wantedName\"]", e, 1);
+ }
+
+ public void testSelectElementsInsideContext() {
+ $(e).html("<spam><p>s</p></spam>");
+ GQuery q = $("spam", e);
+ // TODO: in XPath engine returns 2 when it should return 1
+ executeSelectInAllImplementations("*", q.get(0), 1, 2);
+ }
+
+ public void testSelectorEngineCssToXpath() {
+ SelectorEngineImpl selEng = new SelectorEngineCssToXPath();
+ executeSelectorEngineTests(selEng);
+ }
+
+ public void testSelectorEngineDomAssistant() {
+ if (!runSlow) return;
+ // This test runs very slow in chrome
+ SelectorEngineImpl selEng = new SelectorEngineJS();
+ executeSelectorEngineTests(selEng);
+ }
+
+ public void testSelectorEngineNative() {
+ SelectorEngineImpl selEng = new SelectorEngineNative();
+ if (hasNativeSelector()) {
+ executeSelectorEngineTests(selEng);
+ }
+ }
+
+ public void testSelectorEngineSizzle() {
+ SelectorEngineImpl selEng = new SelectorEngineSizzle();
+ executeSelectorEngineTests(selEng);
+ }
+
+ public void testSelectorEngineSizzleGwt() {
+ if (!runSlow) return;
+ SelectorEngineImpl selEng = new SelectorEngineSizzleGwt();
+ executeSelectorEngineTests(selEng);
+ }
+
+ public void testSelectorEngineXpath() {
+ SelectorEngineImpl selEng = new SelectorEngineXPath();
+ executeSelectorEngineTests(selEng);
+ }
+
+ public void testSelectorsGeneratorNative() {
+ $(e).html(
+ "<input type='radio' name='n' value='v1'>1</input>"
+ + "<input type='radio' name='n' value='v2' checked='checked'>2</input>");
+
+ TestSelectors selectors = GWT.create(TestSelectors.class);
+ assertEquals(1, selectors.allChecked().size());
+ }
+
+ public void testSelectorsInIframe() {
+ $(e).html("<iframe name='miframe' id='miframe' src=\"javascript:''\">");
+ Element d = $("#miframe").contents().empty().get(0);
+ assertNotNull(d);
+
+ $(d).html(
+ "<div class='branchA'><div class='target'>branchA target</div></div>"
+ + "<div class='branchB'><div class='target'>branchB target</div></div>");
+
+
+ executeSelectInAllImplementations(".branchA .target", d, 1, 2); //FIXME:
+ executeSelectInAllImplementations(".branchA .target", body, 0);
+ executeSelectInAllImplementations("div .target", d, 2);
+ executeSelectInAllImplementations("div .target", body, 0);
+
+ TestSelectors selectors = GWT.create(TestSelectors.class);
+ assertEquals(1, selectors.branchAtarget(d).length());
+ assertEquals(0, selectors.branchAtarget().length());
+ assertEquals(2, selectors.divTarget(d).length());
+ assertEquals(0, selectors.divTarget().length());
+
+ }
+
+ public void testSelectorsWithContext() {
+ $(e).append(
+ "<div class='branchA'><div class='target'>branchA target</div></div>"
+ + "<div class='branchB'><div class='target'>branchB target</div></div>");
+
+ TestSelectors selectors = GWT.create(TestSelectors.class);
+
+ assertEquals(2, selectors.target().length());
+ Element branchA = selectors.branchA().get(0);
+ Element branchB = selectors.branchB().get(0);
+ assertNotNull(selectors.branchA().get(0));
+ assertNotNull(selectors.branchB().get(0));
+
+ assertEquals(2, selectors.target(body).length());
+ branchA = selectors.branchA(body).get(0);
+ branchB = selectors.branchB(body).get(0);
+ assertNotNull(branchA);
+ assertNotNull(branchB);
+ assertEquals("branchA target", selectors.target(branchA).text());
+ assertEquals("branchB target", selectors.target(branchB).text());
+
+ selectors.setRoot(branchA);
+ assertEquals(1, selectors.target().length());
+ assertEquals("branchA target", selectors.target().text());
+
+ selectors.setRoot(branchB);
+ assertEquals(1, selectors.target().length());
+ assertEquals("branchB target", selectors.target().text());
+ }
+
+ public void testUnique() {
+ SelectorEngineImpl selSizz = new SelectorEngineSizzleGwt();
+ $(e).html(getTestContent());
+
+ JsArray<Element> a;
+ a = selSizz.select("p", e).cast();
+ int n = a.length();
+ assertTrue(n > 300);
+ for (int i=0; i<n; i++) {
+ a.push(a.get(i));
+ }
+ assertEquals(n * 2 , a.length());
+ a = JsUtils.unique(a);
+ assertEquals(n, a.length());
+ }
+
+ private void assertArrayContains(Object result, Object... array) {
+ assertArrayContains("", result, array);
+ }
+
+ private void assertArrayContains(String message, Object result, Object... array) {
+ String values = "";
+ boolean done = false;
+ for (Object o : array) {
+ values += o.toString() + " ";
+ if (result.equals(o)) {
+ done = true;
+ }
+ }
+ message = message + ", value (" + result + ") not found in: " + values;
+ assertTrue(message, done);
+ }
+
+ private void executeSelectInAllImplementations(String selector, Element elem, Object... array) {
+ SelectorEngineImpl selSizz = new SelectorEngineSizzle();
+ SelectorEngineImpl selSizzGwt = new SelectorEngineSizzleGwt();
+ SelectorEngineImpl selJS = new SelectorEngineJS();
+ SelectorEngineImpl selXpath = new SelectorEngineXPath();
+ SelectorEngineImpl selC2X = new SelectorEngineCssToXPath();
+ SelectorEngineImpl selNative = new SelectorEngineNative();
+ assertArrayContains(selector, selSizz.select(selector, elem).getLength(), array);
+ assertArrayContains(selector, selSizzGwt.select(selector, elem).getLength(), array);
+ assertArrayContains(selector, selJS.select(selector, elem).getLength(), array);
+ if (hasNativeSelector()) {
+ assertArrayContains(selector, selNative.select(selector, elem).getLength(), array);
+ }
+ assertArrayContains(selector, selXpath.select(selector, elem).getLength(), array);
+ assertArrayContains(selector, selC2X.select(selector, elem).getLength(), array);
+ }
+
+ private void executeSelectorEngineTests(SelectorEngineImpl selEng) {
+ $(e).html(getTestContent());
+
+ assertArrayContains(selEng.select("body", document).getLength(), 1);
+ assertArrayContains(selEng.select("body div", document).getLength(), 53, 55);
+
+ assertArrayContains(selEng.select("tr:first", e).getLength(), 0, 1, 5);
+ assertArrayContains(selEng.select("tr:last", e).getLength(), 0, 1, 5);
+ assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54);
+ assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
+ assertArrayContains(selEng.select("div[class!=madeup]", e).getLength(), 52, 53);
+ assertArrayContains(selEng.select("div, p a", e).getLength(), 136, 137, 138);
+ assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54, 55);
+ assertArrayContains(selEng.select("a[href][lang][class]", e).getLength(), 1);
+ assertArrayContains(selEng.select("*:checked", e).getLength(), 1);
+ assertArrayContains(selEng.select("div .example", e).getLength(), 43);
+ assertArrayContains(selEng.select("div > div", e).getLength(), 51, 52);
+ assertArrayContains(selEng.select("div:not(.example)", e).getLength(), 9, 10);
+ assertArrayContains(selEng.select("div p", e).getLength(), 324);
+ assertArrayContains(selEng.select("div p a", e).getLength(), 85, 84);
+ assertArrayContains(selEng.select("div + p", e).getLength(), 22);
+ assertArrayContains(selEng.select("div[class^=exa][class$=mple]", e).getLength(), 43);
+ assertArrayContains(selEng.select("div #title", e).getLength(), 1);
+ assertArrayContains(selEng.select("div ~ p", e).getLength(), 183);
+ assertArrayContains(selEng.select("div[class]", e).getLength(), 51, 52);
+ assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
+ assertArrayContains(selEng.select("div[class*=e]", e).getLength(), 50);
+ assertArrayContains(selEng.select("div[class=example]", e).getLength(), 43);
+ assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
+ assertArrayContains(selEng.select("div[class^=exa]", e).getLength(), 43);
+ assertArrayContains(selEng.select("div[class$=mple]", e).getLength(), 43);
+ assertArrayContains(selEng.select("p:first-child", e).getLength(), 54);
+ assertArrayContains(selEng.select("h1#title", e).getLength(), 1);
+ assertArrayContains(selEng.select("h1#title + em > span", e).getLength(), 1);
+ assertArrayContains(selEng.select("p:last-child", e).getLength(), 19, 22);
+ assertArrayContains(selEng.select(".note", e).getLength(), 14);
+ assertArrayContains(selEng.select("p:nth-child(n)", e).getLength(), 324);
+ assertArrayContains(selEng.select("p:nth-child(2n)", e).getLength(), 159);
+ assertArrayContains(selEng.select("p:nth-child(2n+1)", e).getLength(), 165);
+ assertArrayContains(selEng.select("p:nth-child(even)", e).getLength(), 159);
+ assertArrayContains(selEng.select("p:nth-child(odd)", e).getLength(), 165);
+ assertArrayContains(selEng.select("p:only-child", e).getLength(), 3);
+ assertArrayContains(selEng.select("#title", e).getLength(), 1);
+ // TODO: sizze_gwt returns 2
+ assertArrayContains(selEng.select("#title, h1#title", e).getLength(), 1, 2);
+ assertArrayContains(selEng.select("ul.toc li.tocline2", e).getLength(), 12);
+ assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
+ }
+
+ // This method is used to initialize a huge html String, because
+ // java 1.5 has a limitation in the size of static strings.
+ private String getTestContent() {
+ String ret = "";
+ ret += "<html><head> </head><body><div>";
+ ret += " <div class='head dialog'>";
+ ret += " <p><a href='http://www.w3.org/'><img alt='W3C' src='' height='48' width='72'></a></p>";
+ ret += " <h1 id='title'>Selectors</h1>";
+ ret += " <em><span>.</span></em>";
+ ret += " <h2>W3C Working Draft 15 December 2005</h2>";
+ ret += " <dl>";
+ ret += " <dt>This version:</dt>";
+ ret += " <dd><a href='http://www.w3.org/TR/2005/WD-css3-selectors-20051215'>";
+ ret += " http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a></dd>";
+ ret += " <dt>Latest version:";
+ ret += " </dt><dd><a href='http://www.w3.org/TR/css3-selectors'>";
+ ret += " http://www.w3.org/TR/css3-selectors</a>";
+ ret += " </dd><dt>Previous version:";
+ ret += " </dt><dd><a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113'>";
+ ret += " http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>";
+ ret += " </dd><dt><a name='editors-list'></a>Editors:";
+ ret += " </dt><dd class='vcard'><span class='fn'>Daniel Glazman</span> (Invited";
+ ret += " </dd>";
+ ret += " <dd class='vcard'><a class='url fn' href='http://www.tantek.com/' lang='tr'>Tantek Çelik</a>";
+ ret += " </dd><dd class='vcard'><a href='mailto:ian@hixie.ch' class='url fn'>Ian";
+ ret += " Hickson</a> (<span class='company'><a href='http://www.google.com/'>Google</a></span>)";
+ ret += " </dd><dd class='vcard'><span class='fn'>Peter Linss</span> (former";
+ ret += " editor, <span class='company'><a href='http://www.netscape.com/'>Netscape/AOL</a></span>)";
+ ret += " </dd><dd class='vcard'><span class='fn'>John Williams</span> (former editor, <span class='company'><a href='http://www.quark.com/'>Quark, Inc.</a></span>)";
+ ret += " </dd></dl>";
+ ret += " <p class='copyright'><a href='http://www.w3.org/Consortium/Legal/ipr-notice#Copyright'>";
+ ret += " Copyright</a> © 2005 <a href='http://www.w3.org/'><abbr title='World Wide Web Consortium'>W3C</abbr></a><sup>®</sup>";
+ ret += " (<a href='http://www.csail.mit.edu/'><abbr title='Massachusetts";
+ ret += " Institute of Technology'>MIT</abbr></a>, <a href='http://www.ercim.org/'><acronym title='European Research";
+ ret += " Consortium for Informatics and Mathematics'>ERCIM</acronym></a>, <a href='http://www.keio.ac.jp/'>Keio</a>), All Rights Reserved.";
+ ret += " <a href='http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer'>liability</a>,";
+ ret += " <a href='http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks'>trademark</a>,";
+ ret += " <a href='http://www.w3.org/Consortium/Legal/copyright-documents'>document";
+ ret += " use</a> rules apply.";
+ ret += " </p><hr title='Separator for header'>";
+ ret += " </div>";
+ ret += " <h2><a name='abstract'></a>Abstract</h2>";
+ ret += " <p><em>Selectors</em> are patterns that match against elements in a";
+ ret += " tree. Selectors have been optimized for use with HTML and XML, and";
+ ret += " are designed to be usable in performance-critical code.</p>";
+ ret += " <p><acronym title='Cascading Style Sheets'>CSS</acronym> (Cascading";
+ ret += " Style Sheets) is a language for describing the rendering of <acronym title='Hypertext Markup Language'>HTML</acronym> and <acronym title='Extensible Markup Language'>XML</acronym> documents on";
+ ret += " screen, on paper, in speech, etc. CSS uses Selectors for binding";
+ ret += " describes extensions to the selectors defined in CSS level 2. These";
+ ret += " extended selectors will be used by CSS level 3.";
+ ret += " </p><p>Selectors define the following function:</p>";
+ ret += " <pre>expression ∗ element → boolean</pre>";
+ ret += " <p>That is, given an element and a selector, this specification";
+ ret += " defines whether that element matches the selector.</p>";
+ ret += " <p>These expressions can also be used, for instance, to select a set";
+ ret += " subtree. <acronym title='Simple Tree Transformation";
+ ret += " Sheets'>STTS</acronym> (Simple Tree Transformation Sheets), a";
+ ret += " language for transforming XML trees, uses this mechanism. <a href='#refsSTTS'>[STTS]</a></p>";
+ ret += " <h2><a name='status'></a>Status of this document</h2>";
+ ret += " <p><em>This section describes the status of this document at the";
+ ret += " of this technical report can be found in the <a href='http://www.w3.org/TR/'>W3C technical reports index at";
+ ret += " http://www.w3.org/TR/.</a></em></p>";
+ ret += " <p>This document describes the selectors that already exist in <a href='#refsCSS1'><abbr title='CSS level 1'>CSS1</abbr></a> and <a href='#refsCSS21'><abbr title='CSS level 2'>CSS2</abbr></a>, and";
+ ret += " also proposes new selectors for <abbr title='CSS level";
+ ret += " 3'>CSS3</abbr> and other languages that may need them.</p>";
+ ret += " <p>The CSS Working Group doesn't expect that all implementations of";
+ ret += " CSS3 will have to implement all selectors. Instead, there will";
+ ret += " will include all of the selectors.</p>";
+ ret += " <p>This specification is a last call working draft for the the <a href='http://www.w3.org/Style/CSS/members'>CSS Working Group</a>";
+ ret += " (<a href='/Style/'>Style Activity</a>). This";
+ ret += " document is a revision of the <a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113/'>Candidate";
+ ret += " Recommendation dated 2001 November 13</a>, and has incorporated";
+ ret += " be demonstrable.</p>";
+ ret += " <p>All persons are encouraged to review and implement this";
+ ret += " specification and return comments to the (<a href='http://lists.w3.org/Archives/Public/www-style/'>archived</a>)";
+ ret += " public mailing list <a href='http://www.w3.org/Mail/Lists.html#www-style'>www-style</a>";
+ ret += " (see <a href='http://www.w3.org/Mail/Request'>instructions</a>). W3C";
+ ret += " The deadline for comments is 14 January 2006.</p>";
+ ret += " <p>This is still a draft document and may be updated, replaced, or";
+ ret += " </p><p>This document may be available in <a href='http://www.w3.org/Style/css3-selectors-updates/translations'>translation</a>.";
+ ret += " </p><div class='subtoc'>";
+ ret += " <h2><a name='contents'>Table of contents</a></h2>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline2'><a href='#context'>1. Introduction</a>";
+ ret += " <ul>";
+ ret += " <li><a href='#dependencies'>1.1. Dependencies</a></li>";
+ ret += " <li><a href='#terminology'>1.2. Terminology</a></li>";
+ ret += " <li><a href='#changesFromCSS2'>1.3. Changes from CSS2</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline2'><a href='#selectors'>2. Selectors</a>";
+ ret += " </li><li class='tocline2'><a href='#casesens'>3. Case sensitivity</a>";
+ ret += " </li><li class='tocline2'><a href='#selector-syntax'>4. Selector syntax</a>";
+ ret += " </li><li class='tocline2'><a href='#grouping'>5. Groups of selectors</a>";
+ ret += " </li><li class='tocline2'><a href='#simple-selectors'>6. Simple selectors</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline3'><a href='#type-selectors'>6.1. Type";
+ ret += " selectors</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline4'><a href='#typenmsp'>6.1.1. Type";
+ ret += " selectors and namespaces</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline3'><a href='#universal-selector'>6.2.";
+ ret += " Universal selector</a>";
+ ret += " <ul>";
+ ret += " <li><a href='#univnmsp'>6.2.1. Universal selector and";
+ ret += " namespaces</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline3'><a href='#attribute-selectors'>6.3.";
+ ret += " Attribute selectors</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline4'><a href='#attribute-representation'>6.3.1.";
+ ret += " values</a>";
+ ret += " </li><li><a href='#attribute-substrings'>6.3.2. Substring";
+ ret += " matching attribute selectors</a>";
+ ret += " </li><li class='tocline4'><a href='#attrnmsp'>6.3.3.";
+ ret += " Attribute selectors and namespaces</a>";
+ ret += " </li><li class='tocline4'><a href='#def-values'>6.3.4.";
+ ret += " Default attribute values in DTDs</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline3'><a href='#class-html'>6.4. Class";
+ ret += " selectors</a>";
+ ret += " </li><li class='tocline3'><a href='#id-selectors'>6.5. ID";
+ ret += " selectors</a>";
+ ret += " </li><li class='tocline3'><a href='#pseudo-classes'>6.6.";
+ ret += " Pseudo-classes</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline4'><a href='#dynamic-pseudos'>6.6.1.";
+ ret += " Dynamic pseudo-classes</a>";
+ ret += " </li><li class='tocline4'><a href='#target-pseudo'>6.6.2. The";
+ ret += " :target pseudo-class</a>";
+ ret += " </li><li class='tocline4'><a href='#lang-pseudo'>6.6.3. The";
+ ret += " :lang() pseudo-class</a>";
+ ret += " </li><li class='tocline4'><a href='#UIstates'>6.6.4. UI";
+ ret += " element states pseudo-classes</a>";
+ ret += " </li><li class='tocline4'><a href='#structural-pseudos'>6.6.5.";
+ ret += " Structural pseudo-classes</a>";
+ ret += " <ul>";
+ ret += " <li><a href='#root-pseudo'>:root";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#nth-child-pseudo'>:nth-child()";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#nth-last-child-pseudo'>:nth-last-child()</a>";
+ ret += " </li><li><a href='#nth-of-type-pseudo'>:nth-of-type()";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#nth-last-of-type-pseudo'>:nth-last-of-type()</a>";
+ ret += " </li><li><a href='#first-child-pseudo'>:first-child";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#last-child-pseudo'>:last-child";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#first-of-type-pseudo'>:first-of-type";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#last-of-type-pseudo'>:last-of-type";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#only-child-pseudo'>:only-child";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#only-of-type-pseudo'>:only-of-type";
+ ret += " pseudo-class</a>";
+ ret += " </li><li><a href='#empty-pseudo'>:empty";
+ ret += " pseudo-class</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline4'><a href='#negation'>6.6.7. The";
+ ret += " negation pseudo-class</a></li>";
+ ret += " </ul>";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li><li><a href='#pseudo-elements'>7. Pseudo-elements</a>";
+ ret += " <ul>";
+ ret += " <li><a href='#first-line'>7.1. The ::first-line";
+ ret += " pseudo-element</a>";
+ ret += " </li><li><a href='#first-letter'>7.2. The ::first-letter";
+ ret += " pseudo-element</a>";
+ ret += " </li><li><a href='#UIfragments'>7.3. The ::selection";
+ ret += " pseudo-element</a>";
+ ret += " </li><li><a href='#gen-content'>7.4. The ::before and ::after";
+ ret += " pseudo-elements</a></li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline2'><a href='#combinators'>8. Combinators</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline3'><a href='#descendant-combinators'>8.1.";
+ ret += " Descendant combinators</a>";
+ ret += " </li><li class='tocline3'><a href='#child-combinators'>8.2. Child";
+ ret += " combinators</a>";
+ ret += " </li><li class='tocline3'><a href='#sibling-combinators'>8.3. Sibling";
+ ret += " combinators</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline4'><a href='#adjacent-sibling-combinators'>8.3.1.";
+ ret += " Adjacent sibling combinator</a>";
+ ret += " </li><li class='tocline4'><a href='#general-sibling-combinators'>8.3.2.";
+ ret += " General sibling combinator</a></li>";
+ ret += " </ul>";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline2'><a href='#specificity'>9. Calculating a selector's";
+ ret += " specificity</a>";
+ ret += " </li><li class='tocline2'><a href='#w3cselgrammar'>10. The grammar of";
+ ret += " Selectors</a>";
+ ret += " <ul class='toc'>";
+ ret += " <li class='tocline3'><a href='#grammar'>10.1. Grammar</a>";
+ ret += " </li><li class='tocline3'><a href='#lex'>10.2. Lexical scanner</a>";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li><li class='tocline2'><a href='#downlevel'>11. Namespaces and down-level";
+ ret += " clients</a>";
+ ret += " </li><li class='tocline2'><a href='#profiling'>12. Profiles</a>";
+ ret += " </li><li><a href='#Conformance'>13. Conformance and requirements</a>";
+ ret += " </li><li><a href='#Tests'>14. Tests</a>";
+ ret += " </li><li><a href='#ACKS'>15. Acknowledgements</a>";
+ ret += " </li><li class='tocline2'><a href='#references'>16. References</a>";
+ ret += " </li></ul>";
+ ret += " </div>";
+ ret += " <h2><a name='context'>1. Introduction</a></h2>";
+ ret += " <h3><a name='dependencies'></a>1.1. Dependencies</h3>";
+ ret += " <p>Some features of this specification are specific to CSS, or have";
+ ret += " specification, these have been described in terms of CSS2.1. <a href='#refsCSS21'>[CSS21]</a></p>";
+ ret += " <h3><a name='terminology'></a>1.2. Terminology</h3>";
+ ret += " <p>All of the text of this specification is normative except";
+ ret += " non-normative.</p>";
+ ret += " <h3><a name='changesFromCSS2'></a>1.3. Changes from CSS2</h3>";
+ ret += " <p><em>This section is non-normative.</em></p>";
+ ret += " <p>The main differences between the selectors in CSS2 and those in";
+ ret += " Selectors are:";
+ ret += " </p><ul>";
+ ret += " <li>the list of basic definitions (selector, group of selectors,";
+ ret += " of simple selectors, and the term 'simple selector' is now used for";
+ ret += " </li>";
+ ret += " <li>an optional namespace component is now allowed in type element";
+ ret += " selectors, the universal selector and attribute selectors";
+ ret += " </li>";
+ ret += " <li>a <a href='#general-sibling-combinators'>new combinator</a> has been";
+ ret += " </li>";
+ ret += " <li>new simple selectors including substring matching attribute";
+ ret += " selectors, and new pseudo-classes";
+ ret += " </li>";
+ ret += " <li>new pseudo-elements, and introduction of the '::' convention";
+ ret += " </li>";
+ ret += " <li>the grammar has been rewritten</li>";
+ ret += " <li>profiles to be added to specifications integrating Selectors";
+ ret += " and defining the set of selectors which is actually supported by";
+ ret += " </li>";
+ ret += " <li>Selectors are now a CSS3 Module and an independent";
+ ret += " </li>";
+ ret += " <li>the specification now has its own test suite</li>";
+ ret += " </ul>";
+ ret += " <h2><a name='selectors'></a>2. Selectors</h2>";
+ ret += " <p><em>This section is non-normative, as it merely summarizes the";
+ ret += " following sections.</em></p>";
+ ret += " <p>A Selector represents a structure. This structure can be used as a";
+ ret += " HTML or XML fragment corresponding to that structure.</p>";
+ ret += " <p>Selectors may range from simple element names to rich contextual";
+ ret += " representations.</p>";
+ ret += " <p>The following table summarizes the Selector syntax:</p>";
+ ret += " <table class='selectorsReview'>";
+ ret += " <thead>";
+ ret += " <tr>";
+ ret += " <th class='pattern'>Pattern</th>";
+ ret += " <th class='meaning'>Meaning</th>";
+ ret += " <th class='described'>Described in section</th>";
+ ret += " <th class='origin'>First defined in CSS level</th>";
+ ret += " </tr>";
+ ret += " </thead><tbody>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>*</td>";
+ ret += " <td class='meaning'>any element</td>";
+ ret += " <td class='described'><a href='#universal-selector'>Universal";
+ ret += " selector</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E</td>";
+ ret += " <td class='meaning'>an element of type E</td>";
+ ret += " <td class='described'><a href='#type-selectors'>Type selector</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo]</td>";
+ ret += " <td class='meaning'>an E element with a 'foo' attribute</td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo='bar']</td>";
+ ret += " <td class='meaning'>an E element whose 'foo' attribute value is exactly";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo~='bar']</td>";
+ ret += " <td class='meaning'>an E element whose 'foo' attribute value is a list of";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo^='bar']</td>";
+ ret += " <td class='meaning'>an E element whose 'foo' attribute value begins exactly";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo$='bar']</td>";
+ ret += " <td class='meaning'>an E element whose 'foo' attribute value ends exactly";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[foo*='bar']</td>";
+ ret += " <td class='meaning'>an E element whose 'foo' attribute value contains the";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E[hreflang|='en']</td>";
+ ret += " <td class='meaning'>an E element whose 'hreflang' attribute has a";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#attribute-selectors'>Attribute";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:root</td>";
+ ret += " <td class='meaning'>an E element, root of the document</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:nth-child(n)</td>";
+ ret += " <td class='meaning'>an E element, the n-th child of its parent</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:nth-last-child(n)</td>";
+ ret += " <td class='meaning'>an E element, the n-th child of its parent, counting";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:nth-of-type(n)</td>";
+ ret += " <td class='meaning'>an E element, the n-th sibling of its type</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:nth-last-of-type(n)</td>";
+ ret += " <td class='meaning'>an E element, the n-th sibling of its type, counting";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:first-child</td>";
+ ret += " <td class='meaning'>an E element, first child of its parent</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:last-child</td>";
+ ret += " <td class='meaning'>an E element, last child of its parent</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:first-of-type</td>";
+ ret += " <td class='meaning'>an E element, first sibling of its type</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:last-of-type</td>";
+ ret += " <td class='meaning'>an E element, last sibling of its type</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:only-child</td>";
+ ret += " <td class='meaning'>an E element, only child of its parent</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:only-of-type</td>";
+ ret += " <td class='meaning'>an E element, only sibling of its type</td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:empty</td>";
+ ret += " <td class='meaning'>an E element that has no children (including text";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#structural-pseudos'>Structural";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:link<br>E:visited</td>";
+ ret += " <td class='meaning'>an E element being the source anchor of a hyperlink of";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#link'>The link";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:active<br>E:hover<br>E:focus</td>";
+ ret += " <td class='meaning'>an E element during certain user actions</td>";
+ ret += " <td class='described'><a href='#useraction-pseudos'>The user";
+ ret += " action pseudo-classes</a></td>";
+ ret += " <td class='origin'>1 and 2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:target</td>";
+ ret += " <td class='meaning'>an E element being the target of the referring URI</td>";
+ ret += " <td class='described'><a href='#target-pseudo'>The target";
+ ret += " pseudo-class</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:lang(fr)</td>";
+ ret += " <td class='meaning'>an element of type E in language 'fr' (the document";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#lang-pseudo'>The :lang()";
+ ret += " pseudo-class</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:enabled<br>E:disabled</td>";
+ ret += " <td class='meaning'>a user interface element E which is enabled or";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#UIstates'>The UI element states";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:checked<!--<br>E:indeterminate--></td>";
+ ret += " <td class='meaning'>a user interface element E which is checked<!-- or in an";
+ ret += " indeterminate state--> (for instance a radio-button or checkbox)";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#UIstates'>The UI element states";
+ ret += " pseudo-classes</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E::first-line</td>";
+ ret += " <td class='meaning'>the first formatted line of an E element</td>";
+ ret += " <td class='described'><a href='#first-line'>The ::first-line";
+ ret += " pseudo-element</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E::first-letter</td>";
+ ret += " <td class='meaning'>the first formatted letter of an E element</td>";
+ ret += " <td class='described'><a href='#first-letter'>The ::first-letter";
+ ret += " pseudo-element</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E::selection</td>";
+ ret += " <td class='meaning'>the portion of an E element that is currently";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#UIfragments'>The UI element";
+ ret += " fragments pseudo-elements</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E::before</td>";
+ ret += " <td class='meaning'>generated content before an E element</td>";
+ ret += " <td class='described'><a href='#gen-content'>The ::before";
+ ret += " pseudo-element</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E::after</td>";
+ ret += " <td class='meaning'>generated content after an E element</td>";
+ ret += " <td class='described'><a href='#gen-content'>The ::after";
+ ret += " pseudo-element</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E.warning</td>";
+ ret += " <td class='meaning'>an E element whose class is";
+ ret += " </td>";
+ ret += " <td class='described'><a href='#class-html'>Class";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E#myid</td>";
+ ret += " <td class='meaning'>an E element with ID equal to 'myid'.</td>";
+ ret += " <td class='described'><a href='#id-selectors'>ID";
+ ret += " selectors</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E:not(s)</td>";
+ ret += " <td class='meaning'>an E element that does not match simple selector s</td>";
+ ret += " <td class='described'><a href='#negation'>Negation";
+ ret += " pseudo-class</a></td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E F</td>";
+ ret += " <td class='meaning'>an F element descendant of an E element</td>";
+ ret += " <td class='described'><a href='#descendant-combinators'>Descendant";
+ ret += " combinator</a></td>";
+ ret += " <td class='origin'>1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E > F</td>";
+ ret += " <td class='meaning'>an F element child of an E element</td>";
+ ret += " <td class='described'><a href='#child-combinators'>Child";
+ ret += " combinator</a></td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E + F</td>";
+ ret += " <td class='meaning'>an F element immediately preceded by an E element</td>";
+ ret += " <td class='described'><a href='#adjacent-sibling-combinators'>Adjacent sibling combinator</a>";
+ ret += " </td>";
+ ret += " <td class='origin'>2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <td class='pattern'>E ~ F</td>";
+ ret += " <td class='meaning'>an F element preceded by an E element</td>";
+ ret += " <td class='described'><a href='#general-sibling-combinators'>General sibling combinator</a>";
+ ret += " </td>";
+ ret += " <td class='origin'>3</td>";
+ ret += " </tr>";
+ ret += " </tbody>";
+ ret += " </table>";
+ ret += " <p>The meaning of each selector is derived from the table above by";
+ ret += " column.</p>";
+ ret += " <h2><a name='casesens'>3. Case sensitivity</a></h2>";
+ ret += " <p>The case sensitivity of document language element names, attribute";
+ ret += " names, and attribute values in selectors depends on the document";
+ ret += " but in XML, they are case-sensitive.</p>";
+ ret += " <h2><a name='selector-syntax'>4. Selector syntax</a></h2>";
+ ret += " <p>A <dfn><a name='selector'>selector</a></dfn> is a chain of one";
+ ret += " or more <a href='#sequence'>sequences of simple selectors</a>";
+ ret += " separated by <a href='#combinators'>combinators</a>.</p>";
+ ret += " <p>A <dfn><a name='sequence'>sequence of simple selectors</a></dfn>";
+ ret += " is a chain of <a href='#simple-selectors-dfn'>simple selectors</a>";
+ ret += " that are not separated by a <a href='#combinators'>combinator</a>. It";
+ ret += " always begins with a <a href='#type-selectors'>type selector</a> or a";
+ ret += " <a href='#universal-selector'>universal selector</a>. No other type";
+ ret += " selector or universal selector is allowed in the sequence.</p>";
+ ret += " <p>A <dfn><a name='simple-selectors-dfn'></a><a href='#simple-selectors'>simple selector</a></dfn> is either a <a href='#type-selectors'>type selector</a>, <a href='#universal-selector'>universal selector</a>, <a href='#attribute-selectors'>attribute selector</a>, <a href='#class-html'>class selector</a>, <a href='#id-selectors'>ID selector</a>, <a href='#content-selectors'>content selector</a>, or <a href='#pseudo-classes'>pseudo-class</a>. One <a href='#pseudo-elements'>pseudo-element</a> may be appended to the last";
+ ret += " sequence of simple selectors.</p>";
+ ret += " <p><dfn>Combinators</dfn> are: white space, 'greater-than";
+ ret += " sign' (U+003E, <code>></code>), 'plus sign' (U+002B,";
+ ret += " <code>+</code>) and 'tilde' (U+007E, <code>~</code>). White";
+ ret += " space may appear between a combinator and the simple selectors around";
+ ret += " it. <a name='whitespace'></a>Only the characters 'space' (U+0020), 'tab'";
+ ret += " never part of white space.</p>";
+ ret += " <p>The elements of a document tree that are represented by a selector";
+ ret += " are the <dfn><a name='subject'></a>subjects of the selector</dfn>. A";
+ ret += " selector consisting of a single sequence of simple selectors";
+ ret += " sequence of simple selectors and a combinator to a sequence imposes";
+ ret += " simple selectors.</p>";
+ ret += " <p>An empty selector, containing no sequence of simple selectors and";
+ ret += " no pseudo-element, is an <a href='#Conformance'>invalid";
+ ret += " selector</a>.</p>";
+ ret += " <h2><a name='grouping'>5. Groups of selectors</a></h2>";
+ ret += " <p>When several selectors share the same declarations, they may be";
+ ret += " grouped into a comma-separated list. (A comma is U+002C.)</p>";
+ ret += " <div class='example'>";
+ ret += " <p>CSS examples:</p>";
+ ret += " <p>In this example, we condense three rules with identical";
+ ret += " declarations into one. Thus,</p>";
+ ret += " <pre>h1 { font-family: sans-serif }";
+ ret += " h3 { font-family: sans-serif }</pre>";
+ ret += " <p>is equivalent to:</p>";
+ ret += " <pre>h1, h2, h3 { font-family: sans-serif }</pre>";
+ ret += " </div>";
+ ret += " <p><strong>Warning</strong>: the equivalence is true in this example";
+ ret += " because all the selectors are valid selectors. If just one of these";
+ ret += " selectors were invalid, the entire group of selectors would be";
+ ret += " heading rules would be invalidated.</p>";
+ ret += " <h2><a name='simple-selectors'>6. Simple selectors</a></h2>";
+ ret += " <h3><a name='type-selectors'>6.1. Type selector</a></h3>";
+ ret += " <p>A <dfn>type selector</dfn> is the name of a document language";
+ ret += " type in the document tree.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The following selector represents an <code>h1</code> element in the";
+ ret += " document tree:</p>";
+ ret += " <pre>h1</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='typenmsp'>6.1.1. Type selectors and namespaces</a></h4>";
+ ret += " <p>Type selectors allow an optional namespace (<a href='#refsXMLNAMES'>[XMLNAMES]</a>) component. A namespace prefix";
+ ret += " (U+007C, <code>|</code>).</p>";
+ ret += " <p>The namespace component may be left empty to indicate that the";
+ ret += " selector is only to represent elements with no declared namespace.</p>";
+ ret += " <p>An asterisk may be used for the namespace prefix, indicating that";
+ ret += " with no namespace).</p>";
+ ret += " <p>Element type selectors that have no namespace component (no";
+ ret += " element's namespace (equivalent to '<code>*|</code>') unless a default";
+ ret += " namespace.</p>";
+ ret += " <p>A type selector containing a namespace prefix that has not been";
+ ret += " previously declared is an <a href='#Conformance'>invalid</a> selector.";
+ ret += " language implementing Selectors. In CSS, such a mechanism is defined";
+ ret += " in the General Syntax module.</p>";
+ ret += " <p>In a namespace-aware client, element type selectors will only match";
+ ret += " against the <a href='http://www.w3.org/TR/REC-xml-names/#NT-LocalPart'>local";
+ ret += " part</a>";
+ ret += " of the element's <a href='http://www.w3.org/TR/REC-xml-names/#ns-qualnames'>qualified";
+ ret += " name</a>. See <a href='#downlevel'>below</a> for notes about matching";
+ ret += " behaviors in down-level clients.</p>";
+ ret += " <p>In summary:</p>";
+ ret += " <dl>";
+ ret += " <dt><code>ns|E</code></dt>";
+ ret += " <dd>elements with name E in namespace ns</dd>";
+ ret += " <dt><code>*|E</code></dt>";
+ ret += " <dd>elements with name E in any namespace, including those without any";
+ ret += " </dd>";
+ ret += " <dt><code>|E</code></dt>";
+ ret += " <dd>elements with name E without any declared namespace</dd>";
+ ret += " <dt><code>E</code></dt>";
+ ret += " <dd>if no default namespace has been specified, this is equivalent to *|E.";
+ ret += " </dd>";
+ ret += " </dl>";
+ ret += " <div class='example'>";
+ ret += " <p>CSS examples:</p>";
+ ret += " <pre>@namespace foo url(http://www.example.com);";
+ ret += " h1 { color: green }</pre>";
+ ret += " <p>The first rule will match only <code>h1</code> elements in the";
+ ret += " 'http://www.example.com' namespace.</p>";
+ ret += " <p>The second rule will match all elements in the";
+ ret += " 'http://www.example.com' namespace.</p>";
+ ret += " <p>The third rule will match only <code>h1</code> elements without";
+ ret += " any declared namespace.</p>";
+ ret += " <p>The fourth rule will match <code>h1</code> elements in any";
+ ret += " namespace (including those without any declared namespace).</p>";
+ ret += " <p>The last rule is equivalent to the fourth rule because no default";
+ ret += " namespace has been defined.</p>";
+ ret += " </div>";
+ ret += " <h3><a name='universal-selector'>6.2. Universal selector</a></h3>";
+ ret += " <p>The <dfn>universal selector</dfn>, written 'asterisk'";
+ ret += " (<code>*</code>), represents the qualified name of any element";
+ ret += " specified, see <a href='#univnmsp'>Universal selector and";
+ ret += " Namespaces</a> below.</p>";
+ ret += " <p>If the universal selector is not the only component of a sequence";
+ ret += " of simple selectors, the <code>*</code> may be omitted.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <ul>";
+ ret += " <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are";
+ ret += " </li>";
+ ret += " <li><code>*.warning</code> and <code>.warning</code> are equivalent,";
+ ret += " </li>";
+ ret += " <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>";
+ ret += " </ul>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note:</strong> it is recommended that the";
+ ret += " <code>*</code>, representing the universal selector, not be";
+ ret += " omitted.</p>";
+ ret += " <h4><a name='univnmsp'>6.2.1. Universal selector and namespaces</a></h4>";
+ ret += " <p>The universal selector allows an optional namespace component. It";
+ ret += " is used as follows:</p>";
+ ret += " <dl>";
+ ret += " <dt><code>ns|*</code></dt>";
+ ret += " <dd>all elements in namespace ns</dd>";
+ ret += " <dt><code>*|*</code></dt>";
+ ret += " <dd>all elements</dd>";
+ ret += " <dt><code>|*</code></dt>";
+ ret += " <dd>all elements without any declared namespace</dd>";
+ ret += " <dt><code>*</code></dt>";
+ ret += " <dd>if no default namespace has been specified, this is equivalent to *|*.";
+ ret += " </dd>";
+ ret += " </dl>";
+ ret += " <p>A universal selector containing a namespace prefix that has not";
+ ret += " been previously declared is an <a href='#Conformance'>invalid</a>";
+ ret += " to the language implementing Selectors. In CSS, such a mechanism is";
+ ret += " defined in the General Syntax module.</p>";
+ ret += " <h3><a name='attribute-selectors'>6.3. Attribute selectors</a></h3>";
+ ret += " <p>Selectors allow the representation of an element's attributes. When";
+ ret += " attribute selectors must be considered to match an element if that";
+ ret += " attribute selector.</p>";
+ ret += " <h4><a name='attribute-representation'>6.3.1. Attribute presence and values";
+ ret += " selectors</a></h4>";
+ ret += " <p>CSS2 introduced four attribute selectors:</p>";
+ ret += " <dl>";
+ ret += " <dt><code>[att]</code>";
+ ret += " </dt><dd>Represents an element with the <code>att</code> attribute, whatever the";
+ ret += " </dd>";
+ ret += " <dt><code>[att=val]</code></dt>";
+ ret += " <dd>Represents an element with the <code>att</code> attribute whose value is";
+ ret += " </dd>";
+ ret += " <dt><code>[att~=val]</code></dt>";
+ ret += " <dd>Represents an element with the <code>att</code> attribute whose value is";
+ ret += " a <a href='#whitespace'>whitespace</a>-separated list of words, one";
+ ret += " represent anything (since the words are <em>separated</em> by";
+ ret += " </dd>";
+ ret += " <dt><code>[att|=val]</code>";
+ ret += " </dt><dd>Represents an element with the <code>att</code> attribute, its value";
+ ret += " matches (e.g., the <code>hreflang</code> attribute on the";
+ ret += " <code>link</code> element in HTML) as described in RFC 3066 (<a href='#refsRFC3066'>[RFC3066]</a>). For <code>lang</code> (or";
+ ret += " <code>xml:lang</code>) language subcode matching, please see <a href='#lang-pseudo'>the <code>:lang</code> pseudo-class</a>.";
+ ret += " </dd>";
+ ret += " </dl>";
+ ret += " <p>Attribute values must be identifiers or strings. The";
+ ret += " case-sensitivity of attribute names and values in selectors depends on";
+ ret += " the document language.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following attribute selector represents an <code>h1</code>";
+ ret += " element that carries the <code>title</code> attribute, whatever its";
+ ret += " value:</p>";
+ ret += " <pre>h1[title]</pre>";
+ ret += " <p>In the following example, the selector represents a";
+ ret += " <code>span</code> element whose <code>class</code> attribute has";
+ ret += " exactly the value 'example':</p>";
+ ret += " <pre>span[class='example']</pre>";
+ ret += " <p>Multiple attribute selectors can be used to represent several";
+ ret += " attribute. Here, the selector represents a <code>span</code> element";
+ ret += " whose <code>hello</code> attribute has exactly the value 'Cleveland'";
+ ret += " and whose <code>goodbye</code> attribute has exactly the value";
+ ret += " 'Columbus':</p>";
+ ret += " <pre>span[hello='Cleveland'][goodbye='Columbus']</pre>";
+ ret += " <p>The following selectors illustrate the differences between '='";
+ ret += " 'copyright copyleft copyeditor' on a <code>rel</code> attribute. The";
+ ret += " second selector will only represent an <code>a</code> element with";
+ ret += " an <code>href</code> attribute having the exact value";
+ ret += " 'http://www.w3.org/'.</p>";
+ ret += " <pre>a[rel~='copyright']";
+ ret += " a[href='http://www.w3.org/']</pre>";
+ ret += " <p>The following selector represents a <code>link</code> element";
+ ret += " whose <code>hreflang</code> attribute is exactly 'fr'.</p>";
+ ret += " <pre>link[hreflang=fr]</pre>";
+ ret += " <p>The following selector represents a <code>link</code> element for";
+ ret += " which the values of the <code>hreflang</code> attribute begins with";
+ ret += " 'en', including 'en', 'en-US', and 'en-cockney':</p>";
+ ret += " <pre>link[hreflang|='en']</pre>";
+ ret += " <p>Similarly, the following selectors represents a";
+ ret += " <code>DIALOGUE</code> element whenever it has one of two different";
+ ret += " values for an attribute <code>character</code>:</p>";
+ ret += " <pre>DIALOGUE[character=romeo]";
+ ret += " DIALOGUE[character=juliet]</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='attribute-substrings'></a>6.3.2. Substring matching attribute";
+ ret += " selectors</h4>";
+ ret += " <p>Three additional attribute selectors are provided for matching";
+ ret += " substrings in the value of an attribute:</p>";
+ ret += " <dl>";
+ ret += " <dt><code>[att^=val]</code></dt>";
+ ret += " <dd>Represents an element with the <code>att</code> attribute whose value";
+ ret += " </dd>";
+ ret += " <dt><code>[att$=val]</code>";
+ ret += " </dt><dd>Represents an element with the <code>att</code> attribute whose value";
+ ret += " </dd>";
+ ret += " <dt><code>[att*=val]</code>";
+ ret += " </dt><dd>Represents an element with the <code>att</code> attribute whose value";
+ ret += " </dd>";
+ ret += " </dl>";
+ ret += " <p>Attribute values must be identifiers or strings. The";
+ ret += " case-sensitivity of attribute names in selectors depends on the";
+ ret += " document language.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following selector represents an HTML <code>object</code>,";
+ ret += " image:</p>";
+ ret += " <pre>object[type^='image/']</pre>";
+ ret += " <p>The following selector represents an HTML anchor <code>a</code> with an";
+ ret += " <code>href</code> attribute whose value ends with '.html'.</p>";
+ ret += " <pre>a[href$='.html']</pre>";
+ ret += " <p>The following selector represents an HTML paragraph with a";
+ ret += " <code>title</code>";
+ ret += " attribute whose value contains the substring 'hello'</p>";
+ ret += " <pre>p[title*='hello']</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='attrnmsp'>6.3.3. Attribute selectors and namespaces</a></h4>";
+ ret += " <p>Attribute selectors allow an optional namespace component to the";
+ ret += " separator 'vertical bar' (<code>|</code>). In keeping with";
+ ret += " apply to attributes, therefore attribute selectors without a namespace";
+ ret += " (equivalent to '<code>|attr</code>'). An asterisk may be used for the";
+ ret += " </p><p>An attribute selector with an attribute name containing a namespace";
+ ret += " prefix that has not been previously declared is an <a href='#Conformance'>invalid</a> selector. The mechanism for";
+ ret += " a namespace prefix is left up to the language implementing Selectors.";
+ ret += " </p><div class='example'>";
+ ret += " <p>CSS examples:</p>";
+ ret += " <pre>@namespace foo 'http://www.example.com';";
+ ret += " [att] { color: green }</pre>";
+ ret += " <p>The first rule will match only elements with the attribute";
+ ret += " <code>att</code> in the 'http://www.example.com' namespace with the";
+ ret += " value 'val'.</p>";
+ ret += " <p>The second rule will match only elements with the attribute";
+ ret += " <code>att</code> regardless of the namespace of the attribute";
+ ret += " (including no declared namespace).</p>";
+ ret += " <p>The last two rules are equivalent and will match only elements";
+ ret += " with the attribute <code>att</code> where the attribute is not";
+ ret += " declared to be in a namespace.</p>";
+ ret += " </div>";
+ ret += " <h4><a name='def-values'>6.3.4. Default attribute values in DTDs</a></h4>";
+ ret += " <p>Attribute selectors represent explicitly set attribute values in";
+ ret += " selectors. Selectors should be designed so that they work even if the";
+ ret += " default values are not included in the document tree.</p>";
+ ret += " <p>More precisely, a UA is <em>not</em> required to read an 'external";
+ ret += " subset' of the DTD but <em>is</em> required to look for default";
+ ret += " attribute values in the document's 'internal subset.' (See <a href='#refsXML10'>[XML10]</a> for definitions of these subsets.)</p>";
+ ret += " <p>A UA that recognizes an XML namespace <a href='#refsXMLNAMES'>[XMLNAMES]</a> is not required to use its";
+ ret += " required to use its built-in knowledge of the XHTML DTD.)</p>";
+ ret += " <p class='note'><strong>Note:</strong> Typically, implementations";
+ ret += " choose to ignore external subsets.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>Consider an element EXAMPLE with an attribute 'notation' that has a";
+ ret += " default value of 'decimal'. The DTD fragment might be</p>";
+ ret += " <pre class='dtd-example'><!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'></pre>";
+ ret += " <p>If the style sheet contains the rules</p>";
+ ret += " <pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }";
+ ret += " EXAMPLE[notation=octal] { /*... other settings...*/ }</pre>";
+ ret += " <p>the first rule will not match elements whose 'notation' attribute";
+ ret += " attribute selector for the default value must be dropped:</p>";
+ ret += " <pre>EXAMPLE { /*... default property settings ...*/ }";
+ ret += " EXAMPLE[notation=octal] { /*... other settings...*/ }</pre>";
+ ret += " <p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is";
+ ret += " cases' style rules.</p>";
+ ret += " </div>";
+ ret += " <h3><a name='class-html'>6.4. Class selectors</a></h3>";
+ ret += " <p>Working with HTML, authors may use the period (U+002E,";
+ ret += " <code>.</code>) notation as an alternative to the <code>~=</code>";
+ ret += " notation when representing the <code>class</code> attribute. Thus, for";
+ ret += " HTML, <code>div.value</code> and <code>div[class~=value]</code> have";
+ ret += " 'period' (<code>.</code>).</p>";
+ ret += " <p>UAs may apply selectors using the period (.) notation in XML";
+ ret += " 1.0 <a href='#refsSVG'>[SVG]</a> describes the <a href='http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute'>SVG";
+ ret += " 'class' attribute</a> and how a UA should interpret it, and";
+ ret += " similarly MathML 1.01 <a href='#refsMATH'>[MATH]</a> describes the <a href='http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4'>MathML";
+ ret += " 'class' attribute</a>.)</p>";
+ ret += " <div class='example'>";
+ ret += " <p>CSS examples:</p>";
+ ret += " <p>We can assign style information to all elements with";
+ ret += " <code>class~='pastoral'</code> as follows:</p>";
+ ret += " <pre>*.pastoral { color: green } /* all elements with class~=pastoral */</pre>";
+ ret += " <p>or just</p>";
+ ret += " <pre>.pastoral { color: green } /* all elements with class~=pastoral */</pre>";
+ ret += " <p>The following assigns style only to H1 elements with";
+ ret += " <code>class~='pastoral'</code>:</p>";
+ ret += " <pre>H1.pastoral { color: green } /* H1 elements with class~=pastoral */</pre>";
+ ret += " <p>Given these rules, the first H1 instance below would not have";
+ ret += " green text, while the second would:</p>";
+ ret += " <pre><H1>Not green</H1>";
+ ret += " <H1 class='pastoral'>Very green</H1></pre>";
+ ret += " </div>";
+ ret += " <p>To represent a subset of 'class' values, each value must be preceded";
+ ret += " by a '.', in any order.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>CSS example:</p>";
+ ret += " <p>The following rule matches any P element whose 'class' attribute";
+ ret += " has been assigned a list of <a href='#whitespace'>whitespace</a>-separated values that includes";
+ ret += " 'pastoral' and 'marine':</p>";
+ ret += " <pre>p.pastoral.marine { color: green }</pre>";
+ ret += " <p>This rule matches when <code>class='pastoral blue aqua";
+ ret += " marine'</code> but does not match for <code>class='pastoral";
+ ret += " blue'</code>.</p>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note:</strong> Because CSS gives considerable";
+ ret += " not.</p>";
+ ret += " <p class='note'><strong>Note:</strong> If an element has multiple";
+ ret += " this specification.</p>";
+ ret += " <h3><a name='id-selectors'>6.5. ID selectors</a></h3>";
+ ret += " <p>Document languages may contain attributes that are declared to be";
+ ret += " applies.</p>";
+ ret += " <p>An ID-typed attribute of a document language allows authors to";
+ ret += " ID selectors represent an element instance based on its identifier. An";
+ ret += " <code>#</code>) immediately followed by the ID value, which must be an";
+ ret += " identifier.</p>";
+ ret += " <p>Selectors does not specify how a UA knows the ID-typed attribute of";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following ID selector represents an <code>h1</code> element";
+ ret += " whose ID-typed attribute has the value 'chapter1':</p>";
+ ret += " <pre>h1#chapter1</pre>";
+ ret += " <p>The following ID selector represents any element whose ID-typed";
+ ret += " attribute has the value 'chapter1':</p>";
+ ret += " <pre>#chapter1</pre>";
+ ret += " <p>The following selector represents any element whose ID-typed";
+ ret += " attribute has the value 'z98y'.</p>";
+ ret += " <pre>*#z98y</pre>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note.</strong> In XML 1.0 <a href='#refsXML10'>[XML10]</a>, the information about which attribute";
+ ret += " should use normal attribute selectors instead:";
+ ret += " <code>[name=p371]</code> instead of <code>#p371</code>. Elements in";
+ ret += " XML 1.0 documents without a DTD do not have IDs at all.</p>";
+ ret += " <p>If an element has multiple ID attributes, all of them must be";
+ ret += " DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>";
+ ret += " <h3><a name='pseudo-classes'>6.6. Pseudo-classes</a></h3>";
+ ret += " <p>The pseudo-class concept is introduced to permit selection based on";
+ ret += " expressed using the other simple selectors.</p>";
+ ret += " <p>A pseudo-class always consists of a 'colon'";
+ ret += " (<code>:</code>) followed by the name of the pseudo-class and";
+ ret += " optionally by a value between parentheses.</p>";
+ ret += " <p>Pseudo-classes are allowed in all sequences of simple selectors";
+ ret += " sequences of simple selectors, after the leading type selector or";
+ ret += " document.</p>";
+ ret += " <h4><a name='dynamic-pseudos'>6.6.1. Dynamic pseudo-classes</a></h4>";
+ ret += " <p>Dynamic pseudo-classes classify elements on characteristics other";
+ ret += " that cannot be deduced from the document tree.</p>";
+ ret += " <p>Dynamic pseudo-classes do not appear in the document source or";
+ ret += " document tree.</p>";
+ ret += " <h5>The <a name='link'>link pseudo-classes: :link and :visited</a></h5>";
+ ret += " <p>User agents commonly display unvisited links differently from";
+ ret += " previously visited ones. Selectors";
+ ret += " provides the pseudo-classes <code>:link</code> and";
+ ret += " <code>:visited</code> to distinguish them:</p>";
+ ret += " <ul>";
+ ret += " <li>The <code>:link</code> pseudo-class applies to links that have";
+ ret += " </li>";
+ ret += " <li>The <code>:visited</code> pseudo-class applies once the link has";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " <p>After some amount of time, user agents may choose to return a";
+ ret += " visited link to the (unvisited) ':link' state.</p>";
+ ret += " <p>The two states are mutually exclusive.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The following selector represents links carrying class";
+ ret += " <code>external</code> and already visited:</p>";
+ ret += " <pre>a.external:visited</pre>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note:</strong> It is possible for style sheet";
+ ret += " </p><p>UAs may therefore treat all links as unvisited links, or implement";
+ ret += " and unvisited links differently.</p>";
+ ret += " <h5>The <a name='useraction-pseudos'>user action pseudo-classes";
+ ret += " :hover, :active, and :focus</a></h5>";
+ ret += " <p>Interactive user agents sometimes change the rendering in response";
+ ret += " to user actions. Selectors provides";
+ ret += " acting on.</p>";
+ ret += " <ul>";
+ ret += " <li>The <code>:hover</code> pseudo-class applies while the user";
+ ret += " element. User agents not that do not support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
+ ret += " media</a> do not have to support this pseudo-class. Some conforming";
+ ret += " user agents that support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
+ ret += " media</a> may not be able to support this pseudo-class (e.g., a pen";
+ ret += " </li>";
+ ret += " <li>The <code>:active</code> pseudo-class applies while an element";
+ ret += " </li>";
+ ret += " <li>The <code>:focus</code> pseudo-class applies while an element";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " <p>There may be document language or implementation specific limits on";
+ ret += " which elements can become <code>:active</code> or acquire";
+ ret += " <code>:focus</code>.</p>";
+ ret += " <p>These pseudo-classes are not mutually exclusive. An element may";
+ ret += " match several pseudo-classes at the same time.</p>";
+ ret += " <p>Selectors doesn't define if the parent of an element that is";
+ ret += " ':active' or ':hover' is also in that state.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>a:link /* unvisited links */";
+ ret += " a:active /* active links */</pre>";
+ ret += " <p>An example of combining dynamic pseudo-classes:</p>";
+ ret += " <pre>a:focus";
+ ret += " a:focus:hover</pre>";
+ ret += " <p>The last selector matches <code>a</code> elements that are in";
+ ret += " the pseudo-class :focus and in the pseudo-class :hover.</p>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note:</strong> An element can be both ':visited'";
+ ret += " and ':active' (or ':link' and ':active').</p>";
+ ret += " <h4><a name='target-pseudo'>6.6.2. The target pseudo-class :target</a></h4>";
+ ret += " <p>Some URIs refer to a location within a resource. This kind of URI";
+ ret += " identifier (called the fragment identifier).</p>";
+ ret += " <p>URIs with fragment identifiers link to a certain element within the";
+ ret += " pointing to an anchor named <code>section_2</code> in an HTML";
+ ret += " document:</p>";
+ ret += " <pre>http://example.com/html/top.html#section_2</pre>";
+ ret += " <p>A target element can be represented by the <code>:target</code>";
+ ret += " the document has no target element.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <pre>p.note:target</pre>";
+ ret += " <p>This selector represents a <code>p</code> element of class";
+ ret += " <code>note</code> that is the target element of the referring";
+ ret += " URI.</p>";
+ ret += " </div>";
+ ret += " <div class='example'>";
+ ret += " <p>CSS example:</p>";
+ ret += " <p>Here, the <code>:target</code> pseudo-class is used to make the";
+ ret += " target element red and place an image before it, if there is one:</p>";
+ ret += " <pre>*:target { color : red }";
+ ret += " *:target::before { content : url(target.png) }</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='lang-pseudo'>6.6.3. The language pseudo-class :lang</a></h4>";
+ ret += " <p>If the document language specifies how the human language of an";
+ ret += " element is determined, it is possible to write selectors that";
+ ret += " represent an element based on its language. For example, in HTML <a href='#refsHTML4'>[HTML4]</a>, the language is determined by a";
+ ret += " combination of the <code>lang</code> attribute, the <code>meta</code>";
+ ret += " headers). XML uses an attribute called <code>xml:lang</code>, and";
+ ret += " the language.</p>";
+ ret += " <p>The pseudo-class <code>:lang(C)</code> represents an element that";
+ ret += " <code>:lang()</code> selector is based solely on the identifier C";
+ ret += " element's language value, in the same way as if performed by the <a href='#attribute-representation'>'|='</a> operator in attribute";
+ ret += " selectors. The identifier C does not have to be a valid language";
+ ret += " name.</p>";
+ ret += " <p>C must not be empty. (If it is, the selector is invalid.)</p>";
+ ret += " <p class='note'><strong>Note:</strong> It is recommended that";
+ ret += " documents and protocols indicate language using codes from RFC 3066 <a href='#refsRFC3066'>[RFC3066]</a> or its successor, and by means of";
+ ret += " 'xml:lang' attributes in the case of XML-based documents <a href='#refsXML10'>[XML10]</a>. See <a href='http://www.w3.org/International/questions/qa-lang-2or3.html'>";
+ ret += " 'FAQ: Two-letter or three-letter language codes.'</a></p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The two following selectors represent an HTML document that is in";
+ ret += " Belgian, French, or German. The two next selectors represent";
+ ret += " <code>q</code> quotations in an arbitrary element in Belgian, French,";
+ ret += " or German.</p>";
+ ret += " <pre>html:lang(fr-be)";
+ ret += " :lang(de) > q</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='UIstates'>6.6.4. The UI element states pseudo-classes</a></h4>";
+ ret += " <h5><a name='enableddisabled'>The :enabled and :disabled pseudo-classes</a></h5>";
+ ret += " <p>The <code>:enabled</code> pseudo-class allows authors to customize";
+ ret += " an enabled <code>input</code> element without also specifying what it";
+ ret += " would look like when it was disabled.</p>";
+ ret += " <p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the";
+ ret += " element should look.</p>";
+ ret += " <p>Most elements will be neither enabled nor disabled. An element is";
+ ret += " presently activate it or transfer focus to it.</p>";
+ ret += " <h5><a name='checked'>The :checked pseudo-class</a></h5>";
+ ret += " <p>Radio and checkbox elements can be toggled by the user. Some menu";
+ ret += " toggled 'on' the <code>:checked</code> pseudo-class applies. The";
+ ret += " <code>:checked</code> pseudo-class initially applies to such elements";
+ ret += " that have the HTML4 <code>selected</code> and <code>checked</code>";
+ ret += " attributes as described in <a href='http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1'>Section";
+ ret += " 17.2.1 of HTML4</a>, but of course the user can toggle 'off' such";
+ ret += " elements in which case the <code>:checked</code> pseudo-class would no";
+ ret += " longer apply. While the <code>:checked</code> pseudo-class is dynamic";
+ ret += " on the presence of the semantic HTML4 <code>selected</code> and";
+ ret += " <code>checked</code> attributes, it applies to all media.";
+ ret += " </p><h5><a name='indeterminate'>The :indeterminate pseudo-class</a></h5>";
+ ret += " <div class='note'>";
+ ret += " <p>Radio and checkbox elements can be toggled by the user, but are";
+ ret += " This can be due to an element attribute, or DOM manipulation.</p>";
+ ret += " <p>A future version of this specification may introduce an";
+ ret += " <code>:indeterminate</code> pseudo-class that applies to such elements.";
+ ret += " <!--While the <code>:indeterminate</code> pseudo-class is dynamic in";
+ ret += " the presence of an element attribute, it applies to all media.</p>";
+ ret += " <p>Components of a radio-group initialized with no pre-selected choice";
+ ret += " are an example of :indeterminate state.--></p>";
+ ret += " </div>";
+ ret += " <h4><a name='structural-pseudos'>6.6.5. Structural pseudo-classes</a></h4>";
+ ret += " <p>Selectors introduces the concept of <dfn>structural";
+ ret += " pseudo-classes</dfn> to permit selection based on extra information that";
+ ret += " the document tree but cannot be represented by other simple selectors or";
+ ret += " </p><p>Note that standalone pieces of PCDATA (text nodes in the DOM) are";
+ ret += " </p><h5><a name='root-pseudo'>:root pseudo-class</a></h5>";
+ ret += " <p>The <code>:root</code> pseudo-class represents an element that is";
+ ret += " <code>HTML</code> element.";
+ ret += " </p><h5><a name='nth-child-pseudo'>:nth-child() pseudo-class</a></h5>";
+ ret += " <p>The";
+ ret += " <code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>";
+ ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings";
+ ret += " <strong>before</strong> it in the document tree, for a given positive";
+ ret += " integer or zero value of <code>n</code>, and has a parent element. In";
+ ret += " other words, this matches the <var>b</var>th child of an element after";
+ ret += " all the children have been split into groups of <var>a</var> elements";
+ ret += " each. For example, this allows the selectors to address every other";
+ ret += " of paragraph text in a cycle of four. The <var>a</var> and";
+ ret += " <var>b</var> values must be zero, negative integers or positive";
+ ret += " </p><p>In addition to this, <code>:nth-child()</code> can take";
+ ret += " '<code>odd</code>' and '<code>even</code>' as arguments instead.";
+ ret += " '<code>odd</code>' has the same signification as <code>2n+1</code>,";
+ ret += " and '<code>even</code>' has the same signification as <code>2n</code>.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */";
+ ret += " p:nth-child(4n+4) { color: purple; }</pre>";
+ ret += " </div>";
+ ret += " <p>When <var>a</var>=0, no repeating is used, so for example";
+ ret += " <code>:nth-child(0n+5)</code> matches only the fifth child. When";
+ ret += " <var>a</var>=0, the <var>a</var><code>n</code> part need not be";
+ ret += " <code>:nth-child(<var>b</var>)</code> and the last example simplifies";
+ ret += " to <code>:nth-child(5)</code>.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>foo:nth-child(0n+1) /* represents an element foo, first child of its parent element */";
+ ret += " foo:nth-child(1) /* same */</pre>";
+ ret += " </div>";
+ ret += " <p>When <var>a</var>=1, the number may be omitted from the rule.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following selectors are therefore equivalent:</p>";
+ ret += " <pre>bar:nth-child(1n+0) /* represents all bar elements, specificity (0,1,1) */";
+ ret += " bar /* same but lower specificity (0,0,1) */</pre>";
+ ret += " </div>";
+ ret += " <p>If <var>b</var>=0, then every <var>a</var>th element is picked. In";
+ ret += " such a case, the <var>b</var> part may be omitted.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */";
+ ret += " tr:nth-child(2n) /* same */</pre>";
+ ret += " </div>";
+ ret += " <p>If both <var>a</var> and <var>b</var> are equal to zero, the";
+ ret += " pseudo-class represents no element in the document tree.</p>";
+ ret += " <p>The value <var>a</var> can be negative, but only the positive";
+ ret += " values of <var>a</var><code>n</code>+<var>b</var>, for";
+ ret += " <code>n</code>≥0, may represent an element in the document";
+ ret += " tree.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <pre>html|tr:nth-child(-n+6) /* represents the 6 first rows of XHTML tables */</pre>";
+ ret += " </div>";
+ ret += " <p>When the value <var>b</var> is negative, the '+' character in the";
+ ret += " character indicating the negative value of <var>b</var>).</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>:nth-child(10n-1) /* represents the 9th, 19th, 29th, etc, element */";
+ ret += " :nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='nth-last-child-pseudo'>:nth-last-child() pseudo-class</a></h5>";
+ ret += " <p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>";
+ ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings";
+ ret += " <strong>after</strong> it in the document tree, for a given positive";
+ ret += " integer or zero value of <code>n</code>, and has a parent element. See";
+ ret += " <code>:nth-child()</code> pseudo-class for the syntax of its argument.";
+ ret += " It also accepts the '<code>even</code>' and '<code>odd</code>' values";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>tr:nth-last-child(-n+2) /* represents the two last rows of an HTML table */";
+ ret += " counting from the last one */</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='nth-of-type-pseudo'>:nth-of-type() pseudo-class</a></h5>";
+ ret += " <p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>";
+ ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
+ ret += " element name <strong>before</strong> it in the document tree, for a";
+ ret += " given zero or positive integer value of <code>n</code>, and has a";
+ ret += " parent element. In other words, this matches the <var>b</var>th child";
+ ret += " groups of a elements each. See <code>:nth-child()</code> pseudo-class";
+ ret += " '<code>even</code>' and '<code>odd</code>' values.";
+ ret += " </p><div class='example'>";
+ ret += " <p>CSS example:</p>";
+ ret += " <p>This allows an author to alternate the position of floated images:</p>";
+ ret += " <pre>img:nth-of-type(2n+1) { float: right; }";
+ ret += " img:nth-of-type(2n) { float: left; }</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='nth-last-of-type-pseudo'>:nth-last-of-type() pseudo-class</a></h5>";
+ ret += " <p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>";
+ ret += " <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
+ ret += " element name <strong>after</strong> it in the document tree, for a";
+ ret += " given zero or positive integer value of <code>n</code>, and has a";
+ ret += " parent element. See <code>:nth-child()</code> pseudo-class for the";
+ ret += " syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>'";
+ ret += " </p><div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>To represent all <code>h2</code> children of an XHTML";
+ ret += " <code>body</code> except the first and last, one could use the";
+ ret += " following selector:</p>";
+ ret += " <pre>body > h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>";
+ ret += " <p>In this case, one could also use <code>:not()</code>, although the";
+ ret += " selector ends up being just as long:</p>";
+ ret += " <pre>body > h2:not(:first-of-type):not(:last-of-type)</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='first-child-pseudo'>:first-child pseudo-class</a></h5>";
+ ret += " <p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code>";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following selector represents a <code>p</code> element that is";
+ ret += " the first child of a <code>div</code> element:</p>";
+ ret += " <pre>div > p:first-child</pre>";
+ ret += " <p>This selector can represent the <code>p</code> inside the";
+ ret += " <code>div</code> of the following fragment:</p>";
+ ret += " <pre><p> The last P before the note.</p>";
+ ret += " </div></pre>";
+ ret += " but cannot represent the second <code>p</code> in the following";
+ ret += " <pre><p> The last P before the note.</p>";
+ ret += " </div></pre>";
+ ret += " <p>The following two selectors are usually equivalent:</p>";
+ ret += " <pre>* > a:first-child /* a is first child of any element */";
+ ret += " a:first-child /* Same (assuming a is not the root element) */</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='last-child-pseudo'>:last-child pseudo-class</a></h5>";
+ ret += " <p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code>";
+ ret += " </p><div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The following selector represents a list item <code>li</code> that";
+ ret += " is the last child of an ordered list <code>ol</code>.";
+ ret += " </p><pre>ol > li:last-child</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='first-of-type-pseudo'>:first-of-type pseudo-class</a></h5>";
+ ret += " <p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code>";
+ ret += " </p><div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The following selector represents a definition title";
+ ret += " <code>dt</code> inside a definition list <code>dl</code>, this";
+ ret += " <code>dt</code> being the first of its type in the list of children of";
+ ret += " its parent element.</p>";
+ ret += " <pre>dl dt:first-of-type</pre>";
+ ret += " <p>It is a valid description for the first two <code>dt</code>";
+ ret += " elements in the following example but not for the third one:</p>";
+ ret += " <pre><dl>";
+ ret += " </dl></pre>";
+ ret += " </div>";
+ ret += " <h5><a name='last-of-type-pseudo'>:last-of-type pseudo-class</a></h5>";
+ ret += " <p>Same as <code>:nth-last-of-type(1)</code>. The";
+ ret += " <code>:last-of-type</code> pseudo-class represents an element that is";
+ ret += " element.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The following selector represents the last data cell";
+ ret += " <code>td</code> of a table row.</p>";
+ ret += " <pre>tr > td:last-of-type</pre>";
+ ret += " </div>";
+ ret += " <h5><a name='only-child-pseudo'>:only-child pseudo-class</a></h5>";
+ ret += " <p>Represents an element that has a parent element and whose parent";
+ ret += " <code>:first-child:last-child</code> or";
+ ret += " <code>:nth-child(1):nth-last-child(1)</code>, but with a lower";
+ ret += " specificity.</p>";
+ ret += " <h5><a name='only-of-type-pseudo'>:only-of-type pseudo-class</a></h5>";
+ ret += " <p>Represents an element that has a parent element and whose parent";
+ ret += " as <code>:first-of-type:last-of-type</code> or";
+ ret += " <code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower";
+ ret += " specificity.</p>";
+ ret += " <h5><a name='empty-pseudo'></a>:empty pseudo-class</h5>";
+ ret += " <p>The <code>:empty</code> pseudo-class represents an element that has";
+ ret += " empty or not.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p><code>p:empty</code> is a valid representation of the following fragment:";
+ ret += " </p>";
+ ret += " <pre><p></p></pre>";
+ ret += " <p><code>foo:empty</code> is not a valid representation for the";
+ ret += " following fragments:</p>";
+ ret += " <pre><foo>bar</foo></pre>";
+ ret += " <pre><foo><bar>bla</bar></foo></pre>";
+ ret += " <pre><foo>this is not <bar>:empty</bar></foo></pre>";
+ ret += " </div>";
+ ret += " <h4><a name='content-selectors'>6.6.6. Blank</a></h4>";
+ ret += " <!-- It's the Return of Appendix H!!! Run away! -->";
+ ret += " <p>This section intentionally left blank.</p>";
+ ret += " <!-- (used to be :contains()) -->";
+ ret += " <h4><a name='negation'></a>6.6.7. The negation pseudo-class</h4>";
+ ret += " <p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a";
+ ret += " functional notation taking a <a href='#simple-selectors-dfn'>simple";
+ ret += " selector</a> (excluding the negation pseudo-class itself and";
+ ret += " <!-- pseudo-elements are not simple selectors, so the above paragraph";
+ ret += " may be a bit confusing -->";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following CSS selector matches all <code>button</code>";
+ ret += " elements in an HTML document that are not disabled.</p>";
+ ret += " <pre>button:not([DISABLED])</pre>";
+ ret += " <p>The following selector represents all but <code>FOO</code>";
+ ret += " elements.</p>";
+ ret += " <pre>*:not(FOO)</pre>";
+ ret += " <p>The following group of selectors represents all HTML elements";
+ ret += " except links.</p>";
+ ret += " <pre>html|*:not(:link):not(:visited)</pre>";
+ ret += " </div>";
+ ret += " <p>Default namespace declarations do not affect the argument of the";
+ ret += " type selector.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>Assuming that the default namespace is bound to";
+ ret += " elements that are not in that namespace:</p>";
+ ret += " <pre>*|*:not(*)</pre>";
+ ret += " <p>The following CSS selector matches any element being hovered,";
+ ret += " rule when they <em>are</em> being hovered.</p>";
+ ret += " <pre>*|*:not(:hover)</pre>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note</strong>: the :not() pseudo allows";
+ ret += " useless selectors to be written. For instance <code>:not(*|*)</code>,";
+ ret += " which represents no element at all, or <code>foo:not(bar)</code>,";
+ ret += " which is equivalent to <code>foo</code> but with a higher";
+ ret += " specificity.</p>";
+ ret += " <h3><a name='pseudo-elements'>7. Pseudo-elements</a></h3>";
+ ret += " <p>Pseudo-elements create abstractions about the document tree beyond";
+ ret += " source document (e.g., the <code>::before</code> and";
+ ret += " <code>::after</code> pseudo-elements give access to generated";
+ ret += " content).</p>";
+ ret += " <p>A pseudo-element is made of two colons (<code>::</code>) followed";
+ ret += " by the name of the pseudo-element.</p>";
+ ret += " <p>This <code>::</code> notation is introduced by the current document";
+ ret += " <code>:first-line</code>, <code>:first-letter</code>,";
+ ret += " <code>:before</code> and <code>:after</code>). This compatibility is";
+ ret += " not allowed for the new pseudo-elements introduced in CSS level 3.</p>";
+ ret += " <p>Only one pseudo-element may appear per selector, and if present it";
+ ret += " must appear after the sequence of simple selectors that represents the";
+ ret += " <a href='#subject'>subjects</a> of the selector. <span class='note'>A";
+ ret += " pesudo-elements per selector.</span></p>";
+ ret += " <h4><a name='first-line'>7.1. The ::first-line pseudo-element</a></h4>";
+ ret += " <p>The <code>::first-line</code> pseudo-element describes the contents";
+ ret += " </p><div class='example'>";
+ ret += " <p>CSS example:</p>";
+ ret += " <pre>p::first-line { text-transform: uppercase }</pre>";
+ ret += " <p>The above rule means 'change the letters of the first line of every";
+ ret += " paragraph to uppercase'.</p>";
+ ret += " </div>";
+ ret += " <p>The selector <code>p::first-line</code> does not match any real";
+ ret += " agents will insert at the beginning of every paragraph.</p>";
+ ret += " <p>Note that the length of the first line depends on a number of";
+ ret += " an ordinary HTML paragraph such as:</p>";
+ ret += " <pre> <P>This is a somewhat long HTML ";
+ ret += " </pre>";
+ ret += " <p>the lines of which happen to be broken as follows:";
+ ret += " </p><pre> THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT";
+ ret += " </pre>";
+ ret += " <p>This paragraph might be 'rewritten' by user agents to include the";
+ ret += " <em>fictional tag sequence</em> for <code>::first-line</code>. This";
+ ret += " fictional tag sequence helps to show how properties are inherited.</p>";
+ ret += " <pre> <P><b><P::first-line></b> This is a somewhat long HTML ";
+ ret += " paragraph that <b></P::first-line></b> will be broken into several";
+ ret += " </pre>";
+ ret += " <p>If a pseudo-element breaks up a real element, the desired effect";
+ ret += " with a <code>span</code> element:</p>";
+ ret += " <pre> <P><b><SPAN class='test'></b> This is a somewhat long HTML";
+ ret += " lines.<b></SPAN></b> The first line will be identified";
+ ret += " </pre>";
+ ret += " <p>the user agent could simulate start and end tags for";
+ ret += " <code>span</code> when inserting the fictional tag sequence for";
+ ret += " <code>::first-line</code>.";
+ ret += " </p><pre> <P><P::first-line><b><SPAN class='test'></b> This is a";
+ ret += " paragraph that will <b></SPAN></b></P::first-line><b><SPAN";
+ ret += " class='test'></b> be";
+ ret += " lines.<b></SPAN></b> The first line will be identified";
+ ret += " </pre>";
+ ret += " <p>In CSS, the <code>::first-line</code> pseudo-element can only be";
+ ret += " or a table-cell.</p>";
+ ret += " <p><a name='first-formatted-line'></a>The 'first formatted line' of an";
+ ret += " line of the <code>div</code> in <code><DIV><P>This";
+ ret += " line...</P></DIV></code> is the first line of the <code>p</code>";
+ ret += " that both <code>p</code> and <code>div</code> are block-level).";
+ ret += " </p><p>The first line of a table-cell or inline-block cannot be the first";
+ ret += " formatted line of an ancestor element. Thus, in <code><DIV><P";
+ ret += " etcetera</DIV></code> the first formatted line of the";
+ ret += " <code>div</code> is not the line 'Hello'.";
+ ret += " </p><p class='note'>Note that the first line of the <code>p</code> in this";
+ ret += " fragment: <code><p><br>First...</code> doesn't contain any";
+ ret += " letters (assuming the default style for <code>br</code> in HTML";
+ ret += " </p><p>A UA should act as if the fictional start tags of the";
+ ret += " <code>::first-line</code> pseudo-elements were nested just inside the";
+ ret += " is an example. The fictional tag sequence for</p>";
+ ret += " <pre> <DIV>";
+ ret += " </pre>";
+ ret += " <p>is</p>";
+ ret += " <pre> <DIV>";
+ ret += " </pre>";
+ ret += " <p>The <code>::first-line</code> pseudo-element is similar to an";
+ ret += " following properties apply to a <code>::first-line</code>";
+ ret += " properties as well.</p>";
+ ret += " <h4><a name='first-letter'>7.2. The ::first-letter pseudo-element</a></h4>";
+ ret += " <p>The <code>::first-letter</code> pseudo-element represents the first";
+ ret += " is 'none'; otherwise, it is similar to a floated element.</p>";
+ ret += " <p>In CSS, these are the properties that apply to <code>::first-letter</code>";
+ ret += " of the letter, unlike for normal elements.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>This example shows a possible rendering of an initial cap. Note";
+ ret += " <code>::first-letter</code>";
+ ret += " fictional start tag of the first letter is inside the <span>span</span>,";
+ ret += " the font weight of the first letter is normal, not bold as the <span>span</span>:";
+ ret += " </p><pre> p { line-height: 1.1 }";
+ ret += " </pre>";
+ ret += " <div class='figure'>";
+ ret += " <p><img src='' alt='Image illustrating the ::first-letter pseudo-element'>";
+ ret += " </p></div>";
+ ret += " </div>";
+ ret += " <div class='example'>";
+ ret += " <p>The following CSS will make a drop cap initial letter span about two";
+ ret += " lines:</p>";
+ ret += " <pre> <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'>";
+ ret += " </pre>";
+ ret += " <p>This example might be formatted as follows:</p>";
+ ret += " <div class='figure'>";
+ ret += " <p><img src='' alt='Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements'>";
+ ret += " </p>";
+ ret += " </div>";
+ ret += " <p>The <span class='index-inst' title='fictional tag";
+ ret += " sequence'>fictional tag sequence</span> is:</p>";
+ ret += " <pre> <P>";
+ ret += " </pre>";
+ ret += " <p>Note that the <code>::first-letter</code> pseudo-element tags abut";
+ ret += " block element.</p></div>";
+ ret += " <p>In order to achieve traditional drop caps formatting, user agents";
+ ret += " glyph outline may be taken into account when formatting.</p>";
+ ret += " <p>Punctuation (i.e, characters defined in Unicode in the 'open' (Ps),";
+ ret += " be included. <a href='#refsUNICODE'>[UNICODE]</a></p>";
+ ret += " <div class='figure'>";
+ ret += " <p><img src='' alt='Quotes that precede the";
+ ret += " first letter should be included.'></p>";
+ ret += " </div>";
+ ret += " <p>The <code>::first-letter</code> also applies if the first letter is";
+ ret += " money.'</p>";
+ ret += " <p>In CSS, the <code>::first-letter</code> pseudo-element applies to";
+ ret += " elements. <span class='note'>A future version of this specification";
+ ret += " types.</span></p>";
+ ret += " <p>The <code>::first-letter</code> pseudo-element can be used with all";
+ ret += " the element, even if that first text is in a descendant.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>The fictional tag sequence for this HTMLfragment:";
+ ret += " </p><pre><div>";
+ ret += " <p>The first text.</pre>";
+ ret += " <p>is:";
+ ret += " </p><pre><div>";
+ ret += " <p><div::first-letter><p::first-letter>T</...></...>he first text.</pre>";
+ ret += " </div>";
+ ret += " <p>The first letter of a table-cell or inline-block cannot be the";
+ ret += " first letter of an ancestor element. Thus, in <code><DIV><P";
+ ret += " etcetera</DIV></code> the first letter of the <code>div</code> is";
+ ret += " letter 'H'. In fact, the <code>div</code> doesn't have a first letter.";
+ ret += " </p><p>The first letter must occur on the <a href='#first-formatted-line'>first formatted line.</a> For example, in";
+ ret += " this fragment: <code><p><br>First...</code> the first line";
+ ret += " doesn't contain any letters and <code>::first-letter</code> doesn't";
+ ret += " match anything (assuming the default style for <code>br</code> in HTML";
+ ret += " </p><p>In CSS, if an element is a list item ('display: list-item'), the";
+ ret += " <code>::first-letter</code> applies to the first letter in the";
+ ret += " <code>::first-letter</code> on list items with 'list-style-position:";
+ ret += " inside'. If an element has <code>::before</code> or";
+ ret += " <code>::after</code> content, the <code>::first-letter</code> applies";
+ ret += " to the first letter of the element <em>including</em> that content.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p>After the rule 'p::before {content: 'Note: '}', the selector";
+ ret += " 'p::first-letter' matches the 'N' of 'Note'.</p>";
+ ret += " </div>";
+ ret += " <p>Some languages may have specific rules about how to treat certain";
+ ret += " considered within the <code>::first-letter</code> pseudo-element.";
+ ret += " </p><p>If the letters that would form the ::first-letter are not in the";
+ ret += " same element, such as ''T' in <code><p>'<em>T...</code>, the UA";
+ ret += " both elements, or simply not create a pseudo-element.</p>";
+ ret += " <p>Similarly, if the first letter(s) of the block are not at the start";
+ ret += " </p><div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <p><a name='overlapping-example'>The following example</a> illustrates";
+ ret += " paragraph will be 'red'.</p>";
+ ret += " <pre>p { color: red; font-size: 12pt }";
+ ret += " <P>Some text that ends up on two lines</P></pre>";
+ ret += " <p>Assuming that a line break will occur before the word 'ends', the";
+ ret += " <span class='index-inst' title='fictional tag sequence'>fictional tag";
+ ret += " sequence</span> for this fragment might be:</p>";
+ ret += " <pre><P>";
+ ret += " </P></pre>";
+ ret += " <p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>";
+ ret += " element. Properties set on <code>::first-line</code> are inherited by";
+ ret += " <code>::first-letter</code>, but are overridden if the same property is";
+ ret += " <code>::first-letter</code>.</p>";
+ ret += " </div>";
+ ret += " <h4><a name='UIfragments'>7.3.</a> <a name='selection'>The ::selection";
+ ret += " pseudo-element</a></h4>";
+ ret += " <p>The <code>::selection</code> pseudo-element applies to the portion";
+ ret += " field. This pseudo-element should not be confused with the <code><a href='#checked'>:checked</a></code> pseudo-class (which used to be";
+ ret += " named <code>:selected</code>)";
+ ret += " </p><p>Although the <code>::selection</code> pseudo-element is dynamic in";
+ ret += " <a href='#refsCSS21'>[CSS21]</a>) which was originally rendered to a";
+ ret += " <code>::selection</code> state to that other medium, and have all the";
+ ret += " required — UAs may omit the <code>::selection</code>";
+ ret += " </p><p>These are the CSS properties that apply to <code>::selection</code>";
+ ret += " <code>::selection</code> may be ignored.";
+ ret += " </p><h4><a name='gen-content'>7.4. The ::before and ::after pseudo-elements</a></h4>";
+ ret += " <p>The <code>::before</code> and <code>::after</code> pseudo-elements";
+ ret += " content. They are explained in CSS 2.1 <a href='#refsCSS21'>[CSS21]</a>.</p>";
+ ret += " <p>When the <code>::first-letter</code> and <code>::first-line</code>";
+ ret += " pseudo-elements are combined with <code>::before</code> and";
+ ret += " <code>::after</code>, they apply to the first letter or line of the";
+ ret += " element including the inserted text.</p>";
+ ret += " <h2><a name='combinators'>8. Combinators</a></h2>";
+ ret += " <h3><a name='descendant-combinators'>8.1. Descendant combinator</a></h3>";
+ ret += " <p>At times, authors may want selectors to describe an element that is";
+ ret += " <code>EM</code> element that is contained within an <code>H1</code>";
+ ret += " descendant combinator is <a href='#whitespace'>white space</a> that";
+ ret += " separates two sequences of simple selectors. A selector of the form";
+ ret += " '<code>A B</code>' represents an element <code>B</code> that is an";
+ ret += " arbitrary descendant of some ancestor element <code>A</code>.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>For example, consider the following selector:</p>";
+ ret += " <pre>h1 em</pre>";
+ ret += " <p>It represents an <code>em</code> element being the descendant of";
+ ret += " an <code>h1</code> element. It is a correct and valid, but partial,";
+ ret += " description of the following fragment:</p>";
+ ret += " <pre><h1>This <span class='myclass'>headline";
+ ret += " is <em>very</em> important</span></h1></pre>";
+ ret += " <p>The following selector:</p>";
+ ret += " <pre>div * p</pre>";
+ ret += " <p>represents a <code>p</code> element that is a grandchild or later";
+ ret += " descendant of a <code>div</code> element. Note the whitespace on";
+ ret += " of the P.</p>";
+ ret += " <p>The following selector, which combines descendant combinators and";
+ ret += " <a href='#attribute-selectors'>attribute selectors</a>, represents an";
+ ret += " element that (1) has the <code>href</code> attribute set and (2) is";
+ ret += " inside a <code>p</code> that is itself inside a <code>div</code>:</p>";
+ ret += " <pre>div p *[href]</pre>";
+ ret += " </div>";
+ ret += " <h3><a name='child-combinators'>8.2. Child combinators</a></h3>";
+ ret += " <p>A <dfn>child combinator</dfn> describes a childhood relationship";
+ ret += " 'greater-than sign' (<code>></code>) character and";
+ ret += " separates two sequences of simple selectors.";
+ ret += " </p><div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following selector represents a <code>p</code> element that is";
+ ret += " child of <code>body</code>:</p>";
+ ret += " <pre>body > p</pre>";
+ ret += " <p>The following example combines descendant combinators and child";
+ ret += " combinators.</p>";
+ ret += " <pre>div ol>li p</pre>";
+ ret += " <!-- LEAVE THOSE SPACES OUT! see below -->";
+ ret += " <p>It represents a <code>p</code> element that is a descendant of an";
+ ret += " <code>li</code> element; the <code>li</code> element must be the";
+ ret += " child of an <code>ol</code> element; the <code>ol</code> element must";
+ ret += " be a descendant of a <code>div</code>. Notice that the optional white";
+ ret += " space around the '>' combinator has been left out.</p>";
+ ret += " </div>";
+ ret += " <p>For information on selecting the first child of an element, please";
+ ret += " see the section on the <code><a href='#structural-pseudos'>:first-child</a></code> pseudo-class";
+ ret += " above.</p>";
+ ret += " <h3><a name='sibling-combinators'>8.3. Sibling combinators</a></h3>";
+ ret += " <p>There are two different sibling combinators: the adjacent sibling";
+ ret += " considering adjacency of elements.</p>";
+ ret += " <h4><a name='adjacent-sibling-combinators'>8.3.1. Adjacent sibling combinator</a>";
+ ret += " </h4>";
+ ret += " <p>The adjacent sibling combinator is made of the 'plus";
+ ret += " sign' (U+002B, <code>+</code>) character that separates two";
+ ret += " sequences of simple selectors. The elements represented by the two";
+ ret += " represented by the second one.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <p>The following selector represents a <code>p</code> element";
+ ret += " immediately following a <code>math</code> element:</p>";
+ ret += " <pre>math + p</pre>";
+ ret += " <p>The following selector is conceptually similar to the one in the";
+ ret += " adds a constraint to the <code>h1</code> element, that it must have";
+ ret += " <code>class='opener'</code>:</p>";
+ ret += " <pre>h1.opener + h2</pre>";
+ ret += " </div>";
+ ret += " <h4><a name='general-sibling-combinators'>8.3.2. General sibling combinator</a>";
+ ret += " </h4>";
+ ret += " <p>The general sibling combinator is made of the 'tilde'";
+ ret += " (U+007E, <code>~</code>) character that separates two sequences of";
+ ret += " simple selectors. The elements represented by the two sequences share";
+ ret += " represented by the second one.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Example:</p>";
+ ret += " <pre>h1 ~ pre</pre>";
+ ret += " <p>represents a <code>pre</code> element following an <code>h1</code>. It";
+ ret += " is a correct and valid, but partial, description of:</p>";
+ ret += " <pre><h1>Definition of the function a</h1>";
+ ret += " <pre>function a(x) = 12x/13.5</pre></pre>";
+ ret += " </div>";
+ ret += " <h2><a name='specificity'>9. Calculating a selector's specificity</a></h2>";
+ ret += " <p>A selector's specificity is calculated as follows:</p>";
+ ret += " <ul>";
+ ret += " <li>count the number of ID selectors in the selector (= a)</li>";
+ ret += " <li>count the number of class selectors, attributes selectors, and";
+ ret += " </li>";
+ ret += " <li>count the number of element names in the selector (= c)</li>";
+ ret += " <li>ignore pseudo-elements</li>";
+ ret += " </ul>";
+ ret += " <p>Selectors inside <a href='#negation'>the negation pseudo-class</a>";
+ ret += " a pseudo-class.</p>";
+ ret += " <p>Concatenating the three numbers a-b-c (in a number system with a";
+ ret += " large base) gives the specificity.</p>";
+ ret += " <div class='example'>";
+ ret += " <p>Examples:</p>";
+ ret += " <pre>* /* a=0 b=0 c=0 -> specificity = 0 */";
+ ret += " </pre>";
+ ret += " </div>";
+ ret += " <p class='note'><strong>Note:</strong> the specificity of the styles";
+ ret += " specified in an HTML <code>style</code> attribute is described in CSS";
+ ret += " 2.1. <a href='#refsCSS21'>[CSS21]</a>.</p>";
+ ret += " <h2><a name='w3cselgrammar'>10. The grammar of Selectors</a></h2>";
+ ret += " <h3><a name='grammar'>10.1. Grammar</a></h3>";
+ ret += " <p>The grammar below defines the syntax of Selectors. It is globally";
+ ret += " shorthand notations beyond Yacc (see <a href='#refsYACC'>[YACC]</a>)";
+ ret += " are used:</p>";
+ ret += " <ul>";
+ ret += " <li><b>*</b>: 0 or more";
+ ret += " </li><li><b>+</b>: 1 or more";
+ ret += " </li><li><b>?</b>: 0 or 1";
+ ret += " </li><li><b>|</b>: separates alternatives";
+ ret += " </li><li><b>[ ]</b>: grouping</li>";
+ ret += " </ul>";
+ ret += " <p>The productions are:</p>";
+ ret += " <pre>selectors_group";
+ ret += " ;</pre>";
+ ret += " <h3><a name='lex'>10.2. Lexical scanner</a></h3>";
+ ret += " <p>The following is the <a name='x3'>tokenizer</a>, written in Flex (see";
+ ret += " <a href='#refsFLEX'>[FLEX]</a>) notation. The tokenizer is";
+ ret += " case-insensitive.</p>";
+ ret += " <p>The two occurrences of '\377' represent the highest character";
+ ret += " possible code point in Unicode/ISO-10646. <a href='#refsUNICODE'>[UNICODE]</a></p>";
+ ret += " <pre>%option case-insensitive";
+ ret += " . return *yytext;</pre>";
+ ret += " <h2><a name='downlevel'>11. Namespaces and down-level clients</a></h2>";
+ ret += " <p>An important issue is the interaction of CSS selectors with XML";
+ ret += " to construct a CSS style sheet which will properly match selectors in";
+ ret += " is possible to construct a style sheet in which selectors would match";
+ ret += " elements and attributes correctly.</p>";
+ ret += " <p>It should be noted that a down-level CSS client will (if it";
+ ret += " <code>@namespace</code> at-rules, as well as all style rules that make";
+ ret += " use of namespace qualified element type or attribute selectors. The";
+ ret += " than possibly match them incorrectly.</p>";
+ ret += " <p>The use of default namespaces in CSS makes it possible to write";
+ ret += " element type selectors that will function in both namespace aware CSS";
+ ret += " down-level clients may incorrectly match selectors against XML";
+ ret += " elements in other namespaces.</p>";
+ ret += " <p>The following are scenarios and examples in which it is possible to";
+ ret += " that do not implement this proposal.</p>";
+ ret += " <ol>";
+ ret += " <li>";
+ ret += " <p>The XML document does not use namespaces.</p>";
+ ret += " <ul>";
+ ret += " <li>In this case, it is obviously not necessary to declare or use";
+ ret += " attribute selectors will function adequately in a down-level";
+ ret += " </li>";
+ ret += " <li>In a CSS namespace aware client, the default behavior of";
+ ret += " element selectors matching without regard to namespace will";
+ ret += " present. However, the use of specific element type selectors";
+ ret += " match only elements that have no namespace ('<code>|name</code>')";
+ ret += " will guarantee that selectors will match only XML elements that";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li>";
+ ret += " <li>";
+ ret += " <p>The XML document defines a single, default namespace used";
+ ret += " names.</p>";
+ ret += " <ul>";
+ ret += " <li>In this case, a down-level client will function as if";
+ ret += " element type and attribute selectors will match against all";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li>";
+ ret += " <li>";
+ ret += " <p>The XML document does <b>not</b> use a default namespace, all";
+ ret += " to the same URI).</p>";
+ ret += " <ul>";
+ ret += " <li>In this case, the down-level client will view and match";
+ ret += " element type and attribute selectors based on their fully";
+ ret += " qualified name, not the local part as outlined in the <a href='#typenmsp'>Type selectors and Namespaces</a>";
+ ret += " selectors may be declared using an escaped colon";
+ ret += " '<code>\\:</code>'";
+ ret += " '<code>html\\:h1</code>' will match";
+ ret += " <code><html:h1></code>. Selectors using the qualified name";
+ ret += " </li>";
+ ret += " <li>Note that selectors declared in this fashion will";
+ ret += " <em>only</em> match in down-level clients. A CSS namespace aware";
+ ret += " client will match element type and attribute selectors based on";
+ ret += " the name's local part. Selectors declared with the fully";
+ ret += " </li>";
+ ret += " </ul>";
+ ret += " </li>";
+ ret += " </ol>";
+ ret += " <p>In other scenarios: when the namespace prefixes used in the XML are";
+ ret += " <em>different</em> namespace URIs within the same document, or in";
+ ret += " a CSS and XML namespace aware client.</p>";
+ ret += " <h2><a name='profiling'>12. Profiles</a></h2>";
+ ret += " <p>Each specification using Selectors must define the subset of W3C";
+ ret += " Selectors it allows and excludes, and describe the local meaning of";
+ ret += " all the components of that subset.</p>";
+ ret += " <p>Non normative examples:";
+ ret += " </p><div class='profile'>";
+ ret += " <table class='tprofile'>";
+ ret += " <tbody>";
+ ret += " <tr>";
+ ret += " <th class='title' colspan='2'>Selectors profile</th>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Specification</th>";
+ ret += " <td>CSS level 1</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Accepts</th>";
+ ret += " <td>type selectors<br>class selectors<br>ID selectors<br>:link,";
+ ret += " :visited and :active pseudo-classes<br>descendant combinator";
+ ret += " <br>::first-line and ::first-letter pseudo-elements";
+ ret += " </td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Excludes</th>";
+ ret += " <td>";
+ ret += " <p>universal selector<br>attribute selectors<br>:hover and";
+ ret += " pseudo-classes<br>:target pseudo-class<br>:lang()";
+ ret += " pseudo-class<br>all UI";
+ ret += " element states pseudo-classes<br>all structural";
+ ret += " pseudo-classes<br>negation pseudo-class<br>all";
+ ret += " UI element fragments pseudo-elements<br>::before and ::after";
+ ret += " pseudo-elements<br>child combinators<br>sibling combinators";
+ ret += " </p><p>namespaces</p></td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Extra constraints</th>";
+ ret += " <td>only one class selector allowed per sequence of simple";
+ ret += " selectors";
+ ret += " </td>";
+ ret += " </tr>";
+ ret += " </tbody>";
+ ret += " </table>";
+ ret += " <br><br>";
+ ret += " <table class='tprofile'>";
+ ret += " <tbody>";
+ ret += " <tr>";
+ ret += " <th class='title' colspan='2'>Selectors profile</th>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Specification</th>";
+ ret += " <td>CSS level 2</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Accepts</th>";
+ ret += " <td>type selectors<br>universal selector<br>attribute presence and";
+ ret += " values selectors<br>class selectors<br>ID selectors<br>:link,";
+ ret += " <br>descendant combinator<br>child combinator<br>adjacent";
+ ret += " combinator<br>::first-line and ::first-letter";
+ ret += " pseudo-elements<br>::before";
+ ret += " </td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Excludes</th>";
+ ret += " <td>";
+ ret += " <p>content selectors<br>substring matching attribute";
+ ret += " selectors<br>:target pseudo-classes<br>all UI element";
+ ret += " states pseudo-classes<br>all structural pseudo-classes other";
+ ret += " than :first-child<br>negation pseudo-class<br>all UI element";
+ ret += " fragments pseudo-elements<br>general sibling combinators";
+ ret += " </p><p>namespaces</p></td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Extra constraints</th>";
+ ret += " <td>more than one class selector per sequence of simple selectors";
+ ret += " </td>";
+ ret += " </tr>";
+ ret += " </tbody>";
+ ret += " </table>";
+ ret += " <p>In CSS, selectors express pattern matching rules that determine which";
+ ret += " </p><p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>";
+ ret += " with attribute <code>name</code> set inside a section 1 header";
+ ret += " <code>h1</code>:";
+ ret += " </p><pre>h1 a[name]</pre>";
+ ret += " <p>All CSS declarations attached to such a selector are applied to elements";
+ ret += " matching it.</p></div>";
+ ret += " <div class='profile'>";
+ ret += " <table class='tprofile'>";
+ ret += " <tbody>";
+ ret += " <tr>";
+ ret += " <th class='title' colspan='2'>Selectors profile</th>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Specification</th>";
+ ret += " <td>STTS 3</td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Accepts</th>";
+ ret += " <td>";
+ ret += " <p>type selectors<br>universal selectors<br>attribute";
+ ret += " selectors<br>class";
+ ret += " selectors<br>ID selectors<br>all structural";
+ ret += " pseudo-classes<br>";
+ ret += " </p><p>namespaces</p></td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Excludes</th>";
+ ret += " <td>non-accepted pseudo-classes<br>pseudo-elements<br></td>";
+ ret += " </tr>";
+ ret += " <tr>";
+ ret += " <th>Extra constraints</th>";
+ ret += " <td>some selectors and combinators are not allowed in fragment";
+ ret += " </td>";
+ ret += " </tr>";
+ ret += " </tbody>";
+ ret += " </table>";
+ ret += " <p>Selectors can be used in STTS 3 in two different";
+ ret += " </p><ol>";
+ ret += " <li>a selection mechanism equivalent to CSS selection mechanism:";
+ ret += " </li><li>fragment descriptions that appear on the right side of declarations.";
+ ret += " </li>";
+ ret += " </ol>";
+ ret += " </div>";
+ ret += " <h2><a name='Conformance'></a>13. Conformance and requirements</h2>";
+ ret += " <p>This section defines conformance with the present specification only.";
+ ret += " </p><p>The inability of a user agent to implement part of this specification due to";
+ ret += " </p><p>All specifications reusing Selectors must contain a <a href='#profiling'>Profile</a> listing the";
+ ret += " subset of Selectors it accepts or excludes, and describing the constraints";
+ ret += " </p><p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a";
+ ret += " </p><p>User agents must observe the rules for handling parsing errors:";
+ ret += " </p><ul>";
+ ret += " <li>a simple selector containing an undeclared namespace prefix is invalid";
+ ret += " </li>";
+ ret += " <li>a selector containing an invalid simple selector, an invalid combinator";
+ ret += " </li>";
+ ret += " <li>a group of selectors containing an invalid selector is invalid.</li>";
+ ret += " </ul>";
+ ret += " <p>Specifications reusing Selectors must define how to handle parsing";
+ ret += " used is dropped.)</p>";
+ ret += " <!-- Apparently all these references are out of date:";
+ ret += " <p>Implementations of this specification must behave as";
+ ret += " 'recipients of text data' as defined by <a href='#refsCWWW'>[CWWW]</a>";
+ ret += " when parsing selectors and attempting matches. (In particular,";
+ ret += " <a href='#refsCWWW'>[CWWW]</a> and <a";
+ ret += " href='#refsUNICODE'>[UNICODE]</a> and apply to implementations of this";
+ ret += " specification.</p>-->";
+ ret += " <h2><a name='Tests'></a>14. Tests</h2>";
+ ret += " <p>This specification has <a href='http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/'>a test";
+ ret += " suite</a> allowing user agents to verify their basic conformance to";
+ ret += " and does not cover all possible combined cases of Selectors.</p>";
+ ret += " <h2><a name='ACKS'></a>15. Acknowledgements</h2>";
+ ret += " <p>The CSS working group would like to thank everyone who has sent";
+ ret += " comments on this specification over the years.</p>";
+ ret += " <p>The working group would like to extend special thanks to Donna";
+ ret += " the final editorial review.</p>";
+ ret += " <h2><a name='references'>16. References</a></h2>";
+ ret += " <dl class='refs'>";
+ ret += " <dt>[CSS1]";
+ ret += " </dt><dd><a name='refsCSS1'></a> Bert Bos, Håkon Wium Lie; '<cite>Cascading";
+ ret += " Style Sheets, level 1</cite>', W3C Recommendation, 17 Dec 1996, revised";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/REC-CSS1'>http://www.w3.org/TR/REC-CSS1</a></code>)";
+ ret += " </dd><dt>[CSS21]";
+ ret += " </dt><dd><a name='refsCSS21'></a> Bert Bos, Tantek Çelik, Ian Hickson, Håkon";
+ ret += " Wium Lie, editors; '<cite>Cascading Style Sheets, level 2 revision";
+ ret += " 1</cite>', W3C Working Draft, 13 June 2005";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/CSS21'>http://www.w3.org/TR/CSS21</a></code>)";
+ ret += " </dd><dt>[CWWW]";
+ ret += " </dt><dd><a name='refsCWWW'></a> Martin J. Dürst, François Yergeau,";
+ ret += " Misha Wolf, Asmus Freytag, Tex Texin, editors; '<cite>Character Model";
+ ret += " for the World Wide Web</cite>', W3C Recommendation, 15 February 2005";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/charmod/'>http://www.w3.org/TR/charmod/</a></code>)";
+ ret += " </dd><dt>[FLEX]";
+ ret += " </dt><dd><a name='refsFLEX'></a> '<cite>Flex: The Lexical Scanner";
+ ret += " Generator</cite>', Version 2.3.7, ISBN 1882114213";
+ ret += " </dd><dt>[HTML4]";
+ ret += " </dt><dd><a name='refsHTML4'></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs,";
+ ret += " editors; '<cite>HTML 4.01 Specification</cite>', W3C Recommendation, 24";
+ ret += " </dd><dd>";
+ ret += " (<a href='http://www.w3.org/TR/html4/'><code>http://www.w3.org/TR/html4/</code></a>)";
+ ret += " </dd><dt>[MATH]";
+ ret += " </dt><dd><a name='refsMATH'></a> Patrick Ion, Robert Miner, editors; '<cite>Mathematical";
+ ret += " Markup Language (MathML) 1.01</cite>', W3C Recommendation, revision of 7";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/REC-MathML/'>http://www.w3.org/TR/REC-MathML/</a></code>)";
+ ret += " </dd><dt>[RFC3066]";
+ ret += " </dt><dd><a name='refsRFC3066'></a> H. Alvestrand; '<cite>Tags for the";
+ ret += " Identification of Languages</cite>', Request for Comments 3066, January";
+ ret += " </dd><dd>(<a href='http://www.ietf.org/rfc/rfc3066.txt'><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)";
+ ret += " </dd><dt>[STTS]";
+ ret += " </dt><dd><a name='refsSTTS'></a> Daniel Glazman; '<cite>Simple Tree Transformation";
+ ret += " Sheets 3</cite>', Electricité de France, submission to the W3C,";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/NOTE-STTS3'>http://www.w3.org/TR/NOTE-STTS3</a></code>)";
+ ret += " </dd><dt>[SVG]";
+ ret += " </dt><dd><a name='refsSVG'></a> Jon Ferraiolo, 藤沢 淳, Dean";
+ ret += " Jackson, editors; '<cite>Scalable Vector Graphics (SVG) 1.1";
+ ret += " Specification</cite>', W3C Recommendation, 14 January 2003";
+ ret += " </dd><dd>(<code><a href='http://www.w3.org/TR/SVG/'>http://www.w3.org/TR/SVG/</a></code>)";
+ ret += " </dd><dt>[UNICODE]</dt>";
+ ret += " <dd><a name='refsUNICODE'></a> <cite><a href='http://www.unicode.org/versions/Unicode4.1.0/'>The Unicode";
+ ret += " Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA,";
+ ret += " Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href='http://www.unicode.org/versions/Unicode4.0.1/'>Unicode";
+ ret += " 4.0.1</a> and <a href='http://www.unicode.org/versions/Unicode4.1.0/'>Unicode";
+ ret += " 4.1.0</a>.";
+ ret += " </dd><dd>(<code><a href='http://www.unicode.org/versions/'>http://www.unicode.org/versions/</a></code>)";
+ ret += " </dd>";
+ ret += " <dt>[XML10]";
+ ret += " </dt><dd><a name='refsXML10'></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen,";
+ ret += " Eve Maler, François Yergeau, editors; '<cite>Extensible Markup";
+ ret += " Language (XML) 1.0 (Third Edition)</cite>', W3C Recommendation, 4";
+ ret += " </dd><dd>(<a href='http://www.w3.org/TR/REC-xml/'><code>http://www.w3.org/TR/REC-xml/</code></a>)";
+ ret += " </dd><dt>[XMLNAMES]";
+ ret += " </dt><dd><a name='refsXMLNAMES'></a> Tim Bray, Dave Hollander, Andrew Layman,";
+ ret += " editors; '<cite>Namespaces in XML</cite>', W3C Recommendation, 14";
+ ret += " </dd><dd>(<a href='http://www.w3.org/TR/REC-xml-names/'><code>http://www.w3.org/TR/REC-xml-names/</code></a>)";
+ ret += " </dd><dt>[YACC]";
+ ret += " </dt><dd><a name='refsYACC'></a> S. C. Johnson; '<cite>YACC — Yet another";
+ ret += " compiler compiler</cite>', Technical Report, Murray Hill, 1975";
+ ret += " </dd></dl>'; </div>";
+ ret += " <input name='n' value='v1' type='radio'>1";
+ ret += " <input name='n' value='v2' checked='checked' type='radio'>2";
+ ret += "</body></html>";
+ return ret;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright 2011, The gwtquery team.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.query.client;
-
-import static com.google.gwt.query.client.GQuery.$;
-import static com.google.gwt.query.client.GQuery.document;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.query.client.plugins.Widgets;
-import com.google.gwt.query.client.plugins.widgets.WidgetFactory;
-import com.google.gwt.query.client.plugins.widgets.WidgetsUtils;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.Widget;
-
-/**
- * Test class for testing gwtquery widgets plugin api.
- */
-public class GQueryWidgetsTest extends GWTTestCase {
-
- static Element e = null;
-
- static HTML testPanel = null;
-
- int testSubmitEventCont = 0;
-
- public String getModuleName() {
- return "com.google.gwt.query.Query";
- }
-
- public void testGWTQueryCoreWidgets() {
- final FlowPanel p = new FlowPanel();
- Button b = new Button("test");
- RootPanel.get().add(b);
- RootPanel.get().add(p);
-
- int nitems = 4;
- final String label1 = "I'm the label ";
- final String label2 = "Finally I'm just a simple label";
-
- for (int i = 0; i < nitems; i++) {
- Label l = new Label(label1 + i);
- p.add(l);
- }
- $("<div>whatever</div").appendTo($(p));
-
- b.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- $(".gwt-Label", p).each(new Function() {
- @Override
- public void f(Widget w) {
- Label l = (Label) w;
- l.setText(label2);
- }
- });
- }
- });
-
- $(".gwt-Label", p).each(new Function() {
- @Override
- public Object f(Widget w, int i) {
- assertEquals(label1 + i, ((Label)w).getText());
- return null;
- }
- });
-
- $(b).click();
-
- $(".gwt-Label", p).each(new Function() {
- public void f(Element e) {
- assertEquals(label2, $(e).text());
- }
- });
-
- $("div", p).each(new Function() {
- public void f(Element e) {
- // Just to avoid the exception when non-widget elements match
- }
- public void f(Widget w) {
- if (w instanceof Label) {
- assertEquals(label2, $(w).text());
- }
- }
- });
-
- p.removeFromParent();
- b.removeFromParent();
- }
-
- class TestButtonWidgetFactory implements WidgetFactory<Button> {
- public Button create(Element e) {
- Button button = new Button();
- button.getElement().setInnerText(e.getInnerText());
- WidgetsUtils.replaceOrAppend(e, button);
- return button;
- }
- }
-
- public void testGQueryWidgets() {
- final Button b1 = new Button("click-me");
- RootPanel.get().add(b1);
- GQuery g = $(b1);
- Button b2 = (Button) g.as(Widgets.Widgets).widget();
- assertEquals(b1, b2);
-
- b2 = $("<button>Click-me</button>").appendTo(document)
- .as(Widgets.Widgets).widgets(new TestButtonWidgetFactory(), null).widget();
- b2.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- $(b1).css("color", "red");
- }
- });
-
- b2.click();
- assertEquals("red", $(b1).css("color"));
- }
-
-}
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.document;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.plugins.Widgets;
+import com.google.gwt.query.client.plugins.widgets.WidgetFactory;
+import com.google.gwt.query.client.plugins.widgets.WidgetsUtils;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Test class for testing gwtquery widgets plugin api.
+ */
+public class GQueryWidgetsTestGwt extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ int testSubmitEventCont = 0;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void testGWTQueryCoreWidgets() {
+ final FlowPanel p = new FlowPanel();
+ Button b = new Button("test");
+ RootPanel.get().add(b);
+ RootPanel.get().add(p);
+
+ int nitems = 4;
+ final String label1 = "I'm the label ";
+ final String label2 = "Finally I'm just a simple label";
+
+ for (int i = 0; i < nitems; i++) {
+ Label l = new Label(label1 + i);
+ p.add(l);
+ }
+ $("<div>whatever</div").appendTo($(p));
+
+ b.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ $(".gwt-Label", p).each(new Function() {
+ @Override
+ public void f(Widget w) {
+ Label l = (Label) w;
+ l.setText(label2);
+ }
+ });
+ }
+ });
+
+ $(".gwt-Label", p).each(new Function() {
+ @Override
+ public Object f(Widget w, int i) {
+ assertEquals(label1 + i, ((Label)w).getText());
+ return null;
+ }
+ });
+
+ $(b).click();
+
+ $(".gwt-Label", p).each(new Function() {
+ public void f(Element e) {
+ assertEquals(label2, $(e).text());
+ }
+ });
+
+ $("div", p).each(new Function() {
+ public void f(Element e) {
+ // Just to avoid the exception when non-widget elements match
+ }
+ public void f(Widget w) {
+ if (w instanceof Label) {
+ assertEquals(label2, $(w).text());
+ }
+ }
+ });
+
+ p.removeFromParent();
+ b.removeFromParent();
+ }
+
+ class TestButtonWidgetFactory implements WidgetFactory<Button> {
+ public Button create(Element e) {
+ Button button = new Button();
+ button.getElement().setInnerText(e.getInnerText());
+ WidgetsUtils.replaceOrAppend(e, button);
+ return button;
+ }
+ }
+
+ public void testGQueryWidgets() {
+ final Button b1 = new Button("click-me");
+ RootPanel.get().add(b1);
+ GQuery g = $(b1);
+ Button b2 = (Button) g.as(Widgets.Widgets).widget();
+ assertEquals(b1, b2);
+
+ b2 = $("<button>Click-me</button>").appendTo(document)
+ .as(Widgets.Widgets).widgets(new TestButtonWidgetFactory(), null).widget();
+ b2.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ $(b1).css("color", "red");
+ }
+ });
+
+ b2.click();
+ assertEquals("red", $(b1).css("color"));
+ }
+
+}
}
public void testAssertHtmlEquals() {
- GQueryCoreTest.assertHtmlEquals("<span>hello</span>",
+ GQueryCoreTestGwt.assertHtmlEquals("<span>hello</span>",
"<span $h=\"5\">hello</span>");
- GQueryCoreTest.assertHtmlEquals("<p class=\"abc\">whatever</p> ",
+ GQueryCoreTestGwt.assertHtmlEquals("<p class=\"abc\">whatever</p> ",
" <p class=abc added=\"null\">Whatever</p>");
}
assertEquals("{\"$x\":22.60,\"$y\":\".0\",\"h\":\"#y\"}", Properties
.wrapPropertiesString("$x:22.60,$y:.0,h:#y"));
}
-
- public void testtt() {
- String selector = "div[class!=madeup]";
- if (selector.matches(".*\\[\\w+!=[^\\]]+\\].*")) {
- System.out.println("OK");
- selector = selector.replaceAll("(\\[\\w+)!(=[^\\]]+\\])", ":not($1$2)");
- }
- System.out.println(selector);
- }
}
package com.google.gwt.query.client.impl;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.rebind.SelectorGeneratorCssToXPath;
/**
* Test for selector engine implementations
public class SelectorEnginesTest extends GWTTestCase {
public String getModuleName() {
- return "com.google.gwt.query.Query";
+ return null;
}
public void testCssToXpath() {
SelectorEngineCssToXPath sel = new SelectorEngineCssToXPath();
+ if (getModuleName() == null) {
+ sel = new SelectorEngineCssToXPath(SelectorEngineCssToXPath.replacerGwt);
+ }
+
+
assertEquals(".//div[starts-with(@class,'exa') and (substring(@class,string-length(@class)-3)='mple')]",
sel.css2Xpath("div[class^=exa][class$=mple]"));
assertEquals(".//div[not(contains(concat(' ',normalize-space(@class),' '),' example '))]",
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client.impl;
+
+
+/**
+ * Test for selector engine implementations run in gwt
+ */
+public class SelectorEnginesTestGwt extends SelectorEnginesTest {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+}
Object[] regs = SelectorEngineCssToXPath.regs;
String r1 = s, r2 = s;
for (int i = 0; i < regs.length;) {
- r1 = SelectorGeneratorCssToXPath.replacerJvm.replaceAll(r1, regs[i].toString(), regs[i+1]);
- r2 = SelectorGeneratorCssToXPath.replacer.replaceAll(r2, regs[i].toString(), regs[i+1]);
+ r1 = SelectorGeneratorCssToXPath.replacer.replaceAll(r1, regs[i].toString(), regs[i+1]);
+ r2 = SelectorEngineCssToXPath.replacerGwt.replaceAll(r2, regs[i].toString(), regs[i+1]);
i+=2;
}
assertEquals(r1, r2);
public void testReplaceAll() {
assertEquals("<img src='thumbs/01'/> <img src='thumbs/03'/>",
- SelectorGeneratorCssToXPath.replacerGwt.replaceAll("/[thumb01]/ /[thumb03]/", "/\\[thumb(\\d+)\\]/", new ReplaceCallback() {
+ SelectorEngineCssToXPath.replacerGwt.replaceAll("/[thumb01]/ /[thumb03]/", "/\\[thumb(\\d+)\\]/", new ReplaceCallback() {
public String foundMatch(ArrayList<String>s) {
return "<img src='thumbs/" + s.get(1) + "'/>";
}