]> source.dussan.org Git - gwtquery.git/commitdiff
fix tests, group them in a gwt-suite to run in a jvm instance and speed up maven...
authorManolo Carrasco <manolo@apache.org>
Thu, 3 Nov 2011 10:53:52 +0000 (10:53 +0000)
committerManolo Carrasco <manolo@apache.org>
Thu, 3 Nov 2011 10:53:52 +0000 (10:53 +0000)
28 files changed:
gwtquery-core/pom.xml
gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java
gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorCssToXPath.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTest.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java
gwtquery-core/src/test/java/com/google/gwt/query/client/impl/SelectorEnginesTest.java
gwtquery-core/src/test/java/com/google/gwt/query/client/impl/SelectorEnginesTestGwt.java [new file with mode: 0644]
gwtquery-core/src/test/java/com/google/gwt/query/rebind/SelectorGeneratorsTest.java

index afd465ce615eee75fb77d3b76ef147025e52a936..520531a4655d478bcdf1f46aaf2a11133207fda6 100644 (file)
             </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>
index 5e68a6fc820f8ed296b03f73e7f2d5ff3ca2a2af..1ae86eec602cec1316ac5462d7412883b0449222 100644 (file)
@@ -20,6 +20,7 @@ import java.util.List;
 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;
@@ -43,12 +44,15 @@ import com.google.gwt.query.client.js.JsCache;
 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;
@@ -110,6 +114,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   LazyGQuery<T> andSelf();
 
   /**
+   * 
    * The animate() method allows you to create animation effects on any numeric
    * Attribute, CSS property, or color CSS property.
    * 
@@ -123,11 +128,10 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * 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',
@@ -140,30 +144,35 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * 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.
    * 
@@ -177,10 +186,11 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * 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',
@@ -193,33 +203,27 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * 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
@@ -466,6 +470,17 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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
@@ -490,17 +505,6 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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.
    */
@@ -714,12 +718,12 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   /**
    * 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));
    *  }
@@ -732,7 +736,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * <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));
    *    }
@@ -741,22 +745,21 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *
    * </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){
@@ -764,10 +767,8 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *  }
    * });
    * </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){
@@ -778,24 +779,25 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *  }
    * });
    *
-   * 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));
    *  }
@@ -808,7 +810,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * <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));
    *    }
@@ -817,21 +819,22 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *
    * </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){
@@ -839,8 +842,10 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *  }
    * });
    * </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){
@@ -851,15 +856,14 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    *  }
    * });
    *
-   * </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.
@@ -905,19 +909,19 @@ public interface LazyGQuery<T> extends LazyBase<T>{
 
   /**
    * 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
@@ -1083,15 +1087,15 @@ public interface LazyGQuery<T> extends LazyBase<T>{
 
   /**
    * 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
@@ -1225,6 +1229,11 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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.
@@ -1274,6 +1283,18 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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
@@ -1327,18 +1348,6 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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
@@ -1394,9 +1403,28 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   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.
@@ -1703,12 +1731,6 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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.
    * 
@@ -1738,6 +1760,12 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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.
    * 
@@ -1856,14 +1884,14 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   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.
@@ -2042,7 +2070,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   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();
 
@@ -2077,7 +2105,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{
   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();
 
@@ -2107,6 +2135,11 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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
@@ -2123,13 +2156,13 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    * 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
@@ -2210,11 +2243,6 @@ public interface LazyGQuery<T> extends LazyBase<T>{
    */
   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.
index 9f385dfb07e1dd7b768ed1904bbf5afc87cd06ca..beb89003a9c7b248e16ba2381b6055e3e6cd681c 100644 (file)
@@ -27,6 +27,7 @@ import com.google.gwt.query.client.js.JsNodeArray;
 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
@@ -192,6 +193,32 @@ public class SelectorEngineCssToXPath extends SelectorEngineImpl {
       }\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
index e11030330cb2a4a598dc04f8078ec68d1a374732..5dac25783467303e52108a63b75c5b8fb0bb3b89 100644 (file)
@@ -314,4 +314,9 @@ public class JsUtils {
       return Properties.create();
     }
   }
+  
+  public static native boolean isDefaultPrevented(JavaScriptObject e)/*-{
+      return e.defaultPrevented || e.returnValue === false || e.getPreventDefault && e.getPreventDefault() ? true : false;
+  }-*/;
+  
 }
index 95a92a199426cd95641d3e5392e83052930b8db6..e9bfaeaf81470dca08baf3c3eea95429cd797570 100644 (file)
@@ -228,20 +228,27 @@ public class Events extends GQuery {
     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;
   }
 
@@ -289,11 +296,17 @@ public class Events extends GQuery {
     }
     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);
+          }
+        }
       }
     }
   }
@@ -306,7 +319,5 @@ public class Events extends GQuery {
     }
     return this;
   }
-  
-  
 
 }
index 0dc01b726e234d0e56e7bcea72658a92f6c05133..2e8bac07ccb5d250a708cade2af9031439e676b7 100644 (file)
@@ -19,6 +19,7 @@ import com.google.gwt.dom.client.NativeEvent;
 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;
@@ -114,8 +115,9 @@ public interface LazyEvents<T> extends LazyBase<T>{
    * 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
index a90b6fe2086ae2d15a426c20ea352bacd5481a6e..a726b6bd8fd173e324c4d0419ce77caaf304d4da 100644 (file)
@@ -31,7 +31,6 @@ import com.google.gwt.query.client.Selector;
 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
@@ -44,7 +43,7 @@ public class SelectorGeneratorCssToXPath extends SelectorGeneratorBase {
   /**\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
@@ -68,34 +67,6 @@ public class SelectorGeneratorCssToXPath extends SelectorGeneratorBase {
     }\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
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTest.java
deleted file mode 100644 (file)
index 7056a9a..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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());
-  }
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java
new file mode 100644 (file)
index 0000000..231db88
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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());
+  }
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java
deleted file mode 100644 (file)
index 0149df5..0000000
+++ /dev/null
@@ -1,1820 +0,0 @@
-/*
- * 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());
-  }
-
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java
new file mode 100644 (file)
index 0000000..347adb1
--- /dev/null
@@ -0,0 +1,1825 @@
+/*
+ * 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());
+  }
+
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTest.java
deleted file mode 100644 (file)
index 9ad7d71..0000000
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * 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));
-
-  }
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCssTestGwt.java
new file mode 100644 (file)
index 0000000..561a029
--- /dev/null
@@ -0,0 +1,1149 @@
+/*
+ * 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));
+
+  }
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTest.java
deleted file mode 100644 (file)
index bc4f1b7..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * 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);
-  
-  }
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java
new file mode 100644 (file)
index 0000000..f286d6f
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * 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);
+  
+  }
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java
deleted file mode 100644 (file)
index 601d9e9..0000000
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * 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));
-  }
-
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java
new file mode 100644 (file)
index 0000000..5a8ba73
--- /dev/null
@@ -0,0 +1,874 @@
+/*
+ * 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));
+  }
+
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java
new file mode 100644 (file)
index 0000000..613d1b5
--- /dev/null
@@ -0,0 +1,31 @@
+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;
+  }
+
+
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTest.java
deleted file mode 100644 (file)
index 6a1a008..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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"));
-  }
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryJsTestGwt.java
new file mode 100644 (file)
index 0000000..3884286
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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"));
+  }
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java
deleted file mode 100644 (file)
index 9cba7b2..0000000
+++ /dev/null
@@ -1,2342 +0,0 @@
-/*
- * 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 &gt; 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>&gt;</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'>&lt;!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'&gt;</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>&lt;H1&gt;Not green&lt;/H1&gt;";
-    ret += "      &lt;H1 class='pastoral'&gt;Very green&lt;/H1&gt;</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) &gt; 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 &gt; 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 &gt; 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 &gt; 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>&lt;p&gt; The last P before the note.&lt;/p&gt;";
-    ret += "      &lt;/div&gt;</pre>";
-    ret += "          but cannot represent the second <code>p</code> in the following";
-    ret += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";
-    ret += "      &lt;/div&gt;</pre>";
-    ret += "          <p>The following two selectors are usually equivalent:</p>";
-    ret += "        <pre>* &gt; 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 &gt; 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>&lt;dl&gt;";
-    ret += "      &lt;/dl&gt;</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 &gt; 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>&lt;p&gt;&lt;/p&gt;</pre>";
-    ret += "          <p><code>foo:empty</code> is not a valid representation for the";
-    ret += "              following fragments:</p>";
-    ret += "          <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>";
-    ret += "          <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>";
-    ret += "          <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</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>      &lt;P&gt;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>      &lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML ";
-    ret += "      paragraph that <b>&lt;/P::first-line&gt;</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>      &lt;P&gt;<b>&lt;SPAN class='test'&gt;</b> This is a somewhat long HTML";
-    ret += "      lines.<b>&lt;/SPAN&gt;</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>      &lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class='test'&gt;</b> This is a";
-    ret += "      paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN";
-    ret += "          class='test'&gt;</b> be";
-    ret += "      lines.<b>&lt;/SPAN&gt;</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>&lt;DIV&gt;&lt;P&gt;This";
-    ret += "              line...&lt;/P&gt;&lt;/DIV&gt;</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>&lt;DIV&gt;&lt;P";
-    ret += "              etcetera&lt;/DIV&gt;</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>&lt;p&gt;&lt;br&gt;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>      &lt;DIV&gt;";
-    ret += "      </pre>";
-    ret += "      <p>is</p>";
-    ret += "      <pre>      &lt;DIV&gt;";
-    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>      &lt;!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'&gt;";
-    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>      &lt;P&gt;";
-    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>&lt;div&gt;";
-    ret += "      &lt;p&gt;The first text.</pre>";
-    ret += "          <p>is:";
-    ret += "      </p><pre>&lt;div&gt;";
-    ret += "      &lt;p&gt;&lt;div::first-letter&gt;&lt;p::first-letter&gt;T&lt;/...&gt;&lt;/...&gt;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>&lt;DIV&gt;&lt;P";
-    ret += "              etcetera&lt;/DIV&gt;</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>&lt;p&gt;&lt;br&gt;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>&lt;p&gt;'&lt;em&gt;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 += "      &lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</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>&lt;P&gt;";
-    ret += "      &lt;/P&gt;</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>&lt;h1&gt;This &lt;span class='myclass'&gt;headline";
-    ret += "      is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</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>&gt;</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 &gt; p</pre>";
-    ret += "          <p>The following example combines descendant combinators and child";
-    ret += "              combinators.</p>";
-    ret += "          <pre>div ol&gt;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 '&gt;' 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>&lt;h1&gt;Definition of the function a&lt;/h1&gt;";
-    ret += "      &lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</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 -&gt; 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>&lt;html:h1&gt;</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;
-  }
-
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTestGwt.java
new file mode 100644 (file)
index 0000000..ea54759
--- /dev/null
@@ -0,0 +1,2347 @@
+/*
+ * 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 &gt; 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>&gt;</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'>&lt;!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'&gt;</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>&lt;H1&gt;Not green&lt;/H1&gt;";
+    ret += "      &lt;H1 class='pastoral'&gt;Very green&lt;/H1&gt;</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) &gt; 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 &gt; 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 &gt; 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 &gt; 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>&lt;p&gt; The last P before the note.&lt;/p&gt;";
+    ret += "      &lt;/div&gt;</pre>";
+    ret += "          but cannot represent the second <code>p</code> in the following";
+    ret += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";
+    ret += "      &lt;/div&gt;</pre>";
+    ret += "          <p>The following two selectors are usually equivalent:</p>";
+    ret += "        <pre>* &gt; 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 &gt; 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>&lt;dl&gt;";
+    ret += "      &lt;/dl&gt;</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 &gt; 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>&lt;p&gt;&lt;/p&gt;</pre>";
+    ret += "          <p><code>foo:empty</code> is not a valid representation for the";
+    ret += "              following fragments:</p>";
+    ret += "          <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>";
+    ret += "          <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>";
+    ret += "          <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</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>      &lt;P&gt;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>      &lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML ";
+    ret += "      paragraph that <b>&lt;/P::first-line&gt;</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>      &lt;P&gt;<b>&lt;SPAN class='test'&gt;</b> This is a somewhat long HTML";
+    ret += "      lines.<b>&lt;/SPAN&gt;</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>      &lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class='test'&gt;</b> This is a";
+    ret += "      paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN";
+    ret += "          class='test'&gt;</b> be";
+    ret += "      lines.<b>&lt;/SPAN&gt;</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>&lt;DIV&gt;&lt;P&gt;This";
+    ret += "              line...&lt;/P&gt;&lt;/DIV&gt;</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>&lt;DIV&gt;&lt;P";
+    ret += "              etcetera&lt;/DIV&gt;</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>&lt;p&gt;&lt;br&gt;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>      &lt;DIV&gt;";
+    ret += "      </pre>";
+    ret += "      <p>is</p>";
+    ret += "      <pre>      &lt;DIV&gt;";
+    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>      &lt;!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'&gt;";
+    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>      &lt;P&gt;";
+    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>&lt;div&gt;";
+    ret += "      &lt;p&gt;The first text.</pre>";
+    ret += "          <p>is:";
+    ret += "      </p><pre>&lt;div&gt;";
+    ret += "      &lt;p&gt;&lt;div::first-letter&gt;&lt;p::first-letter&gt;T&lt;/...&gt;&lt;/...&gt;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>&lt;DIV&gt;&lt;P";
+    ret += "              etcetera&lt;/DIV&gt;</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>&lt;p&gt;&lt;br&gt;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>&lt;p&gt;'&lt;em&gt;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 += "      &lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</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>&lt;P&gt;";
+    ret += "      &lt;/P&gt;</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>&lt;h1&gt;This &lt;span class='myclass'&gt;headline";
+    ret += "      is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</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>&gt;</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 &gt; p</pre>";
+    ret += "          <p>The following example combines descendant combinators and child";
+    ret += "              combinators.</p>";
+    ret += "          <pre>div ol&gt;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 '&gt;' 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>&lt;h1&gt;Definition of the function a&lt;/h1&gt;";
+    ret += "      &lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</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 -&gt; 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>&lt;html:h1&gt;</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;
+  }
+
+}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTest.java
deleted file mode 100644 (file)
index 9a9ee9d..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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"));
-  }
-
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryWidgetsTestGwt.java
new file mode 100644 (file)
index 0000000..57d87db
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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"));
+  }
+
+}
index f51e119b2d805c4fc1be473dbbbae58d77d013e4..41aabee6c47ed18dfc75c21352c41c6d5423b209 100644 (file)
@@ -27,9 +27,9 @@ public class JreQueryCoreTest extends GWTTestCase {
   }
 
   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>");
   }
 
@@ -53,14 +53,5 @@ public class JreQueryCoreTest extends GWTTestCase {
     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);
-  }
 
 }
index 51a63104b56c5cffdd01a26e40febe4b92d40981..a3422438f27747254626782854af7fae6af7820d 100644 (file)
@@ -16,6 +16,7 @@
 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
@@ -23,12 +24,17 @@ import com.google.gwt.junit.client.GWTTestCase;
 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 '))]",
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/impl/SelectorEnginesTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/impl/SelectorEnginesTestGwt.java
new file mode 100644 (file)
index 0000000..8ff63a5
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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";
+  }
+
+}
index 7ebf3fa360fe320bad85eb031e86045680d4f9cc..5830e9ec083f6ce3247240fd6333efd34528db72 100644 (file)
@@ -36,8 +36,8 @@ public class SelectorGeneratorsTest extends GWTTestCase {
     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);
@@ -100,7 +100,7 @@ public class SelectorGeneratorsTest extends GWTTestCase {
 
   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) + "'/>";
       }