]> source.dussan.org Git - gwtquery.git/commitdiff
Many changes almost related with effects and the re-factor of plugins:
authorManolo Carrasco <manolo@apache.org>
Fri, 11 Jun 2010 09:53:32 +0000 (09:53 +0000)
committerManolo Carrasco <manolo@apache.org>
Fri, 11 Jun 2010 09:53:32 +0000 (09:53 +0000)
- Removed plugin stuff which already were moved to the plugins module
- Moved all GQuery core plugin stuff into the plugins namespace
- Redesign and recode of the Effects plugin using GWT animate as base
- Documented many undocumented methods
- Added a couple of scripts to generate Lazy interfaces from the class
- Modifications to the effects sample to show the usage of the effects plugin
- More tests cases in the devtest module.
- Many other minor changes.

38 files changed:
devtest/pom.xml
devtest/src/main/java/com/google/gwt/query/client/DevTestRunner.java
devtest/src/main/java/com/google/gwt/query/client/MyTestCase.java
extractInterface.pl [new file with mode: 0644]
extractLazyInterfaces.sh [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/Events.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/EventsListener.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/GQueryQueue.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/LazyEffects.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImplIE.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ClipAnimation.java [new file with mode: 0755]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java [new file with mode: 0755]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/GQueryQueue.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/PropertiesAnimation.java [new file with mode: 0755]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Widgets.java [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/public/delete.gif [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css [deleted file]
gwtquery-core/src/main/java/com/google/gwt/query/public/star.gif [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTest.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java
plugins/src/main/java/gwtquery/plugins/collapser/Collapser.java
samples/pom.xml
samples/src/main/java/gwtquery/samples/client/GwtQueryBenchModule.java
samples/src/main/java/gwtquery/samples/client/GwtQueryDemoModule.java
samples/src/main/java/gwtquery/samples/client/GwtQueryEffectsModule.java
samples/src/main/java/gwtquery/samples/client/MySelectors.java
samples/src/main/java/gwtquery/samples/public/GwtQueryEffects.html
samples/src/main/java/gwtquery/samples/public/racetrack.html

index 2f9c64387a4ee539129c35f78f600596bbb86b6b..d7de4e7948ae3d77187c96a596fbcde064fee6fe 100644 (file)
@@ -53,7 +53,7 @@
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>gwt-maven-plugin</artifactId>
             <configuration>
-                <style>PRETTY</style>
+                <!-- <style>PRETTY</style> -->
                 <gwtVersion>${gwtversion}</gwtVersion>
                 <modules>
                     <module>com.google.gwt.query.DevTestRunner</module>
index 47da99e9c81dfb9a40939d9c044feef9457023c6..ba24fcf14c6a233b253b4a99ed627603c14883d9 100644 (file)
@@ -18,9 +18,22 @@ package com.google.gwt.query.client;
 import static com.google.gwt.query.client.GQuery.$;\r
 \r
 import com.google.gwt.core.client.EntryPoint;\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.JsArray;\r
 import com.google.gwt.dom.client.Document;\r
 import com.google.gwt.dom.client.Element;\r
-import com.google.gwt.user.client.Event;\r
+import com.google.gwt.dom.client.Node;\r
+import com.google.gwt.dom.client.NodeList;\r
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;\r
+import com.google.gwt.query.client.impl.SelectorEngineImpl;\r
+import com.google.gwt.query.client.impl.SelectorEngineJS;\r
+import com.google.gwt.query.client.impl.SelectorEngineNative;\r
+import com.google.gwt.query.client.impl.SelectorEngineSizzle;\r
+import com.google.gwt.query.client.impl.SelectorEngineXPath;\r
+import com.google.gwt.user.client.Timer;\r
+import com.google.gwt.user.client.Window;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.RootPanel;\r
 \r
 /**\r
  * This module is thought to emulate a test environment similar to\r
@@ -38,43 +51,2308 @@ public class DevTestRunner extends MyTestCase implements EntryPoint {
     try {\r
       gwtSetUp();\r
       \r
-      testIssue23();\r
-\r
-      $(e).after("<div>OK</div>");\r
+      testCompiledSelectors();\r
+      testIssue12();\r
+      testSelectElementsInsideContext();\r
+      testSelectorEngineDomAssistant();\r
+      testSelectorEngineSizzle();\r
+      testSelectorEngineXpath();\r
+      testSelectorEngineCssToXpath();\r
+      testSelectorEngineNative();\r
+      testSelectorsGeneratorNative();\r
+      testSelectorsWithContext();\r
+      testUnique();\r
+      \r
+      testFade();\r
+      \r
+//      $(e).html("").after("<div>OK</div>");\r
     } catch (Exception ex) {\r
       ex.printStackTrace();\r
-      $(e).after("<div>ERROR: " + ex.getMessage() + "</div>");\r
+      $(e).html("").after("<div>ERROR: " + ex.getMessage() + "</div>");\r
     }\r
   }\r
+\r
+  public void testFade() {\r
+    $(e)\r
+    .html(\r
+        "<p id='id1' style='display: inline'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");\r
+\r
+    final GQuery sectA = $("#id1");\r
+    final GQuery sectB = $("#id2");\r
+    \r
+    // fadeIn() & fadeOut() are tested with delayed assertions\r
+    sectA.hide();\r
+    sectA.fadeIn(2000);\r
+    sectB.fadeOut(2000);\r
+\r
+    // Configure the max duration for this test\r
+    // If the test exceeds the timeout without calling finishTest() it will fail\r
+    delayTestFinish(2500);\r
+\r
+    // Delayed assertions at different intervals\r
+    Timer timerShortTime = new Timer() {\r
+      public void run() {\r
+        double o = Double.valueOf(sectA.css("opacity"));\r
+        assertTrue(\r
+            "'sectA' opacity must be in the interval 0-0.5 but is: " + o, o > 0\r
+                && o < 0.5);\r
+        o = Double.valueOf(sectB.css("opacity"));\r
+        assertTrue(\r
+            "'sectB' opacity must be in the interval 0.5-1 but is: " + o,\r
+            o > 0.5 && o < 1);\r
+      }\r
+    };\r
+    Timer timerMidTime = new Timer() {\r
+      public void run() {\r
+        assertEquals("inline", sectA.css("display"));\r
+        assertEquals("", sectB.css("display"));\r
+        double o = Double.valueOf(sectA.css("opacity"));\r
+        assertTrue(\r
+            "'sectA' opacity must be in the interval 0.5-1 but is: " + o,\r
+            o > 0.5 && o < 1);\r
+        o = Double.valueOf(sectB.css("opacity"));\r
+        assertTrue(\r
+            "'sectB' opacity must be in the interval 0-0.5 but is: " + o, o > 0\r
+                && o < 0.5);\r
+      }\r
+    };\r
+    Timer timerLongTime = new Timer() {\r
+      public void run() {\r
+        assertEquals("inline", sectA.css("display"));\r
+        assertEquals("none", sectB.css("display"));\r
+        // Last delayed assertion has to stop the test to avoid a timeout\r
+        // failure\r
+        finishTest();\r
+      }\r
+    };\r
+\r
+    // schedule the delayed assertions\r
+    timerShortTime.schedule(200);\r
+    timerMidTime.schedule(1200);\r
+    timerLongTime.schedule(2200);    \r
+  }  \r
   \r
-  int done = 0;\r
+  protected interface AllSelectors extends Selectors {\r
+    // @Selector("h1[id]:contains(Selectors)")\r
+    // NodeList<Element> h1IdContainsSelectors();\r
+    // @Selector("*:first")\r
+    // NodeList<Element> allFirst();\r
+    // @Selector("div[class!=madeup]")\r
+    // NodeList<Element> divWithClassNotContainsMadeup();\r
+    // @Selector("div, p a")\r
+    // NodeList<Element> divCommaPA();\r
+    // @Selector("p:contains(selectors)")\r
+    // NodeList<Element> pContainsSelectors();\r
+    @Selector("a[href][lang][class]")\r
+    NodeList<Element> aHrefLangClass();\r
+    @Selector("*:checked")\r
+    NodeList<Element> allChecked();\r
+    @Selector("body")\r
+    NodeList<Element> body();\r
+    @Selector("body div")\r
+    NodeList<Element> bodyDiv();\r
+    @Selector("div .example")\r
+    NodeList<Element> divExample();\r
+    @Selector("div > div")\r
+    NodeList<Element> divGtP();\r
+    @Selector("div:not(.example)")\r
+    NodeList<Element> divNotExample();\r
+    @Selector("div p")\r
+    NodeList<Element> divP();\r
+    @Selector("div p a")\r
+    NodeList<Element> divPA();\r
+    @Selector("div + p")\r
+    NodeList<Element> divPlusP();\r
+    @Selector("div[class^=exa][class$=mple]")\r
+    NodeList<Element> divPrefixExaSuffixMple();\r
+    @Selector("div #title")\r
+    NodeList<Element> divSpaceTitle();\r
+    @Selector("div ~ p")\r
+    NodeList<Element> divTildeP();\r
+    @Selector("div[class]")\r
+    NodeList<Element> divWithClass();\r
+    @Selector("div[class~=dialog]")\r
+    NodeList<Element> divWithClassContainsDialog();\r
+    @Selector("div[class*=e]")\r
+    NodeList<Element> divWithClassContainsE();\r
+    @Selector("div[class=example]")\r
+    NodeList<Element> divWithClassExample();\r
+    @Selector("div[class~=dialog]")\r
+    NodeList<Element> divWithClassListContainsDialog();\r
+    @Selector("div[class^=exa]")\r
+    NodeList<Element> divWithClassPrefixExa();\r
+    @Selector("div[class$=mple]")\r
+    NodeList<Element> divWithClassSuffixMple();\r
+    @Selector("p:first-child")\r
+    NodeList<Element> firstChild();\r
+    @Selector("h1#title")\r
+    NodeList<Element> h1Title();\r
+    @Selector("h1#title + em > span")\r
+    NodeList<Element> h1TitlePlusEmGtSpan();\r
+    @Selector("p:last-child")\r
+    NodeList<Element> lastChild();\r
+    @Selector(".note")\r
+    NodeList<Element> note();\r
+    @Selector("p:nth-child(n)")\r
+    NodeList<Element> nthChild();\r
+    @Selector("p:nth-child(2n)")\r
+    NodeList<Element> nThChild2n();\r
+    @Selector("p:nth-child(2n+1)")\r
+    NodeList<Element> nThChild2nPlus1();\r
+    @Selector("p:nth-child(even)")\r
+    NodeList<Element> nThChildEven();\r
+    @Selector("p:nth-child(odd)")\r
+    NodeList<Element> nThChildOdd();\r
+    @Selector("p:only-child")\r
+    NodeList<Element> onlyChild();\r
+    @Selector("#title")\r
+    NodeList<Element> title();\r
+    @Selector("#title,h1#title")\r
+    NodeList<Element> titleAndh1Title();\r
+    @Selector("ul .tocline2")\r
+    NodeList<Element> ulTocline2();\r
+    @Selector("ul.toc li.tocline2")\r
+    NodeList<Element> ulTocLiTocLine2();\r
+  }\r
+\r
+  protected interface TestSelectors extends Selectors {\r
+    @Selector("*:checked")\r
+    GQuery allChecked();\r
+    @Selector("*:checked")\r
+    GQuery allChecked(Node n);\r
+    @Selector(".branchA")\r
+    GQuery branchA();\r
+    @Selector(".branchA")\r
+    GQuery branchA(Node n);\r
+    @Selector(".branchB")\r
+    GQuery branchB();\r
+    @Selector(".branchB")\r
+    GQuery branchB(Node n);\r
+    @Selector(".target")\r
+    GQuery target();\r
+    @Selector(".target")\r
+    GQuery target(Node n);\r
+  }\r
+\r
+  static Element e = null;\r
+  static HTML testPanel = null;\r
+\r
+  public String getModuleName() {\r
+    return "com.google.gwt.query.Query";\r
+  }\r
+\r
+  public void gwtSetUp() {\r
+    if (e == null) {\r
+      testPanel = new HTML();\r
+      RootPanel.get().add(testPanel);\r
+      e = testPanel.getElement();\r
+      e.setId("select-tst");\r
+    } else {\r
+      e.setInnerHTML("");\r
+    }\r
+  }\r
+\r
+  public void testCompiledSelectors() {\r
+    final AllSelectors sel = GWT.create(AllSelectors.class);\r
+    $(e).html(getTestContent());\r
+\r
+    // TODO: fix these selectors\r
+    // sel.h1IdContainsSelectors().getLength()\r
+    // sel.allFirst().getLength()\r
+    // sel.divWithClassNotContainsMadeup().getLength()\r
+    // sel.divCommaPA().getLength()\r
+    // sel.pContainsSelectors().getLength()\r
+    // assertArrayContains(sel.title().getLength(), 1);\r
+\r
+    assertEquals(1, sel.body().getLength());\r
+    assertArrayContains(sel.bodyDiv().getLength(), 53, 55);\r
+    sel.setRoot(e);\r
+    assertArrayContains(sel.aHrefLangClass().getLength(), 0, 1);\r
+    assertArrayContains(sel.allChecked().getLength(), 1);\r
+    assertArrayContains(sel.divExample().getLength(), 43);\r
+    assertArrayContains(sel.divGtP().getLength(), 51, 52);\r
+    assertArrayContains(sel.divNotExample().getLength(), 9, 10);\r
+    assertArrayContains(sel.divP().getLength(), 324);\r
+    assertArrayContains(sel.divPA().getLength(), 84);\r
+    assertArrayContains(sel.divPlusP().getLength(), 22);\r
+    assertArrayContains(sel.divPrefixExaSuffixMple().getLength(), 43);\r
+    assertArrayContains(sel.divSpaceTitle().getLength(), 1);\r
+    assertArrayContains(sel.divTildeP().getLength(), 183);\r
+    assertArrayContains(sel.divWithClass().getLength(), 51, 52);\r
+    assertArrayContains(sel.divWithClassContainsDialog().getLength(), 1);\r
+    assertArrayContains(sel.divWithClassContainsE().getLength(), 50);\r
+    assertArrayContains(sel.divWithClassExample().getLength(), 43);\r
+    assertArrayContains(sel.divWithClassListContainsDialog().getLength(), 1);\r
+    assertArrayContains(sel.divWithClassPrefixExa().getLength(), 43);\r
+    assertArrayContains(sel.divWithClassSuffixMple().getLength(), 43);\r
+    assertArrayContains(sel.firstChild().getLength(), 54);\r
+    assertArrayContains(sel.h1Title().getLength(), 1);\r
+    assertArrayContains(sel.h1TitlePlusEmGtSpan().getLength(), 1);\r
+    assertArrayContains(sel.lastChild().getLength(), 19);\r
+    assertArrayContains(sel.note().getLength(), 14);\r
+    assertArrayContains(sel.nthChild().getLength(), 324);\r
+    assertArrayContains(sel.nThChild2n().getLength(), 159);\r
+    assertArrayContains(sel.nThChild2nPlus1().getLength(), 165);\r
+    assertArrayContains(sel.nThChildEven().getLength(), 159);\r
+    assertArrayContains(sel.nThChildOdd().getLength(), 165);\r
+    assertArrayContains(sel.onlyChild().getLength(), 3);\r
+    assertArrayContains(sel.titleAndh1Title().getLength(), 0, 1);\r
+    assertArrayContains(sel.ulTocline2().getLength(), 12);\r
+    assertArrayContains(sel.ulTocLiTocLine2().getLength(), 12);\r
+  }\r
+\r
+  public void testIssue12() {\r
+    $(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>");\r
+    executeSelectInAllImplementations(":checked", e, 1);\r
+    executeSelectInAllImplementations(":disabled", e, 1);\r
+    executeSelectInAllImplementations("input:enabled", e, 1);\r
+    executeSelectInAllImplementations("[myCustomAttr]", e, 2);\r
+    executeSelectInAllImplementations("*[myCustomAttr]", e, 2);\r
+    executeSelectInAllImplementations("input[name=wantedName]", e, 1);\r
+    executeSelectInAllImplementations("input[name='wantedName']", e, 1);\r
+    executeSelectInAllImplementations("input[name=\"wantedName\"]", e, 1);\r
+  }\r
   \r
-  public void testIssue23() {\r
-    $(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>");\r
-    $("button").click(new Function() {\r
-      public boolean f(Event e) {\r
-        $("table > tbody > tr > td > input:checked").each(new Function() {\r
-          public void f(Element e) {\r
-            done ++;\r
-          }\r
-        });\r
-        return true;\r
-      }\r
-    });\r
-    done = 0;\r
-    $("button").click();\r
-    assertEquals(1,done);\r
+  public void testSelectElementsInsideContext() {\r
+    $(e).html("<spam><p>s</p></spam>");\r
+    GQuery q = $("spam", e);\r
+    // TODO: in XPath engine it returns 2 when it should return 1\r
+    executeSelectInAllImplementations("*", q.get(0), 1, 2);\r
+  }\r
+\r
+  public void testSelectorEngineDomAssistant() {\r
+    // This test runs very slow in chrome\r
+    SelectorEngineImpl selEng = new SelectorEngineJS();\r
+    executeSelectorEngineTests(selEng);\r
+  }\r
+\r
+  public void testSelectorEngineSizzle() {\r
+    SelectorEngineImpl selEng = new SelectorEngineSizzle();\r
+    executeSelectorEngineTests(selEng);\r
+  }\r
+\r
+  public void testSelectorEngineNative() {\r
+    SelectorEngineImpl selEng = new SelectorEngineNative();\r
+    if (hasNativeSelector()) {\r
+      Window.alert("Testing native selector");\r
+      executeSelectorEngineTests(selEng);\r
+    }\r
+  }\r
+\r
+  public void testSelectorEngineXpath() {\r
+    SelectorEngineImpl selEng = new SelectorEngineXPath();\r
+    executeSelectorEngineTests(selEng);\r
+  }\r
+\r
+  public void testSelectorEngineCssToXpath() {\r
+    SelectorEngineImpl selEng = new SelectorEngineCssToXPath();\r
+    executeSelectorEngineTests(selEng);\r
+  }\r
+\r
+  public void testSelectorsGeneratorNative() {\r
+    $(e).html(\r
+            "<input type='radio' name='n' value='v1'>1</input>"\r
+                + "<input type='radio' name='n' value='v2' checked='checked'>2</input>");\r
+\r
+    TestSelectors selectors = GWT.create(TestSelectors.class);\r
+    assertEquals(1, selectors.allChecked().size());\r
   }\r
   \r
-  public void testDomManip() {\r
-    String content = "<span class='branchA'><span class='target'>branchA target</span></span>"\r
-      + "<span class='branchB'><span class='target'>branchB target</span></span>";\r
+  public void testSelectorsWithContext() {\r
+    $(e).append(\r
+            "<div class='branchA'><div class='target'>branchA target</div></div>"\r
+                + "<div class='branchB'><div class='target'>branchB target</div></div>");\r
+\r
+    TestSelectors selectors = GWT.create(TestSelectors.class);\r
+\r
+    assertEquals(2, selectors.target().length());\r
+    Element branchA = selectors.branchA().get(0);\r
+    Element branchB = selectors.branchB().get(0);\r
+    assertNotNull(selectors.branchA().get(0));\r
+    assertNotNull(selectors.branchB().get(0));\r
+\r
+    assertEquals(2, selectors.target(RootPanel.getBodyElement()).length());\r
+    branchA = selectors.branchA(RootPanel.getBodyElement()).get(0);\r
+    branchB = selectors.branchB(RootPanel.getBodyElement()).get(0);\r
+    assertNotNull(branchA);\r
+    assertNotNull(branchB);\r
+    assertEquals("branchA target", selectors.target(branchA).text());\r
+    assertEquals("branchB target", selectors.target(branchB).text());\r
+\r
+    selectors.setRoot(branchA);\r
+    assertEquals(1, selectors.target().length());\r
+    assertEquals("branchA target", selectors.target().text());\r
+\r
+    selectors.setRoot(branchB);\r
+    assertEquals(1, selectors.target().length());\r
+    assertEquals("branchB target", selectors.target().text());\r
+  }\r
+  \r
+  public void testUnique() {\r
+    SelectorEngineImpl selSizz = new SelectorEngineSizzle();\r
+    $(e).html(getTestContent());\r
     \r
-    $(e).html("");\r
-    $(e).append(content);\r
-    assertEquals(4, $("span", e).size());\r
-    assertEquals(2, $("span.target", e).size());\r
-    assertHtmlEquals(content, $(e).html());\r
+    JsArray<Element> a;\r
+    a = selSizz.select("p", e).cast();\r
+    int n = a.length();\r
+    assertTrue(n > 300);\r
+    for (int i=0; i<n; i++) {\r
+      a.push(a.get(i));\r
+    }\r
+    assertEquals(n * 2 , a.length());\r
+    a = SelectorEngineImpl.unique(a);\r
+    assertEquals(n, a.length());\r
+  }\r
+  \r
+  private void executeSelectInAllImplementations(String selector, Element elem, Object... array) {\r
+    SelectorEngineImpl selSizz = new SelectorEngineSizzle();\r
+    SelectorEngineImpl selJS = new SelectorEngineJS();\r
+    SelectorEngineImpl selXpath = new SelectorEngineXPath();\r
+    SelectorEngineImpl selC2X = new SelectorEngineCssToXPath();\r
+    SelectorEngineImpl selNative = new SelectorEngineNative();\r
+    assertArrayContains(selector, selSizz.select(selector, elem).getLength(), array);\r
+    assertArrayContains(selector, selJS.select(selector, elem).getLength(), array);\r
+    if (hasNativeSelector()) {\r
+      assertArrayContains(selector, selNative.select(selector, elem).getLength(), array);\r
+    }   \r
+//    assertArrayContains(selector, selXpath.select(selector, elem).getLength(), array);\r
+//    assertArrayContains(selector, selC2X.select(selector, elem).getLength(), array);\r
\r
+  }\r
+  \r
+  private static native boolean hasNativeSelector() /*-{\r
+//    alert(document.querySelectorAll + " " + document.querySelector);\r
+    return !!(document.querySelectorAll && /native/.test(String(document.querySelectorAll)));\r
+  }-*/;\r
+\r
+  private void executeSelectorEngineTests(SelectorEngineImpl selEng) {\r
+    $(e).html(getTestContent());\r
+\r
+    assertArrayContains(selEng.select("body", Document.get()).getLength(), 1);\r
+    assertArrayContains(selEng.select("body div", Document.get()).getLength(), 53, 55);\r
+\r
+    assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("div[class!=madeup]", e).getLength(), 52, 53);\r
+    assertArrayContains(selEng.select("div, p a", e).getLength(), 136, 137, 138);\r
+    assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54, 55);\r
+    assertArrayContains(selEng.select("a[href][lang][class]", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("*:checked", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("div .example", e).getLength(), 43);\r
+    assertArrayContains(selEng.select("div > div", e).getLength(), 51, 52);\r
+    assertArrayContains(selEng.select("div:not(.example)", e).getLength(), 9, 10);\r
+    assertArrayContains(selEng.select("div p", e).getLength(), 324);\r
+    assertArrayContains(selEng.select("div p a", e).getLength(), 85, 84);\r
+    assertArrayContains(selEng.select("div + p", e).getLength(), 22);\r
+    assertArrayContains(selEng.select("div[class^=exa][class$=mple]", e).getLength(), 43);\r
+    assertArrayContains(selEng.select("div #title", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("div ~ p", e).getLength(), 183);\r
+    assertArrayContains(selEng.select("div[class]", e).getLength(), 51, 52);\r
+    assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("div[class*=e]", e).getLength(), 50);\r
+    assertArrayContains(selEng.select("div[class=example]", e).getLength(), 43);\r
+    assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("div[class^=exa]", e).getLength(), 43);\r
+    assertArrayContains(selEng.select("div[class$=mple]", e).getLength(), 43);\r
+    assertArrayContains(selEng.select("p:first-child", e).getLength(), 54);\r
+    assertArrayContains(selEng.select("h1#title", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("h1#title + em > span", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("p:last-child", e).getLength(), 19, 22);\r
+    assertArrayContains(selEng.select(".note", e).getLength(), 14);\r
+    assertArrayContains(selEng.select("p:nth-child(n)", e).getLength(), 324);\r
+    assertArrayContains(selEng.select("p:nth-child(2n)", e).getLength(), 159);\r
+    assertArrayContains(selEng.select("p:nth-child(2n+1)", e).getLength(), 165);\r
+    assertArrayContains(selEng.select("p:nth-child(even)", e).getLength(), 159);\r
+    assertArrayContains(selEng.select("p:nth-child(odd)", e).getLength(), 165);\r
+    assertArrayContains(selEng.select("p:only-child", e).getLength(), 3);\r
+    assertArrayContains(selEng.select("#title", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("#title, h1#title", e).getLength(), 1);\r
+    assertArrayContains(selEng.select("ul.toc li.tocline2", e).getLength(), 12);    \r
+//    assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(),  1);\r
+  }\r
+\r
+  // This method is used to initialize a huge html String, because\r
+  // java 1.5 has a limitation in the size of static strings.\r
+  private String getTestContent() {\r
+    String ret = "";\r
+    ret += "<html><head>      </head><body><div>";\r
+    ret += "      <div class='head dialog'>";\r
+    ret += "          <p><a href='http://www.w3.org/'><img alt='W3C' src='' height='48' width='72'></a></p>";\r
+    ret += "          <h1 id='title'>Selectors</h1>";\r
+    ret += "          <em><span>.</span></em>";\r
+    ret += "          <h2>W3C Working Draft 15 December 2005</h2>";\r
+    ret += "          <dl>";\r
+    ret += "              <dt>This version:</dt>";\r
+    ret += "              <dd><a href='http://www.w3.org/TR/2005/WD-css3-selectors-20051215'>";\r
+    ret += "                  http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a></dd>";\r
+    ret += "              <dt>Latest version:";\r
+    ret += "              </dt><dd><a href='http://www.w3.org/TR/css3-selectors'>";\r
+    ret += "                  http://www.w3.org/TR/css3-selectors</a>";\r
+    ret += "              </dd><dt>Previous version:";\r
+    ret += "              </dt><dd><a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113'>";\r
+    ret += "                  http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>";\r
+    ret += "              </dd><dt><a name='editors-list'></a>Editors:";\r
+    ret += "              </dt><dd class='vcard'><span class='fn'>Daniel Glazman</span> (Invited";\r
+    ret += "              </dd>";\r
+    ret += "              <dd class='vcard'><a class='url fn' href='http://www.tantek.com/' lang='tr'>Tantek Ã‡elik</a>";\r
+    ret += "              </dd><dd class='vcard'><a href='mailto:ian@hixie.ch' class='url fn'>Ian";\r
+    ret += "                  Hickson</a> (<span class='company'><a href='http://www.google.com/'>Google</a></span>)";\r
+    ret += "              </dd><dd class='vcard'><span class='fn'>Peter Linss</span> (former";\r
+    ret += "                  editor, <span class='company'><a href='http://www.netscape.com/'>Netscape/AOL</a></span>)";\r
+    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>)";\r
+    ret += "          </dd></dl>";\r
+    ret += "          <p class='copyright'><a href='http://www.w3.org/Consortium/Legal/ipr-notice#Copyright'>";\r
+    ret += "              Copyright</a> Â© 2005 <a href='http://www.w3.org/'><abbr title='World Wide Web Consortium'>W3C</abbr></a><sup>®</sup>";\r
+    ret += "              (<a href='http://www.csail.mit.edu/'><abbr title='Massachusetts";\r
+    ret += "         Institute of Technology'>MIT</abbr></a>, <a href='http://www.ercim.org/'><acronym title='European Research";\r
+    ret += "         Consortium for Informatics and Mathematics'>ERCIM</acronym></a>, <a href='http://www.keio.ac.jp/'>Keio</a>), All Rights Reserved.";\r
+    ret += "              <a href='http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer'>liability</a>,";\r
+    ret += "              <a href='http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks'>trademark</a>,";\r
+    ret += "              <a href='http://www.w3.org/Consortium/Legal/copyright-documents'>document";\r
+    ret += "                  use</a> rules apply.";\r
+    ret += "          </p><hr title='Separator for header'>";\r
+    ret += "      </div>";\r
+    ret += "      <h2><a name='abstract'></a>Abstract</h2>";\r
+    ret += "      <p><em>Selectors</em> are patterns that match against elements in a";\r
+    ret += "          tree. Selectors have been optimized for use with HTML and XML, and";\r
+    ret += "          are designed to be usable in performance-critical code.</p>";\r
+    ret += "      <p><acronym title='Cascading Style Sheets'>CSS</acronym> (Cascading";\r
+    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";\r
+    ret += "          screen, on paper, in speech, etc. CSS uses Selectors for binding";\r
+    ret += "          describes extensions to the selectors defined in CSS level 2. These";\r
+    ret += "          extended selectors will be used by CSS level 3.";\r
+    ret += "      </p><p>Selectors define the following function:</p>";\r
+    ret += "      <pre>expression âˆ— element â†’ boolean</pre>";\r
+    ret += "      <p>That is, given an element and a selector, this specification";\r
+    ret += "          defines whether that element matches the selector.</p>";\r
+    ret += "      <p>These expressions can also be used, for instance, to select a set";\r
+    ret += "          subtree. <acronym title='Simple Tree Transformation";\r
+    ret += "        Sheets'>STTS</acronym> (Simple Tree Transformation Sheets), a";\r
+    ret += "          language for transforming XML trees, uses this mechanism. <a href='#refsSTTS'>[STTS]</a></p>";\r
+    ret += "      <h2><a name='status'></a>Status of this document</h2>";\r
+    ret += "      <p><em>This section describes the status of this document at the";\r
+    ret += "          of this technical report can be found in the <a href='http://www.w3.org/TR/'>W3C technical reports index at";\r
+    ret += "              http://www.w3.org/TR/.</a></em></p>";\r
+    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";\r
+    ret += "          also proposes new selectors for <abbr title='CSS level";\r
+    ret += "        3'>CSS3</abbr> and other languages that may need them.</p>";\r
+    ret += "      <p>The CSS Working Group doesn't expect that all implementations of";\r
+    ret += "          CSS3 will have to implement all selectors. Instead, there will";\r
+    ret += "          will include all of the selectors.</p>";\r
+    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>";\r
+    ret += "          (<a href='/Style/'>Style Activity</a>). This";\r
+    ret += "          document is a revision of the <a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113/'>Candidate";\r
+    ret += "              Recommendation dated 2001 November 13</a>, and has incorporated";\r
+    ret += "          be demonstrable.</p>";\r
+    ret += "      <p>All persons are encouraged to review and implement this";\r
+    ret += "          specification and return comments to the (<a href='http://lists.w3.org/Archives/Public/www-style/'>archived</a>)";\r
+    ret += "          public mailing list <a href='http://www.w3.org/Mail/Lists.html#www-style'>www-style</a>";\r
+    ret += "          (see <a href='http://www.w3.org/Mail/Request'>instructions</a>). W3C";\r
+    ret += "          The deadline for comments is 14 January 2006.</p>";\r
+    ret += "      <p>This is still a draft document and may be updated, replaced, or";\r
+    ret += "      </p><p>This document may be available in <a href='http://www.w3.org/Style/css3-selectors-updates/translations'>translation</a>.";\r
+    ret += "      </p><div class='subtoc'>";\r
+    ret += "          <h2><a name='contents'>Table of contents</a></h2>";\r
+    ret += "          <ul class='toc'>";\r
+    ret += "              <li class='tocline2'><a href='#context'>1. Introduction</a>";\r
+    ret += "                  <ul>";\r
+    ret += "                      <li><a href='#dependencies'>1.1. Dependencies</a></li>";\r
+    ret += "                      <li><a href='#terminology'>1.2. Terminology</a></li>";\r
+    ret += "                      <li><a href='#changesFromCSS2'>1.3. Changes from CSS2</a></li>";\r
+    ret += "                  </ul>";\r
+    ret += "              </li><li class='tocline2'><a href='#selectors'>2. Selectors</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#casesens'>3. Case sensitivity</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#selector-syntax'>4. Selector syntax</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#grouping'>5. Groups of selectors</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#simple-selectors'>6. Simple selectors</a>";\r
+    ret += "                  <ul class='toc'>";\r
+    ret += "                      <li class='tocline3'><a href='#type-selectors'>6.1. Type";\r
+    ret += "                          selectors</a>";\r
+    ret += "                          <ul class='toc'>";\r
+    ret += "                              <li class='tocline4'><a href='#typenmsp'>6.1.1. Type";\r
+    ret += "                                  selectors and namespaces</a></li>";\r
+    ret += "                          </ul>";\r
+    ret += "                      </li><li class='tocline3'><a href='#universal-selector'>6.2.";\r
+    ret += "                          Universal selector</a>";\r
+    ret += "                          <ul>";\r
+    ret += "                              <li><a href='#univnmsp'>6.2.1. Universal selector and";\r
+    ret += "                                  namespaces</a></li>";\r
+    ret += "                          </ul>";\r
+    ret += "                      </li><li class='tocline3'><a href='#attribute-selectors'>6.3.";\r
+    ret += "                          Attribute selectors</a>";\r
+    ret += "                          <ul class='toc'>";\r
+    ret += "                              <li class='tocline4'><a href='#attribute-representation'>6.3.1.";\r
+    ret += "                                  values</a>";\r
+    ret += "                              </li><li><a href='#attribute-substrings'>6.3.2. Substring";\r
+    ret += "                                  matching attribute selectors</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#attrnmsp'>6.3.3.";\r
+    ret += "                                  Attribute selectors and namespaces</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#def-values'>6.3.4.";\r
+    ret += "                                  Default attribute values in DTDs</a></li>";\r
+    ret += "                          </ul>";\r
+    ret += "                      </li><li class='tocline3'><a href='#class-html'>6.4. Class";\r
+    ret += "                          selectors</a>";\r
+    ret += "                      </li><li class='tocline3'><a href='#id-selectors'>6.5. ID";\r
+    ret += "                          selectors</a>";\r
+    ret += "                      </li><li class='tocline3'><a href='#pseudo-classes'>6.6.";\r
+    ret += "                          Pseudo-classes</a>";\r
+    ret += "                          <ul class='toc'>";\r
+    ret += "                              <li class='tocline4'><a href='#dynamic-pseudos'>6.6.1.";\r
+    ret += "                                  Dynamic pseudo-classes</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#target-pseudo'>6.6.2. The";\r
+    ret += "                                  :target pseudo-class</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#lang-pseudo'>6.6.3. The";\r
+    ret += "                                  :lang() pseudo-class</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#UIstates'>6.6.4. UI";\r
+    ret += "                                  element states pseudo-classes</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#structural-pseudos'>6.6.5.";\r
+    ret += "                                  Structural pseudo-classes</a>";\r
+    ret += "                                  <ul>";\r
+    ret += "                                      <li><a href='#root-pseudo'>:root";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#nth-child-pseudo'>:nth-child()";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#nth-last-child-pseudo'>:nth-last-child()</a>";\r
+    ret += "                                      </li><li><a href='#nth-of-type-pseudo'>:nth-of-type()";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#nth-last-of-type-pseudo'>:nth-last-of-type()</a>";\r
+    ret += "                                      </li><li><a href='#first-child-pseudo'>:first-child";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#last-child-pseudo'>:last-child";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#first-of-type-pseudo'>:first-of-type";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#last-of-type-pseudo'>:last-of-type";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#only-child-pseudo'>:only-child";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#only-of-type-pseudo'>:only-of-type";\r
+    ret += "                                          pseudo-class</a>";\r
+    ret += "                                      </li><li><a href='#empty-pseudo'>:empty";\r
+    ret += "                                          pseudo-class</a></li>";\r
+    ret += "                                  </ul>";\r
+    ret += "                              </li><li class='tocline4'><a href='#negation'>6.6.7. The";\r
+    ret += "                                  negation pseudo-class</a></li>";\r
+    ret += "                          </ul>";\r
+    ret += "                      </li>";\r
+    ret += "                  </ul>";\r
+    ret += "              </li><li><a href='#pseudo-elements'>7. Pseudo-elements</a>";\r
+    ret += "                  <ul>";\r
+    ret += "                      <li><a href='#first-line'>7.1. The ::first-line";\r
+    ret += "                          pseudo-element</a>";\r
+    ret += "                      </li><li><a href='#first-letter'>7.2. The ::first-letter";\r
+    ret += "                          pseudo-element</a>";\r
+    ret += "                      </li><li><a href='#UIfragments'>7.3. The ::selection";\r
+    ret += "                          pseudo-element</a>";\r
+    ret += "                      </li><li><a href='#gen-content'>7.4. The ::before and ::after";\r
+    ret += "                          pseudo-elements</a></li>";\r
+    ret += "                  </ul>";\r
+    ret += "              </li><li class='tocline2'><a href='#combinators'>8. Combinators</a>";\r
+    ret += "                  <ul class='toc'>";\r
+    ret += "                      <li class='tocline3'><a href='#descendant-combinators'>8.1.";\r
+    ret += "                          Descendant combinators</a>";\r
+    ret += "                      </li><li class='tocline3'><a href='#child-combinators'>8.2. Child";\r
+    ret += "                          combinators</a>";\r
+    ret += "                      </li><li class='tocline3'><a href='#sibling-combinators'>8.3. Sibling";\r
+    ret += "                          combinators</a>";\r
+    ret += "                          <ul class='toc'>";\r
+    ret += "                              <li class='tocline4'><a href='#adjacent-sibling-combinators'>8.3.1.";\r
+    ret += "                                  Adjacent sibling combinator</a>";\r
+    ret += "                              </li><li class='tocline4'><a href='#general-sibling-combinators'>8.3.2.";\r
+    ret += "                                  General sibling combinator</a></li>";\r
+    ret += "                          </ul>";\r
+    ret += "                      </li>";\r
+    ret += "                  </ul>";\r
+    ret += "              </li><li class='tocline2'><a href='#specificity'>9. Calculating a selector's";\r
+    ret += "                  specificity</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#w3cselgrammar'>10. The grammar of";\r
+    ret += "                  Selectors</a>";\r
+    ret += "                  <ul class='toc'>";\r
+    ret += "                      <li class='tocline3'><a href='#grammar'>10.1. Grammar</a>";\r
+    ret += "                      </li><li class='tocline3'><a href='#lex'>10.2. Lexical scanner</a>";\r
+    ret += "                      </li>";\r
+    ret += "                  </ul>";\r
+    ret += "              </li><li class='tocline2'><a href='#downlevel'>11. Namespaces and down-level";\r
+    ret += "                  clients</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#profiling'>12. Profiles</a>";\r
+    ret += "              </li><li><a href='#Conformance'>13. Conformance and requirements</a>";\r
+    ret += "              </li><li><a href='#Tests'>14. Tests</a>";\r
+    ret += "              </li><li><a href='#ACKS'>15. Acknowledgements</a>";\r
+    ret += "              </li><li class='tocline2'><a href='#references'>16. References</a>";\r
+    ret += "          </li></ul>";\r
+    ret += "      </div>";\r
+    ret += "      <h2><a name='context'>1. Introduction</a></h2>";\r
+    ret += "      <h3><a name='dependencies'></a>1.1. Dependencies</h3>";\r
+    ret += "      <p>Some features of this specification are specific to CSS, or have";\r
+    ret += "          specification, these have been described in terms of CSS2.1. <a href='#refsCSS21'>[CSS21]</a></p>";\r
+    ret += "      <h3><a name='terminology'></a>1.2. Terminology</h3>";\r
+    ret += "      <p>All of the text of this specification is normative except";\r
+    ret += "          non-normative.</p>";\r
+    ret += "      <h3><a name='changesFromCSS2'></a>1.3. Changes from CSS2</h3>";\r
+    ret += "      <p><em>This section is non-normative.</em></p>";\r
+    ret += "      <p>The main differences between the selectors in CSS2 and those in";\r
+    ret += "          Selectors are:";\r
+    ret += "      </p><ul>";\r
+    ret += "          <li>the list of basic definitions (selector, group of selectors,";\r
+    ret += "              of simple selectors, and the term 'simple selector' is now used for";\r
+    ret += "          </li>";\r
+    ret += "          <li>an optional namespace component is now allowed in type element";\r
+    ret += "              selectors, the universal selector and attribute selectors";\r
+    ret += "          </li>";\r
+    ret += "          <li>a <a href='#general-sibling-combinators'>new combinator</a> has been";\r
+    ret += "          </li>";\r
+    ret += "          <li>new simple selectors including substring matching attribute";\r
+    ret += "              selectors, and new pseudo-classes";\r
+    ret += "          </li>";\r
+    ret += "          <li>new pseudo-elements, and introduction of the '::' convention";\r
+    ret += "          </li>";\r
+    ret += "          <li>the grammar has been rewritten</li>";\r
+    ret += "          <li>profiles to be added to specifications integrating Selectors";\r
+    ret += "              and defining the set of selectors which is actually supported by";\r
+    ret += "          </li>";\r
+    ret += "          <li>Selectors are now a CSS3 Module and an independent";\r
+    ret += "          </li>";\r
+    ret += "          <li>the specification now has its own test suite</li>";\r
+    ret += "      </ul>";\r
+    ret += "      <h2><a name='selectors'></a>2. Selectors</h2>";\r
+    ret += "      <p><em>This section is non-normative, as it merely summarizes the";\r
+    ret += "          following sections.</em></p>";\r
+    ret += "      <p>A Selector represents a structure. This structure can be used as a";\r
+    ret += "          HTML or XML fragment corresponding to that structure.</p>";\r
+    ret += "      <p>Selectors may range from simple element names to rich contextual";\r
+    ret += "          representations.</p>";\r
+    ret += "      <p>The following table summarizes the Selector syntax:</p>";\r
+    ret += "      <table class='selectorsReview'>";\r
+    ret += "      <thead>";\r
+    ret += "      <tr>";\r
+    ret += "          <th class='pattern'>Pattern</th>";\r
+    ret += "          <th class='meaning'>Meaning</th>";\r
+    ret += "          <th class='described'>Described in section</th>";\r
+    ret += "          <th class='origin'>First defined in CSS level</th>";\r
+    ret += "      </tr>";\r
+    ret += "      </thead><tbody>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>*</td>";\r
+    ret += "          <td class='meaning'>any element</td>";\r
+    ret += "          <td class='described'><a href='#universal-selector'>Universal";\r
+    ret += "              selector</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E</td>";\r
+    ret += "          <td class='meaning'>an element of type E</td>";\r
+    ret += "          <td class='described'><a href='#type-selectors'>Type selector</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo]</td>";\r
+    ret += "          <td class='meaning'>an E element with a 'foo' attribute</td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo='bar']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'foo' attribute value is exactly";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo~='bar']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'foo' attribute value is a list of";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo^='bar']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'foo' attribute value begins exactly";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo$='bar']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'foo' attribute value ends exactly";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[foo*='bar']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'foo' attribute value contains the";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E[hreflang|='en']</td>";\r
+    ret += "          <td class='meaning'>an E element whose 'hreflang' attribute has a";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#attribute-selectors'>Attribute";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:root</td>";\r
+    ret += "          <td class='meaning'>an E element, root of the document</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:nth-child(n)</td>";\r
+    ret += "          <td class='meaning'>an E element, the n-th child of its parent</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:nth-last-child(n)</td>";\r
+    ret += "          <td class='meaning'>an E element, the n-th child of its parent, counting";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:nth-of-type(n)</td>";\r
+    ret += "          <td class='meaning'>an E element, the n-th sibling of its type</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:nth-last-of-type(n)</td>";\r
+    ret += "          <td class='meaning'>an E element, the n-th sibling of its type, counting";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:first-child</td>";\r
+    ret += "          <td class='meaning'>an E element, first child of its parent</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:last-child</td>";\r
+    ret += "          <td class='meaning'>an E element, last child of its parent</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:first-of-type</td>";\r
+    ret += "          <td class='meaning'>an E element, first sibling of its type</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:last-of-type</td>";\r
+    ret += "          <td class='meaning'>an E element, last sibling of its type</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:only-child</td>";\r
+    ret += "          <td class='meaning'>an E element, only child of its parent</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:only-of-type</td>";\r
+    ret += "          <td class='meaning'>an E element, only sibling of its type</td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:empty</td>";\r
+    ret += "          <td class='meaning'>an E element that has no children (including text";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#structural-pseudos'>Structural";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:link<br>E:visited</td>";\r
+    ret += "          <td class='meaning'>an E element being the source anchor of a hyperlink of";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#link'>The link";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:active<br>E:hover<br>E:focus</td>";\r
+    ret += "          <td class='meaning'>an E element during certain user actions</td>";\r
+    ret += "          <td class='described'><a href='#useraction-pseudos'>The user";\r
+    ret += "              action pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>1 and 2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:target</td>";\r
+    ret += "          <td class='meaning'>an E element being the target of the referring URI</td>";\r
+    ret += "          <td class='described'><a href='#target-pseudo'>The target";\r
+    ret += "              pseudo-class</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:lang(fr)</td>";\r
+    ret += "          <td class='meaning'>an element of type E in language 'fr' (the document";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#lang-pseudo'>The :lang()";\r
+    ret += "              pseudo-class</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:enabled<br>E:disabled</td>";\r
+    ret += "          <td class='meaning'>a user interface element E which is enabled or";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#UIstates'>The UI element states";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:checked<!--<br>E:indeterminate--></td>";\r
+    ret += "          <td class='meaning'>a user interface element E which is checked<!-- or in an";\r
+    ret += "            indeterminate state--> (for instance a radio-button or checkbox)";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#UIstates'>The UI element states";\r
+    ret += "              pseudo-classes</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E::first-line</td>";\r
+    ret += "          <td class='meaning'>the first formatted line of an E element</td>";\r
+    ret += "          <td class='described'><a href='#first-line'>The ::first-line";\r
+    ret += "              pseudo-element</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E::first-letter</td>";\r
+    ret += "          <td class='meaning'>the first formatted letter of an E element</td>";\r
+    ret += "          <td class='described'><a href='#first-letter'>The ::first-letter";\r
+    ret += "              pseudo-element</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E::selection</td>";\r
+    ret += "          <td class='meaning'>the portion of an E element that is currently";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#UIfragments'>The UI element";\r
+    ret += "              fragments pseudo-elements</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E::before</td>";\r
+    ret += "          <td class='meaning'>generated content before an E element</td>";\r
+    ret += "          <td class='described'><a href='#gen-content'>The ::before";\r
+    ret += "              pseudo-element</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E::after</td>";\r
+    ret += "          <td class='meaning'>generated content after an E element</td>";\r
+    ret += "          <td class='described'><a href='#gen-content'>The ::after";\r
+    ret += "              pseudo-element</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E.warning</td>";\r
+    ret += "          <td class='meaning'>an E element whose class is";\r
+    ret += "          </td>";\r
+    ret += "          <td class='described'><a href='#class-html'>Class";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E#myid</td>";\r
+    ret += "          <td class='meaning'>an E element with ID equal to 'myid'.</td>";\r
+    ret += "          <td class='described'><a href='#id-selectors'>ID";\r
+    ret += "              selectors</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E:not(s)</td>";\r
+    ret += "          <td class='meaning'>an E element that does not match simple selector s</td>";\r
+    ret += "          <td class='described'><a href='#negation'>Negation";\r
+    ret += "              pseudo-class</a></td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E F</td>";\r
+    ret += "          <td class='meaning'>an F element descendant of an E element</td>";\r
+    ret += "          <td class='described'><a href='#descendant-combinators'>Descendant";\r
+    ret += "              combinator</a></td>";\r
+    ret += "          <td class='origin'>1</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E &gt; F</td>";\r
+    ret += "          <td class='meaning'>an F element child of an E element</td>";\r
+    ret += "          <td class='described'><a href='#child-combinators'>Child";\r
+    ret += "              combinator</a></td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E + F</td>";\r
+    ret += "          <td class='meaning'>an F element immediately preceded by an E element</td>";\r
+    ret += "          <td class='described'><a href='#adjacent-sibling-combinators'>Adjacent sibling combinator</a>";\r
+    ret += "          </td>";\r
+    ret += "          <td class='origin'>2</td>";\r
+    ret += "      </tr>";\r
+    ret += "      <tr>";\r
+    ret += "          <td class='pattern'>E ~ F</td>";\r
+    ret += "          <td class='meaning'>an F element preceded by an E element</td>";\r
+    ret += "          <td class='described'><a href='#general-sibling-combinators'>General sibling combinator</a>";\r
+    ret += "          </td>";\r
+    ret += "          <td class='origin'>3</td>";\r
+    ret += "      </tr>";\r
+    ret += "      </tbody>";\r
+    ret += "      </table>";\r
+    ret += "      <p>The meaning of each selector is derived from the table above by";\r
+    ret += "          column.</p>";\r
+    ret += "      <h2><a name='casesens'>3. Case sensitivity</a></h2>";\r
+    ret += "      <p>The case sensitivity of document language element names, attribute";\r
+    ret += "          names, and attribute values in selectors depends on the document";\r
+    ret += "          but in XML, they are case-sensitive.</p>";\r
+    ret += "      <h2><a name='selector-syntax'>4. Selector syntax</a></h2>";\r
+    ret += "      <p>A <dfn><a name='selector'>selector</a></dfn> is a chain of one";\r
+    ret += "          or more <a href='#sequence'>sequences of simple selectors</a>";\r
+    ret += "          separated by <a href='#combinators'>combinators</a>.</p>";\r
+    ret += "      <p>A <dfn><a name='sequence'>sequence of simple selectors</a></dfn>";\r
+    ret += "          is a chain of <a href='#simple-selectors-dfn'>simple selectors</a>";\r
+    ret += "          that are not separated by a <a href='#combinators'>combinator</a>. It";\r
+    ret += "          always begins with a <a href='#type-selectors'>type selector</a> or a";\r
+    ret += "          <a href='#universal-selector'>universal selector</a>. No other type";\r
+    ret += "          selector or universal selector is allowed in the sequence.</p>";\r
+    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";\r
+    ret += "          sequence of simple selectors.</p>";\r
+    ret += "      <p><dfn>Combinators</dfn> are: white space, 'greater-than";\r
+    ret += "          sign' (U+003E, <code>&gt;</code>), 'plus sign' (U+002B,";\r
+    ret += "          <code>+</code>) and 'tilde' (U+007E, <code>~</code>). White";\r
+    ret += "          space may appear between a combinator and the simple selectors around";\r
+    ret += "          it. <a name='whitespace'></a>Only the characters 'space' (U+0020), 'tab'";\r
+    ret += "          never part of white space.</p>";\r
+    ret += "      <p>The elements of a document tree that are represented by a selector";\r
+    ret += "          are the <dfn><a name='subject'></a>subjects of the selector</dfn>. A";\r
+    ret += "          selector consisting of a single sequence of simple selectors";\r
+    ret += "          sequence of simple selectors and a combinator to a sequence imposes";\r
+    ret += "          simple selectors.</p>";\r
+    ret += "      <p>An empty selector, containing no sequence of simple selectors and";\r
+    ret += "          no pseudo-element, is an <a href='#Conformance'>invalid";\r
+    ret += "              selector</a>.</p>";\r
+    ret += "      <h2><a name='grouping'>5. Groups of selectors</a></h2>";\r
+    ret += "      <p>When several selectors share the same declarations, they may be";\r
+    ret += "          grouped into a comma-separated list. (A comma is U+002C.)</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>CSS examples:</p>";\r
+    ret += "          <p>In this example, we condense three rules with identical";\r
+    ret += "              declarations into one. Thus,</p>";\r
+    ret += "      <pre>h1 { font-family: sans-serif }";\r
+    ret += "      h3 { font-family: sans-serif }</pre>";\r
+    ret += "          <p>is equivalent to:</p>";\r
+    ret += "          <pre>h1, h2, h3 { font-family: sans-serif }</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p><strong>Warning</strong>: the equivalence is true in this example";\r
+    ret += "          because all the selectors are valid selectors. If just one of these";\r
+    ret += "          selectors were invalid, the entire group of selectors would be";\r
+    ret += "          heading rules would be invalidated.</p>";\r
+    ret += "      <h2><a name='simple-selectors'>6. Simple selectors</a></h2>";\r
+    ret += "      <h3><a name='type-selectors'>6.1. Type selector</a></h3>";\r
+    ret += "      <p>A <dfn>type selector</dfn> is the name of a document language";\r
+    ret += "          type in the document tree.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The following selector represents an <code>h1</code> element in the";\r
+    ret += "              document tree:</p>";\r
+    ret += "          <pre>h1</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='typenmsp'>6.1.1. Type selectors and namespaces</a></h4>";\r
+    ret += "      <p>Type selectors allow an optional namespace (<a href='#refsXMLNAMES'>[XMLNAMES]</a>) component. A namespace prefix";\r
+    ret += "          (U+007C, <code>|</code>).</p>";\r
+    ret += "      <p>The namespace component may be left empty to indicate that the";\r
+    ret += "          selector is only to represent elements with no declared namespace.</p>";\r
+    ret += "      <p>An asterisk may be used for the namespace prefix, indicating that";\r
+    ret += "          with no namespace).</p>";\r
+    ret += "      <p>Element type selectors that have no namespace component (no";\r
+    ret += "          element's namespace (equivalent to '<code>*|</code>') unless a default";\r
+    ret += "          namespace.</p>";\r
+    ret += "      <p>A type selector containing a namespace prefix that has not been";\r
+    ret += "          previously declared is an <a href='#Conformance'>invalid</a> selector.";\r
+    ret += "          language implementing Selectors. In CSS, such a mechanism is defined";\r
+    ret += "          in the General Syntax module.</p>";\r
+    ret += "      <p>In a namespace-aware client, element type selectors will only match";\r
+    ret += "          against the <a href='http://www.w3.org/TR/REC-xml-names/#NT-LocalPart'>local";\r
+    ret += "              part</a>";\r
+    ret += "          of the element's <a href='http://www.w3.org/TR/REC-xml-names/#ns-qualnames'>qualified";\r
+    ret += "              name</a>. See <a href='#downlevel'>below</a> for notes about matching";\r
+    ret += "          behaviors in down-level clients.</p>";\r
+    ret += "      <p>In summary:</p>";\r
+    ret += "      <dl>";\r
+    ret += "          <dt><code>ns|E</code></dt>";\r
+    ret += "          <dd>elements with name E in namespace ns</dd>";\r
+    ret += "          <dt><code>*|E</code></dt>";\r
+    ret += "          <dd>elements with name E in any namespace, including those without any";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>|E</code></dt>";\r
+    ret += "          <dd>elements with name E without any declared namespace</dd>";\r
+    ret += "          <dt><code>E</code></dt>";\r
+    ret += "          <dd>if no default namespace has been specified, this is equivalent to *|E.";\r
+    ret += "          </dd>";\r
+    ret += "      </dl>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>CSS examples:</p>";\r
+    ret += "       <pre>@namespace foo url(http://www.example.com);";\r
+    ret += "       h1 { color: green }</pre>";\r
+    ret += "          <p>The first rule will match only <code>h1</code> elements in the";\r
+    ret += "              'http://www.example.com' namespace.</p>";\r
+    ret += "          <p>The second rule will match all elements in the";\r
+    ret += "              'http://www.example.com' namespace.</p>";\r
+    ret += "          <p>The third rule will match only <code>h1</code> elements without";\r
+    ret += "              any declared namespace.</p>";\r
+    ret += "          <p>The fourth rule will match <code>h1</code> elements in any";\r
+    ret += "              namespace (including those without any declared namespace).</p>";\r
+    ret += "          <p>The last rule is equivalent to the fourth rule because no default";\r
+    ret += "              namespace has been defined.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <h3><a name='universal-selector'>6.2. Universal selector</a></h3>";\r
+    ret += "      <p>The <dfn>universal selector</dfn>, written 'asterisk'";\r
+    ret += "          (<code>*</code>), represents the qualified name of any element";\r
+    ret += "          specified, see <a href='#univnmsp'>Universal selector and";\r
+    ret += "              Namespaces</a> below.</p>";\r
+    ret += "      <p>If the universal selector is not the only component of a sequence";\r
+    ret += "          of simple selectors, the <code>*</code> may be omitted.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <ul>";\r
+    ret += "              <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are";\r
+    ret += "              </li>";\r
+    ret += "              <li><code>*.warning</code> and <code>.warning</code> are equivalent,";\r
+    ret += "              </li>";\r
+    ret += "              <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>";\r
+    ret += "          </ul>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note:</strong> it is recommended that the";\r
+    ret += "          <code>*</code>, representing the universal selector, not be";\r
+    ret += "          omitted.</p>";\r
+    ret += "      <h4><a name='univnmsp'>6.2.1. Universal selector and namespaces</a></h4>";\r
+    ret += "      <p>The universal selector allows an optional namespace component. It";\r
+    ret += "          is used as follows:</p>";\r
+    ret += "      <dl>";\r
+    ret += "          <dt><code>ns|*</code></dt>";\r
+    ret += "          <dd>all elements in namespace ns</dd>";\r
+    ret += "          <dt><code>*|*</code></dt>";\r
+    ret += "          <dd>all elements</dd>";\r
+    ret += "          <dt><code>|*</code></dt>";\r
+    ret += "          <dd>all elements without any declared namespace</dd>";\r
+    ret += "          <dt><code>*</code></dt>";\r
+    ret += "          <dd>if no default namespace has been specified, this is equivalent to *|*.";\r
+    ret += "          </dd>";\r
+    ret += "      </dl>";\r
+    ret += "      <p>A universal selector containing a namespace prefix that has not";\r
+    ret += "          been previously declared is an <a href='#Conformance'>invalid</a>";\r
+    ret += "          to the language implementing Selectors. In CSS, such a mechanism is";\r
+    ret += "          defined in the General Syntax module.</p>";\r
+    ret += "      <h3><a name='attribute-selectors'>6.3. Attribute selectors</a></h3>";\r
+    ret += "      <p>Selectors allow the representation of an element's attributes. When";\r
+    ret += "          attribute selectors must be considered to match an element if that";\r
+    ret += "          attribute selector.</p>";\r
+    ret += "      <h4><a name='attribute-representation'>6.3.1. Attribute presence and values";\r
+    ret += "          selectors</a></h4>";\r
+    ret += "      <p>CSS2 introduced four attribute selectors:</p>";\r
+    ret += "      <dl>";\r
+    ret += "          <dt><code>[att]</code>";\r
+    ret += "          </dt><dd>Represents an element with the <code>att</code> attribute, whatever the";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>[att=val]</code></dt>";\r
+    ret += "          <dd>Represents an element with the <code>att</code> attribute whose value is";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>[att~=val]</code></dt>";\r
+    ret += "          <dd>Represents an element with the <code>att</code> attribute whose value is";\r
+    ret += "              a <a href='#whitespace'>whitespace</a>-separated list of words, one";\r
+    ret += "              represent anything (since the words are <em>separated</em> by";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>[att|=val]</code>";\r
+    ret += "          </dt><dd>Represents an element with the <code>att</code> attribute, its value";\r
+    ret += "              matches (e.g., the <code>hreflang</code> attribute on the";\r
+    ret += "              <code>link</code> element in HTML) as described in RFC 3066 (<a href='#refsRFC3066'>[RFC3066]</a>). For <code>lang</code> (or";\r
+    ret += "              <code>xml:lang</code>) language subcode matching, please see <a href='#lang-pseudo'>the <code>:lang</code> pseudo-class</a>.";\r
+    ret += "          </dd>";\r
+    ret += "      </dl>";\r
+    ret += "      <p>Attribute values must be identifiers or strings. The";\r
+    ret += "          case-sensitivity of attribute names and values in selectors depends on";\r
+    ret += "          the document language.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following attribute selector represents an <code>h1</code>";\r
+    ret += "              element that carries the <code>title</code> attribute, whatever its";\r
+    ret += "              value:</p>";\r
+    ret += "          <pre>h1[title]</pre>";\r
+    ret += "          <p>In the following example, the selector represents a";\r
+    ret += "              <code>span</code> element whose <code>class</code> attribute has";\r
+    ret += "              exactly the value 'example':</p>";\r
+    ret += "          <pre>span[class='example']</pre>";\r
+    ret += "          <p>Multiple attribute selectors can be used to represent several";\r
+    ret += "              attribute. Here, the selector represents a <code>span</code> element";\r
+    ret += "              whose <code>hello</code> attribute has exactly the value 'Cleveland'";\r
+    ret += "              and whose <code>goodbye</code> attribute has exactly the value";\r
+    ret += "              'Columbus':</p>";\r
+    ret += "          <pre>span[hello='Cleveland'][goodbye='Columbus']</pre>";\r
+    ret += "          <p>The following selectors illustrate the differences between '='";\r
+    ret += "              'copyright copyleft copyeditor' on a <code>rel</code> attribute. The";\r
+    ret += "              second selector will only represent an <code>a</code> element with";\r
+    ret += "              an <code>href</code> attribute having the exact value";\r
+    ret += "              'http://www.w3.org/'.</p>";\r
+    ret += "        <pre>a[rel~='copyright']";\r
+    ret += "      a[href='http://www.w3.org/']</pre>";\r
+    ret += "          <p>The following selector represents a <code>link</code> element";\r
+    ret += "              whose <code>hreflang</code> attribute is exactly 'fr'.</p>";\r
+    ret += "          <pre>link[hreflang=fr]</pre>";\r
+    ret += "          <p>The following selector represents a <code>link</code> element for";\r
+    ret += "              which the values of the <code>hreflang</code> attribute begins with";\r
+    ret += "              'en', including 'en', 'en-US', and 'en-cockney':</p>";\r
+    ret += "          <pre>link[hreflang|='en']</pre>";\r
+    ret += "          <p>Similarly, the following selectors represents a";\r
+    ret += "              <code>DIALOGUE</code> element whenever it has one of two different";\r
+    ret += "              values for an attribute <code>character</code>:</p>";\r
+    ret += "        <pre>DIALOGUE[character=romeo]";\r
+    ret += "      DIALOGUE[character=juliet]</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='attribute-substrings'></a>6.3.2. Substring matching attribute";\r
+    ret += "          selectors</h4>";\r
+    ret += "      <p>Three additional attribute selectors are provided for matching";\r
+    ret += "          substrings in the value of an attribute:</p>";\r
+    ret += "      <dl>";\r
+    ret += "          <dt><code>[att^=val]</code></dt>";\r
+    ret += "          <dd>Represents an element with the <code>att</code> attribute whose value";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>[att$=val]</code>";\r
+    ret += "          </dt><dd>Represents an element with the <code>att</code> attribute whose value";\r
+    ret += "          </dd>";\r
+    ret += "          <dt><code>[att*=val]</code>";\r
+    ret += "          </dt><dd>Represents an element with the <code>att</code> attribute whose value";\r
+    ret += "          </dd>";\r
+    ret += "      </dl>";\r
+    ret += "      <p>Attribute values must be identifiers or strings. The";\r
+    ret += "          case-sensitivity of attribute names in selectors depends on the";\r
+    ret += "          document language.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following selector represents an HTML <code>object</code>,";\r
+    ret += "              image:</p>";\r
+    ret += "          <pre>object[type^='image/']</pre>";\r
+    ret += "          <p>The following selector represents an HTML anchor <code>a</code> with an";\r
+    ret += "              <code>href</code> attribute whose value ends with '.html'.</p>";\r
+    ret += "          <pre>a[href$='.html']</pre>";\r
+    ret += "          <p>The following selector represents an HTML paragraph with a";\r
+    ret += "              <code>title</code>";\r
+    ret += "              attribute whose value contains the substring 'hello'</p>";\r
+    ret += "          <pre>p[title*='hello']</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='attrnmsp'>6.3.3. Attribute selectors and namespaces</a></h4>";\r
+    ret += "      <p>Attribute selectors allow an optional namespace component to the";\r
+    ret += "          separator 'vertical bar' (<code>|</code>). In keeping with";\r
+    ret += "          apply to attributes, therefore attribute selectors without a namespace";\r
+    ret += "          (equivalent to '<code>|attr</code>'). An asterisk may be used for the";\r
+    ret += "      </p><p>An attribute selector with an attribute name containing a namespace";\r
+    ret += "          prefix that has not been previously declared is an <a href='#Conformance'>invalid</a> selector. The mechanism for";\r
+    ret += "          a namespace prefix is left up to the language implementing Selectors.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>CSS examples:</p>";\r
+    ret += "        <pre>@namespace foo 'http://www.example.com';";\r
+    ret += "      [att] { color: green }</pre>";\r
+    ret += "          <p>The first rule will match only elements with the attribute";\r
+    ret += "              <code>att</code> in the 'http://www.example.com' namespace with the";\r
+    ret += "              value 'val'.</p>";\r
+    ret += "          <p>The second rule will match only elements with the attribute";\r
+    ret += "              <code>att</code> regardless of the namespace of the attribute";\r
+    ret += "              (including no declared namespace).</p>";\r
+    ret += "          <p>The last two rules are equivalent and will match only elements";\r
+    ret += "              with the attribute <code>att</code> where the attribute is not";\r
+    ret += "              declared to be in a namespace.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='def-values'>6.3.4. Default attribute values in DTDs</a></h4>";\r
+    ret += "      <p>Attribute selectors represent explicitly set attribute values in";\r
+    ret += "          selectors. Selectors should be designed so that they work even if the";\r
+    ret += "          default values are not included in the document tree.</p>";\r
+    ret += "      <p>More precisely, a UA is <em>not</em> required to read an 'external";\r
+    ret += "          subset' of the DTD but <em>is</em> required to look for default";\r
+    ret += "          attribute values in the document's 'internal subset.' (See <a href='#refsXML10'>[XML10]</a> for definitions of these subsets.)</p>";\r
+    ret += "      <p>A UA that recognizes an XML namespace <a href='#refsXMLNAMES'>[XMLNAMES]</a> is not required to use its";\r
+    ret += "          required to use its built-in knowledge of the XHTML DTD.)</p>";\r
+    ret += "      <p class='note'><strong>Note:</strong> Typically, implementations";\r
+    ret += "          choose to ignore external subsets.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>Consider an element EXAMPLE with an attribute 'notation' that has a";\r
+    ret += "              default value of 'decimal'. The DTD fragment might be</p>";\r
+    ret += "          <pre class='dtd-example'>&lt;!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'&gt;</pre>";\r
+    ret += "          <p>If the style sheet contains the rules</p>";\r
+    ret += "      <pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }";\r
+    ret += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>";\r
+    ret += "          <p>the first rule will not match elements whose 'notation' attribute";\r
+    ret += "              attribute selector for the default value must be dropped:</p>";\r
+    ret += "      <pre>EXAMPLE                   { /*... default property settings ...*/ }";\r
+    ret += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>";\r
+    ret += "          <p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is";\r
+    ret += "              cases' style rules.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <h3><a name='class-html'>6.4. Class selectors</a></h3>";\r
+    ret += "      <p>Working with HTML, authors may use the period (U+002E,";\r
+    ret += "          <code>.</code>) notation as an alternative to the <code>~=</code>";\r
+    ret += "          notation when representing the <code>class</code> attribute. Thus, for";\r
+    ret += "          HTML, <code>div.value</code> and <code>div[class~=value]</code> have";\r
+    ret += "          'period' (<code>.</code>).</p>";\r
+    ret += "      <p>UAs may apply selectors using the period (.) notation in XML";\r
+    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";\r
+    ret += "              'class' attribute</a> and how a UA should interpret it, and";\r
+    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";\r
+    ret += "              'class' attribute</a>.)</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>CSS examples:</p>";\r
+    ret += "          <p>We can assign style information to all elements with";\r
+    ret += "              <code>class~='pastoral'</code> as follows:</p>";\r
+    ret += "          <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>";\r
+    ret += "          <p>or just</p>";\r
+    ret += "          <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>";\r
+    ret += "          <p>The following assigns style only to H1 elements with";\r
+    ret += "              <code>class~='pastoral'</code>:</p>";\r
+    ret += "          <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>";\r
+    ret += "          <p>Given these rules, the first H1 instance below would not have";\r
+    ret += "              green text, while the second would:</p>";\r
+    ret += "        <pre>&lt;H1&gt;Not green&lt;/H1&gt;";\r
+    ret += "      &lt;H1 class='pastoral'&gt;Very green&lt;/H1&gt;</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>To represent a subset of 'class' values, each value must be preceded";\r
+    ret += "          by a '.', in any order.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>CSS example:</p>";\r
+    ret += "          <p>The following rule matches any P element whose 'class' attribute";\r
+    ret += "              has been assigned a list of <a href='#whitespace'>whitespace</a>-separated values that includes";\r
+    ret += "              'pastoral' and 'marine':</p>";\r
+    ret += "          <pre>p.pastoral.marine { color: green }</pre>";\r
+    ret += "          <p>This rule matches when <code>class='pastoral blue aqua";\r
+    ret += "              marine'</code> but does not match for <code>class='pastoral";\r
+    ret += "              blue'</code>.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note:</strong> Because CSS gives considerable";\r
+    ret += "          not.</p>";\r
+    ret += "      <p class='note'><strong>Note:</strong> If an element has multiple";\r
+    ret += "          this specification.</p>";\r
+    ret += "      <h3><a name='id-selectors'>6.5. ID selectors</a></h3>";\r
+    ret += "      <p>Document languages may contain attributes that are declared to be";\r
+    ret += "          applies.</p>";\r
+    ret += "      <p>An ID-typed attribute of a document language allows authors to";\r
+    ret += "          ID selectors represent an element instance based on its identifier. An";\r
+    ret += "          <code>#</code>) immediately followed by the ID value, which must be an";\r
+    ret += "          identifier.</p>";\r
+    ret += "      <p>Selectors does not specify how a UA knows the ID-typed attribute of";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following ID selector represents an <code>h1</code> element";\r
+    ret += "              whose ID-typed attribute has the value 'chapter1':</p>";\r
+    ret += "          <pre>h1#chapter1</pre>";\r
+    ret += "          <p>The following ID selector represents any element whose ID-typed";\r
+    ret += "              attribute has the value 'chapter1':</p>";\r
+    ret += "          <pre>#chapter1</pre>";\r
+    ret += "          <p>The following selector represents any element whose ID-typed";\r
+    ret += "              attribute has the value 'z98y'.</p>";\r
+    ret += "          <pre>*#z98y</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note.</strong> In XML 1.0 <a href='#refsXML10'>[XML10]</a>, the information about which attribute";\r
+    ret += "          should use normal attribute selectors instead:";\r
+    ret += "          <code>[name=p371]</code> instead of <code>#p371</code>. Elements in";\r
+    ret += "          XML 1.0 documents without a DTD do not have IDs at all.</p>";\r
+    ret += "      <p>If an element has multiple ID attributes, all of them must be";\r
+    ret += "          DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>";\r
+    ret += "      <h3><a name='pseudo-classes'>6.6. Pseudo-classes</a></h3>";\r
+    ret += "      <p>The pseudo-class concept is introduced to permit selection based on";\r
+    ret += "          expressed using the other simple selectors.</p>";\r
+    ret += "      <p>A pseudo-class always consists of a 'colon'";\r
+    ret += "          (<code>:</code>) followed by the name of the pseudo-class and";\r
+    ret += "          optionally by a value between parentheses.</p>";\r
+    ret += "      <p>Pseudo-classes are allowed in all sequences of simple selectors";\r
+    ret += "          sequences of simple selectors, after the leading type selector or";\r
+    ret += "          document.</p>";\r
+    ret += "      <h4><a name='dynamic-pseudos'>6.6.1. Dynamic pseudo-classes</a></h4>";\r
+    ret += "      <p>Dynamic pseudo-classes classify elements on characteristics other";\r
+    ret += "          that cannot be deduced from the document tree.</p>";\r
+    ret += "      <p>Dynamic pseudo-classes do not appear in the document source or";\r
+    ret += "          document tree.</p>";\r
+    ret += "      <h5>The <a name='link'>link pseudo-classes: :link and :visited</a></h5>";\r
+    ret += "      <p>User agents commonly display unvisited links differently from";\r
+    ret += "          previously visited ones. Selectors";\r
+    ret += "          provides the pseudo-classes <code>:link</code> and";\r
+    ret += "          <code>:visited</code> to distinguish them:</p>";\r
+    ret += "      <ul>";\r
+    ret += "          <li>The <code>:link</code> pseudo-class applies to links that have";\r
+    ret += "          </li>";\r
+    ret += "          <li>The <code>:visited</code> pseudo-class applies once the link has";\r
+    ret += "          </li>";\r
+    ret += "      </ul>";\r
+    ret += "      <p>After some amount of time, user agents may choose to return a";\r
+    ret += "          visited link to the (unvisited) ':link' state.</p>";\r
+    ret += "      <p>The two states are mutually exclusive.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The following selector represents links carrying class";\r
+    ret += "              <code>external</code> and already visited:</p>";\r
+    ret += "          <pre>a.external:visited</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note:</strong> It is possible for style sheet";\r
+    ret += "      </p><p>UAs may therefore treat all links as unvisited links, or implement";\r
+    ret += "          and unvisited links differently.</p>";\r
+    ret += "      <h5>The <a name='useraction-pseudos'>user action pseudo-classes";\r
+    ret += "          :hover, :active, and :focus</a></h5>";\r
+    ret += "      <p>Interactive user agents sometimes change the rendering in response";\r
+    ret += "          to user actions. Selectors provides";\r
+    ret += "          acting on.</p>";\r
+    ret += "      <ul>";\r
+    ret += "          <li>The <code>:hover</code> pseudo-class applies while the user";\r
+    ret += "              element. User agents not that do not support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";\r
+    ret += "                  media</a> do not have to support this pseudo-class. Some conforming";\r
+    ret += "              user agents that support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";\r
+    ret += "                  media</a> may not be able to support this pseudo-class (e.g., a pen";\r
+    ret += "          </li>";\r
+    ret += "          <li>The <code>:active</code> pseudo-class applies while an element";\r
+    ret += "          </li>";\r
+    ret += "          <li>The <code>:focus</code> pseudo-class applies while an element";\r
+    ret += "          </li>";\r
+    ret += "      </ul>";\r
+    ret += "      <p>There may be document language or implementation specific limits on";\r
+    ret += "          which elements can become <code>:active</code> or acquire";\r
+    ret += "          <code>:focus</code>.</p>";\r
+    ret += "      <p>These pseudo-classes are not mutually exclusive. An element may";\r
+    ret += "          match several pseudo-classes at the same time.</p>";\r
+    ret += "      <p>Selectors doesn't define if the parent of an element that is";\r
+    ret += "          ':active' or ':hover' is also in that state.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "        <pre>a:link    /* unvisited links */";\r
+    ret += "      a:active  /* active links */</pre>";\r
+    ret += "          <p>An example of combining dynamic pseudo-classes:</p>";\r
+    ret += "        <pre>a:focus";\r
+    ret += "      a:focus:hover</pre>";\r
+    ret += "          <p>The last selector matches <code>a</code> elements that are in";\r
+    ret += "              the pseudo-class :focus and in the pseudo-class :hover.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note:</strong> An element can be both ':visited'";\r
+    ret += "          and ':active' (or ':link' and ':active').</p>";\r
+    ret += "      <h4><a name='target-pseudo'>6.6.2. The target pseudo-class :target</a></h4>";\r
+    ret += "      <p>Some URIs refer to a location within a resource. This kind of URI";\r
+    ret += "          identifier (called the fragment identifier).</p>";\r
+    ret += "      <p>URIs with fragment identifiers link to a certain element within the";\r
+    ret += "          pointing to an anchor named <code>section_2</code> in an HTML";\r
+    ret += "          document:</p>";\r
+    ret += "      <pre>http://example.com/html/top.html#section_2</pre>";\r
+    ret += "      <p>A target element can be represented by the <code>:target</code>";\r
+    ret += "          the document has no target element.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <pre>p.note:target</pre>";\r
+    ret += "          <p>This selector represents a <code>p</code> element of class";\r
+    ret += "              <code>note</code> that is the target element of the referring";\r
+    ret += "              URI.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>CSS example:</p>";\r
+    ret += "          <p>Here, the <code>:target</code> pseudo-class is used to make the";\r
+    ret += "              target element red and place an image before it, if there is one:</p>";\r
+    ret += "       <pre>*:target { color : red }";\r
+    ret += "      *:target::before { content : url(target.png) }</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='lang-pseudo'>6.6.3. The language pseudo-class :lang</a></h4>";\r
+    ret += "      <p>If the document language specifies how the human language of an";\r
+    ret += "          element is determined, it is possible to write selectors that";\r
+    ret += "          represent an element based on its language. For example, in HTML <a href='#refsHTML4'>[HTML4]</a>, the language is determined by a";\r
+    ret += "          combination of the <code>lang</code> attribute, the <code>meta</code>";\r
+    ret += "          headers). XML uses an attribute called <code>xml:lang</code>, and";\r
+    ret += "          the language.</p>";\r
+    ret += "      <p>The pseudo-class <code>:lang(C)</code> represents an element that";\r
+    ret += "          <code>:lang()</code> selector is based solely on the identifier C";\r
+    ret += "          element's language value, in the same way as if performed by the <a href='#attribute-representation'>'|='</a> operator in attribute";\r
+    ret += "          selectors. The identifier C does not have to be a valid language";\r
+    ret += "          name.</p>";\r
+    ret += "      <p>C must not be empty. (If it is, the selector is invalid.)</p>";\r
+    ret += "      <p class='note'><strong>Note:</strong> It is recommended that";\r
+    ret += "          documents and protocols indicate language using codes from RFC 3066 <a href='#refsRFC3066'>[RFC3066]</a> or its successor, and by means of";\r
+    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'>";\r
+    ret += "              'FAQ: Two-letter or three-letter language codes.'</a></p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The two following selectors represent an HTML document that is in";\r
+    ret += "              Belgian, French, or German. The two next selectors represent";\r
+    ret += "              <code>q</code> quotations in an arbitrary element in Belgian, French,";\r
+    ret += "              or German.</p>";\r
+    ret += "        <pre>html:lang(fr-be)";\r
+    ret += "      :lang(de) &gt; q</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='UIstates'>6.6.4. The UI element states pseudo-classes</a></h4>";\r
+    ret += "      <h5><a name='enableddisabled'>The :enabled and :disabled pseudo-classes</a></h5>";\r
+    ret += "      <p>The <code>:enabled</code> pseudo-class allows authors to customize";\r
+    ret += "          an enabled <code>input</code> element without also specifying what it";\r
+    ret += "          would look like when it was disabled.</p>";\r
+    ret += "      <p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the";\r
+    ret += "          element should look.</p>";\r
+    ret += "      <p>Most elements will be neither enabled nor disabled. An element is";\r
+    ret += "          presently activate it or transfer focus to it.</p>";\r
+    ret += "      <h5><a name='checked'>The :checked pseudo-class</a></h5>";\r
+    ret += "      <p>Radio and checkbox elements can be toggled by the user. Some menu";\r
+    ret += "          toggled 'on' the <code>:checked</code> pseudo-class applies. The";\r
+    ret += "          <code>:checked</code> pseudo-class initially applies to such elements";\r
+    ret += "          that have the HTML4 <code>selected</code> and <code>checked</code>";\r
+    ret += "          attributes as described in <a href='http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1'>Section";\r
+    ret += "              17.2.1 of HTML4</a>, but of course the user can toggle 'off' such";\r
+    ret += "          elements in which case the <code>:checked</code> pseudo-class would no";\r
+    ret += "          longer apply. While the <code>:checked</code> pseudo-class is dynamic";\r
+    ret += "          on the presence of the semantic HTML4 <code>selected</code> and";\r
+    ret += "          <code>checked</code> attributes, it applies to all media.";\r
+    ret += "      </p><h5><a name='indeterminate'>The :indeterminate pseudo-class</a></h5>";\r
+    ret += "      <div class='note'>";\r
+    ret += "          <p>Radio and checkbox elements can be toggled by the user, but are";\r
+    ret += "              This can be due to an element attribute, or DOM manipulation.</p>";\r
+    ret += "          <p>A future version of this specification may introduce an";\r
+    ret += "              <code>:indeterminate</code> pseudo-class that applies to such elements.";\r
+    ret += "              <!--While the <code>:indeterminate</code> pseudo-class is dynamic in";\r
+    ret += "         the presence of an element attribute, it applies to all media.</p>";\r
+    ret += "         <p>Components of a radio-group initialized with no pre-selected choice";\r
+    ret += "         are an example of :indeterminate state.--></p>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='structural-pseudos'>6.6.5. Structural pseudo-classes</a></h4>";\r
+    ret += "      <p>Selectors introduces the concept of <dfn>structural";\r
+    ret += "          pseudo-classes</dfn> to permit selection based on extra information that";\r
+    ret += "          the document tree but cannot be represented by other simple selectors or";\r
+    ret += "      </p><p>Note that standalone pieces of PCDATA (text nodes in the DOM) are";\r
+    ret += "      </p><h5><a name='root-pseudo'>:root pseudo-class</a></h5>";\r
+    ret += "      <p>The <code>:root</code> pseudo-class represents an element that is";\r
+    ret += "          <code>HTML</code> element.";\r
+    ret += "      </p><h5><a name='nth-child-pseudo'>:nth-child() pseudo-class</a></h5>";\r
+    ret += "      <p>The";\r
+    ret += "          <code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>";\r
+    ret += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings";\r
+    ret += "          <strong>before</strong> it in the document tree, for a given positive";\r
+    ret += "          integer or zero value of <code>n</code>, and has a parent element. In";\r
+    ret += "          other words, this matches the <var>b</var>th child of an element after";\r
+    ret += "          all the children have been split into groups of <var>a</var> elements";\r
+    ret += "          each. For example, this allows the selectors to address every other";\r
+    ret += "          of paragraph text in a cycle of four. The <var>a</var> and";\r
+    ret += "          <var>b</var> values must be zero, negative integers or positive";\r
+    ret += "      </p><p>In addition to this, <code>:nth-child()</code> can take";\r
+    ret += "          '<code>odd</code>' and '<code>even</code>' as arguments instead.";\r
+    ret += "          '<code>odd</code>' has the same signification as <code>2n+1</code>,";\r
+    ret += "          and '<code>even</code>' has the same signification as <code>2n</code>.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */";\r
+    ret += "      p:nth-child(4n+4) { color: purple; }</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>When <var>a</var>=0, no repeating is used, so for example";\r
+    ret += "          <code>:nth-child(0n+5)</code> matches only the fifth child. When";\r
+    ret += "          <var>a</var>=0, the <var>a</var><code>n</code> part need not be";\r
+    ret += "          <code>:nth-child(<var>b</var>)</code> and the last example simplifies";\r
+    ret += "          to <code>:nth-child(5)</code>.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */";\r
+    ret += "      foo:nth-child(1)      /* same */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>When <var>a</var>=1, the number may be omitted from the rule.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following selectors are therefore equivalent:</p>";\r
+    ret += "      <pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */";\r
+    ret += "      bar                   /* same but lower specificity (0,0,1) */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>If <var>b</var>=0, then every <var>a</var>th element is picked. In";\r
+    ret += "          such a case, the <var>b</var> part may be omitted.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */";\r
+    ret += "      tr:nth-child(2n) /* same */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>If both <var>a</var> and <var>b</var> are equal to zero, the";\r
+    ret += "          pseudo-class represents no element in the document tree.</p>";\r
+    ret += "      <p>The value <var>a</var> can be negative, but only the positive";\r
+    ret += "          values of <var>a</var><code>n</code>+<var>b</var>, for";\r
+    ret += "          <code>n</code>≥0, may represent an element in the document";\r
+    ret += "          tree.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>When the value <var>b</var> is negative, the '+' character in the";\r
+    ret += "          character indicating the negative value of <var>b</var>).</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */";\r
+    ret += "      :nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='nth-last-child-pseudo'>:nth-last-child() pseudo-class</a></h5>";\r
+    ret += "      <p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>";\r
+    ret += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings";\r
+    ret += "          <strong>after</strong> it in the document tree, for a given positive";\r
+    ret += "          integer or zero value of <code>n</code>, and has a parent element. See";\r
+    ret += "          <code>:nth-child()</code> pseudo-class for the syntax of its argument.";\r
+    ret += "          It also accepts the '<code>even</code>' and '<code>odd</code>' values";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */";\r
+    ret += "                                    counting from the last one */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='nth-of-type-pseudo'>:nth-of-type() pseudo-class</a></h5>";\r
+    ret += "      <p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>";\r
+    ret += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";\r
+    ret += "          element name <strong>before</strong> it in the document tree, for a";\r
+    ret += "          given zero or positive integer value of <code>n</code>, and has a";\r
+    ret += "          parent element. In other words, this matches the <var>b</var>th child";\r
+    ret += "          groups of a elements each. See <code>:nth-child()</code> pseudo-class";\r
+    ret += "          '<code>even</code>' and '<code>odd</code>' values.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>CSS example:</p>";\r
+    ret += "          <p>This allows an author to alternate the position of floated images:</p>";\r
+    ret += "      <pre>img:nth-of-type(2n+1) { float: right; }";\r
+    ret += "      img:nth-of-type(2n) { float: left; }</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='nth-last-of-type-pseudo'>:nth-last-of-type() pseudo-class</a></h5>";\r
+    ret += "      <p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>";\r
+    ret += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";\r
+    ret += "          element name <strong>after</strong> it in the document tree, for a";\r
+    ret += "          given zero or positive integer value of <code>n</code>, and has a";\r
+    ret += "          parent element. See <code>:nth-child()</code> pseudo-class for the";\r
+    ret += "          syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>'";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>To represent all <code>h2</code> children of an XHTML";\r
+    ret += "              <code>body</code> except the first and last, one could use the";\r
+    ret += "              following selector:</p>";\r
+    ret += "          <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>";\r
+    ret += "          <p>In this case, one could also use <code>:not()</code>, although the";\r
+    ret += "              selector ends up being just as long:</p>";\r
+    ret += "          <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='first-child-pseudo'>:first-child pseudo-class</a></h5>";\r
+    ret += "      <p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code>";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following selector represents a <code>p</code> element that is";\r
+    ret += "              the first child of a <code>div</code> element:</p>";\r
+    ret += "          <pre>div &gt; p:first-child</pre>";\r
+    ret += "          <p>This selector can represent the <code>p</code> inside the";\r
+    ret += "              <code>div</code> of the following fragment:</p>";\r
+    ret += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";\r
+    ret += "      &lt;/div&gt;</pre>";\r
+    ret += "          but cannot represent the second <code>p</code> in the following";\r
+    ret += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";\r
+    ret += "      &lt;/div&gt;</pre>";\r
+    ret += "          <p>The following two selectors are usually equivalent:</p>";\r
+    ret += "        <pre>* &gt; a:first-child /* a is first child of any element */";\r
+    ret += "      a:first-child /* Same (assuming a is not the root element) */</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='last-child-pseudo'>:last-child pseudo-class</a></h5>";\r
+    ret += "      <p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code>";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The following selector represents a list item <code>li</code> that";\r
+    ret += "              is the last child of an ordered list <code>ol</code>.";\r
+    ret += "          </p><pre>ol &gt; li:last-child</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='first-of-type-pseudo'>:first-of-type pseudo-class</a></h5>";\r
+    ret += "      <p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code>";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The following selector represents a definition title";\r
+    ret += "              <code>dt</code> inside a definition list <code>dl</code>, this";\r
+    ret += "              <code>dt</code> being the first of its type in the list of children of";\r
+    ret += "              its parent element.</p>";\r
+    ret += "          <pre>dl dt:first-of-type</pre>";\r
+    ret += "          <p>It is a valid description for the first two <code>dt</code>";\r
+    ret += "              elements in the following example but not for the third one:</p>";\r
+    ret += "      <pre>&lt;dl&gt;";\r
+    ret += "      &lt;/dl&gt;</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='last-of-type-pseudo'>:last-of-type pseudo-class</a></h5>";\r
+    ret += "      <p>Same as <code>:nth-last-of-type(1)</code>. The";\r
+    ret += "          <code>:last-of-type</code> pseudo-class represents an element that is";\r
+    ret += "          element.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The following selector represents the last data cell";\r
+    ret += "              <code>td</code> of a table row.</p>";\r
+    ret += "          <pre>tr &gt; td:last-of-type</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h5><a name='only-child-pseudo'>:only-child pseudo-class</a></h5>";\r
+    ret += "      <p>Represents an element that has a parent element and whose parent";\r
+    ret += "          <code>:first-child:last-child</code> or";\r
+    ret += "          <code>:nth-child(1):nth-last-child(1)</code>, but with a lower";\r
+    ret += "          specificity.</p>";\r
+    ret += "      <h5><a name='only-of-type-pseudo'>:only-of-type pseudo-class</a></h5>";\r
+    ret += "      <p>Represents an element that has a parent element and whose parent";\r
+    ret += "          as <code>:first-of-type:last-of-type</code> or";\r
+    ret += "          <code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower";\r
+    ret += "          specificity.</p>";\r
+    ret += "      <h5><a name='empty-pseudo'></a>:empty pseudo-class</h5>";\r
+    ret += "      <p>The <code>:empty</code> pseudo-class represents an element that has";\r
+    ret += "          empty or not.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p><code>p:empty</code> is a valid representation of the following fragment:";\r
+    ret += "          </p>";\r
+    ret += "          <pre>&lt;p&gt;&lt;/p&gt;</pre>";\r
+    ret += "          <p><code>foo:empty</code> is not a valid representation for the";\r
+    ret += "              following fragments:</p>";\r
+    ret += "          <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>";\r
+    ret += "          <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>";\r
+    ret += "          <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='content-selectors'>6.6.6. Blank</a></h4>";\r
+    ret += "      <!-- It's the Return of Appendix H!!! Run away! -->";\r
+    ret += "      <p>This section intentionally left blank.</p>";\r
+    ret += "      <!-- (used to be :contains()) -->";\r
+    ret += "      <h4><a name='negation'></a>6.6.7. The negation pseudo-class</h4>";\r
+    ret += "      <p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a";\r
+    ret += "          functional notation taking a <a href='#simple-selectors-dfn'>simple";\r
+    ret += "              selector</a> (excluding the negation pseudo-class itself and";\r
+    ret += "          <!-- pseudo-elements are not simple selectors, so the above paragraph";\r
+    ret += "      may be a bit confusing -->";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following CSS selector matches all <code>button</code>";\r
+    ret += "              elements in an HTML document that are not disabled.</p>";\r
+    ret += "          <pre>button:not([DISABLED])</pre>";\r
+    ret += "          <p>The following selector represents all but <code>FOO</code>";\r
+    ret += "              elements.</p>";\r
+    ret += "          <pre>*:not(FOO)</pre>";\r
+    ret += "          <p>The following group of selectors represents all HTML elements";\r
+    ret += "              except links.</p>";\r
+    ret += "          <pre>html|*:not(:link):not(:visited)</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>Default namespace declarations do not affect the argument of the";\r
+    ret += "          type selector.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>Assuming that the default namespace is bound to";\r
+    ret += "              elements that are not in that namespace:</p>";\r
+    ret += "          <pre>*|*:not(*)</pre>";\r
+    ret += "          <p>The following CSS selector matches any element being hovered,";\r
+    ret += "              rule when they <em>are</em> being hovered.</p>";\r
+    ret += "          <pre>*|*:not(:hover)</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note</strong>: the :not() pseudo allows";\r
+    ret += "          useless selectors to be written. For instance <code>:not(*|*)</code>,";\r
+    ret += "          which represents no element at all, or <code>foo:not(bar)</code>,";\r
+    ret += "          which is equivalent to <code>foo</code> but with a higher";\r
+    ret += "          specificity.</p>";\r
+    ret += "      <h3><a name='pseudo-elements'>7. Pseudo-elements</a></h3>";\r
+    ret += "      <p>Pseudo-elements create abstractions about the document tree beyond";\r
+    ret += "          source document (e.g., the <code>::before</code> and";\r
+    ret += "          <code>::after</code> pseudo-elements give access to generated";\r
+    ret += "          content).</p>";\r
+    ret += "      <p>A pseudo-element is made of two colons (<code>::</code>) followed";\r
+    ret += "          by the name of the pseudo-element.</p>";\r
+    ret += "      <p>This <code>::</code> notation is introduced by the current document";\r
+    ret += "          <code>:first-line</code>, <code>:first-letter</code>,";\r
+    ret += "          <code>:before</code> and <code>:after</code>). This compatibility is";\r
+    ret += "          not allowed for the new pseudo-elements introduced in CSS level 3.</p>";\r
+    ret += "      <p>Only one pseudo-element may appear per selector, and if present it";\r
+    ret += "          must appear after the sequence of simple selectors that represents the";\r
+    ret += "          <a href='#subject'>subjects</a> of the selector. <span class='note'>A";\r
+    ret += "      pesudo-elements per selector.</span></p>";\r
+    ret += "      <h4><a name='first-line'>7.1. The ::first-line pseudo-element</a></h4>";\r
+    ret += "      <p>The <code>::first-line</code> pseudo-element describes the contents";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>CSS example:</p>";\r
+    ret += "          <pre>p::first-line { text-transform: uppercase }</pre>";\r
+    ret += "          <p>The above rule means 'change the letters of the first line of every";\r
+    ret += "              paragraph to uppercase'.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <p>The selector <code>p::first-line</code> does not match any real";\r
+    ret += "          agents will insert at the beginning of every paragraph.</p>";\r
+    ret += "      <p>Note that the length of the first line depends on a number of";\r
+    ret += "          an ordinary HTML paragraph such as:</p>";\r
+    ret += "      <pre>      &lt;P&gt;This is a somewhat long HTML ";\r
+    ret += "      </pre>";\r
+    ret += "      <p>the lines of which happen to be broken as follows:";\r
+    ret += "      </p><pre>      THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT";\r
+    ret += "      </pre>";\r
+    ret += "      <p>This paragraph might be 'rewritten' by user agents to include the";\r
+    ret += "          <em>fictional tag sequence</em> for <code>::first-line</code>. This";\r
+    ret += "          fictional tag sequence helps to show how properties are inherited.</p>";\r
+    ret += "      <pre>      &lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML ";\r
+    ret += "      paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several";\r
+    ret += "      </pre>";\r
+    ret += "      <p>If a pseudo-element breaks up a real element, the desired effect";\r
+    ret += "          with a <code>span</code> element:</p>";\r
+    ret += "      <pre>      &lt;P&gt;<b>&lt;SPAN class='test'&gt;</b> This is a somewhat long HTML";\r
+    ret += "      lines.<b>&lt;/SPAN&gt;</b> The first line will be identified";\r
+    ret += "      </pre>";\r
+    ret += "      <p>the user agent could simulate start and end tags for";\r
+    ret += "          <code>span</code> when inserting the fictional tag sequence for";\r
+    ret += "          <code>::first-line</code>.";\r
+    ret += "      </p><pre>      &lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class='test'&gt;</b> This is a";\r
+    ret += "      paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN";\r
+    ret += "          class='test'&gt;</b> be";\r
+    ret += "      lines.<b>&lt;/SPAN&gt;</b> The first line will be identified";\r
+    ret += "      </pre>";\r
+    ret += "      <p>In CSS, the <code>::first-line</code> pseudo-element can only be";\r
+    ret += "          or a table-cell.</p>";\r
+    ret += "      <p><a name='first-formatted-line'></a>The 'first formatted line' of an";\r
+    ret += "          line of the <code>div</code> in <code>&lt;DIV&gt;&lt;P&gt;This";\r
+    ret += "              line...&lt;/P&gt;&lt;/DIV&gt;</code> is the first line of the <code>p</code>";\r
+    ret += "          that both <code>p</code> and <code>div</code> are block-level).";\r
+    ret += "      </p><p>The first line of a table-cell or inline-block cannot be the first";\r
+    ret += "          formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P";\r
+    ret += "              etcetera&lt;/DIV&gt;</code> the first formatted line of the";\r
+    ret += "          <code>div</code> is not the line 'Hello'.";\r
+    ret += "      </p><p class='note'>Note that the first line of the <code>p</code> in this";\r
+    ret += "          fragment: <code>&lt;p&gt;&lt;br&gt;First...</code> doesn't contain any";\r
+    ret += "          letters (assuming the default style for <code>br</code> in HTML";\r
+    ret += "      </p><p>A UA should act as if the fictional start tags of the";\r
+    ret += "          <code>::first-line</code> pseudo-elements were nested just inside the";\r
+    ret += "          is an example. The fictional tag sequence for</p>";\r
+    ret += "      <pre>      &lt;DIV&gt;";\r
+    ret += "      </pre>";\r
+    ret += "      <p>is</p>";\r
+    ret += "      <pre>      &lt;DIV&gt;";\r
+    ret += "      </pre>";\r
+    ret += "      <p>The <code>::first-line</code> pseudo-element is similar to an";\r
+    ret += "          following properties apply to a <code>::first-line</code>";\r
+    ret += "          properties as well.</p>";\r
+    ret += "      <h4><a name='first-letter'>7.2. The ::first-letter pseudo-element</a></h4>";\r
+    ret += "      <p>The <code>::first-letter</code> pseudo-element represents the first";\r
+    ret += "          is 'none'; otherwise, it is similar to a floated element.</p>";\r
+    ret += "      <p>In CSS, these are the properties that apply to <code>::first-letter</code>";\r
+    ret += "          of the letter, unlike for normal elements.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>This example shows a possible rendering of an initial cap. Note";\r
+    ret += "              <code>::first-letter</code>";\r
+    ret += "              fictional start tag of the first letter is inside the <span>span</span>,";\r
+    ret += "              the font weight of the first letter is normal, not bold as the <span>span</span>:";\r
+    ret += "      </p><pre>      p { line-height: 1.1 }";\r
+    ret += "      </pre>";\r
+    ret += "          <div class='figure'>";\r
+    ret += "              <p><img src='' alt='Image illustrating the ::first-letter pseudo-element'>";\r
+    ret += "          </p></div>";\r
+    ret += "      </div>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>The following CSS will make a drop cap initial letter span about two";\r
+    ret += "              lines:</p>";\r
+    ret += "      <pre>      &lt;!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'&gt;";\r
+    ret += "      </pre>";\r
+    ret += "          <p>This example might be formatted as follows:</p>";\r
+    ret += "          <div class='figure'>";\r
+    ret += "              <p><img src='' alt='Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements'>";\r
+    ret += "              </p>";\r
+    ret += "          </div>";\r
+    ret += "          <p>The <span class='index-inst' title='fictional tag";\r
+    ret += "      sequence'>fictional tag sequence</span> is:</p>";\r
+    ret += "      <pre>      &lt;P&gt;";\r
+    ret += "      </pre>";\r
+    ret += "          <p>Note that the <code>::first-letter</code> pseudo-element tags abut";\r
+    ret += "              block element.</p></div>";\r
+    ret += "      <p>In order to achieve traditional drop caps formatting, user agents";\r
+    ret += "          glyph outline may be taken into account when formatting.</p>";\r
+    ret += "      <p>Punctuation (i.e, characters defined in Unicode in the 'open' (Ps),";\r
+    ret += "          be included. <a href='#refsUNICODE'>[UNICODE]</a></p>";\r
+    ret += "      <div class='figure'>";\r
+    ret += "          <p><img src='' alt='Quotes that precede the";\r
+    ret += "      first letter should be included.'></p>";\r
+    ret += "      </div>";\r
+    ret += "      <p>The <code>::first-letter</code> also applies if the first letter is";\r
+    ret += "          money.'</p>";\r
+    ret += "      <p>In CSS, the <code>::first-letter</code> pseudo-element applies to";\r
+    ret += "          elements. <span class='note'>A future version of this specification";\r
+    ret += "      types.</span></p>";\r
+    ret += "      <p>The <code>::first-letter</code> pseudo-element can be used with all";\r
+    ret += "          the element, even if that first text is in a descendant.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>The fictional tag sequence for this HTMLfragment:";\r
+    ret += "      </p><pre>&lt;div&gt;";\r
+    ret += "      &lt;p&gt;The first text.</pre>";\r
+    ret += "          <p>is:";\r
+    ret += "      </p><pre>&lt;div&gt;";\r
+    ret += "      &lt;p&gt;&lt;div::first-letter&gt;&lt;p::first-letter&gt;T&lt;/...&gt;&lt;/...&gt;he first text.</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p>The first letter of a table-cell or inline-block cannot be the";\r
+    ret += "          first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P";\r
+    ret += "              etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is";\r
+    ret += "          letter 'H'. In fact, the <code>div</code> doesn't have a first letter.";\r
+    ret += "      </p><p>The first letter must occur on the <a href='#first-formatted-line'>first formatted line.</a> For example, in";\r
+    ret += "          this fragment: <code>&lt;p&gt;&lt;br&gt;First...</code> the first line";\r
+    ret += "          doesn't contain any letters and <code>::first-letter</code> doesn't";\r
+    ret += "          match anything (assuming the default style for <code>br</code> in HTML";\r
+    ret += "      </p><p>In CSS, if an element is a list item ('display: list-item'), the";\r
+    ret += "          <code>::first-letter</code> applies to the first letter in the";\r
+    ret += "          <code>::first-letter</code> on list items with 'list-style-position:";\r
+    ret += "          inside'. If an element has <code>::before</code> or";\r
+    ret += "          <code>::after</code> content, the <code>::first-letter</code> applies";\r
+    ret += "          to the first letter of the element <em>including</em> that content.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p>After the rule 'p::before {content: 'Note: '}', the selector";\r
+    ret += "              'p::first-letter' matches the 'N' of 'Note'.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <p>Some languages may have specific rules about how to treat certain";\r
+    ret += "          considered within the <code>::first-letter</code> pseudo-element.";\r
+    ret += "      </p><p>If the letters that would form the ::first-letter are not in the";\r
+    ret += "          same element, such as ''T' in <code>&lt;p&gt;'&lt;em&gt;T...</code>, the UA";\r
+    ret += "          both elements, or simply not create a pseudo-element.</p>";\r
+    ret += "      <p>Similarly, if the first letter(s) of the block are not at the start";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <p><a name='overlapping-example'>The following example</a> illustrates";\r
+    ret += "              paragraph will be 'red'.</p>";\r
+    ret += "      <pre>p { color: red; font-size: 12pt }";\r
+    ret += "      &lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>";\r
+    ret += "          <p>Assuming that a line break will occur before the word 'ends', the";\r
+    ret += "      <span class='index-inst' title='fictional tag sequence'>fictional tag";\r
+    ret += "      sequence</span> for this fragment might be:</p>";\r
+    ret += "      <pre>&lt;P&gt;";\r
+    ret += "      &lt;/P&gt;</pre>";\r
+    ret += "          <p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>";\r
+    ret += "              element. Properties set on <code>::first-line</code> are inherited by";\r
+    ret += "              <code>::first-letter</code>, but are overridden if the same property is";\r
+    ret += "              <code>::first-letter</code>.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='UIfragments'>7.3.</a> <a name='selection'>The ::selection";\r
+    ret += "          pseudo-element</a></h4>";\r
+    ret += "      <p>The <code>::selection</code> pseudo-element applies to the portion";\r
+    ret += "          field. This pseudo-element should not be confused with the <code><a href='#checked'>:checked</a></code> pseudo-class (which used to be";\r
+    ret += "          named <code>:selected</code>)";\r
+    ret += "      </p><p>Although the <code>::selection</code> pseudo-element is dynamic in";\r
+    ret += "          <a href='#refsCSS21'>[CSS21]</a>) which was originally rendered to a";\r
+    ret += "          <code>::selection</code> state to that other medium, and have all the";\r
+    ret += "          required â€” UAs may omit the <code>::selection</code>";\r
+    ret += "      </p><p>These are the CSS properties that apply to <code>::selection</code>";\r
+    ret += "          <code>::selection</code> may be ignored.";\r
+    ret += "      </p><h4><a name='gen-content'>7.4. The ::before and ::after pseudo-elements</a></h4>";\r
+    ret += "      <p>The <code>::before</code> and <code>::after</code> pseudo-elements";\r
+    ret += "          content. They are explained in CSS 2.1 <a href='#refsCSS21'>[CSS21]</a>.</p>";\r
+    ret += "      <p>When the <code>::first-letter</code> and <code>::first-line</code>";\r
+    ret += "          pseudo-elements are combined with <code>::before</code> and";\r
+    ret += "          <code>::after</code>, they apply to the first letter or line of the";\r
+    ret += "          element including the inserted text.</p>";\r
+    ret += "      <h2><a name='combinators'>8. Combinators</a></h2>";\r
+    ret += "      <h3><a name='descendant-combinators'>8.1. Descendant combinator</a></h3>";\r
+    ret += "      <p>At times, authors may want selectors to describe an element that is";\r
+    ret += "          <code>EM</code> element that is contained within an <code>H1</code>";\r
+    ret += "          descendant combinator is <a href='#whitespace'>white space</a> that";\r
+    ret += "          separates two sequences of simple selectors. A selector of the form";\r
+    ret += "          '<code>A B</code>' represents an element <code>B</code> that is an";\r
+    ret += "          arbitrary descendant of some ancestor element <code>A</code>.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>For example, consider the following selector:</p>";\r
+    ret += "          <pre>h1 em</pre>";\r
+    ret += "          <p>It represents an <code>em</code> element being the descendant of";\r
+    ret += "              an <code>h1</code> element. It is a correct and valid, but partial,";\r
+    ret += "              description of the following fragment:</p>";\r
+    ret += "       <pre>&lt;h1&gt;This &lt;span class='myclass'&gt;headline";\r
+    ret += "      is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>";\r
+    ret += "          <p>The following selector:</p>";\r
+    ret += "          <pre>div * p</pre>";\r
+    ret += "          <p>represents a <code>p</code> element that is a grandchild or later";\r
+    ret += "              descendant of a <code>div</code> element. Note the whitespace on";\r
+    ret += "              of the P.</p>";\r
+    ret += "          <p>The following selector, which combines descendant combinators and";\r
+    ret += "              <a href='#attribute-selectors'>attribute selectors</a>, represents an";\r
+    ret += "              element that (1) has the <code>href</code> attribute set and (2) is";\r
+    ret += "              inside a <code>p</code> that is itself inside a <code>div</code>:</p>";\r
+    ret += "          <pre>div p *[href]</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h3><a name='child-combinators'>8.2. Child combinators</a></h3>";\r
+    ret += "      <p>A <dfn>child combinator</dfn> describes a childhood relationship";\r
+    ret += "          'greater-than sign' (<code>&gt;</code>) character and";\r
+    ret += "          separates two sequences of simple selectors.";\r
+    ret += "      </p><div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following selector represents a <code>p</code> element that is";\r
+    ret += "              child of <code>body</code>:</p>";\r
+    ret += "          <pre>body &gt; p</pre>";\r
+    ret += "          <p>The following example combines descendant combinators and child";\r
+    ret += "              combinators.</p>";\r
+    ret += "          <pre>div ol&gt;li p</pre>";\r
+    ret += "          <!-- LEAVE THOSE SPACES OUT! see below -->";\r
+    ret += "          <p>It represents a <code>p</code> element that is a descendant of an";\r
+    ret += "              <code>li</code> element; the <code>li</code> element must be the";\r
+    ret += "              child of an <code>ol</code> element; the <code>ol</code> element must";\r
+    ret += "              be a descendant of a <code>div</code>. Notice that the optional white";\r
+    ret += "              space around the '&gt;' combinator has been left out.</p>";\r
+    ret += "      </div>";\r
+    ret += "      <p>For information on selecting the first child of an element, please";\r
+    ret += "          see the section on the <code><a href='#structural-pseudos'>:first-child</a></code> pseudo-class";\r
+    ret += "          above.</p>";\r
+    ret += "      <h3><a name='sibling-combinators'>8.3. Sibling combinators</a></h3>";\r
+    ret += "      <p>There are two different sibling combinators: the adjacent sibling";\r
+    ret += "          considering adjacency of elements.</p>";\r
+    ret += "      <h4><a name='adjacent-sibling-combinators'>8.3.1. Adjacent sibling combinator</a>";\r
+    ret += "      </h4>";\r
+    ret += "      <p>The adjacent sibling combinator is made of the 'plus";\r
+    ret += "          sign' (U+002B, <code>+</code>) character that separates two";\r
+    ret += "          sequences of simple selectors. The elements represented by the two";\r
+    ret += "          represented by the second one.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "          <p>The following selector represents a <code>p</code> element";\r
+    ret += "              immediately following a <code>math</code> element:</p>";\r
+    ret += "          <pre>math + p</pre>";\r
+    ret += "          <p>The following selector is conceptually similar to the one in the";\r
+    ret += "              adds a constraint to the <code>h1</code> element, that it must have";\r
+    ret += "              <code>class='opener'</code>:</p>";\r
+    ret += "          <pre>h1.opener + h2</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h4><a name='general-sibling-combinators'>8.3.2. General sibling combinator</a>";\r
+    ret += "      </h4>";\r
+    ret += "      <p>The general sibling combinator is made of the 'tilde'";\r
+    ret += "          (U+007E, <code>~</code>) character that separates two sequences of";\r
+    ret += "          simple selectors. The elements represented by the two sequences share";\r
+    ret += "          represented by the second one.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Example:</p>";\r
+    ret += "          <pre>h1 ~ pre</pre>";\r
+    ret += "          <p>represents a <code>pre</code> element following an <code>h1</code>. It";\r
+    ret += "              is a correct and valid, but partial, description of:</p>";\r
+    ret += "       <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;";\r
+    ret += "      &lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>";\r
+    ret += "      </div>";\r
+    ret += "      <h2><a name='specificity'>9. Calculating a selector's specificity</a></h2>";\r
+    ret += "      <p>A selector's specificity is calculated as follows:</p>";\r
+    ret += "      <ul>";\r
+    ret += "          <li>count the number of ID selectors in the selector (= a)</li>";\r
+    ret += "          <li>count the number of class selectors, attributes selectors, and";\r
+    ret += "          </li>";\r
+    ret += "          <li>count the number of element names in the selector (= c)</li>";\r
+    ret += "          <li>ignore pseudo-elements</li>";\r
+    ret += "      </ul>";\r
+    ret += "      <p>Selectors inside <a href='#negation'>the negation pseudo-class</a>";\r
+    ret += "          a pseudo-class.</p>";\r
+    ret += "      <p>Concatenating the three numbers a-b-c (in a number system with a";\r
+    ret += "          large base) gives the specificity.</p>";\r
+    ret += "      <div class='example'>";\r
+    ret += "          <p>Examples:</p>";\r
+    ret += "      <pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */";\r
+    ret += "      </pre>";\r
+    ret += "      </div>";\r
+    ret += "      <p class='note'><strong>Note:</strong> the specificity of the styles";\r
+    ret += "          specified in an HTML <code>style</code> attribute is described in CSS";\r
+    ret += "          2.1. <a href='#refsCSS21'>[CSS21]</a>.</p>";\r
+    ret += "      <h2><a name='w3cselgrammar'>10. The grammar of Selectors</a></h2>";\r
+    ret += "      <h3><a name='grammar'>10.1. Grammar</a></h3>";\r
+    ret += "      <p>The grammar below defines the syntax of Selectors. It is globally";\r
+    ret += "          shorthand notations beyond Yacc (see <a href='#refsYACC'>[YACC]</a>)";\r
+    ret += "          are used:</p>";\r
+    ret += "      <ul>";\r
+    ret += "          <li><b>*</b>: 0 or more";\r
+    ret += "          </li><li><b>+</b>: 1 or more";\r
+    ret += "          </li><li><b>?</b>: 0 or 1";\r
+    ret += "          </li><li><b>|</b>: separates alternatives";\r
+    ret += "          </li><li><b>[ ]</b>: grouping</li>";\r
+    ret += "      </ul>";\r
+    ret += "      <p>The productions are:</p>";\r
+    ret += "      <pre>selectors_group";\r
+    ret += "        ;</pre>";\r
+    ret += "      <h3><a name='lex'>10.2. Lexical scanner</a></h3>";\r
+    ret += "      <p>The following is the <a name='x3'>tokenizer</a>, written in Flex (see";\r
+    ret += "          <a href='#refsFLEX'>[FLEX]</a>) notation. The tokenizer is";\r
+    ret += "          case-insensitive.</p>";\r
+    ret += "      <p>The two occurrences of '\377' represent the highest character";\r
+    ret += "          possible code point in Unicode/ISO-10646. <a href='#refsUNICODE'>[UNICODE]</a></p>";\r
+    ret += "      <pre>%option case-insensitive";\r
+    ret += "      .                return *yytext;</pre>";\r
+    ret += "      <h2><a name='downlevel'>11. Namespaces and down-level clients</a></h2>";\r
+    ret += "      <p>An important issue is the interaction of CSS selectors with XML";\r
+    ret += "          to construct a CSS style sheet which will properly match selectors in";\r
+    ret += "          is possible to construct a style sheet in which selectors would match";\r
+    ret += "          elements and attributes correctly.</p>";\r
+    ret += "      <p>It should be noted that a down-level CSS client will (if it";\r
+    ret += "          <code>@namespace</code> at-rules, as well as all style rules that make";\r
+    ret += "          use of namespace qualified element type or attribute selectors. The";\r
+    ret += "          than possibly match them incorrectly.</p>";\r
+    ret += "      <p>The use of default namespaces in CSS makes it possible to write";\r
+    ret += "          element type selectors that will function in both namespace aware CSS";\r
+    ret += "          down-level clients may incorrectly match selectors against XML";\r
+    ret += "          elements in other namespaces.</p>";\r
+    ret += "      <p>The following are scenarios and examples in which it is possible to";\r
+    ret += "          that do not implement this proposal.</p>";\r
+    ret += "      <ol>";\r
+    ret += "          <li>";\r
+    ret += "              <p>The XML document does not use namespaces.</p>";\r
+    ret += "              <ul>";\r
+    ret += "                  <li>In this case, it is obviously not necessary to declare or use";\r
+    ret += "                      attribute selectors will function adequately in a down-level";\r
+    ret += "                  </li>";\r
+    ret += "                  <li>In a CSS namespace aware client, the default behavior of";\r
+    ret += "                      element selectors matching without regard to namespace will";\r
+    ret += "                      present. However, the use of specific element type selectors";\r
+    ret += "                      match only elements that have no namespace ('<code>|name</code>')";\r
+    ret += "                      will guarantee that selectors will match only XML elements that";\r
+    ret += "                  </li>";\r
+    ret += "              </ul>";\r
+    ret += "          </li>";\r
+    ret += "          <li>";\r
+    ret += "              <p>The XML document defines a single, default namespace used";\r
+    ret += "                  names.</p>";\r
+    ret += "              <ul>";\r
+    ret += "                  <li>In this case, a down-level client will function as if";\r
+    ret += "                      element type and attribute selectors will match against all";\r
+    ret += "                  </li>";\r
+    ret += "              </ul>";\r
+    ret += "          </li>";\r
+    ret += "          <li>";\r
+    ret += "              <p>The XML document does <b>not</b> use a default namespace, all";\r
+    ret += "                  to the same URI).</p>";\r
+    ret += "              <ul>";\r
+    ret += "                  <li>In this case, the down-level client will view and match";\r
+    ret += "                      element type and attribute selectors based on their fully";\r
+    ret += "                      qualified name, not the local part as outlined in the <a href='#typenmsp'>Type selectors and Namespaces</a>";\r
+    ret += "                      selectors may be declared using an escaped colon";\r
+    ret += "                      '<code>\\:</code>'";\r
+    ret += "                      '<code>html\\:h1</code>' will match";\r
+    ret += "                      <code>&lt;html:h1&gt;</code>. Selectors using the qualified name";\r
+    ret += "                  </li>";\r
+    ret += "                  <li>Note that selectors declared in this fashion will";\r
+    ret += "                      <em>only</em> match in down-level clients. A CSS namespace aware";\r
+    ret += "                      client will match element type and attribute selectors based on";\r
+    ret += "                      the name's local part. Selectors declared with the fully";\r
+    ret += "                  </li>";\r
+    ret += "              </ul>";\r
+    ret += "          </li>";\r
+    ret += "      </ol>";\r
+    ret += "      <p>In other scenarios: when the namespace prefixes used in the XML are";\r
+    ret += "          <em>different</em> namespace URIs within the same document, or in";\r
+    ret += "          a CSS and XML namespace aware client.</p>";\r
+    ret += "      <h2><a name='profiling'>12. Profiles</a></h2>";\r
+    ret += "      <p>Each specification using Selectors must define the subset of W3C";\r
+    ret += "          Selectors it allows and excludes, and describe the local meaning of";\r
+    ret += "          all the components of that subset.</p>";\r
+    ret += "      <p>Non normative examples:";\r
+    ret += "      </p><div class='profile'>";\r
+    ret += "          <table class='tprofile'>";\r
+    ret += "              <tbody>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th class='title' colspan='2'>Selectors profile</th>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Specification</th>";\r
+    ret += "                  <td>CSS level 1</td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Accepts</th>";\r
+    ret += "                  <td>type selectors<br>class selectors<br>ID selectors<br>:link,";\r
+    ret += "                      :visited and :active pseudo-classes<br>descendant combinator";\r
+    ret += "                      <br>::first-line and ::first-letter pseudo-elements";\r
+    ret += "                  </td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Excludes</th>";\r
+    ret += "                  <td>";\r
+    ret += "                      <p>universal selector<br>attribute selectors<br>:hover and";\r
+    ret += "                          pseudo-classes<br>:target pseudo-class<br>:lang()";\r
+    ret += "                          pseudo-class<br>all UI";\r
+    ret += "                          element states pseudo-classes<br>all structural";\r
+    ret += "                          pseudo-classes<br>negation pseudo-class<br>all";\r
+    ret += "                          UI element fragments pseudo-elements<br>::before and ::after";\r
+    ret += "                          pseudo-elements<br>child combinators<br>sibling combinators";\r
+    ret += "                      </p><p>namespaces</p></td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Extra constraints</th>";\r
+    ret += "                  <td>only one class selector allowed per sequence of simple";\r
+    ret += "                      selectors";\r
+    ret += "                  </td>";\r
+    ret += "              </tr>";\r
+    ret += "              </tbody>";\r
+    ret += "          </table>";\r
+    ret += "          <br><br>";\r
+    ret += "          <table class='tprofile'>";\r
+    ret += "              <tbody>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th class='title' colspan='2'>Selectors profile</th>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Specification</th>";\r
+    ret += "                  <td>CSS level 2</td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Accepts</th>";\r
+    ret += "                  <td>type selectors<br>universal selector<br>attribute presence and";\r
+    ret += "                      values selectors<br>class selectors<br>ID selectors<br>:link,";\r
+    ret += "                      <br>descendant combinator<br>child combinator<br>adjacent";\r
+    ret += "                      combinator<br>::first-line and ::first-letter";\r
+    ret += "                      pseudo-elements<br>::before";\r
+    ret += "                  </td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Excludes</th>";\r
+    ret += "                  <td>";\r
+    ret += "                      <p>content selectors<br>substring matching attribute";\r
+    ret += "                          selectors<br>:target pseudo-classes<br>all UI element";\r
+    ret += "                          states pseudo-classes<br>all structural pseudo-classes other";\r
+    ret += "                          than :first-child<br>negation pseudo-class<br>all UI element";\r
+    ret += "                          fragments pseudo-elements<br>general sibling combinators";\r
+    ret += "                      </p><p>namespaces</p></td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Extra constraints</th>";\r
+    ret += "                  <td>more than one class selector per sequence of simple selectors";\r
+    ret += "                  </td>";\r
+    ret += "              </tr>";\r
+    ret += "              </tbody>";\r
+    ret += "          </table>";\r
+    ret += "          <p>In CSS, selectors express pattern matching rules that determine which";\r
+    ret += "          </p><p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>";\r
+    ret += "              with attribute <code>name</code> set inside a section 1 header";\r
+    ret += "              <code>h1</code>:";\r
+    ret += "          </p><pre>h1 a[name]</pre>";\r
+    ret += "          <p>All CSS declarations attached to such a selector are applied to elements";\r
+    ret += "              matching it.</p></div>";\r
+    ret += "      <div class='profile'>";\r
+    ret += "          <table class='tprofile'>";\r
+    ret += "              <tbody>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th class='title' colspan='2'>Selectors profile</th>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Specification</th>";\r
+    ret += "                  <td>STTS 3</td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Accepts</th>";\r
+    ret += "                  <td>";\r
+    ret += "                      <p>type selectors<br>universal selectors<br>attribute";\r
+    ret += "                          selectors<br>class";\r
+    ret += "                          selectors<br>ID selectors<br>all structural";\r
+    ret += "                          pseudo-classes<br>";\r
+    ret += "                      </p><p>namespaces</p></td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Excludes</th>";\r
+    ret += "                  <td>non-accepted pseudo-classes<br>pseudo-elements<br></td>";\r
+    ret += "              </tr>";\r
+    ret += "              <tr>";\r
+    ret += "                  <th>Extra constraints</th>";\r
+    ret += "                  <td>some selectors and combinators are not allowed in fragment";\r
+    ret += "                  </td>";\r
+    ret += "              </tr>";\r
+    ret += "              </tbody>";\r
+    ret += "          </table>";\r
+    ret += "          <p>Selectors can be used in STTS 3 in two different";\r
+    ret += "          </p><ol>";\r
+    ret += "              <li>a selection mechanism equivalent to CSS selection mechanism:";\r
+    ret += "              </li><li>fragment descriptions that appear on the right side of declarations.";\r
+    ret += "              </li>";\r
+    ret += "          </ol>";\r
+    ret += "      </div>";\r
+    ret += "      <h2><a name='Conformance'></a>13. Conformance and requirements</h2>";\r
+    ret += "      <p>This section defines conformance with the present specification only.";\r
+    ret += "      </p><p>The inability of a user agent to implement part of this specification due to";\r
+    ret += "      </p><p>All specifications reusing Selectors must contain a <a href='#profiling'>Profile</a> listing the";\r
+    ret += "          subset of Selectors it accepts or excludes, and describing the constraints";\r
+    ret += "      </p><p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a";\r
+    ret += "      </p><p>User agents must observe the rules for handling parsing errors:";\r
+    ret += "      </p><ul>";\r
+    ret += "          <li>a simple selector containing an undeclared namespace prefix is invalid";\r
+    ret += "          </li>";\r
+    ret += "          <li>a selector containing an invalid simple selector, an invalid combinator";\r
+    ret += "          </li>";\r
+    ret += "          <li>a group of selectors containing an invalid selector is invalid.</li>";\r
+    ret += "      </ul>";\r
+    ret += "      <p>Specifications reusing Selectors must define how to handle parsing";\r
+    ret += "          used is dropped.)</p>";\r
+    ret += "      <!-- Apparently all these references are out of date:";\r
+    ret += "      <p>Implementations of this specification must behave as";\r
+    ret += "      'recipients of text data' as defined by <a href='#refsCWWW'>[CWWW]</a>";\r
+    ret += "      when parsing selectors and attempting matches. (In particular,";\r
+    ret += "      <a href='#refsCWWW'>[CWWW]</a> and <a";\r
+    ret += "      href='#refsUNICODE'>[UNICODE]</a> and apply to implementations of this";\r
+    ret += "      specification.</p>-->";\r
+    ret += "      <h2><a name='Tests'></a>14. Tests</h2>";\r
+    ret += "      <p>This specification has <a href='http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/'>a test";\r
+    ret += "          suite</a> allowing user agents to verify their basic conformance to";\r
+    ret += "          and does not cover all possible combined cases of Selectors.</p>";\r
+    ret += "      <h2><a name='ACKS'></a>15. Acknowledgements</h2>";\r
+    ret += "      <p>The CSS working group would like to thank everyone who has sent";\r
+    ret += "          comments on this specification over the years.</p>";\r
+    ret += "      <p>The working group would like to extend special thanks to Donna";\r
+    ret += "          the final editorial review.</p>";\r
+    ret += "      <h2><a name='references'>16. References</a></h2>";\r
+    ret += "      <dl class='refs'>";\r
+    ret += "          <dt>[CSS1]";\r
+    ret += "          </dt><dd><a name='refsCSS1'></a> Bert Bos, HÃ¥kon Wium Lie; '<cite>Cascading";\r
+    ret += "              Style Sheets, level 1</cite>', W3C Recommendation, 17 Dec 1996, revised";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/REC-CSS1'>http://www.w3.org/TR/REC-CSS1</a></code>)";\r
+    ret += "          </dd><dt>[CSS21]";\r
+    ret += "          </dt><dd><a name='refsCSS21'></a> Bert Bos, Tantek Ã‡elik, Ian Hickson, HÃ¥kon";\r
+    ret += "              Wium Lie, editors; '<cite>Cascading Style Sheets, level 2 revision";\r
+    ret += "                  1</cite>', W3C Working Draft, 13 June 2005";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/CSS21'>http://www.w3.org/TR/CSS21</a></code>)";\r
+    ret += "          </dd><dt>[CWWW]";\r
+    ret += "          </dt><dd><a name='refsCWWW'></a> Martin J. Dürst, François Yergeau,";\r
+    ret += "              Misha Wolf, Asmus Freytag, Tex Texin, editors; '<cite>Character Model";\r
+    ret += "                  for the World Wide Web</cite>', W3C Recommendation, 15 February 2005";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/charmod/'>http://www.w3.org/TR/charmod/</a></code>)";\r
+    ret += "          </dd><dt>[FLEX]";\r
+    ret += "          </dt><dd><a name='refsFLEX'></a> '<cite>Flex: The Lexical Scanner";\r
+    ret += "              Generator</cite>', Version 2.3.7, ISBN 1882114213";\r
+    ret += "          </dd><dt>[HTML4]";\r
+    ret += "          </dt><dd><a name='refsHTML4'></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs,";\r
+    ret += "              editors; '<cite>HTML 4.01 Specification</cite>', W3C Recommendation, 24";\r
+    ret += "          </dd><dd>";\r
+    ret += "              (<a href='http://www.w3.org/TR/html4/'><code>http://www.w3.org/TR/html4/</code></a>)";\r
+    ret += "          </dd><dt>[MATH]";\r
+    ret += "          </dt><dd><a name='refsMATH'></a> Patrick Ion, Robert Miner, editors; '<cite>Mathematical";\r
+    ret += "              Markup Language (MathML) 1.01</cite>', W3C Recommendation, revision of 7";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/REC-MathML/'>http://www.w3.org/TR/REC-MathML/</a></code>)";\r
+    ret += "          </dd><dt>[RFC3066]";\r
+    ret += "          </dt><dd><a name='refsRFC3066'></a> H. Alvestrand; '<cite>Tags for the";\r
+    ret += "              Identification of Languages</cite>', Request for Comments 3066, January";\r
+    ret += "          </dd><dd>(<a href='http://www.ietf.org/rfc/rfc3066.txt'><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)";\r
+    ret += "          </dd><dt>[STTS]";\r
+    ret += "          </dt><dd><a name='refsSTTS'></a> Daniel Glazman; '<cite>Simple Tree Transformation";\r
+    ret += "              Sheets 3</cite>', Electricité de France, submission to the W3C,";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/NOTE-STTS3'>http://www.w3.org/TR/NOTE-STTS3</a></code>)";\r
+    ret += "          </dd><dt>[SVG]";\r
+    ret += "          </dt><dd><a name='refsSVG'></a> Jon Ferraiolo, è—¤æ²¢ æ·³, Dean";\r
+    ret += "              Jackson, editors; '<cite>Scalable Vector Graphics (SVG) 1.1";\r
+    ret += "                  Specification</cite>', W3C Recommendation, 14 January 2003";\r
+    ret += "          </dd><dd>(<code><a href='http://www.w3.org/TR/SVG/'>http://www.w3.org/TR/SVG/</a></code>)";\r
+    ret += "          </dd><dt>[UNICODE]</dt>";\r
+    ret += "          <dd><a name='refsUNICODE'></a> <cite><a href='http://www.unicode.org/versions/Unicode4.1.0/'>The Unicode";\r
+    ret += "              Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA,";\r
+    ret += "              Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href='http://www.unicode.org/versions/Unicode4.0.1/'>Unicode";\r
+    ret += "                  4.0.1</a> and <a href='http://www.unicode.org/versions/Unicode4.1.0/'>Unicode";\r
+    ret += "                  4.1.0</a>.";\r
+    ret += "          </dd><dd>(<code><a href='http://www.unicode.org/versions/'>http://www.unicode.org/versions/</a></code>)";\r
+    ret += "          </dd>";\r
+    ret += "          <dt>[XML10]";\r
+    ret += "          </dt><dd><a name='refsXML10'></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen,";\r
+    ret += "              Eve Maler, François Yergeau, editors; '<cite>Extensible Markup";\r
+    ret += "                  Language (XML) 1.0 (Third Edition)</cite>', W3C Recommendation, 4";\r
+    ret += "          </dd><dd>(<a href='http://www.w3.org/TR/REC-xml/'><code>http://www.w3.org/TR/REC-xml/</code></a>)";\r
+    ret += "          </dd><dt>[XMLNAMES]";\r
+    ret += "          </dt><dd><a name='refsXMLNAMES'></a> Tim Bray, Dave Hollander, Andrew Layman,";\r
+    ret += "              editors; '<cite>Namespaces in XML</cite>', W3C Recommendation, 14";\r
+    ret += "          </dd><dd>(<a href='http://www.w3.org/TR/REC-xml-names/'><code>http://www.w3.org/TR/REC-xml-names/</code></a>)";\r
+    ret += "          </dd><dt>[YACC]";\r
+    ret += "          </dt><dd><a name='refsYACC'></a> S. C. Johnson; '<cite>YACC â€” Yet another";\r
+    ret += "              compiler compiler</cite>', Technical Report, Murray Hill, 1975";\r
+    ret += "      </dd></dl>'; </div>";\r
+    ret += "      <input name='n' value='v1' type='radio'>1";\r
+    ret += "      <input name='n' value='v2' checked='checked' type='radio'>2";\r
+    ret += "</body></html>";\r
+    return ret;\r
   }\r
   \r
 }\r
index a409da0b563462df41f07e92ead4f38e3f411285..9701cd72ab87edaaff699a70a0a8abd5c06ae353 100644 (file)
 package com.google.gwt.query.client;\r
 \r
 import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.user.client.Timer;\r
 import com.google.gwt.user.client.ui.HTML;\r
 import com.google.gwt.user.client.ui.RootPanel;\r
 \r
 /**\r
- * Just a simple class to emulate JUnit TestCase\r
+ * Just a simple class to emulate JUnit TestCase.\r
  */\r
 public class MyTestCase {\r
 \r
   static Element e = null;\r
   static HTML testPanel = null;\r
 \r
-  public void gwtSetUp() {\r
-    if (e == null) {\r
-      testPanel = new HTML();\r
-      RootPanel.get().add(testPanel);\r
-      e = testPanel.getElement();\r
-      e.setId("core-tst");\r
-    } else {\r
-      e.setInnerHTML("");\r
-    }\r
+  public static void assertEquals(Object a, Object b) {\r
+    check(a.equals(b), "assertEquals: expected=" + a + " actual=" + b);\r
   }\r
   \r
-  public static void assertNotNull(Object a) {\r
-    check(a != null, "assertNotNull: actual object is null");\r
+  public static void assertFalse(boolean b) {\r
+    check(!b, "assertTrue: actual should be false but is true");\r
   }\r
 \r
-  public static void assertEquals(Object a, Object b) {\r
-    check(a.equals(b), "assertEquals: expected=" + a + " actual=" + b);\r
+  public static void assertNotNull(Object a) {\r
+    check(a != null, "assertNotNull: actual object is null");\r
   }\r
 \r
   public static void assertTrue(boolean b) {\r
     check(b, "assertTrue: actual should be true but is false");\r
   }\r
   \r
-  public static void assertFalse(boolean b) {\r
-    check(!b, "assertTrue: actual should be false but is true");\r
+  public static void assertTrue(String msg, boolean b) {\r
+    check(b, msg);\r
   }\r
   \r
   public static void check(boolean condition, String message) {\r
     if (!condition) {\r
-      RuntimeException e = new RuntimeException(message);\r
-      e.printStackTrace();\r
-      throw e;\r
+      RuntimeException ex = new RuntimeException(message);\r
+      ex.printStackTrace();\r
+      throw ex;\r
     }\r
   }\r
   \r
   protected static void assertHtmlEquals(Object expected, Object actual) {\r
     assertEquals(iExplorerFixHtml(expected), iExplorerFixHtml(actual));\r
   }\r
-\r
+  \r
   protected static String iExplorerFixHtml(Object s) {\r
-    return s.toString().trim().toLowerCase().\r
-        replaceAll("[\r\n]", "").\r
-        replaceAll(" ([\\w]+)=[\"']([^\"']+)[\"']", " $1=$2").\r
-        replaceAll("\\s+\\$h=\"[^\"]+\"", "").\r
-        replaceAll(" added=[^ >]+", "");\r
+    return s.toString().trim().toLowerCase().replaceAll(\r
+        "[\r\n]", "").replaceAll(\r
+        " ([\\w]+)=[\"']([^\"']+)[\"']", " $1=$2").replaceAll(\r
+        "\\s+\\$h=\"[^\"]+\"", "").replaceAll(\r
+        " added=[^ >]+", "");\r
   }\r
+\r
+  public void gwtSetUp() {\r
+    if (e == null) {\r
+      testPanel = new HTML();\r
+      RootPanel.get().add(testPanel);\r
+      e = testPanel.getElement();\r
+      e.setId("core-tst");\r
+    } else {\r
+      e.setInnerHTML("");\r
+    }\r
+  }\r
+  \r
+  protected static void assertArrayContains(Object result, Object... array) {\r
+    assertArrayContains("", result, array);\r
+  }\r
+  \r
+  protected static void assertArrayContains(String message, Object result, Object... array) {\r
+    String values = "";\r
+    boolean done = false;\r
+    for (Object o : array) {\r
+      values += o.toString() + " ";\r
+      if (result.equals(o)) {\r
+        done = true;\r
+      }\r
+    }\r
+    message = message + ", value (" + result + ") not found in: " + values;\r
+    assertTrue(message, done);\r
+  }  \r
+  \r
+  private boolean testRunning = false;\r
   \r
+  protected void delayTestFinish(int millis) {\r
+    testRunning = true;\r
+    new Timer(){\r
+      public void run() {\r
+        assertFalse(testRunning);\r
+      }\r
+    }.schedule(millis);\r
+  }\r
+  \r
+  protected void finishTest() {\r
+    testRunning = false;\r
+  }\r
   \r
   \r
 }\r
diff --git a/extractInterface.pl b/extractInterface.pl
new file mode 100644 (file)
index 0000000..eeb4fed
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+
+## Just a perl script to extract an interface from a class.
+## It extract all public methods and copies the javadoc.
+## - With the option --lazy it does the work for Lazy classes 
+##     and generates the file with the 'Lazy' prefix
+## - Without --lazy it generates a file with the 'I' prefix
+
+my ($i, $o, $lazy);
+
+foreach (@ARGV) {
+  if (/^--input=(.*)$/) {
+    $o = $i = $1;
+  } elsif (/^--lazy$/) {
+    $lazy = 1;
+  }
+}
+
+my $iclass = $1 if ($i =~ /^.*\/([^\.]+)\.java$/);
+my $oclass = ($lazy ? "Lazy" : "I") . $iclass;
+
+$o =~ s/$iclass/$oclass/;
+my $c = 0;
+
+open(F, $i) || die $!;
+my ($in, $com, $ingq, $inclass, $inh, $head, $body, $inmeth, $meth) = (0, "", 0, 0, 1, "", "", 0, "");
+my ($a, $b) = (0,0);
+while(<F>) {
+   s/\r+//g;
+   s/^\s+//g;
+   s/^(\*.*)$/ $1/g;
+   $inh = 0 if (/^\/\*\*/);
+   $head .= $_ if ($inh);
+   $inclass=1 if ($ingq && m/(^|\s+|\()(class|enum|new) /);
+   if ($ingq && !$inclass) {
+      $in = 1 if (/^\/\**\s*$/);
+      $com = "" if (/^\/\**\s*$/);
+      next if /static/;
+      next if /$iclass\s*\(/;
+      $inmeth = 1 if (!$inmeth && !$in && /(public .*?\(.*)\s*$/);
+      $meth .= $_ if ($inmeth);
+      if ($inmeth && /\{/) {
+         $meth =~ s/final\s+//g;
+         $meth =~ s/public\s+//g;
+         $meth =~ s/\{\s*//g;
+         $meth =~ s/\s+$//g;
+         if (!/$oclass/) {
+            $meth =~ s/([^\(]*?)$iclass(\s+.*\()/$1$oclass<T>$2/g if ($lazy);
+            $meth =~ s/\n/ /g;
+            $meth =~ s/ +/ /g;
+            $body .= "$com" if (!$in);
+            $body .= "  " .$meth . ";\n\n";
+         }
+         $com = "";
+         $meth = "";
+         $inmeth = 0;
+      }
+      $com .= "  " . $_ if ($in);
+      $in = 0 if (/^\s+\*\/\s*$/);
+   }
+   if ($inclass) {
+      my $l = $_;
+      $a ++ while($l =~ /(\{)/g);
+      $b ++ while($l =~ /(\})/g);
+      $inclass = $a = $b = 0 if ($a == $b);
+   }
+   $ingq = 1 if (!$ingq && m/(^|\s+)class /);
+   #$body .= "$c $ingq $inclass $a $b\n";
+   $c ++;
+}
+close(F);
+
+my $class = "public interface $oclass";
+if ($lazy) {
+  $class .= "<T> extends LazyBase<T>" if ($lazy);
+  $head .= "import com.google.gwt.query.client.LazyBase;\n\n";
+}
+
+open(F, ">$o") || die $!;
+print F $head . $class . "{\n\n" . $body . "}\n";
+close(F);
diff --git a/extractLazyInterfaces.sh b/extractLazyInterfaces.sh
new file mode 100644 (file)
index 0000000..25d480c
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+perl extractInterface.pl --lazy --input=./gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java
+perl extractInterface.pl --lazy --input=./gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java
+perl extractInterface.pl --lazy --input=./gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java
deleted file mode 100644 (file)
index 9c103c8..0000000
+++ /dev/null
@@ -1,711 +0,0 @@
-/*\r
- * Copyright 2009 Google Inc.\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
- * use this file except in compliance with the License. You may obtain a copy of\r
- * the License at\r
- * \r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
- * License for the specific language governing permissions and limitations under\r
- * the License.\r
- */\r
-package com.google.gwt.query.client;\r
-\r
-import com.google.gwt.core.client.Duration;\r
-import com.google.gwt.dom.client.Element;\r
-import com.google.gwt.dom.client.NodeList;\r
-import com.google.gwt.user.client.Timer;\r
-\r
-/**\r
- * Effects plugin for Gwt Query.\r
- */\r
-public class Effects extends GQueryQueue {\r
-\r
-  /**\r
-   * Built in easing functions.\r
-   */\r
-  public enum Easing {\r
-\r
-    /**\r
-     * Linear easing function.\r
-     */\r
-    LINEAR {\r
-      public double ease(double p, double n, double firstNum, double diff) {\r
-        return firstNum + diff * p;\r
-      }\r
-    },\r
-    /**\r
-     * Sinusoidal easing function.\r
-     */\r
-    SWING {\r
-      public double ease(double p, double n, double firstNum, double diff) {\r
-        return ((-Math.cos(p * Math.PI) / 2) + 0.5) * diff + firstNum;\r
-      }\r
-    };\r
-\r
-    /**\r
-     * Override to implement custom easing functions.\r
-     */\r
-    public abstract double ease(double p, double n, double firstNum,\r
-        double diff);\r
-  }\r
-\r
-  /**\r
-   * Build in speed constants.\r
-   */\r
-  public enum Speed {\r
-\r
-    /**\r
-     * 400 millisecond animation.\r
-     */\r
-    DEFAULT(400),\r
-    /**\r
-     * 200 millisecond animation.\r
-     */\r
-    FAST(200),\r
-    /**\r
-     * 600 millisecond animation.\r
-     */\r
-    SLOW(600);\r
-\r
-    private final int duration;\r
-\r
-    Speed(int dur) {\r
-      this.duration = dur;\r
-    }\r
-\r
-    public int getDuration() {\r
-      return duration;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Utility class.\r
-   */\r
-  protected class PropFx {\r
-\r
-    public Element elem;\r
-\r
-    public SpeedOpts opt;\r
-\r
-    public String prop;\r
-\r
-    private double end;\r
-\r
-    private double now;\r
-\r
-    private double pos;\r
-\r
-    private double start;\r
-\r
-    private double startTime;\r
-\r
-    private double state;\r
-\r
-    private String unit;\r
-\r
-    public double cur(boolean force) {\r
-      if (elem.getPropertyString(prop) != null && (elem.getStyle() == null\r
-          || elem.getStyle().getProperty(prop) == null)) {\r
-        return elem.getPropertyDouble(prop);\r
-      }\r
-      double r = parseDouble(GQuery.curCSS(elem, prop, force));\r
-      r = !Double.isNaN(r) && r > -10000 ? r\r
-          : parseDouble(GQuery.curCSS(elem, prop, false));\r
-      if (Double.isNaN(r)) {\r
-        r = 0;\r
-      }\r
-      return r;\r
-    }\r
-\r
-    public void hide() {\r
-      opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
-      opt.hide = true;\r
-      custom(cur(false), 0);\r
-    }\r
-\r
-    public Effects hide(Speed speed) {\r
-      return hide(speed, null);\r
-    }\r
-\r
-    public Effects hide(Speed speed, Function callback) {\r
-      return animate(genFx("hide", 3), speed, Easing.LINEAR, callback);\r
-    }\r
-\r
-    public void show() {\r
-      opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
-      opt.show = true;\r
-      custom("width".equals(prop) || "height".equals(prop) ? 1 : 0, cur(false));\r
-      $(elem).show();\r
-    }\r
-\r
-    public Effects show(Speed speed) {\r
-      return show(speed, null);\r
-    }\r
-\r
-    public Effects show(Speed speed, Function callback) {\r
-      return animate(genFx("show", 3), speed, Easing.LINEAR, callback);\r
-    }\r
-\r
-    public Effects toggle(Speed speed) {\r
-      return hide(speed, null);\r
-    }\r
-\r
-    public Effects toggle(Speed speed, Function callback) {\r
-      return animate(genFx("toggle", 3), speed, Easing.LINEAR, callback);\r
-    }\r
-\r
-    public void update() {\r
-      if ("opacity".equals(prop)) {\r
-        GQuery.setStyleProperty(prop, "" + now, elem);\r
-      } else {\r
-        if (elem.getStyle() != null\r
-            && elem.getStyle().getProperty(prop) != null) {\r
-          elem.getStyle().setProperty(prop, now + unit);\r
-        } else {\r
-          elem.setPropertyString(prop, "" + now);\r
-        }\r
-      }\r
-      if (("height".equals(prop) || "width".equals(prop))\r
-          && elem.getStyle() != null) {\r
-        elem.getStyle().setProperty("display", "block");\r
-      }\r
-    }\r
-\r
-    private void custom(double from, double to) {\r
-      custom(from, to, "px");\r
-    }\r
-\r
-    private void custom(double from, double to, String unit) {\r
-      startTime = Duration.currentTimeMillis();\r
-      start = from;\r
-      end = to;\r
-      now = start;\r
-      this.unit = unit;\r
-      Timer t = new Timer() {\r
-        @Override\r
-        public void run() {\r
-          if (!step(false)) {\r
-            cancel();\r
-          }\r
-        }\r
-      };\r
-      t.scheduleRepeating(13);\r
-    }\r
-\r
-    private boolean step(boolean gotoEnd) {\r
-      double t = Duration.currentTimeMillis();\r
-\r
-      if (gotoEnd || t >= opt.duration + startTime) {\r
-        now = end;\r
-        pos = start = 1;\r
-        update();\r
-        opt.curAnim.set(prop, "true");\r
-        boolean done = true;\r
-        for (String key : opt.curAnim.keys()) {\r
-          if (!"true".equals(opt.curAnim.get(key))) {\r
-            done = false;\r
-          }\r
-        }\r
-        if (done) {\r
-          if (opt.display != null) {\r
-            elem.getStyle().setProperty("overflow", opt.overflow);\r
-            elem.getStyle().setProperty("display", opt.display);\r
-            if ("none".equals(GQuery.curCSS(elem, "display", false))) {\r
-              elem.getStyle().setProperty("display", "block");\r
-            }\r
-          }\r
-          if (opt.hide) {\r
-            $(elem).hide();\r
-          }\r
-          if (opt.hide || opt.show) {\r
-            for (String key : opt.curAnim.keys()) {\r
-              elem.getStyle().setProperty(key, opt.cache.getString(key));\r
-            }\r
-          }\r
-          opt.complete(elem);\r
-        }\r
-        return false;\r
-      } else {\r
-        double n = t - startTime;\r
-        state = n / opt.duration;\r
-        pos = opt.easing.ease(this.state, n, 0, 1);\r
-        now = start + ((this.end - this.start) * this.pos);\r
-\r
-        update();\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Used to register the plugin.\r
-   */\r
-  private static class EffectsPlugin implements Plugin<Effects> {\r
-\r
-    public Effects init(GQuery gq) {\r
-      return new Effects(gq.get());\r
-    }\r
-  }\r
-\r
-  private class SpeedOpts {\r
-\r
-    public Properties curAnim;\r
-\r
-    public String display;\r
-\r
-    public boolean hide;\r
-\r
-    public String overflow;\r
-\r
-    public boolean show;\r
-\r
-    private GQuery.DataCache cache = DataCache.createObject().cast();\r
-\r
-    private Function complete;\r
-\r
-    private int duration;\r
-\r
-    private Effects.Easing easing;\r
-\r
-    private Properties properties;\r
-\r
-    private boolean queue = true;\r
-\r
-    protected SpeedOpts(int speed, Easing easing, Function complete) {\r
-      this.complete = complete;\r
-      this.easing = easing;\r
-      this.duration = speed;\r
-    }\r
-\r
-    protected SpeedOpts(Speed speed, Easing easing, Function complete) {\r
-      this.complete = complete;\r
-      this.easing = easing;\r
-      this.duration = speed.getDuration();\r
-    }\r
-\r
-    public void complete(Element elem) {\r
-      if (queue) {\r
-        new Effects(elem).dequeue();\r
-      }\r
-      if (complete != null) {\r
-        complete.f(elem);\r
-      }\r
-    }\r
-\r
-    public Function getComplete() {\r
-      return complete;\r
-    }\r
-\r
-    public int getDuration() {\r
-      return duration;\r
-    }\r
-\r
-    public Easing getEasing() {\r
-      return easing;\r
-    }\r
-\r
-    public Properties getProperties() {\r
-      return properties;\r
-    }\r
-\r
-    public boolean isQueue() {\r
-      return queue;\r
-    }\r
-\r
-    public void setComplete(Function complete) {\r
-      this.complete = complete;\r
-    }\r
-\r
-    public void setDuration(int duration) {\r
-      this.duration = duration;\r
-    }\r
-\r
-    public void setEasing(Easing easing) {\r
-      this.easing = easing;\r
-    }\r
-\r
-    public void setProperties(Properties properties) {\r
-      this.properties = properties;\r
-    }\r
-\r
-    public void setQueue(boolean queue) {\r
-      this.queue = queue;\r
-    }\r
-  }\r
-\r
-  public static final Class<Effects> Effects = Effects.class;\r
-\r
-  private static String[][] fxAttrs = {\r
-      {"height", "marginTop", "marginBottom", "paddingTop", "paddingBottom"},\r
-      {"width", "marginLeft", "marginRight", "paddingLeft", "paddingRight"},\r
-      {"opacity"}};\r
-\r
-  static {\r
-    GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
-  }\r
-\r
-  private static Properties genFx(String type, int num) {\r
-    Properties prop = Properties.createObject().cast();\r
-    for (int i = 0; i < num; i++) {\r
-      for (int j = 0; j < fxAttrs[i].length; j++) {\r
-        prop.set(fxAttrs[i][j], type);\r
-      }\r
-    }\r
-    return prop;\r
-  }\r
-\r
-  // don't valid double after parsing\r
-  private static native double parseDouble(String dstr) /*-{\r
-    return parseFloat(dstr);\r
-  }-*/;\r
-\r
-  private DataCache elemDisplay = DataCache.createObject().cast();\r
-\r
-  public Effects(Element element) {\r
-    super(element);\r
-  }\r
-\r
-  public Effects(JSArray elements) {\r
-    super(elements);\r
-  }\r
-\r
-  public Effects(NodeList list) {\r
-    super(list);\r
-  }\r
-\r
-  public Effects animate(final Properties properties, final int speed,\r
-      final Easing easing, final Function complete) {\r
-    if (!"false".equals(properties.get("queue"))) {\r
-      queue(new Function() {\r
-        final SpeedOpts optall = new SpeedOpts(speed, easing, complete);\r
-\r
-        @Override\r
-        public void f(Element e) {\r
-          boolean hidden = !$(e).visible();\r
-          for (String key : properties.keys()) {\r
-            String prop = properties.get(key);\r
-            if ("hide".equals(prop) && hidden\r
-                || "show".equals(prop) && !hidden) {\r
-              optall.complete(e);\r
-              return;\r
-            }\r
-            if ("height".equals(key)\r
-                || "width".equals(key) && e.getStyle() != null) {\r
-              optall.display = $(e).css("display");\r
-              optall.overflow = e.getStyle().getProperty("overflow");\r
-            }\r
-          }\r
-          if (optall.overflow != null) {\r
-            e.getStyle().setProperty("overflow", "hidden");\r
-          }\r
-          optall.curAnim = properties.cloneProps();\r
-          for (String key : properties.keys()) {\r
-            PropFx fx = new PropFx();\r
-            String val = properties.get(key);\r
-            fx.elem = e;\r
-            fx.opt = optall;\r
-            fx.prop = key;\r
-            if ("toggle".equals(val)) {\r
-              if (hidden) {\r
-                fx.show();\r
-              } else {\r
-                fx.hide();\r
-              }\r
-            } else if ("show".equals(val)) {\r
-              fx.show();\r
-            } else if ("hide".equals(val)) {\r
-              fx.hide();\r
-            } else {\r
-              JSArray parts = new Regexp("^([+-]=)?([0-9+-.]+)(.*)$")\r
-                  .match(val);\r
-              double start = fx.cur(true);\r
-\r
-              if (parts != null) {\r
-                double end = parseDouble(parts.getStr(2));\r
-                String unit = parts.getStr(3);\r
-                if (unit == null) {\r
-                  unit = "px";\r
-                }\r
-                if (!"px".equals(unit)) {\r
-                  e.getStyle().setProperty(key, (end != 0 ? end : 1) + unit);\r
-                  start = (end != 0 ? end : 1) / fx.cur(true) * start;\r
-                  e.getStyle().setProperty(key, start + unit);\r
-                }\r
-                if (parts.getStr(1) != null) {\r
-                  end = (("-=".equals(parts.getStr(1)) ? -1 : 1) * end) + start;\r
-                }\r
-                fx.custom(start, end, unit);\r
-              } else {\r
-                fx.custom(start, parseDouble(val), "");\r
-              }\r
-            }\r
-          }\r
-        }\r
-      });\r
-    }\r
-    return this;\r
-  }\r
-\r
-\r
-  public Effects animate(final Properties properties, final Speed speed,\r
-      final Easing easing, final Function complete) {\r
-    return animate(properties, speed.getDuration(), easing, complete);\r
-  }\r
-\r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity. Only the opacity\r
-   * is adjusted for this animation, meaning that all of the matched elements\r
-   * should already have some form of height and width associated with them.\r
-   */\r
-  public Effects fadeIn() {\r
-    return fadeIn(Speed.DEFAULT);\r
-  }\r
-\r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity. Only the opacity\r
-   * is adjusted for this animation, meaning that all of the matched elements\r
-   * should already have some form of height and width associated with them.\r
-   */\r
-  public Effects fadeIn(int speed) {\r
-    return fadeIn(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity and firing an\r
-   * optional callback after completion. Only the opacity is adjusted for this\r
-   * animation, meaning that all of the matched elements should already have\r
-   * some form of height and width associated with them.\r
-   */\r
-  public Effects fadeIn(int speed, Function callback) {\r
-    return animate($$("opacity: \"show\""), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity. Only the opacity\r
-   * is adjusted for this animation, meaning that all of the matched elements\r
-   * should already have some form of height and width associated with them.\r
-   */\r
-  public Effects fadeIn(Speed speed) {\r
-    return fadeIn(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity and firing an\r
-   * optional callback after completion. Only the opacity is adjusted for this\r
-   * animation, meaning that all of the matched elements should already have\r
-   * some form of height and width associated with them.\r
-   */\r
-  public Effects fadeIn(Speed speed, Function callback) {\r
-    return fadeIn(speed.duration, callback);\r
-  }\r
-\r
-  /**\r
-   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
-   * display to "none". Only the opacity is adjusted for this animation, meaning\r
-   * that all of the matched elements should already have some form of height\r
-   * and width associated with them.\r
-   */\r
-  public Effects fadeOut() {\r
-    return fadeOut(Speed.DEFAULT);\r
-  }\r
-\r
-  /**\r
-   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
-   * display to "none". Only the opacity is adjusted for this animation, meaning\r
-   * that all of the matched elements should already have some form of height\r
-   * and width associated with them.\r
-   */\r
-  public Effects fadeOut(int speed) {\r
-    return fadeOut(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
-   * display to "none" and firing an optional callback after completion. Only\r
-   * the opacity is adjusted for this animation, meaning that all of the matched\r
-   * elements should already have some form of height and width associated with\r
-   * them.\r
-   */\r
-  public Effects fadeOut(int speed, Function callback) {\r
-    return animate($$("opacity: \"hide\""), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
-   * display to "none". Only the opacity is adjusted for this animation, meaning\r
-   * that all of the matched elements should already have some form of height\r
-   * and width associated with them.\r
-   */\r
-  public Effects fadeOut(Speed speed) {\r
-    return fadeOut(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
-   * display to "none" and firing an optional callback after completion. Only\r
-   * the opacity is adjusted for this animation, meaning that all of the matched\r
-   * elements should already have some form of height and width associated with\r
-   * them.\r
-   */\r
-  public Effects fadeOut(Speed speed, Function callback) {\r
-    return fadeOut(speed.duration, callback);\r
-  }\r
-\r
-  /**\r
-   * Fade the opacity of all matched elements to a specified opacity. Only the\r
-   * opacity is adjusted for this animation, meaning that all of the matched\r
-   * elements should already have some form of height and width associated with\r
-   * them.\r
-   */\r
-  public Effects fadeTo(Speed speed, double opacity) {\r
-    return fadeTo(speed, opacity, null);\r
-  }\r
-\r
-  /**\r
-   * Fade the opacity of all matched elements to a specified opacity and firing\r
-   * an optional callback after completion. Only the opacity is adjusted for\r
-   * this animation, meaning that all of the matched elements should already\r
-   * have some form of height and width associated with them.\r
-   */\r
-  public Effects fadeTo(Speed speed, double opacity, Function callback) {\r
-    return animate($$("opacity: " + opacity), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Hides each of the set of matched elements if they are shown.\r
-   */\r
-  public Effects hide() {\r
-    for (Element e : elements()) {\r
-      GQuery q = $(e);\r
-      String old = (String) q.data("olddisplay");\r
-      if (old != null && !"none".equals(old)) {\r
-        q.data("olddisplay", GQuery.curCSS(e, "display", false));\r
-      }\r
-      e.getStyle().setProperty("display", "none");\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Displays each of the set of matched elements if they are hidden.\r
-   */\r
-  public Effects show() {\r
-    for (Element e : elements()) {\r
-      GQuery q = $(e);\r
-      String old = (String) q.data("olddisplay");\r
-      e.getStyle().setProperty("display", SelectorEngine.or(old, ""));\r
-      if ("none".equals(GQuery.curCSS(e, "display", false))) {\r
-        String tagName = e.getTagName();\r
-        String display = "";\r
-        if (elemDisplay.getString(tagName) != null) {\r
-          display = elemDisplay.getString(tagName);\r
-        } else {\r
-          Element elem = $("<" + tagName + ">").appendTo($("body")).get(0);\r
-          display = GQuery.curCSS(elem, "display", false);\r
-          if ("none".equals(display)) {\r
-            display = "block";\r
-          }\r
-        }\r
-        e.getStyle().setProperty("display", display);\r
-        q.data("olddisplay", display);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Reveal all matched elements by adjusting their height .\r
-   */\r
-  public Effects slideDown() {\r
-    return slideDown(Speed.DEFAULT, null);\r
-  }\r
-\r
-  /**\r
-   * Reveal all matched elements by adjusting their height .\r
-   */\r
-  public Effects slideDown(Speed speed) {\r
-    return slideDown(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Reveal all matched elements by adjusting their height and firing an\r
-   * optional callback after completion.\r
-   */\r
-  public Effects slideDown(Speed speed, Function callback) {\r
-    return animate(genFx("show", 1), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Toggle the visibility of all matched elements by adjusting their height.\r
-   * Only the height is adjusted for this animation, causing all matched\r
-   * elements to be hidden or shown in a "sliding" manner\r
-   */\r
-  public Effects slideToggle() {\r
-    return slideToggle(Speed.DEFAULT, null);\r
-  }\r
-\r
-  /**\r
-   * Toggle the visibility of all matched elements by adjusting their height.\r
-   * Only the height is adjusted for this animation, causing all matched\r
-   * elements to be hidden or shown in a "sliding" manner\r
-   */\r
-  public Effects slideToggle(Speed speed) {\r
-    return slideToggle(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Toggle the visibility of all matched elements by adjusting their height and\r
-   * firing an optional callback after completion. Only the height is adjusted\r
-   * for this animation, causing all matched elements to be hidden or shown in a\r
-   * "sliding" manner\r
-   */\r
-  public Effects slideToggle(Speed speed, Function callback) {\r
-    return animate(genFx("toggle", 1), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Hide all matched elements by adjusting their height .\r
-   */\r
-  public Effects slideUp() {\r
-    return slideUp(Speed.DEFAULT, null);\r
-  }\r
-\r
-  /**\r
-   * Hide all matched elements by adjusting their height.\r
-   */\r
-  public Effects slideUp(Speed speed) {\r
-    return slideUp(speed, null);\r
-  }\r
-\r
-  /**\r
-   * Hide all matched elements by adjusting their height and firing an optional\r
-   * callback after completion.\r
-   */\r
-  public Effects slideUp(Speed speed, Function callback) {\r
-    return animate(genFx("hide", 1), speed, Easing.LINEAR, callback);\r
-  }\r
-\r
-  /**\r
-   * Toggle displaying each of the set of matched elements.\r
-   */\r
-  public Effects toggle() {\r
-    for (Element e : elements()) {\r
-      Effects ef = new Effects(e);\r
-      if (ef.visible()) {\r
-        ef.hide();\r
-      } else {\r
-        ef.show();\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  public boolean visible() {\r
-    return !"none".equalsIgnoreCase(this.css("display"));\r
-  }\r
-}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Events.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Events.java
deleted file mode 100644 (file)
index 30120d6..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * 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.dom.client.Element;
-import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.user.client.Event;
-
-/**
- * GQuery Plugin for handling and queuing browser events.
- */
-public class Events extends GQuery {
-
-  public static final Class<Events> Events = Events.class;
-
-  static {
-    GQuery.registerPlugin(Events.class, new Plugin<Events>() {
-      public Events init(GQuery gq) {
-        return new Events(gq.get());
-      }
-    });
-  }
-
-  public Events(Element element) {
-    super(element);
-  }
-
-  public Events(JSArray elements) {
-    super(elements);
-  }
-
-  public Events(NodeList<Element> list) {
-    super(list);
-  }
-
-  /**
-   * Binds a set of handlers to a particular Event for each matched element.
-   * 
-   * The event handlers are passed as Functions that you can use to prevent
-   * default behavior. To stop both default action and event bubbling, the
-   * function event handler has to return false.
-   * 
-   * You can pass an additional Object data to your Function as the second
-   * parameter
-   * 
-   */
-  public GQuery bind(int eventbits, Object data, Function...funcs) {
-    for (Element e : elements()) {
-      EventsListener.getInstance(e).bind(eventbits, data, funcs);
-    }
-    return this;
-  }
-  
-  /**
-   * Execute all handlers and behaviors attached to the matched elements for the given event types.
-   * 
-   * Different event types can be passed joining these using the or bit wise operator.
-   * 
-   * For keyboard events you can pass a second parameter which represents 
-   * the key-code of the pushed key. 
-   * 
-   * Example: fire(Event.ONCLICK | Event.ONFOCUS)
-   * Example: fire(Event.ONKEYDOWN. 'a');
-   */
-  public GQuery trigger(int eventbits, int... keys) {
-    if ((eventbits | Event.ONBLUR) == Event.ONBLUR)
-      dispatchEvent(document.createBlurEvent());
-    if ((eventbits | Event.ONCHANGE) == Event.ONCHANGE)
-      dispatchEvent(document.createChangeEvent());
-    if ((eventbits | Event.ONCLICK) == Event.ONCLICK)
-      dispatchEvent(document.createClickEvent(0, 0, 0, 0, 0, false, false, false, false));
-    if ((eventbits | Event.ONDBLCLICK) == Event.ONDBLCLICK)
-      dispatchEvent(document.createDblClickEvent(0, 0, 0, 0, 0, false, false, false, false));
-    if ((eventbits | Event.ONFOCUS) == Event.ONFOCUS)
-      dispatchEvent(document.createFocusEvent());
-    if ((eventbits | Event.ONKEYDOWN) == Event.ONKEYDOWN)
-      dispatchEvent(document.createKeyDownEvent(false, false, false, false, keys[0], 0));
-    if ((eventbits | Event.ONKEYPRESS) == Event.ONKEYPRESS)
-      dispatchEvent(document.createKeyPressEvent(false, false, false, false, keys[0], 0));
-    if ((eventbits | Event.ONKEYUP) == Event.ONKEYUP)
-      dispatchEvent(document.createKeyUpEvent(false, false, false, false, keys[0], 0));
-    if ((eventbits | Event.ONLOSECAPTURE) == Event.ONLOSECAPTURE)
-      triggerHtmlEvent("losecapture");
-    if ((eventbits | Event.ONMOUSEDOWN) == Event.ONMOUSEDOWN)
-      dispatchEvent(document.createMouseDownEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
-    if ((eventbits | Event.ONMOUSEMOVE) == Event.ONMOUSEMOVE)
-      dispatchEvent(document.createMouseMoveEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
-    if ((eventbits | Event.ONMOUSEOUT) == Event.ONMOUSEOUT)
-      dispatchEvent(document.createMouseOutEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, null));
-    if ((eventbits | Event.ONMOUSEOVER) == Event.ONMOUSEOVER)
-      dispatchEvent(document.createMouseOverEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, null));
-    if ((eventbits | Event.ONMOUSEUP) == Event.ONMOUSEUP)
-      dispatchEvent(document.createMouseUpEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
-    if ((eventbits | Event.ONSCROLL) == Event.ONSCROLL)
-      dispatchEvent(document.createScrollEvent());
-    if ((eventbits | Event.ONERROR) == Event.ONERROR)
-      dispatchEvent(document.createErrorEvent());
-    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));
-    return this;
-  }
-  
-  protected GQuery triggerHtmlEvent(String htmlEvent) {
-    dispatchEvent(document.createHtmlEvent(htmlEvent, false, false));
-    return this;
-  }
-
-  /**
-   * Removes all handlers, that matches the events bits passed, from each
-   * element.
-   * 
-   * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER)
-   */
-  public GQuery unbind(int eventbits) {
-    for (Element e : elements()) {
-      EventsListener.getInstance(e).unbind(eventbits);
-    }
-    return this;
-  }
-  
-  private void dispatchEvent(NativeEvent evt) {
-    for (Element e : elements()) {
-      e.dispatchEvent(evt);
-    }
-  }
-}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/EventsListener.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/EventsListener.java
deleted file mode 100644 (file)
index fe7bc2e..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * 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.Duration;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.EventListener;
-
-/**
- * This class implements an event queue instance for one Element. The queue
- * instance is configured as the default event listener in GWT.
- * 
- * The reference to this queue is stored as a unique variable in the element's
- * DOM
- * 
- * The class takes care of calling the appropriate functions for each browser
- * event and it also calls sinkEvents method.
- */
-class EventsListener implements EventListener {
-
-  private static class BindFunction {
-
-    Object data;
-
-    Function function;
-
-    int times = -1;
-
-    int type;
-
-    BindFunction(int t, Function f, Object d) {
-      type = t;
-      function = f;
-      data = d;
-    }
-
-    BindFunction(int t, Function f, Object d, int times) {
-      this(t, f, d);
-      this.times = times;
-    }
-
-    public boolean fire(Event event) {
-      if (times != 0) {
-        times--;
-        return function.f(event, data);
-      }
-      return true;
-    }
-
-    public boolean hasEventType(int etype) {
-      return (type | etype) == type;
-    }
-  }
-
-  public static EventsListener getInstance(Element e) {
-    EventsListener ret = getGQueryEventLinstener(e);
-    return ret != null ? ret : new EventsListener(e);
-  }
-
-  private static native EventsListener getGQueryEventLinstener(Element elem) /*-{
-    return elem.__gqueryevent;
-  }-*/;
-
-  private static native EventListener getOriginalEventListener(Element elem) /*-{
-    return elem.__listener;
-  }-*/;
-
-  private static native void setFocusable(Element elem) /*-{
-    elem.tabIndex = 0;
-  }-*/;
-
-  private static native void setGQueryEventListener(Element elem,
-      EventsListener gqevent) /*-{
-    elem.__gqueryevent = gqevent;
-  }-*/;
-
-  private Element element;
-
-  private JsObjectArray<EventsListener.BindFunction> elementEvents = JsObjectArray
-      .createArray().cast();
-  private EventListener originalEventListener;
-
-  private EventsListener(Element element) {
-    this.element = element;
-    originalEventListener = getOriginalEventListener(element);
-    setGQueryEventListener(element, this);
-    DOM.setEventListener((com.google.gwt.user.client.Element) element, this);
-  }
-
-  public void bind(int eventbits, final Object data, Function...funcs) {
-    for (Function function: funcs) {
-      bind(eventbits, data, function, -1);
-    }
-  }
-
-  public void bind(int eventbits, final Object data, final Function function,
-      int times) {
-    if (function == null) {
-      unbind(eventbits);
-    } else {
-      DOM.sinkEvents((com.google.gwt.user.client.Element) element, eventbits
-          | DOM.getEventsSunk((com.google.gwt.user.client.Element) element));
-
-      if ((eventbits | Event.FOCUSEVENTS) == Event.FOCUSEVENTS) {
-        setFocusable(element);
-      }
-
-      elementEvents.add(new EventsListener.BindFunction(eventbits, function,
-          data, times));
-    }
-  }
-
-  double lastEvnt=0;
-  int lastType=0;
-  
-  public void onBrowserEvent(Event event) {
-    // Workaround for Issue_20
-    if (lastType == event.getTypeInt()
-        && lastEvnt - Duration.currentTimeMillis() < 10
-        && "body".equalsIgnoreCase(element.getTagName())) {
-      return;
-    }
-    lastEvnt = Duration.currentTimeMillis();
-    lastType = event.getTypeInt();
-
-    if (originalEventListener != null) {
-      originalEventListener.onBrowserEvent(event);
-    }
-
-    int etype = DOM.eventGetType(event);
-    for (int i = 0; i < elementEvents.length(); i++) {
-      EventsListener.BindFunction listener = elementEvents.get(i);
-      if (listener.hasEventType(etype)) {
-        if (!listener.fire(event)) {
-          event.stopPropagation();
-          event.preventDefault();
-        }
-      }
-    }
-  }
-
-  public void unbind(int eventbits) {
-    JsObjectArray<EventsListener.BindFunction> newList = JsObjectArray
-        .createArray().cast();
-    for (int i = 0; i < elementEvents.length(); i++) {
-      EventsListener.BindFunction listener = elementEvents.get(i);
-      if (!listener.hasEventType(eventbits)) {
-        newList.add(listener);
-      }
-    }
-    elementEvents = newList;
-  }
-}
index b278c203066e84232fd275b0f3a20cee435dc5a4..94900185ffe152d5023ee28d1eba052f9bdb7a27 100644 (file)
@@ -15,8 +15,9 @@
  */\r
 package com.google.gwt.query.client;\r
 \r
-import static com.google.gwt.query.client.Effects.Effects;\r
-import static com.google.gwt.query.client.Events.Events;\r
+\r
+import static com.google.gwt.query.client.plugins.Effects.Effects;\r
+import static com.google.gwt.query.client.plugins.Events.Events;\r
 \r
 import com.google.gwt.core.client.GWT;\r
 import com.google.gwt.core.client.JavaScriptObject;\r
@@ -33,6 +34,7 @@ import com.google.gwt.dom.client.OptionElement;
 import com.google.gwt.dom.client.SelectElement;\r
 import com.google.gwt.dom.client.Style;\r
 import com.google.gwt.dom.client.TextAreaElement;\r
+import com.google.gwt.dom.client.Style.Display;\r
 import com.google.gwt.query.client.css.CssProperty;\r
 import com.google.gwt.query.client.css.Length;\r
 import com.google.gwt.query.client.css.Percentage;\r
@@ -40,7 +42,6 @@ import com.google.gwt.query.client.css.TakesLength;
 import com.google.gwt.query.client.css.TakesPercentage;\r
 import com.google.gwt.query.client.impl.DocumentStyleImpl;\r
 import com.google.gwt.query.client.impl.SelectorEngineImpl;\r
-import com.google.gwt.user.client.DOM;\r
 import com.google.gwt.user.client.Event;\r
 import com.google.gwt.user.client.Window;\r
 \r
@@ -53,10 +54,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * A POJO used to store the top/left CSS positioning values of an element.\r
    */\r
   public static class Offset {\r
-\r
-    public int top;\r
-\r
     public int left;\r
+    public int top;\r
 \r
     Offset(int left, int top) {\r
       this.left = left;\r
@@ -77,11 +76,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     protected DataCache() {\r
     }\r
 \r
-    public native void delete(String name) /*-{\r
+    public native void delete(int name) /*-{\r
       delete this[name];\r
     }-*/;\r
 \r
-    public native void delete(int name) /*-{\r
+    public native void delete(String name) /*-{\r
       delete this[name];\r
     }-*/;\r
 \r
@@ -89,11 +88,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
       return !!this[id];\r
     }-*/;\r
 \r
-    public native JavaScriptObject get(String id) /*-{\r
+    public native JavaScriptObject get(int id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
-    public native JavaScriptObject get(int id) /*-{\r
+    public native JavaScriptObject get(String id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
@@ -101,19 +100,19 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
       return get(id).cast();\r
     }\r
 \r
-    public native double getDouble(String id) /*-{\r
+    public native double getDouble(int id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
-    public native double getDouble(int id) /*-{\r
+    public native double getDouble(String id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
-    public native int getInt(String id) /*-{\r
+    public native int getInt(int id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
-    public native int getInt(int id) /*-{\r
+    public native int getInt(String id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
@@ -121,11 +120,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
           return this[id];\r
         }-*/;\r
 \r
-    public native String getString(String id) /*-{\r
+    public native String getString(int id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
-    public native String getString(int id) /*-{\r
+    public native String getString(String id) /*-{\r
       return this[id];\r
     }-*/;\r
 \r
@@ -135,34 +134,34 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
         return !foo;\r
     }-*/;\r
 \r
-    public native void put(String id, Object obj) /*-{\r
+    public native void put(int id, Object obj) /*-{\r
       this[id]=obj;\r
     }-*/;\r
 \r
-    public native void put(int id, Object obj) /*-{\r
+    public native void put(String id, Object obj) /*-{\r
       this[id]=obj;\r
     }-*/;\r
   }\r
   \r
-  public static final Element window = window();\r
   public static final Document document = Document.get();\r
-\r
   public static boolean fxOff = false;\r
 \r
   public static Class<GQuery> GQUERY = GQuery.class;\r
 \r
-  private static JsMap<Class<? extends GQuery>, Plugin<? extends GQuery>>\r
-      plugins;\r
-\r
-  private static Element windowData = null;\r
+  public static final Element window = window();\r
 \r
   private static DataCache dataCache = null;\r
 \r
-  private static DocumentStyleImpl styleImpl;\r
-\r
   private static final int FUNC_PREPEND = 0, FUNC_APPEND = 1, FUNC_AFTER = 2,\r
       FUNC_BEFORE = 3;\r
 \r
+  private static JsMap<Class<? extends GQuery>, Plugin<? extends GQuery>>\r
+      plugins;\r
+\r
+  private static DocumentStyleImpl styleImpl;\r
+\r
+  private static Element windowData = null;\r
+\r
   /**\r
    * Create an empty GQuery object.\r
    */\r
@@ -170,22 +169,44 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return new GQuery(JSArray.create());\r
   }\r
 \r
+  /**\r
+   * Wrap a GQuery around an existing element.\r
+   */\r
+  public static GQuery $(Element element) {\r
+    JSArray a = JSArray.create();\r
+    a.addNode(element);\r
+    return new GQuery(a);\r
+  }\r
+\r
+  /**\r
+   * Wrap a GQuery around an event's target element.\r
+   */\r
+  public static GQuery $(Event event) {\r
+    return $((Element)event.getCurrentEventTarget().cast());\r
+  }\r
+\r
+  /**\r
+   * Wrap a GQuery around  existing Elements.\r
+   */\r
+  public static GQuery $(NodeList<Element> elements) {\r
+    return new GQuery(elements);\r
+  }\r
+\r
   /**\r
    * This function accepts a string containing a CSS selector which is then used\r
    * to match a set of elements, or it accepts raw HTML creating a GQuery\r
    * element containing those elements.\r
    */\r
   public static GQuery $(String selectorOrHtml) {\r
+    if (selectorOrHtml == null || selectorOrHtml.trim().length() == 0) {\r
+      return $();\r
+    }\r
     if (selectorOrHtml.trim().charAt(0) == '<') {\r
       return innerHtml(selectorOrHtml);\r
     }\r
     return $(selectorOrHtml, document);\r
   }\r
 \r
-  public static <T extends GQuery> T $(T gq) {\r
-    return gq;\r
-  }\r
-\r
   /**\r
    * This function accepts a string containing a CSS selector which is then used\r
    * to match a set of elements, or it accepts raw HTML creating a GQuery\r
@@ -226,27 +247,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
   }\r
 \r
-  /**\r
-   * Wrap a GQuery around  existing Elements.\r
-   */\r
-  public static GQuery $(NodeList<Element> elements) {\r
-    return new GQuery(elements);\r
-  }\r
-\r
-  /**\r
-   * Wrap a GQuery around an existing element.\r
-   */\r
-  public static GQuery $(Element element) {\r
-    JSArray a = JSArray.create();\r
-    a.addNode(element);\r
-    return new GQuery(a);\r
-  }\r
-\r
-  /**\r
-   * Wrap a GQuery around an event's target element.\r
-   */\r
-  public static GQuery $(Event event) {\r
-    return $((Element)event.getCurrentEventTarget().cast());\r
+  public static <T extends GQuery> T $(T gq) {\r
+    return gq;\r
   }\r
 \r
   /**\r
@@ -274,19 +276,73 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
                        });\r
    }-*/;\r
 \r
+  /**\r
+   * Returns the numeric value of a css propery of the element.\r
+   */\r
+  public static double cur(Element elem, String prop) {\r
+    GQuery g = $(elem);\r
+    if ("height".equals(prop)) {\r
+      return g.clientHeight();\r
+    }\r
+    if ("width".equals(prop)) {\r
+      return g.clientWidth();\r
+    }\r
+    if ("absolute".equalsIgnoreCase(g.css("position"))) {\r
+      if ("left".equals(prop)) {\r
+        return g.offset().left;\r
+      }\r
+      if ("top".equals(prop)) {\r
+        return g.offset().top;\r
+      }\r
+    }\r
+    if ("opacity".equals(prop)) {\r
+      return Double.parseDouble(g.css("opacity"));\r
+    }\r
+    if (elem.getPropertyString(prop) != null\r
+        && (elem.getStyle() == null || elem.getStyle().getProperty(prop) == null)) {\r
+      return elem.getPropertyDouble(prop);\r
+    }\r
+    String val = g.css(prop);\r
+    if (val != null) {\r
+      if ("thick".equals(val)) {\r
+        return (5);\r
+      } else if ("medium".equals(val)) {\r
+        return (3);\r
+      } else if ("thin".equals(val)) {\r
+        return (1);\r
+      }\r
+      val = "0" + val.replaceAll("[^\\d\\.]+", "");\r
+      return Double.parseDouble(val);\r
+    }\r
+    return 0.0;\r
+  }\r
+  \r
+  /**\r
+   * Returns the string value of a css propery of the element.\r
+   * TODO: use implementations\r
+   */\r
   public static String curCSS(Element elem, String name, boolean force) {\r
     name = fixAttributeName(name);\r
     Style s = elem.getStyle();\r
+    if ("opacity".equals(name)) {\r
+      String o = s.getProperty("filter");\r
+      if (o != null) { \r
+        return !o.matches(".*opacity=.*") ? "1" : \r
+            ("" + (Double.valueOf(o.replaceAll("[^\\d]", "")) / 100));\r
+      }\r
+      o = s.getProperty("opacity");\r
+      return o == null || o.length() == 0 ? "1" : o; \r
+    }    \r
     if (!force) {\r
       if (SelectorEngine.truth(s.getProperty(name))) {\r
         return s.getProperty(name);\r
       }\r
-      return name.equals("opacity") ? "1" : "";\r
     } else {\r
       return styleImpl.getCurrentStyle(elem, name);\r
     }\r
+    return "";\r
   }\r
-\r
+  \r
   /**\r
    * Return a lazy version of the GQuery interface. Lazy function calls are\r
    * simply queued up and not executed immediately.\r
@@ -303,6 +359,67 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     plugins.put(plugin, pluginFactory);\r
   }\r
 \r
+  protected static JSArray clean(String elem) {\r
+    String tags = elem.trim().toLowerCase();\r
+    String preWrap = "", postWrap = "";\r
+    int wrapPos = 0;\r
+    if (tags.contains("<opt")) {\r
+      wrapPos = 1;\r
+      preWrap = "<select multiple=\"multiple\">";\r
+      postWrap = "</select>";\r
+    } else if (tags.contains("<legend")) {\r
+      wrapPos = 1;\r
+      preWrap = "<fieldset>";\r
+      postWrap = "</fieldset>";\r
+    } else if (tags.matches("^<(thead|tbody|tfoot|colg|cap)")) {\r
+      wrapPos = 1;\r
+      preWrap = "<table>";\r
+      postWrap = "</table>";\r
+    } else if (tags.contains("<tr")) {\r
+      wrapPos = 2;\r
+      preWrap = "<table><tbody>";\r
+      postWrap = "</tbody></table>";\r
+    } else if (tags.contains("<td") || tags.contains("<th")) {\r
+      wrapPos = 3;\r
+      preWrap = "<table><tbody><tr>";\r
+      postWrap = "</tr></tbody></table>";\r
+    } else if (tags.contains("<col")) {\r
+      wrapPos = 2;\r
+      preWrap = "<table><tbody></tbody><colgroup>";\r
+      postWrap = "</colgroup></table>";\r
+    }\r
+    // TODO: fix IE link tag serialization\r
+    Element div = document.createDivElement();\r
+    div.setInnerHTML(preWrap + elem + postWrap);\r
+    Node n = div;\r
+    while (wrapPos-- != 0) {\r
+      n = n.getLastChild();\r
+    }\r
+    // TODO: add fixes for IE TBODY issue\r
+    return n.getChildNodes().cast();\r
+  }\r
+\r
+  protected static <S> Object data(Element item, String name, S value) {\r
+    if (dataCache == null) {\r
+      windowData = JavaScriptObject.createObject().cast();\r
+      dataCache = JavaScriptObject.createObject().cast();\r
+    }\r
+    item = item == window ? windowData : item;\r
+    if (item == null) {\r
+      return value;\r
+    }\r
+    int id = item.hashCode();\r
+    if (name != null && !dataCache.exists(id)) {\r
+      dataCache.put(id, DataCache.createObject().cast());\r
+    }\r
+\r
+    DataCache d = dataCache.get(id).cast();\r
+    if (name != null && value != null) {\r
+      d.put(name, value);\r
+    }\r
+    return name != null ? d.getObject(name) : id;\r
+  }\r
+\r
   protected static String[] jsArrayToString(JsArrayString array) {\r
     if (GWT.isScript()) {\r
       return jsArrayToString0(array);\r
@@ -349,6 +466,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
   }\r
 \r
+  private static String fixAttributeName(String key) {\r
+    ensureStyleImpl();\r
+    return styleImpl.getPropertyName(key);\r
+  }\r
+\r
   private static boolean hasClass(Element e, String clz) {\r
     return ((" " + e.getClassName() + " ").matches(".*\\s" + clz + "\\s.*"));\r
   }\r
@@ -371,38 +493,34 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return res;\r
   }\r
 \r
+  private static native Element window() /*-{\r
+    return $wnd;\r
+  }-*/;\r
+\r
   protected NodeList<Element> elements = null;\r
 \r
   private String currentSelector;\r
 \r
   private GQuery previousObject;\r
-\r
+  \r
   public GQuery() {\r
     elements = JavaScriptObject.createArray().cast();\r
   }\r
 \r
-  public GQuery(NodeList<Element> list) {\r
-    elements = list;\r
-  }\r
-\r
-  public GQuery(JSArray elements) {\r
-    this.elements = elements;\r
-  }\r
-\r
   public GQuery(Element element) {\r
     elements = JSArray.create(element);\r
   }\r
-  \r
+\r
   public GQuery(GQuery gq) {\r
     this(gq.get());\r
   }\r
 \r
-  /**\r
-   * Add elements to the set of matched elements if they are not included yet.\r
-   */\r
+  public GQuery(JSArray elements) {\r
+    this.elements = elements;\r
+  }\r
 \r
-  public GQuery add(String selector) {\r
-    return add($(selector));\r
+  public GQuery(NodeList<Element> list) {\r
+    elements = list;\r
   }\r
 \r
   /**\r
@@ -414,6 +532,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
         getSelector() + "," + previousObject.getSelector());\r
   }\r
 \r
+  /**\r
+   * Add elements to the set of matched elements if they are not included yet.\r
+   */\r
+\r
+  public GQuery add(String selector) {\r
+    return add($(selector));\r
+  }\r
+\r
   /**\r
    * Adds the specified classes to each matched element.\r
    */\r
@@ -431,8 +557,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * already be inserted into the document (you can't insert an element after\r
    * another if it's not in the page).\r
    */\r
-  public GQuery after(Node n) {\r
-    return domManip(JSArray.create(n), FUNC_AFTER);\r
+  public GQuery after(GQuery query) {\r
+    return domManip(query.elements, FUNC_AFTER);\r
   }\r
 \r
   /**\r
@@ -440,8 +566,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * already be inserted into the document (you can't insert an element after\r
    * another if it's not in the page).\r
    */\r
-  public GQuery after(String html) {\r
-    return domManip(html, FUNC_AFTER);\r
+  public GQuery after(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_AFTER);\r
   }\r
 \r
   /**\r
@@ -449,8 +575,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * already be inserted into the document (you can't insert an element after\r
    * another if it's not in the page).\r
    */\r
-  public GQuery after(GQuery query) {\r
-    return domManip(query.elements, FUNC_AFTER);\r
+  public GQuery after(String html) {\r
+    return domManip(html, FUNC_AFTER);\r
   }\r
 \r
   /**\r
@@ -467,8 +593,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * similar to doing an appendChild to all the specified elements, adding them\r
    * into the document.\r
    */\r
-  public GQuery append(String html) {\r
-    return domManip(html, FUNC_APPEND);\r
+  public GQuery append(GQuery query) {\r
+    return domManip(query.elements, FUNC_APPEND);\r
   }\r
 \r
   /**\r
@@ -485,8 +611,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * similar to doing an appendChild to all the specified elements, adding them\r
    * into the document.\r
    */\r
-  public GQuery append(GQuery query) {\r
-    return domManip(query.elements, FUNC_APPEND);\r
+  public GQuery append(String html) {\r
+    return domManip(html, FUNC_APPEND);\r
   }\r
 \r
   /**\r
@@ -513,27 +639,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     throw new RuntimeException("No plugin registered for class " + plugin);\r
   }\r
 \r
-  /**\r
-   * Access a property on the first matched element. This method makes it easy\r
-   * to retrieve a property value from the first matched element. If the element\r
-   * does not have an attribute with such a name, undefined is returned.\r
-   * Attributes include title, alt, src, href, width, style, etc.\r
-   */\r
-  public String attr(String name) {\r
-    return elements.getItem(0).getAttribute(fixAttributeName(name));\r
-  }\r
-\r
-  /**\r
-   * Set a single property to a value, on all matched elements.\r
-   */\r
-  public GQuery attr(String key, String value) {\r
-    key = fixAttributeName(key);\r
-    for (Element e : elements()) {\r
-      e.setAttribute(key, value);\r
-    }\r
-    return this;\r
-  }\r
-\r
   /**\r
    * Set a key/value object as properties to all matched elements.\r
    *\r
@@ -549,6 +654,16 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
+  /**\r
+   * Access a property on the first matched element. This method makes it easy\r
+   * to retrieve a property value from the first matched element. If the element\r
+   * does not have an attribute with such a name, undefined is returned.\r
+   * Attributes include title, alt, src, href, width, style, etc.\r
+   */\r
+  public String attr(String name) {\r
+    return elements.getItem(0).getAttribute(fixAttributeName(name));\r
+  }\r
+\r
   /**\r
    * Set a single property to a computed value, on all matched elements.\r
    */\r
@@ -560,13 +675,24 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
+  /**\r
+   * Set a single property to a value, on all matched elements.\r
+   */\r
+  public GQuery attr(String key, String value) {\r
+    key = fixAttributeName(key);\r
+    for (Element e : elements()) {\r
+      e.setAttribute(key, value);\r
+    }\r
+    return this;\r
+  }\r
+\r
   /**\r
    * Insert content before each of the matched elements. The elements must\r
    * already be inserted into the document (you can't insert an element before\r
    * another if it's not in the page).\r
    */\r
-  public GQuery before(Node n) {\r
-    return domManip(JSArray.create(n), FUNC_BEFORE);\r
+  public GQuery before(GQuery query) {\r
+    return domManip(query.elements, FUNC_BEFORE);\r
   }\r
 \r
   /**\r
@@ -574,8 +700,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * already be inserted into the document (you can't insert an element before\r
    * another if it's not in the page).\r
    */\r
-  public GQuery before(GQuery query) {\r
-    return domManip(query.elements, FUNC_BEFORE);\r
+  public GQuery before(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_BEFORE);\r
   }\r
 \r
   /**\r
@@ -602,17 +728,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return as(Events).bind(eventbits, data, funcs);\r
   }\r
 \r
-  /**\r
-   * Bind Handlers or fire Events for each matched element. \r
-   */\r
-  private GQuery bindOrFire(int eventbits, final Object data, final Function...funcs) {\r
-    if (funcs.length == 0) {\r
-      return trigger(eventbits);\r
-    } else {\r
-      return bind(eventbits, data, funcs);\r
-    }\r
-  }\r
-\r
   /**\r
    * Bind a set of functions to the blur event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
@@ -628,16 +743,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public GQuery change(Function...f) {\r
     return bindOrFire(Event.ONCHANGE, null, f);\r
   }\r
-\r
-  /**\r
-   * Get a set of elements containing all of the unique children of each of the\r
-   * matched set of elements. This set is filtered with the expressions that\r
-   * will cause only elements matching any of the selectors to be collected.\r
-   */\r
-  public GQuery children(String... filters) {\r
-    return find(filters);\r
-  }\r
-\r
+  \r
   /**\r
    * Get a set of elements containing all of the unique immediate children of\r
    * each of the matched set of elements. Also note: while parents() will look\r
@@ -651,6 +757,15 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return new GQuery(unique(result));\r
   }\r
 \r
+  /**\r
+   * Get a set of elements containing all of the unique children of each of the\r
+   * matched set of elements. This set is filtered with the expressions that\r
+   * will cause only elements matching any of the selectors to be collected.\r
+   */\r
+  public GQuery children(String... filters) {\r
+    return find(filters);\r
+  }\r
+\r
   /**\r
    * Bind a set of functions to the click event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
@@ -658,7 +773,23 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public GQuery click(Function...f) {\r
     return bindOrFire(Event.ONCLICK, null, f);\r
   }\r
-  \r
+\r
+  /**\r
+   * Returns the inner height of the first matched element, including padding \r
+   * but not the vertical scrollbar height, border, or margin.\r
+   */\r
+  public int clientHeight() {\r
+    return get(0).getClientHeight();\r
+  }\r
+\r
+  /**\r
+   * Returns the inner width of the first matched element, including padding \r
+   * but not the vertical scrollbar width, border, or margin.\r
+   */\r
+  public int clientWidth() {\r
+    return get(0).getClientWidth();\r
+  }\r
+\r
   /**\r
    * Clone matched DOM Elements and select the clones. This is useful for moving\r
    * copies of the elements to another location in the DOM.\r
@@ -709,64 +840,64 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   }\r
 \r
   /**\r
-   * Set CSS property on every matched element using type-safe enumerations.\r
+   * Set a key/value object as style properties to all matched elements. This\r
+   * serves as the best way to set a large number of style properties on all\r
+   * matched elements.\r
+   *\r
+   * Example: $(".item").css(Properties.create("color: 'red', background:\r
+   * 'blue'"))\r
    */\r
-  public <S, T extends CssProperty<S>> GQuery css(T cssProperty, S value) {\r
-    for (Element e : elements()) {\r
-      cssProperty.set(e.getStyle(), value);\r
+  public GQuery css(Properties properties) {\r
+    for (String property : properties.keys()) {\r
+      css(property, properties.get(property));\r
     }\r
     return this;\r
   }\r
 \r
   /**\r
-   * Set CSS property on every matched element using type-safe enumerations.\r
+   * Return a style property on the first matched element.\r
    */\r
-  public GQuery css(TakesLength cssProperty, Length value) {\r
-    for (Element e : elements()) {\r
-      cssProperty.setLength(e.getStyle(), value);\r
-    }\r
-    return this;\r
+  public String css(String name) {\r
+    return curCSS(get(0), name);\r
   }\r
 \r
   /**\r
-   * Set CSS property on every matched element using type-safe enumerations.\r
+   * Set a single style property to a value, on all matched elements.\r
    */\r
-  public GQuery css(TakesPercentage cssProperty, Percentage value) {\r
+  public GQuery css(String prop, String val) {\r
+    prop = fixAttributeName(prop);\r
     for (Element e : elements()) {\r
-      cssProperty.setPercentage(e.getStyle(), value);\r
+      setStyleProperty(prop, val, e);\r
     }\r
     return this;\r
   }\r
 \r
   /**\r
-   * Return a style property on the first matched element.\r
+   * Set CSS property on every matched element using type-safe enumerations.\r
    */\r
-  public String css(String name) {\r
-    return curCSS(get(0), name);\r
+  public <S, T extends CssProperty<S>> GQuery css(T cssProperty, S value) {\r
+    for (Element e : elements()) {\r
+      cssProperty.set(e.getStyle(), value);\r
+    }\r
+    return this;\r
   }\r
-\r
+  \r
   /**\r
-   * Set a key/value object as style properties to all matched elements. This\r
-   * serves as the best way to set a large number of style properties on all\r
-   * matched elements.\r
-   *\r
-   * Example: $(".item").css(Properties.create("color: 'red', background:\r
-   * 'blue'"))\r
+   * Set CSS property on every matched element using type-safe enumerations.\r
    */\r
-  public GQuery css(Properties properties) {\r
-    for (String property : properties.keys()) {\r
-      css(property, properties.get(property));\r
+  public GQuery css(TakesLength cssProperty, Length value) {\r
+    for (Element e : elements()) {\r
+      cssProperty.setLength(e.getStyle(), value);\r
     }\r
     return this;\r
   }\r
 \r
   /**\r
-   * Set a single style property to a value, on all matched elements.\r
+   * Set CSS property on every matched element using type-safe enumerations.\r
    */\r
-  public GQuery css(String prop, String val) {\r
-    prop = fixAttributeName(prop);\r
+  public GQuery css(TakesPercentage cssProperty, Percentage value) {\r
     for (Element e : elements()) {\r
-      setStyleProperty(prop, val, e);\r
+      cssProperty.setPercentage(e.getStyle(), value);\r
     }\r
     return this;\r
   }\r
@@ -798,7 +929,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
     return this;\r
   }\r
-  \r
+\r
   /**\r
    * Bind a set of functions to the dblclick event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
@@ -822,8 +953,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
       }\r
     }\r
     return this;\r
-  }\r
-\r
+  }  \r
+  \r
   /**\r
    * Returns the working set of nodes as a Java array. <b>Do NOT</b attempt to\r
    * modify this array, e.g. assign to its elements, or call Arrays.sort()\r
@@ -866,38 +997,38 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * Bind a set of functions to the error event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
    */\r
-  public GQuery error(Function...f) {\r
+  public GQuery error(Function... f) {\r
     return bindOrFire(Event.ONERROR, null, f);\r
-  }  \r
-  \r
-  /**\r
-   * Fade in all matched elements by adjusting their opacity.\r
-   */\r
-  public GQuery fadeIn(int millisecs) {\r
-    return $(as(Effects).fadeIn(millisecs));\r
   }\r
 \r
   /**\r
    * Fade in all matched elements by adjusting their opacity. The effect will\r
    * take 1000 milliseconds to complete\r
    */\r
-  public GQuery fadeIn() {\r
-    return $(as(Effects).fadeIn());\r
+  public GQuery fadeIn(Function... f) {\r
+    return $(as(Effects).fadeIn(f));\r
   }\r
 \r
   /**\r
-   * Fade out all matched elements by adjusting their opacity.\r
+   * Fade in all matched elements by adjusting their opacity.\r
    */\r
-  public GQuery fadeOut(int millisecs) {\r
-    return as(Effects).fadeOut(millisecs);\r
+  public GQuery fadeIn(int millisecs, Function... f) {\r
+    return $(as(Effects).fadeIn(millisecs, f));\r
   }\r
 \r
   /**\r
    * Fade out all matched elements by adjusting their opacity. The effect will\r
    * take 1000 milliseconds to complete\r
    */\r
-  public GQuery fadeOut() {\r
-    return $(as(Effects).fadeOut());\r
+  public GQuery fadeOut(Function... f) {\r
+    return $(as(Effects).fadeOut(f));\r
+  }  \r
+  \r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity.\r
+   */\r
+  public GQuery fadeOut(int millisecs, Function... f) {\r
+    return as(Effects).fadeOut(millisecs, f);\r
   }\r
 \r
   /**\r
@@ -964,8 +1095,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery focus(Function...f) {\r
     return bindOrFire(Event.ONFOCUS, null, f);\r
-  }  \r
-  \r
+  }\r
+\r
   /**\r
    * Return all elements matched in the GQuery as a NodeList. @see #elements()\r
    * for a method which returns them as an immutable Java array.\r
@@ -1005,7 +1136,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public GQuery gt(int pos) {\r
     return $(slice(pos + 1, -1));\r
   }\r
-\r
+  \r
   /**\r
    * Returns true any of the specified classes are present on any of the matched\r
    * elements.\r
@@ -1021,6 +1152,13 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return false;\r
   }\r
 \r
+  /**\r
+   * Get the current computed, pixel, height of the first matched element.\r
+   */\r
+  public int height() {\r
+    return get(0).getOffsetHeight();\r
+  }\r
+\r
   /**\r
    * Set the height of every element in the matched set.\r
    */\r
@@ -1039,20 +1177,18 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return css("height", height);\r
   }\r
 \r
-  /**\r
-   * Get the current computed, pixel, height of the first matched element.\r
-   */\r
-  public int height() {\r
-    return DOM.\r
-        getElementPropertyInt((com.google.gwt.user.client.Element) get(0),\r
-            "offsetHeight");\r
-  }\r
-\r
   /**\r
    * Make invisible all matched elements.\r
    */\r
   public GQuery hide() {\r
-    return $(as(Effects).hide());\r
+    for (Element e : elements()) {\r
+      Object old = data(e, "oldDisplay", null);\r
+      if (old == null) {\r
+        data(e, "oldDisplay", e.getStyle().getDisplay());\r
+      }\r
+      e.getStyle().setDisplay(Display.NONE);\r
+    }\r
+    return this;\r
   }\r
 \r
   /**\r
@@ -1097,14 +1233,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return -1;\r
   }\r
 \r
-  /**\r
-   * Insert all of the matched elements after another, specified, set of\r
-   * elements.\r
-   */\r
-  public GQuery insertAfter(String selector) {\r
-    return insertAfter($(selector));\r
-  }\r
-\r
   /**\r
    * Insert all of the matched elements after another, specified, set of\r
    * elements.\r
@@ -1124,6 +1252,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
+  /**\r
+   * Insert all of the matched elements after another, specified, set of\r
+   * elements.\r
+   */\r
+  public GQuery insertAfter(String selector) {\r
+    return insertAfter($(selector));\r
+  }\r
+\r
   /**\r
    * Insert all of the matched elements before another, specified, set of\r
    * elements.\r
@@ -1134,7 +1270,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public GQuery insertBefore(Element item) {\r
     return insertBefore($(item));\r
   }\r
-\r
+  \r
   /**\r
    * Insert all of the matched elements before another, specified, set of\r
    * elements.\r
@@ -1147,7 +1283,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
       query.before(e);\r
     }\r
     return this;\r
-  }\r
+  }  \r
 \r
   /**\r
    * Insert all of the matched elements before another, specified, set of\r
@@ -1167,22 +1303,22 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public boolean is(String... filters) {\r
     return filter(filters).size() > 0;\r
-  }\r
-  \r
+  }  \r
+\r
   /**\r
    * Bind a set of functions to the keydown event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
    */\r
   public GQuery keydown(Function...f) {\r
     return bindOrFire(Event.ONKEYDOWN, null, f);\r
-  }  \r
+  }\r
 \r
   /**\r
    * Trigger a keydown event passing the key pushed\r
    */\r
   public GQuery keydown(int key) {\r
     return trigger(Event.ONKEYDOWN, key);\r
-  }\r
+  }  \r
 \r
   /**\r
    * Bind a set of functions to the keypress event of each matched element.\r
@@ -1205,29 +1341,29 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery keyup(Function...f) {\r
     return bindOrFire(Event.ONKEYUP, null, f);\r
-  }  \r
+  }\r
 \r
   /**\r
    * Trigger a keyup event passing the key pushed\r
    */\r
   public GQuery keyup(int key) {\r
     return trigger(Event.ONKEYUP, key);\r
-  }  \r
-\r
+  }\r
+  \r
   /**\r
    * Returns the number of elements currently matched. The size function will\r
    * return the same value.\r
    */\r
   public int length() {\r
     return size();\r
-  }\r
-\r
+  }  \r
\r
   /**\r
    * Bind a function to the load event of each matched element.\r
    */\r
   public GQuery load(Function f) {\r
     return bind(Event.ONLOAD, null, f);\r
-  }\r
+  }  \r
 \r
   /**\r
    * Reduce the set of matched elements to all elements before a given position.\r
@@ -1236,8 +1372,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery lt(int pos) {\r
     return $(slice(0, pos));\r
-  }\r
-  \r
+  }  \r
+\r
   /**\r
    * Bind a set of functions to the mousedown event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
@@ -1245,14 +1381,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public GQuery mousedown(Function...f) {\r
     return bindOrFire(Event.ONMOUSEDOWN, null, f);\r
   }  \r
\r
+  \r
   /**\r
    * Bind a set of functions to the mousemove event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
    */\r
   public GQuery mousemove(Function...f) {\r
     return bindOrFire(Event.ONMOUSEMOVE, null, f);\r
-  }  \r
+  }    \r
 \r
   /**\r
    * Bind a set of functions to the mouseout event of each matched element.\r
@@ -1260,7 +1396,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery mouseout(Function...f) {\r
     return bindOrFire(Event.ONMOUSEOUT, null, f);\r
-  }  \r
+  }\r
 \r
   /**\r
    * Bind a set of functions to the mouseover event of each matched element.\r
@@ -1268,15 +1404,15 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery mouseover(Function...f) {\r
     return bindOrFire(Event.ONMOUSEOVER, null, f);\r
-  }  \r
-  \r
+  }\r
+\r
   /**\r
    * Bind a set of functions to the mouseup event of each matched element.\r
    * Or trigger the event if no functions are provided.\r
    */\r
   public GQuery mouseup(Function...f) {\r
     return bindOrFire(Event.ONMOUSEUP, null, f);\r
-  }    \r
+  }\r
 \r
   /**\r
    * Get a set of elements containing the unique next siblings of each of the\r
@@ -1365,8 +1501,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * the document. The returned object contains two integer properties, top and\r
    * left. The method works only with visible elements.\r
    */\r
-  public Offset offset() {\r
-    return new Offset(get(0).getAbsoluteTop(), get(0).getAbsoluteLeft());\r
+  public com.google.gwt.query.client.GQuery.Offset offset() {\r
+    return new Offset(get(0).getAbsoluteLeft(), get(0).getAbsoluteTop());\r
   }\r
 \r
   /**\r
@@ -1390,17 +1526,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * element. The handler is executed only once for each element.\r
    *\r
    * The event handler is passed as a Function that you can use to prevent\r
-   * default behaviour. To stop both default action and event bubbling, the\r
+   * default behavior. To stop both default action and event bubbling, the\r
    * function event handler has to return false.\r
    *\r
    * You can pass an additional Object data to your Function as the second\r
    * parameter\r
    */\r
   public GQuery one(int eventbits, final Object data, final Function f) {\r
-    for (Element e : elements()) {\r
-      EventsListener.getInstance(e).bind(eventbits, data, f, 1);\r
-    }\r
-    return this;\r
+    return as(Events).one(eventbits, data, f);\r
   }\r
 \r
   /**\r
@@ -1424,15 +1557,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return parent().filter(filters);\r
   }\r
 \r
-  /**\r
-   * Get a set of elements containing the unique ancestors of the matched set of\r
-   * elements (except for the root element). The matched elements are filtered,\r
-   * returning those that match any of the filters.\r
-   */\r
-  public GQuery parents(String... filters) {\r
-    return parents().filter(filters);\r
-  }\r
-\r
   /**\r
    * Get a set of elements containing the unique ancestors of the matched set of\r
    * elements (except for the root element).\r
@@ -1449,14 +1573,23 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return new GQuery(unique(result));\r
   }\r
 \r
+  /**\r
+   * Get a set of elements containing the unique ancestors of the matched set of\r
+   * elements (except for the root element). The matched elements are filtered,\r
+   * returning those that match any of the filters.\r
+   */\r
+  public GQuery parents(String... filters) {\r
+    return parents().filter(filters);\r
+  }\r
+\r
   /**\r
    * Gets the top and left position of an element relative to its offset parent.\r
    * The returned object contains two Integer properties, top and left. For\r
    * accurate calculations make sure to use pixel values for margins, borders\r
    * and padding. This method only works with visible elements.\r
    */\r
-  public Offset position() {\r
-    return new Offset(get(0).getOffsetTop(), get(0).getAbsoluteLeft());\r
+  public com.google.gwt.query.client.GQuery.Offset position() {\r
+    return new Offset(get(0).getOffsetLeft(), get(0).getOffsetTop());\r
   }\r
 \r
   /**\r
@@ -1464,8 +1597,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * the best way to insert elements inside, at the beginning, of all matched\r
    * elements.\r
    */\r
-  public GQuery prepend(String html) {\r
-    return domManip(html, FUNC_PREPEND);\r
+  public GQuery prepend(GQuery query) {\r
+    return domManip(query.elements, FUNC_PREPEND);\r
   }\r
 \r
   /**\r
@@ -1473,8 +1606,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * the best way to insert elements inside, at the beginning, of all matched\r
    * elements.\r
    */\r
-  public GQuery prepend(GQuery query) {\r
-    return domManip(query.elements, FUNC_PREPEND);\r
+  public GQuery prepend(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_PREPEND);\r
   }\r
 \r
   /**\r
@@ -1482,8 +1615,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * the best way to insert elements inside, at the beginning, of all matched\r
    * elements.\r
    */\r
-  public GQuery prepend(Node n) {\r
-    return domManip(JSArray.create(n), FUNC_PREPEND);\r
+  public GQuery prepend(String html) {\r
+    return domManip(html, FUNC_PREPEND);\r
   }\r
 \r
   /**\r
@@ -1585,6 +1718,15 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
+  /**\r
+   * Replaces the elements matched by the specified selector with the matched\r
+   * elements. This function is the complement to replaceWith() which does the\r
+   * same task with the parameters reversed.\r
+   */\r
+  public GQuery replaceAll(Element elem) {\r
+    return replaceAll($(elem));\r
+  }\r
+\r
   /**\r
    * Replaces the elements matched by the specified selector with the matched\r
    * elements. This function is the complement to replaceWith() which does the\r
@@ -1606,15 +1748,16 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return replaceAll($(html));\r
   }\r
 \r
+\r
   /**\r
-   * Replaces the elements matched by the specified selector with the matched\r
-   * elements. This function is the complement to replaceWith() which does the\r
-   * same task with the parameters reversed.\r
+   * Replaces all matched elements with the specified HTML or DOM elements. This\r
+   * returns the GQuery element that was just replaced, which has been removed\r
+   * from the DOM.\r
    */\r
-  public GQuery replaceAll(Element elem) {\r
-    return replaceAll($(elem));\r
-  }\r
-\r
+  public GQuery replaceWith(Element elem) {\r
+    return replaceWith($(elem));\r
+  }    \r
+  \r
   /**\r
    * Replaces all matched elements with the specified HTML or DOM elements. This\r
    * returns the GQuery element that was just replaced, which has been removed\r
@@ -1634,14 +1777,26 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   }\r
 \r
   /**\r
-   * Replaces all matched elements with the specified HTML or DOM elements. This\r
-   * returns the GQuery element that was just replaced, which has been removed\r
-   * from the DOM.\r
+   * Save a set of Css properties of every matched element.\r
    */\r
-  public GQuery replaceWith(Element elem) {\r
-    return replaceWith($(elem));\r
+  public void restoreCssAttrs(String[] cssProps) {\r
+    for (Element e : elements()) {\r
+      for (String a : cssProps) {\r
+        setStyleProperty(a, (String) data(e, "old-" + a, null), e);\r
+      }\r
+    }\r
   }\r
 \r
+  /**\r
+   * Restore a set of previously saved Css properties in every matched element.\r
+   */\r
+  public void saveCssAttrs(String[] cssProps) {\r
+    for (Element e : elements()) {\r
+      for (String a : cssProps) {\r
+        data("old-" + a, curCSS(e, a));\r
+      }\r
+    }\r
+  }\r
 \r
   /**\r
    * Bind a set of functions to the scroll event of each matched element.\r
@@ -1649,22 +1804,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery scroll(Function...f) {\r
     return bindOrFire(Event.ONSCROLL, null, f);\r
-  }    \r
-  \r
-  /**\r
-   * When a value is passed in, the scroll left offset is set to that value on\r
-   * all matched elements. This method works for both visible and hidden\r
-   * elements.\r
-   */\r
-  public GQuery scrollLeft(int left) {\r
-    for (Element e : elements()) {\r
-      if (e == window || e == (Node) document) {\r
-        Window.scrollTo(left, $(e).scrollTop());\r
-      } else {\r
-        e.setPropertyInt("scrollLeft", left);\r
-      }\r
-    }\r
-    return this;\r
   }\r
 \r
   /**\r
@@ -1683,16 +1822,16 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   }\r
 \r
   /**\r
-   * When a value is passed in, the scroll top offset is set to that value on\r
+   * When a value is passed in, the scroll left offset is set to that value on\r
    * all matched elements. This method works for both visible and hidden\r
    * elements.\r
    */\r
-  public GQuery scrollTop(int top) {\r
+  public GQuery scrollLeft(int left) {\r
     for (Element e : elements()) {\r
       if (e == window || e == (Node) document) {\r
-        Window.scrollTo($(e).scrollLeft(), top);\r
+        Window.scrollTo(left, $(e).scrollTop());\r
       } else {\r
-        e.setPropertyInt("scrollTop", top);\r
+        e.setPropertyInt("scrollLeft", left);\r
       }\r
     }\r
     return this;\r
@@ -1713,6 +1852,22 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
   }\r
 \r
+  /**\r
+   * When a value is passed in, the scroll top offset is set to that value on\r
+   * all matched elements. This method works for both visible and hidden\r
+   * elements.\r
+   */\r
+  public GQuery scrollTop(int top) {\r
+    for (Element e : elements()) {\r
+      if (e == window || e == (Node) document) {\r
+        Window.scrollTo($(e).scrollLeft(), top);\r
+      } else {\r
+        e.setPropertyInt("scrollTop", top);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
   public GQuery select() {\r
     return as(Events).triggerHtmlEvent("select");\r
   }\r
@@ -1754,7 +1909,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * elements\r
    */\r
   public GQuery show() {\r
-    return $(as(Effects).show());\r
+    for (Element e : elements()) {\r
+      Object old = data(e, "oldDisplay", null);\r
+      e.getStyle().setProperty("display", old != null? old.toString() : "");\r
+    }\r
+    return this;\r
   }\r
 \r
   /**\r
@@ -1828,9 +1987,18 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * Toggle visibility of elements.\r
    */\r
   public GQuery toggle() {\r
-    return as(Effects).toggle();\r
+    for (Element e: elements()) {\r
+      if ($(e).visible()) {\r
+        $(e).hide();\r
+      } else {\r
+        $(e).show();\r
+        e.getStyle().setDisplay(Display.BLOCK);\r
+      }\r
+    }\r
+    return this;\r
   }\r
 \r
+\r
   /**\r
    * Toggle among two or more function calls every other click.\r
    */\r
@@ -1838,7 +2006,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return click(new Function() {\r
       int click = 0;\r
       public boolean f(Event e) {\r
-        return fn[(click++ % fn.length)].f(e);\r
+        int n = fn.length == 1 ? 0 : (click++ % fn.length); \r
+        return fn[n].f(e);\r
       }\r
     });\r
   }\r
@@ -1897,7 +2066,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return r;\r
   }\r
 \r
-\r
   /**\r
    * Trigger a set of events on each matched element.\r
    * \r
@@ -2050,7 +2218,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * Return true if the first element is visible.\r
    */\r
   public boolean visible() {\r
-    return as(Effects).visible();\r
+    return !"none".equalsIgnoreCase(get(0).getStyle().getDisplay());\r
+  }\r
+\r
+  /**\r
+   * Get the current computed, pixel, width of the first matched element.\r
+   */\r
+  public int width() {\r
+    return get(0).getClientWidth();\r
   }\r
 \r
   /**\r
@@ -2063,15 +2238,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
-  /**\r
-   * Get the current computed, pixel, width of the first matched element.\r
-   */\r
-  public int width() {\r
-    return DOM.\r
-        getElementPropertyInt((com.google.gwt.user.client.Element) get(0),\r
-            "offsetWidth");\r
-  }\r
-\r
   /**\r
    * Wrap each matched element with the specified HTML content. This wrapping\r
    * process is most useful for injecting additional structure into a document,\r
@@ -2081,11 +2247,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * within its structure -- it is that element that will enwrap everything\r
    * else.\r
    */\r
-  public GQuery wrap(GQuery query) {\r
-    for (Element e : elements()) {\r
-      $(e).wrapAll(query);\r
-    }\r
-    return this;\r
+  public GQuery wrap(Element elem) {\r
+    return wrap($(elem));\r
   }\r
 \r
   /**\r
@@ -2097,8 +2260,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * within its structure -- it is that element that will enwrap everything\r
    * else.\r
    */\r
-  public GQuery wrap(Element elem) {\r
-    return wrap($(elem));\r
+  public GQuery wrap(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).wrapAll(query);\r
+    }\r
+    return this;\r
   }\r
 \r
   /**\r
@@ -2114,22 +2280,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return wrap($(html));\r
   }\r
 \r
-  /**\r
-   * Wrap all the elements in the matched set into a single wrapper element.\r
-   * This is different from .wrap() where each element in the matched set would\r
-   * get wrapped with an element. This wrapping process is most useful for\r
-   * injecting additional structure into a document, without ruining the\r
-   * original semantic qualities of a document.\r
-   *\r
-   * This works by going through the first element provided (which is generated,\r
-   * on the fly, from the provided HTML) and finds the deepest descendant\r
-   * element within its structure -- it is that element that will enwrap\r
-   * everything else.\r
-   */\r
-  public GQuery wrapAll(String html) {\r
-    return wrapAll($(html));\r
-  }\r
-\r
   /**\r
    * Wrap all the elements in the matched set into a single wrapper element.\r
    * This is different from .wrap() where each element in the matched set would\r
@@ -2174,6 +2324,22 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
+  /**\r
+   * Wrap all the elements in the matched set into a single wrapper element.\r
+   * This is different from .wrap() where each element in the matched set would\r
+   * get wrapped with an element. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document.\r
+   *\r
+   * This works by going through the first element provided (which is generated,\r
+   * on the fly, from the provided HTML) and finds the deepest descendant\r
+   * element within its structure -- it is that element that will enwrap\r
+   * everything else.\r
+   */\r
+  public GQuery wrapAll(String html) {\r
+    return wrapAll($(html));\r
+  }\r
+\r
   /**\r
    * Wrap the inner child contents of each matched element (including text\r
    * nodes) with an HTML structure. This wrapping process is most useful for\r
@@ -2183,11 +2349,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * HTML) and finds the deepest ancestor element within its structure -- it is\r
    * that element that will enwrap everything else.\r
    */\r
-  public GQuery wrapInner(GQuery query) {\r
-    for (Element e : elements()) {\r
-      $(e).contents().wrapAll(query);\r
-    }\r
-    return this;\r
+  public GQuery wrapInner(Element elem) {\r
+    return wrapInner($(elem));\r
   }\r
 \r
   /**\r
@@ -2199,8 +2362,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * HTML) and finds the deepest ancestor element within its structure -- it is\r
    * that element that will enwrap everything else.\r
    */\r
-  public GQuery wrapInner(String html) {\r
-    return wrapInner($(html));\r
+  public GQuery wrapInner(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).contents().wrapAll(query);\r
+    }\r
+    return this;\r
   }\r
 \r
   /**\r
@@ -2212,8 +2378,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * HTML) and finds the deepest ancestor element within its structure -- it is\r
    * that element that will enwrap everything else.\r
    */\r
-  public GQuery wrapInner(Element elem) {\r
-    return wrapInner($(elem));\r
+  public GQuery wrapInner(String html) {\r
+    return wrapInner($(html));\r
   }\r
 \r
   protected GQuery pushStack(JSArray elts, String name, String selector) {\r
@@ -2241,69 +2407,15 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
   }\r
 \r
-  protected static JSArray clean(String elem) {\r
-    String tags = elem.trim().toLowerCase();\r
-    String preWrap = "", postWrap = "";\r
-    int wrapPos = 0;\r
-    if (tags.contains("<opt")) {\r
-      wrapPos = 1;\r
-      preWrap = "<select multiple=\"multiple\">";\r
-      postWrap = "</select>";\r
-    } else if (tags.contains("<legend")) {\r
-      wrapPos = 1;\r
-      preWrap = "<fieldset>";\r
-      postWrap = "</fieldset>";\r
-    } else if (tags.matches("^<(thead|tbody|tfoot|colg|cap)")) {\r
-      wrapPos = 1;\r
-      preWrap = "<table>";\r
-      postWrap = "</table>";\r
-    } else if (tags.contains("<tr")) {\r
-      wrapPos = 2;\r
-      preWrap = "<table><tbody>";\r
-      postWrap = "</tbody></table>";\r
-    } else if (tags.contains("<td") || tags.contains("<th")) {\r
-      wrapPos = 3;\r
-      preWrap = "<table><tbody><tr>";\r
-      postWrap = "</tr></tbody></table>";\r
-    } else if (tags.contains("<col")) {\r
-      wrapPos = 2;\r
-      preWrap = "<table><tbody></tbody><colgroup>";\r
-      postWrap = "</colgroup></table>";\r
-    }\r
-    // TODO: fix IE link tag serialization\r
-    Element div = document.createDivElement();\r
-    div.setInnerHTML(preWrap + elem + postWrap);\r
-    Node n = div;\r
-    while (wrapPos-- != 0) {\r
-      n = n.getLastChild();\r
-    }\r
-    // TODO: add fixes for IE TBODY issue\r
-    return n.getChildNodes().cast();\r
-  }\r
-\r
-  protected <S> Object data(Element item, String name, S value) {\r
-    if (dataCache == null) {\r
-      windowData = JavaScriptObject.createObject().cast();\r
-      dataCache = JavaScriptObject.createObject().cast();\r
-    }\r
-    item = item == window ? windowData : item;\r
-    if (item == null) {\r
-      return value;\r
-    }\r
-    int id = item.hashCode();\r
-    if (name != null && !dataCache.exists(id)) {\r
-      dataCache.put(id, DataCache.createObject().cast());\r
-    }\r
-\r
-    DataCache d = dataCache.get(id).cast();\r
-    if (name != null && value != null) {\r
-      d.put(name, value);\r
+  /**\r
+   * Bind Handlers or fire Events for each matched element. \r
+   */\r
+  private GQuery bindOrFire(int eventbits, final Object data, final Function...funcs) {\r
+    if (funcs.length == 0) {\r
+      return trigger(eventbits);\r
+    } else {\r
+      return bind(eventbits, data, funcs);\r
     }\r
-    return name != null ? d.getObject(name) : id;\r
-  }\r
-\r
-  private GQuery domManip(String html, int func) {\r
-    return domManip(clean(html), func);\r
   }\r
 \r
   private GQuery domManip(NodeList<?> nodes, int func) {\r
@@ -2313,7 +2425,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
         if (nodes.getLength() > 1) {\r
           n = n.cloneNode(true);\r
         }\r
-\r
         switch (func) {\r
           case FUNC_PREPEND:\r
             e.insertBefore(n, e.getFirstChild());\r
@@ -2333,9 +2444,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
-  private static String fixAttributeName(String key) {\r
-    ensureStyleImpl();\r
-    return styleImpl.getPropertyName(key);\r
+  private GQuery domManip(String html, int func) {\r
+    return domManip(clean(html), func);\r
   }\r
 \r
   private native Document getContentDocument(Node n) /*-{\r
@@ -2349,10 +2459,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return sib;\r
   }-*/;\r
 \r
-  private void init(GQuery gQuery) {\r
-    this.elements = gQuery.elements;\r
-  }\r
-\r
   private JSArray merge(NodeList<Element> first, NodeList<Element> second) {\r
     JSArray res = copyNodeList(first);\r
     for (int i = 0; i < second.getLength(); i++) {\r
@@ -2360,19 +2466,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
     return res;\r
   }\r
-\r
-  private int num(GQuery gQuery, String val) {\r
-    Element elem = gQuery.get(0);\r
-    try {\r
-      if (elem != null) {\r
-        String v = GQuery.curCSS(elem, val);\r
-        return Integer.parseInt(v);\r
-      }\r
-    } catch (NumberFormatException e) {\r
-    }\r
-    return 0;\r
-  }\r
-\r
+  \r
   private void removeData(Element item, String name) {\r
     if (dataCache == null) {\r
       windowData = JavaScriptObject.createObject().cast();\r
@@ -2390,9 +2484,5 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     } else {\r
       dataCache.delete(id);\r
     }\r
-  }\r
-\r
-  private static native Element window() /*-{\r
-    return $wnd;\r
-  }-*/;\r
+  }   \r
 }\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQueryQueue.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQueryQueue.java
deleted file mode 100644 (file)
index 16c9506..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * 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.JavaScriptObject;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
-
-/**
- * Class used in plugins which need a queue system.
- */
-public abstract class GQueryQueue extends GQuery {
-
-  private static final class Queue<T> extends JavaScriptObject {
-
-    public static Queue<?> newInstance() {
-      return createArray().cast();
-    }
-
-    @SuppressWarnings("unused")
-    protected Queue() {
-    }
-
-    public native T dequeue() /*-{
-      return this.shift();
-    }-*/;
-
-    public native void enqueue(T foo) /*-{
-      this.push(foo);
-    }-*/;
-
-    public native int length() /*-{
-      return this.length;
-    }-*/;
-
-    public native T peek(int i) /*-{
-      return this[i];
-    }-*/;
-  }
-
-  public GQueryQueue(GQuery gq) {
-    super(gq);
-  }
-
-  public GQueryQueue(JSArray elements) {
-    super(elements);
-  }
-
-  public GQueryQueue(NodeList<Element> list) {
-    super(list);
-  }
-
-  public GQueryQueue(Element element) {
-    super(element);
-  }
-
-  /**
-   * Removes a queued function from the front of the queue and executes it.
-   */
-  public GQueryQueue dequeue() {
-    for (Element e : elements()) {
-      dequeue(e);
-    }
-    return this;
-  }
-
-
-  /**
-   * Adds a new function, to be executed, onto the end of the queue of all
-   * matched elements.
-   */
-  public GQueryQueue queue(Function func) {
-    for (Element e : elements()) {
-      queue(e, func);
-    }
-    return this;
-  }
-
-  /**
-   * Replaces the current queue with the given queue on all matched elements.
-   */
-  public GQueryQueue queue(Queue<?> queue) {
-    for (Element e : elements()) {
-      replacequeue(e, queue);
-    }
-    return this;
-  }
-
-  private void dequeue(Element elem) {
-    Queue<Function> q = queue(elem, null);
-    if (q != null) {
-      Function f = q.dequeue();
-      f = q.peek(0);
-      if (f != null) {
-        f.f(elem);
-      }
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private Queue<Function> queue(Element elem, Function func) {
-    if (elem != null) {
-      Queue<Function> q = (Queue<Function>) data(elem, getQueueType(), null);
-      if (q == null) {
-        q = (Queue<Function>) data(elem, getQueueType(), Queue.newInstance());
-      }
-      if (func != null) {
-        q.enqueue(func);
-      }
-      if (q.length() == 1 && func != null) {
-        func.f(elem);
-      }
-      return q;
-    }
-    return null;
-  }
-
-  private void replacequeue(Element elem, Queue<?> queue) {
-    if (elem != null) {
-      data(elem, getQueueType(), queue);
-    }
-  }
-  
-  protected String getQueueType() {
-    return "GQueryQueue_" + this.getClass().getName(); 
-  }
-}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyEffects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyEffects.java
deleted file mode 100644 (file)
index 35ae7b8..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.google.gwt.query.client;
-
-/**
- *
- */
-public interface LazyEffects extends LazyGQuery<Effects> {
-
-  LazyEffects animate(Properties properties, Effects.Speed speed,
-      Effects.Easing easing, Function complete);
-
-  LazyEffects animate(Properties properties, int speed, Effects.Easing easing,
-      Function complete);
-
-  GQueryQueue dequeue();
-
-  GQueryQueue dequeue(String type);
-
-  LazyEffects fadeIn();
-
-  LazyEffects fadeIn(Effects.Speed speed);
-
-  LazyEffects fadeIn(Effects.Speed speed, Function callback);
-
-  LazyEffects fadeIn(int speed);
-
-  LazyEffects fadeIn(int speed, Function callback);
-
-  LazyEffects fadeOut();
-
-  LazyEffects fadeOut(Effects.Speed speed);
-
-  LazyEffects fadeOut(Effects.Speed speed, Function callback);
-
-  LazyEffects fadeOut(int speed);
-
-  LazyEffects fadeOut(int speed, Function callback);
-
-  LazyEffects fadeTo(Effects.Speed speed, double opacity);
-
-  LazyEffects fadeTo(Effects.Speed speed, double opacity, Function callback);
-
-  LazyEffects hide();
-
-  GQueryQueue queue(Function data);
-
-  GQueryQueue queue(String type, Function data);
-
-  LazyEffects show();
-
-  LazyEffects slideDown();
-
-  LazyEffects slideDown(Effects.Speed speed);
-
-  LazyEffects slideDown(Effects.Speed speed, Function callback);
-
-  LazyEffects slideToggle();
-
-  LazyEffects slideToggle(Effects.Speed speed);
-
-  LazyEffects slideToggle(Effects.Speed speed, Function callback);
-
-  LazyEffects slideUp();
-
-  LazyEffects slideUp(Effects.Speed speed);
-
-  LazyEffects slideUp(Effects.Speed speed, Function callback);
-
-  LazyEffects toggle();
-}
index 724ac34727815d7a15c163edc64a611c2c6d265e..9b0ca01a8a60e7d943524b8ef69a5e4e23002ba8 100644 (file)
@@ -1,14 +1,49 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins.Effects.Effects;
+import static com.google.gwt.query.client.plugins.Events.Events;
+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.JsArrayString;
+import com.google.gwt.dom.client.ButtonElement;
+import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.IFrameElement;
+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.dom.client.OptionElement;
+import com.google.gwt.dom.client.SelectElement;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.TextAreaElement;
+import com.google.gwt.dom.client.Style.Display;
 import com.google.gwt.query.client.css.CssProperty;
+import com.google.gwt.query.client.css.Length;
+import com.google.gwt.query.client.css.Percentage;
+import com.google.gwt.query.client.css.TakesLength;
+import com.google.gwt.query.client.css.TakesPercentage;
+import com.google.gwt.query.client.impl.DocumentStyleImpl;
+import com.google.gwt.query.client.impl.SelectorEngineImpl;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.query.client.LazyBase;
 
-/**
- * Created by IntelliJ IDEA. User: ray Date: May 2, 2009 Time: 10:48:07 PM To
- * change this template use File | Settings | File Templates.
- */
-public interface LazyGQuery<T> extends LazyBase<T> {
+public interface LazyGQuery<T> extends LazyBase<T>{
 
   /**
    * Add elements to the set of matched elements if they are not included yet.
@@ -86,7 +121,15 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   /**
    * Convert to Plugin interface provided by Class literal.
    */
-  <P extends GQuery> P as(Class<P> plugin);
+  <T extends GQuery> T as(Class<T> plugin);
+
+  /**
+   * Access a property on the first matched element. This method makes it easy
+   * to retrieve a property value from the first matched element. If the element
+   * does not have an attribute with such a name, undefined is returned.
+   * Attributes include title, alt, src, href, width, style, etc.
+   */
+  String attr(String name);
 
   /**
    * Set a single property to a value, on all matched elements.
@@ -95,8 +138,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
 
   /**
    * Set a key/value object as properties to all matched elements.
-   * 
-   * Example: $("img").attr(new Properties("src: 'test.jpg', alt: 'Test
+   *
    * Image'"))
    */
   LazyGQuery<T> attr(Properties properties);
@@ -138,19 +180,19 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * parameter
    * 
    */
-  LazyGQuery<T> bind(int eventbits, Object data, Function... f);
+  LazyGQuery<T> bind(int eventbits, Object data, Function...funcs);
 
   /**
-   * Bind a set of functions to the blur event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the blur event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> blur(Function... f);
+  LazyGQuery<T> blur(Function...f);
 
   /**
-   * Bind a set of functions to the change event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the change event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> change(Function... f);
+  LazyGQuery<T> change(Function...f);
 
   /**
    * Get a set of elements containing all of the unique children of each of the
@@ -167,10 +209,10 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> children();
 
   /**
-   * Bind a set of functions to the click event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the click event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> click(Function... f);
+  LazyGQuery<T> click(Function...f);
 
   /**
    * Clone matched DOM Elements and select the clones. This is useful for moving
@@ -190,25 +232,30 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> contents();
 
   /**
-   * Set a single style property to a value, on all matched elements using
-   * type-safe overhead-free enumerations.
-   * 
-   * @param property
-   *          a CSS property type
-   * @param value
-   *          a legal value from the type T
-   * @param <T>
-   *          inferred from the CSS property type
-   * @return
+   * Set CSS property on every matched element using type-safe enumerations.
    */
-   <S, P extends CssProperty<S>> LazyGQuery<T> css(P cssProperty, S value);
+  <S, T extends CssProperty<S>> LazyGQuery<T> css(T cssProperty, S value);
 
+  /**
+   * Set CSS property on every matched element using type-safe enumerations.
+   */
+  LazyGQuery<T> css(TakesLength cssProperty, Length value);
+
+  /**
+   * Set CSS property on every matched element using type-safe enumerations.
+   */
+  LazyGQuery<T> css(TakesPercentage cssProperty, Percentage value);
+
+  /**
+   * Return a style property on the first matched element.
+   */
+  String css(String name);
 
   /**
    * Set a key/value object as style properties to all matched elements. This
    * serves as the best way to set a large number of style properties on all
    * matched elements.
-   * 
+   *
    * Example: $(".item").css(Properties.create("color: 'red', background:
    * 'blue'"))
    */
@@ -220,18 +267,43 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> css(String prop, String val);
 
   /**
-   * Bind a set of functions to the dblclick event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Returns value at named data store for the element, as set by data(name,
+   * value).
    */
-  LazyGQuery<T> dblclick(Function... f);
+  Object data(String name);
 
   /**
-   * Run one or more Functions over each element of the GQuery. You have to
-   * override one of these funcions: public void f(Element e) public String
-   * f(Element e, int i)
+   * Returns value at named data store for the element, as set by data(name,
+   * value) with desired return type.
+   *
+   */
+  <T> T data(String name, Class<T> clz);
+
+  /**
+   * Stores the value in the named spot with desired return type.
+   */
+  Object data(String name, Object value);
+
+  /**
+   * Bind a set of functions to the dblclick event of each matched element.
+   * Or trigger the event if no functions are provided.
+   */
+  LazyGQuery<T> dblclick(Function...f);
+
+  /**
+   * Run one or more Functions over each element of the GQuery.
+   * You have to override one of these funcions:
+   *    public void f(Element e)
+   *    public String f(Element e, int i)
    */
   LazyGQuery<T> each(Function... f);
 
+  /**
+   * Returns the working set of nodes as a Java array. <b>Do NOT</b attempt to
+   * modify this array, e.g. assign to its elements, or call Arrays.sort()
+   */
+  Element[] elements();
+
   /**
    * Remove all child nodes from the set of matched elements.
    */
@@ -249,32 +321,32 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> eq(int pos);
 
   /**
-   * Bind a set of functions to the error event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the error event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
   LazyGQuery<T> error(Function... f);
 
   /**
    * Fade in all matched elements by adjusting their opacity.
    */
-  LazyGQuery<T> fadeIn(int millisecs);
+  LazyGQuery<T> fadeIn(int millisecs, Function... f);
 
   /**
    * Fade in all matched elements by adjusting their opacity. The effect will
    * take 1000 milliseconds to complete
    */
-  LazyGQuery<T> fadeIn();
+  LazyGQuery<T> fadeIn(Function... f);
 
   /**
    * Fade out all matched elements by adjusting their opacity.
    */
-  LazyGQuery<T> fadeOut(int millisecs);
+  LazyGQuery<T> fadeOut(int millisecs, Function... f);
 
   /**
    * Fade out all matched elements by adjusting their opacity. The effect will
    * take 1000 milliseconds to complete
    */
-  LazyGQuery<T> fadeOut();
+  LazyGQuery<T> fadeOut(Function... f);
 
   /**
    * Removes all elements from the set of matched elements that do not match the
@@ -296,17 +368,28 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * Searches for all elements that match the specified css expression. This
    * method is a good way to find additional descendant elements with which to
    * process.
-   * 
+   *
    * Provide a comma-separated list of expressions to apply multiple filters at
    * once.
    */
   LazyGQuery<T> find(String... filters);
 
   /**
-   * Bind a set of functions to the focus event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the focus event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> focus(Function... f);
+  LazyGQuery<T> focus(Function...f);
+
+  /**
+   * Return all elements matched in the GQuery as a NodeList. @see #elements()
+   * for a method which returns them as an immutable Java array.
+   */
+  NodeList<Element> get();
+
+  /**
+   * Return the ith element matched.
+   */
+  Element get(int i);
 
   /**
    * Return the previous set of matched elements prior to the last destructive
@@ -314,6 +397,11 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> getPreviousObject();
 
+  /**
+   * Return the selector representing the current set of matched elements.
+   */
+  String getSelector();
+
   /**
    * Returns true any of the specified classes are present on any of the matched
    * Reduce the set of matched elements to all elements after a given position.
@@ -322,6 +410,12 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> gt(int pos);
 
+  /**
+   * Returns true any of the specified classes are present on any of the matched
+   * elements.
+   */
+  boolean hasClass(String... classes);
+
   /**
    * Set the height of every element in the matched set.
    */
@@ -333,6 +427,23 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> height(String height);
 
+  /**
+   * Get the current computed, pixel, height of the first matched element.
+   */
+  int height();
+
+  /**
+   * Returns the inner height of the first matched element, including padding 
+   * but not the vertical scrollbar height, border, or margin.
+   */
+  int clientHeight();
+
+  /**
+   * Returns the inner width of the first matched element, including padding 
+   * but not the vertical scrollbar width, border, or margin.
+   */
+  int clientWidth();
+
   /**
    * Make invisible all matched elements.
    */
@@ -348,11 +459,21 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> hover(Function fover, Function fout);
 
+  /**
+   * Get the innerHTML of the first matched element.
+   */
+  String html();
+
   /**
    * Set the innerHTML of every matched element.
    */
   LazyGQuery<T> html(String html);
 
+  /**
+   * Find the index of the specified Element.
+   */
+  int index(Element element);
+
   /**
    * Insert all of the matched elements after another, specified, set of
    * elements.
@@ -374,7 +495,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   /**
    * Insert all of the matched elements before another, specified, set of
    * elements.
-   * 
+   *
    * The elements must already be inserted into the document (you can't insert
    * an element after another if it's not in the page).
    */
@@ -383,7 +504,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   /**
    * Insert all of the matched elements before another, specified, set of
    * elements.
-   * 
+   *
    * The elements must already be inserted into the document (you can't insert
    * an element after another if it's not in the page).
    */
@@ -392,17 +513,24 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   /**
    * Insert all of the matched elements before another, specified, set of
    * elements.
-   * 
+   *
    * The elements must already be inserted into the document (you can't insert
    * an element after another if it's not in the page).
    */
   LazyGQuery<T> insertBefore(String selector);
 
   /**
-   * Bind a set of functions to the keydown event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Checks the current selection against an expression and returns true, if at
+   * least one element of the selection fits the given expression. Does return
+   * false, if no element fits or the expression is not valid.
+   */
+  boolean is(String... filters);
+
+  /**
+   * Bind a set of functions to the keydown event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> keydown(Function... f);
+  LazyGQuery<T> keydown(Function...f);
 
   /**
    * Trigger a keydown event passing the key pushed
@@ -410,10 +538,10 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> keydown(int key);
 
   /**
-   * Bind a set of functions to the keypress event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the keypress event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> keypress(Function... f);
+  LazyGQuery<T> keypress(Function...f);
 
   /**
    * Trigger a keypress event passing the key pushed
@@ -421,16 +549,22 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> keypress(int key);
 
   /**
-   * Bind a set of functions to the keyup event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the keyup event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> keyup(Function... f);
+  LazyGQuery<T> keyup(Function...f);
 
   /**
    * Trigger a keyup event passing the key pushed
    */
   LazyGQuery<T> keyup(int key);
 
+  /**
+   * Returns the number of elements currently matched. The size function will
+   * return the same value.
+   */
+  int length();
+
   /**
    * Bind a function to the load event of each matched element.
    */
@@ -444,34 +578,34 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> lt(int pos);
 
   /**
-   * Bind a set of functions to the mousedown event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the mousedown event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> mousedown(Function... f);
+  LazyGQuery<T> mousedown(Function...f);
 
   /**
-   * Bind a set of functions to the mousemove event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the mousemove event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> mousemove(Function... f);
+  LazyGQuery<T> mousemove(Function...f);
 
   /**
-   * Bind a set of functions to the mouseout event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the mouseout event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> mouseout(Function... f);
+  LazyGQuery<T> mouseout(Function...f);
 
   /**
-   * Bind a set of functions to the mouseover event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the mouseover event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> mouseover(Function... f);
+  LazyGQuery<T> mouseover(Function...f);
 
   /**
-   * Bind a set of functions to the mouseup event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the mouseup event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> mouseup(Function... f);
+  LazyGQuery<T> mouseup(Function...f);
 
   /**
    * Get a set of elements containing the unique next siblings of each of the
@@ -511,6 +645,13 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> not(String... filters);
 
+  /**
+   * Get the current offset of the first matched element, in pixels, relative to
+   * the document. The returned object contains two integer properties, top and
+   * left. The method works only with visible elements.
+   */
+  com.google.gwt.query.client.GQuery.Offset offset();
+
   /**
    * Returns a GQuery collection with the positioned parent of the first matched
    * element. This is the first parent of the element that has position (as in
@@ -521,11 +662,11 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   /**
    * Binds a handler to a particular Event (like Event.ONCLICK) for each matched
    * element. The handler is executed only once for each element.
-   * 
+   *
    * The event handler is passed as a Function that you can use to prevent
-   * default behaviour. To stop both default action and event bubbling, the
+   * default behavior. To stop both default action and event bubbling, the
    * function event handler has to return false.
-   * 
+   *
    * You can pass an additional Object data to your Function as the second
    * parameter
    */
@@ -557,6 +698,14 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> parents();
 
+  /**
+   * Gets the top and left position of an element relative to its offset parent.
+   * The returned object contains two Integer properties, top and left. For
+   * accurate calculations make sure to use pixel values for margins, borders
+   * and padding. This method only works with visible elements.
+   */
+  com.google.gwt.query.client.GQuery.Offset position();
+
   /**
    * Prepend content to the inside of every matched element. This operation is
    * the best way to insert elements inside, at the beginning, of all matched
@@ -668,10 +817,10 @@ public interface LazyGQuery<T> extends LazyBase<T> {
   LazyGQuery<T> replaceWith(Element elem);
 
   /**
-   * Bind a set of functions to the scroll event of each matched element. Or
-   * trigger the event if no functions are provided.
+   * Bind a set of functions to the scroll event of each matched element.
+   * Or trigger the event if no functions are provided.
    */
-  LazyGQuery<T> scroll(Function... f);
+  LazyGQuery<T> scroll(Function...f);
 
   /**
    * When a value is passed in, the scroll left offset is set to that value on
@@ -701,6 +850,25 @@ public interface LazyGQuery<T> extends LazyBase<T> {
 
   LazyGQuery<T> select();
 
+  /**
+   * Set CSS property on the first element.
+   */
+  <S, T extends CssProperty<S>> LazyGQuery<T> setCss(T cssProperty, S value);
+
+  /**
+   * Set CSS property on first matched element using type-safe enumerations.
+   */
+  LazyGQuery<T> setCss(TakesLength cssProperty, Length value);
+
+  /**
+   * Set CSS property on first matched element using type-safe enumerations.
+   */
+  LazyGQuery<T> setCss(TakesPercentage cssProperty, Percentage value);
+
+  void setPreviousObject(GQuery previousObject);
+
+  void setSelector(String selector);
+
   /**
    * Return the number of elements in the matched set. Make visible all mached
    * elements
@@ -719,6 +887,11 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> siblings(String... selectors);
 
+  /**
+   * Return the number of elements in the matched set.
+   */
+  int size();
+
   /**
    * Selects a subset of the matched elements.
    */
@@ -726,28 +899,58 @@ public interface LazyGQuery<T> extends LazyBase<T> {
 
   LazyGQuery<T> submit();
 
+  /**
+   * Return the text contained in the first matched element.
+   */
+  String text();
+
   /**
    * Set the innerText of every matched element.
    */
   LazyGQuery<T> text(String txt);
 
+  /**
+   * Toggle visibility of elements.
+   */
+  LazyGQuery<T> toggle();
+
   /**
    * Toggle among two or more function calls every other click.
    */
   LazyGQuery<T> toggle(Function... fn);
 
   /**
-   * Adds or removes the specified classes to each matched element.
+   * Adds or removes the specified classes to each matched element
+   * depending on the class's presence
    */
   LazyGQuery<T> toggleClass(String... classes);
 
   /**
-   * Adds or removes the specified classes to each matched element.
+   * Adds or removes the specified classes to each matched element
+   * depending on the value of the switch argument.
+   * 
+   * false it is removed.
+   */
+  LazyGQuery<T> toggleClass(String clz, boolean addOrRemove);
+
+  /**
+   * Produces a string representation of the matched elements.
    */
-  LazyGQuery<T> toggleClass(String clz, boolean sw);
+  String toString();
 
   /**
-   * Trigger an event of type eventbits on every matched element.
+   * Produces a string representation of the matched elements.
+   */
+  String toString(boolean pretty);
+
+  /**
+   * Trigger a set of events on each matched element.
+   * 
+   * For keyboard events you can pass a second parameter which represents 
+   * the key-code of the pushed key. 
+   * 
+   * Example: fire(Event.ONCLICK | Event.ONFOCUS)
+   * Example: fire(Event.ONKEYDOWN. 'a');
    */
   LazyGQuery<T> trigger(int eventbits, int... keys);
 
@@ -756,6 +959,23 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> unbind(int eventbits);
 
+  /**
+   * Remove all duplicate elements from an array of elements. Note that this
+   * only works on arrays of DOM elements, not strings or numbers.
+   */
+  JSArray unique(JSArray result);
+
+  /**
+   * Gets the content of the value attribute of the first matched element,
+   * returns only the first value even if it is a multivalued element. To get an
+   * array of all values in multivalues elements use vals()
+   *
+   * When the first element is a radio-button and is not checked, then it looks
+   * for a the first checked radio-button that has the same name in the list of
+   * matched elements.
+   */
+  String val();
+
   /**
    * Sets the value attribute of every matched element In the case of multivalue
    * elements, all values are setted for other elements, only the first value is
@@ -763,11 +983,34 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    */
   LazyGQuery<T> val(String... values);
 
+  /**
+   * Gets the content of the value attribute of the first matched element,
+   * returns more than one value if it is a multiple select.
+   *
+   * When the first element is a radio-button and is not checked, then it looks
+   * for a the first checked radio-button that has the same name in the list of
+   * matched elements.
+   *
+   * This method always returns an array. If no valid value can be determined
+   * the array will be empty, otherwise it will contain one or more values.
+   */
+  String[] vals();
+
+  /**
+   * Return true if the first element is visible.
+   */
+  boolean visible();
+
   /**
    * Set the width of every matched element.
    */
   LazyGQuery<T> width(int width);
 
+  /**
+   * Get the current computed, pixel, width of the first matched element.
+   */
+  int width();
+
   /**
    * Wrap each matched element with the specified HTML content. This wrapping
    * process is most useful for injecting additional structure into a document,
@@ -807,7 +1050,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * get wrapped with an element. This wrapping process is most useful for
    * injecting additional structure into a document, without ruining the
    * original semantic qualities of a document.
-   * 
+   *
    * This works by going through the first element provided (which is generated,
    * on the fly, from the provided HTML) and finds the deepest descendant
    * element within its structure -- it is that element that will enwrap
@@ -821,7 +1064,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * get wrapped with an element. This wrapping process is most useful for
    * injecting additional structure into a document, without ruining the
    * original semantic qualities of a document.
-   * 
+   *
    * This works by going through the first element provided (which is generated,
    * on the fly, from the provided HTML) and finds the deepest descendant
    * element within its structure -- it is that element that will enwrap
@@ -835,7 +1078,7 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * get wrapped with an element. This wrapping process is most useful for
    * injecting additional structure into a document, without ruining the
    * original semantic qualities of a document.
-   * 
+   *
    * This works by going through the first element provided (which is generated,
    * on the fly, from the provided HTML) and finds the deepest descendant
    * element within its structure -- it is that element that will enwrap
@@ -875,4 +1118,15 @@ public interface LazyGQuery<T> extends LazyBase<T> {
    * that element that will enwrap everything else.
    */
   LazyGQuery<T> wrapInner(Element elem);
+
+  /**
+   * Save a set of Css properties of every matched element.
+   */
+  void restoreCssAttrs(String[] cssProps);
+
+  /**
+   * Restore a set of previously saved Css properties in every matched element.
+   */
+  void saveCssAttrs(String[] cssProps);
+
 }
index ac7c32adc2641f07884adfa6382571cc97497719..74e52af715df9119450c6cf859b77b6f01fbfe5d 100644 (file)
@@ -34,7 +34,7 @@ public class Properties extends JavaScriptObject {
     }-*/;\r
 \r
   protected static String wrapPropertiesString(String s) {\r
-    return "({" + s.replaceFirst("^[({]+", "").replaceFirst("[})]+", "") + "})";\r
+    return "({" + s.replaceFirst("^[({]+", "").replaceFirst("[})]+$", "") + "})";\r
   }\r
 \r
   protected Properties() {\r
@@ -93,4 +93,12 @@ public class Properties extends JavaScriptObject {
   public final native void set(String key, String val) /*-{\r
     this[key]=val;\r
   }-*/;\r
+  \r
+  public final String tostring() {\r
+    String ret = "";\r
+    for (String k : keys()){\r
+      ret += k + ": '" + get(k) + "', ";\r
+    }\r
+    return "({" + ret.replaceAll("[, ]+","") + "})";\r
+  }\r
 }\r
index 0fa3c3cdf8339b4d241329290cf20c14bb7ae283..a8bbb23fc9f8d3920b4096eeae97babdcc9e8714 100644 (file)
@@ -41,6 +41,8 @@ public class DocumentStyleImplIE extends DocumentStyleImpl {
     }
     return name;
   }
+  
+  
 
   // code lifted from jQuery
   private native String getComputedStyle(Element elem, String name,
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ClipAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ClipAnimation.java
new file mode 100755 (executable)
index 0000000..fc701a3
--- /dev/null
@@ -0,0 +1,139 @@
+/*\r
+ * Copyright 2009 Google Inc.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.client.plugins;\r
+\r
+import com.google.gwt.animation.client.Animation;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.query.client.Function;\r
+import com.google.gwt.query.client.GQuery;\r
+\r
+/**\r
+ * Animation wich uses the css clip property to show/hide an element.\r
+ */\r
+public class ClipAnimation extends Animation {\r
+\r
+  /**\r
+   * Type of the effect action.\r
+   */\r
+  public static enum Action {\r
+    HIDE, SHOW\r
+  }\r
+\r
+  /**\r
+   * Corner from which the effect starts.\r
+   */\r
+  public static enum Corner {\r
+    BOTTOM_LEFT, BOTTOM_RIGHT, CENTER, TOP_LEFT, TOP_RIGHT\r
+  }\r
+\r
+  /**\r
+   * Direction of the effect.\r
+   */\r
+  public static enum Direction {\r
+    BIDIRECTIONAL, HORIZONTAL, VERTICAL\r
+  }\r
+\r
+  private static final String[] attrsToSave = new String[] { "position",\r
+      "overflow", "visibility", "white-space", "top", "left" };\r
+\r
+  Action action;\r
+  Corner corner;\r
+  Direction direction;\r
+  Element e;\r
+  int percent;\r
+  private GQuery back = Effects.$();\r
+  private Function[] funcs;\r
+  private Effects g;\r
+\r
+  public ClipAnimation(Element elem, Action a, Corner c, Direction d,\r
+      final Function... funcs) {\r
+    this.action = a;\r
+    this.corner = c;\r
+    this.direction = d;\r
+    this.funcs = funcs;\r
+    e = elem;\r
+    g = new Effects(e);\r
+  }\r
+\r
+  @Override\r
+  public void onCancel() {\r
+    onComplete();\r
+  }\r
+\r
+  @Override\r
+  public void onComplete() {\r
+    super.onComplete();\r
+    if (action == Action.HIDE) {\r
+      g.hide();\r
+    }\r
+    g.restoreCssAttrs(attrsToSave);\r
+    back.remove();\r
+    back = Effects.$();\r
+    g.css("clip", "");\r
+    g.each(funcs);\r
+    g.dequeue();\r
+  }\r
+\r
+  @Override\r
+  public void onStart() {\r
+    g.show();\r
+    g.saveCssAttrs(attrsToSave);\r
+    if (!"absolute".equalsIgnoreCase(g.css("position"))) {\r
+      g.css("position", "absolute");\r
+      g.css("top", g.offset().top + "px");\r
+      g.css("left", g.offset().left + "px");\r
+      back = back.add(g.before("<div></div>")).prev();\r
+      back.height(g.height());\r
+      back.width(g.width());\r
+    }\r
+    g.css("overflow", "hidden");\r
+    g.css("visivility", "visible");\r
+    g.css("white-space", "nowrap");\r
+    super.onStart();\r
+  }\r
+\r
+  @Override\r
+  public void onUpdate(double progress) {\r
+    if (action == Action.HIDE) {\r
+      progress = (1 - progress);\r
+    }\r
+    int top = 0;\r
+    int left = 0;\r
+    int right = g.width();\r
+    int bottom = g.height();\r
+\r
+    if (direction == Direction.VERTICAL || direction == Direction.BIDIRECTIONAL) {\r
+      bottom = (int) (g.height() * progress);\r
+    }\r
+    if (direction == Direction.HORIZONTAL\r
+        || direction == Direction.BIDIRECTIONAL) {\r
+      right = (int) (g.width() * progress);\r
+    }\r
+    if (corner == Corner.CENTER) {\r
+      top = (g.height() - bottom) / 2;\r
+      left = (g.width() - right) / 2;\r
+    } else if (corner == Corner.BOTTOM_LEFT) {\r
+      top = (g.height() - bottom);\r
+    } else if (corner == Corner.TOP_RIGHT) {\r
+      left = (g.width() - right);\r
+    } else if (corner == Corner.BOTTOM_RIGHT) {\r
+      left = (g.width() - right);\r
+      top = (g.height() - bottom);\r
+    }\r
+    String rect = top + "px " + right + "px " + bottom + "px  " + left + "px";\r
+    g.css("clip", "rect(" + rect + ")");\r
+  }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java
new file mode 100755 (executable)
index 0000000..d1b12fd
--- /dev/null
@@ -0,0 +1,386 @@
+/*\r
+ * Copyright 2009 Google Inc.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.client.plugins;\r
+\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.dom.client.NodeList;\r
+import com.google.gwt.query.client.Function;\r
+import com.google.gwt.query.client.GQuery;\r
+import com.google.gwt.query.client.JSArray;\r
+import com.google.gwt.query.client.Plugin;\r
+import com.google.gwt.query.client.Properties;\r
+import com.google.gwt.query.client.plugins.ClipAnimation.Action;\r
+import com.google.gwt.query.client.plugins.ClipAnimation.Direction;\r
+import com.google.gwt.query.client.plugins.PropertiesAnimation.Easing;\r
+\r
+/**\r
+ *  Effects plugin for Gwt Query. \r
+ */\r
+public class Effects extends GQueryQueue  {\r
+  \r
+  public static int DEFAULT_SPEED = 400;\r
+\r
+  public static Class<Effects> Effects = Effects.class;\r
+\r
+  public static int FAST = 200;\r
+\r
+  public static int SLOW = 600;\r
+  \r
+  static {\r
+    GQuery.registerPlugin(Effects.class, new Plugin<Effects>() {\r
+      public Effects init(GQuery gq) {\r
+        return new Effects(gq);\r
+      }\r
+    });\r
+  }\r
+\r
+  public Effects(final Element element) {\r
+    super(element);\r
+  }\r
+\r
+  public Effects(GQuery gq) {\r
+    super(gq);\r
+  }\r
+\r
+  public Effects(final JSArray elements) {\r
+    super(elements);\r
+  }\r
+\r
+  public Effects(final NodeList<Element> list) {\r
+    super(list);\r
+  }\r
+\r
+  /**\r
+   * The animate() method allows us to create animation effects on any numeric CSS property. \r
+   * The only required parameter is a map of CSS properties. \r
+   * This map is similar to the one that can be sent to the .css() method, \r
+   * except that the range of properties is more restrictive.\r
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. \r
+   * (For example, width, height, or left can be animated but background-color cannot be.) \r
+   * Property values are treated as a number of pixels unless otherwise specified.\r
+   *  The units em and % can be specified where applicable.\r
+   *  \r
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. \r
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.\r
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= \r
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number \r
+   *  from the current value of the property.\r
+   */  \r
+  public Effects animate(final Properties p, final int duration,\r
+      final Easing easing, final Function... funcs) {\r
+    queue(new Function() {\r
+      public void f(Element e) {\r
+        new PropertiesAnimation(easing, e, p, funcs).run(duration);\r
+      }\r
+    });\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * The animate() method allows us to create animation effects on any numeric CSS property. \r
+   * The only required parameter is a map of CSS properties. \r
+   * This map is similar to the one that can be sent to the .css() method, \r
+   * except that the range of properties is more restrictive.\r
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. \r
+   * (For example, width, height, or left can be animated but background-color cannot be.) \r
+   * Property values are treated as a number of pixels unless otherwise specified.\r
+   *  The units em and % can be specified where applicable.\r
+   *  \r
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. \r
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.\r
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= \r
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number \r
+   *  from the current value of the property.\r
+   */\r
+  public Effects animate(String prop, Function... funcs) {\r
+    return animate(prop, 500, funcs);\r
+  }\r
+\r
+  /**\r
+   * The animate() method allows us to create animation effects on any numeric CSS property. \r
+   * The only required parameter is a map of CSS properties. \r
+   * This map is similar to the one that can be sent to the .css() method, \r
+   * except that the range of properties is more restrictive.\r
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. \r
+   * (For example, width, height, or left can be animated but background-color cannot be.) \r
+   * Property values are treated as a number of pixels unless otherwise specified.\r
+   *  The units em and % can be specified where applicable.\r
+   *  \r
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. \r
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.\r
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= \r
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number \r
+   *  from the current value of the property.\r
+   */  \r
+  public Effects animate(String prop, int duration, Function... funcs) {\r
+    return animate($$(prop), duration, Easing.SWING, funcs);\r
+  }\r
+\r
+  /**\r
+   * Animate the set of matched elements using the clip property.\r
+   * It is possible to show or hide a set of elements, \r
+   * specify the direction of the animation and the start corner of the effect.\r
+   * Finally it executes the set of functions passed as arguments.\r
+   */\r
+  public Effects clip(ClipAnimation.Action a, ClipAnimation.Corner c,\r
+      ClipAnimation.Direction d, Function... f) {\r
+    return clip(a, c, d, DEFAULT_SPEED, f);\r
+  }\r
+  \r
+  /**\r
+   * Animate the set of matched elements using the clip property.\r
+   * It is possible to show or hide a set of elements, \r
+   * specify the direction of the animation and the start corner of the effect.\r
+   * Finally it executes the set of functions passed as arguments.\r
+   */\r
+  public Effects clip(final ClipAnimation.Action a, final ClipAnimation.Corner c, \r
+      final ClipAnimation.Direction d, final int duration, final Function... f) {\r
+    queue(new Function() {\r
+      public void f(Element e) {\r
+        new ClipAnimation(e, a, c, d, f).run(duration);\r
+      }\r
+    });\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Animate the set of matched elements using the clip property.\r
+   * It is possible to show or hide a set of elements, \r
+   * specify the direction of the animation and the start corner of the effect.\r
+   * Finally it executes the set of functions passed as arguments.\r
+   */\r
+  public Effects clip(ClipAnimation.Action a, ClipAnimation.Corner c,\r
+      Function... f) {\r
+    return clip(a, c, Direction.BIDIRECTIONAL, DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the center to the perimeter.\r
+   */\r
+  public Effects clipAppear(Function... f) {\r
+    return clipAppear(DEFAULT_SPEED, f);\r
+  }\r
+  \r
+  /**\r
+   * Reveal all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the center to the perimeter.\r
+   */\r
+  public Effects clipAppear(int millisecs, Function... f) {\r
+    return clip(ClipAnimation.Action.SHOW, ClipAnimation.Corner.CENTER,\r
+        ClipAnimation.Direction.BIDIRECTIONAL, millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the perimeter to the center.\r
+   */\r
+  public Effects clipDisappear(Function... f) {\r
+    return clipDisappear(DEFAULT_SPEED, f);\r
+  }\r
+  \r
+  /**\r
+   * Hide all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the perimeter to the center.\r
+   */\r
+  public Effects clipDisappear(int millisecs, Function... f) {\r
+    return clip(ClipAnimation.Action.HIDE, ClipAnimation.Corner.CENTER,\r
+        ClipAnimation.Direction.BIDIRECTIONAL, millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the top to the bottom.\r
+   */\r
+  public Effects clipDown(Function... f) {\r
+    return clipDown(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the top to the bottom.\r
+   */\r
+  public Effects clipDown(int millisecs, Function... f) {\r
+    return clip(Action.SHOW, ClipAnimation.Corner.TOP_LEFT,\r
+        ClipAnimation.Direction.BIDIRECTIONAL, millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the bottom to the top.\r
+   */\r
+  public Effects clipUp(Function... f) {\r
+    return clipUp(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting the clip property firing an\r
+   * optional callback after completion.\r
+   * The effect goes from the bottom to the top.\r
+   */\r
+  public Effects clipUp(int millisecs, Function... f) {\r
+    return clip(Action.HIDE, ClipAnimation.Corner.TOP_LEFT,\r
+        ClipAnimation.Direction.BIDIRECTIONAL, millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Fade in all matched elements by adjusting their opacity and firing an\r
+   * optional callback after completion. Only the opacity is adjusted for this\r
+   * animation, meaning that all of the matched elements should already have\r
+   * some form of height and width associated with them.\r
+   */  \r
+  public Effects fadeIn(Function... f) {\r
+    return fadeIn(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Fade in all matched elements by adjusting their opacity and firing an\r
+   * optional callback after completion. Only the opacity is adjusted for this\r
+   * animation, meaning that all of the matched elements should already have\r
+   * some form of height and width associated with them.\r
+   */\r
+  public Effects fadeIn(int millisecs, Function... f) {\r
+    return animate("opacity: 'show'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
+   * display to "none" and firing an optional callback after completion. Only\r
+   * the opacity is adjusted for this animation, meaning that all of the matched\r
+   * elements should already have some form of height and width associated with\r
+   * them.\r
+   */  \r
+  public Effects fadeOut(Function... f) {\r
+    return fadeOut(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
+   * display to "none" and firing an optional callback after completion. Only\r
+   * the opacity is adjusted for this animation, meaning that all of the matched\r
+   * elements should already have some form of height and width associated with\r
+   * them.\r
+   */  \r
+  public Effects fadeOut(int millisecs, Function... f) {\r
+    return animate("opacity: 'hide'", millisecs, f);\r
+  };\r
+  \r
+  /**\r
+   * Fade the opacity of all matched elements to a specified opacity and firing\r
+   * an optional callback after completion. Only the opacity is adjusted for\r
+   * this animation, meaning that all of the matched elements should already\r
+   * have some form of height and width associated with them.\r
+   */\r
+  public Effects fadeTo(int millisecs, double opacity, Function... f) {\r
+    return animate("opacity: " + opacity, millisecs, f);\r
+  }\r
+  \r
+  /**\r
+   * Reveal all matched elements by adjusting their height and firing an\r
+   * optional callback after completion.\r
+   */\r
+  public Effects slideDown(Function... f) {\r
+    return slideDown(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting their height and firing an\r
+   * optional callback after completion.\r
+   */\r
+  public Effects slideDown(int millisecs, Function... f) {\r
+    return animate("height: 'show'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their width and firing an optional\r
+   * callback after completion.\r
+   */\r
+  public Effects slideLeft(Function... f) {\r
+    return slideLeft(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their width and firing an optional\r
+   * callback after completion.\r
+   */\r
+  public Effects slideLeft(int millisecs, Function... f) {\r
+    return animate("width: 'hide'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting their width and firing an\r
+   * optional callback after completion.\r
+   */\r
+  public Effects slideRight(Function... f) {\r
+    return slideRight(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting their width and firing an\r
+   * optional callback after completion.\r
+   */\r
+  public Effects slideRight(final int millisecs, Function... f) {\r
+    return animate("width: 'show'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Toggle the visibility of all matched elements by adjusting their height and\r
+   * firing an optional callback after completion. Only the height is adjusted\r
+   * for this animation, causing all matched elements to be hidden or shown in a\r
+   * "sliding" manner\r
+   */  \r
+  public Effects slideToggle(int millisecs, Function... f) {\r
+    return animate("height: 'toggle'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their height and firing an optional\r
+   * callback after completion.\r
+   */\r
+  public Effects slideUp(Function... f) {\r
+    return slideUp(DEFAULT_SPEED, f);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their height and firing an optional\r
+   * callback after completion.\r
+   */\r
+  public Effects slideUp(int millisecs, Function... f) {\r
+    return animate("height: 'hide'", millisecs, f);\r
+  }\r
+\r
+  /**\r
+   * Toggle displaying each of the set of matched elements.\r
+   */\r
+  @Override\r
+  public Effects toggle() {\r
+    return toggle(DEFAULT_SPEED);\r
+  }\r
+\r
+  /**\r
+   * Toggle displaying each of the set of matched elements.\r
+   */\r
+  public Effects toggle(int millisecs, Function... f) {\r
+    return animate("opacity: 'toggle'", millisecs, f);\r
+  }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java
new file mode 100644 (file)
index 0000000..67b8a08
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.JSArray;
+import com.google.gwt.query.client.Plugin;
+import com.google.gwt.user.client.Event;
+
+/**
+ * GQuery Plugin for handling and queuing browser events.
+ */
+public class Events extends GQuery {
+
+  public static final Class<Events> Events = Events.class;
+
+  static {
+    GQuery.registerPlugin(Events.class, new Plugin<Events>() {
+      public Events init(GQuery gq) {
+        return new Events(gq.get());
+      }
+    });
+  }
+
+  public Events(Element element) {
+    super(element);
+  }
+
+  public Events(JSArray elements) {
+    super(elements);
+  }
+
+  public Events(NodeList<Element> list) {
+    super(list);
+  }
+
+  /**
+   * Binds a set of handlers to a particular Event for each matched element.
+   * 
+   * The event handlers are passed as Functions that you can use to prevent
+   * default behavior. To stop both default action and event bubbling, the
+   * function event handler has to return false.
+   * 
+   * You can pass an additional Object data to your Function as the second
+   * parameter
+   * 
+   */
+  public Events bind(int eventbits, Object data, Function...funcs) {
+    for (Element e : elements()) {
+      EventsListener.getInstance(e).bind(eventbits, data, funcs);
+    }
+    return this;
+  }
+  
+  /**
+   * Binds a handler to a particular Event (like Event.ONCLICK) for each matched
+   * element. The handler is executed only once for each element.
+   *
+   * The event handler is passed as a Function that you can use to prevent
+   * default behavior. To stop both default action and event bubbling, the
+   * function event handler has to return false.
+   *
+   * You can pass an additional Object data to your Function as the second
+   * parameter
+   */  
+  public Events one(int eventbits, final Object data, final Function f) {
+    for (Element e : elements()) {
+      EventsListener.getInstance(e).bind(eventbits, data, f, 1);
+    }
+    return this;
+  }
+  
+  /**
+   * Execute all handlers and behaviors attached to the matched elements for the given event types.
+   * 
+   * Different event types can be passed joining these using the or bit wise operator.
+   * 
+   * For keyboard events you can pass a second parameter which represents 
+   * the key-code of the pushed key. 
+   * 
+   * Example: fire(Event.ONCLICK | Event.ONFOCUS)
+   * Example: fire(Event.ONKEYDOWN. 'a');
+   */
+  public Events trigger(int eventbits, int... keys) {
+    if ((eventbits | Event.ONBLUR) == Event.ONBLUR)
+      dispatchEvent(document.createBlurEvent());
+    if ((eventbits | Event.ONCHANGE) == Event.ONCHANGE)
+      dispatchEvent(document.createChangeEvent());
+    if ((eventbits | Event.ONCLICK) == Event.ONCLICK)
+      dispatchEvent(document.createClickEvent(0, 0, 0, 0, 0, false, false, false, false));
+    if ((eventbits | Event.ONDBLCLICK) == Event.ONDBLCLICK)
+      dispatchEvent(document.createDblClickEvent(0, 0, 0, 0, 0, false, false, false, false));
+    if ((eventbits | Event.ONFOCUS) == Event.ONFOCUS)
+      dispatchEvent(document.createFocusEvent());
+    if ((eventbits | Event.ONKEYDOWN) == Event.ONKEYDOWN)
+      dispatchEvent(document.createKeyDownEvent(false, false, false, false, keys[0], 0));
+    if ((eventbits | Event.ONKEYPRESS) == Event.ONKEYPRESS)
+      dispatchEvent(document.createKeyPressEvent(false, false, false, false, keys[0], 0));
+    if ((eventbits | Event.ONKEYUP) == Event.ONKEYUP)
+      dispatchEvent(document.createKeyUpEvent(false, false, false, false, keys[0], 0));
+    if ((eventbits | Event.ONLOSECAPTURE) == Event.ONLOSECAPTURE)
+      triggerHtmlEvent("losecapture");
+    if ((eventbits | Event.ONMOUSEDOWN) == Event.ONMOUSEDOWN)
+      dispatchEvent(document.createMouseDownEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
+    if ((eventbits | Event.ONMOUSEMOVE) == Event.ONMOUSEMOVE)
+      dispatchEvent(document.createMouseMoveEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
+    if ((eventbits | Event.ONMOUSEOUT) == Event.ONMOUSEOUT)
+      dispatchEvent(document.createMouseOutEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, null));
+    if ((eventbits | Event.ONMOUSEOVER) == Event.ONMOUSEOVER)
+      dispatchEvent(document.createMouseOverEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, null));
+    if ((eventbits | Event.ONMOUSEUP) == Event.ONMOUSEUP)
+      dispatchEvent(document.createMouseUpEvent(0, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT));
+    if ((eventbits | Event.ONSCROLL) == Event.ONSCROLL)
+      dispatchEvent(document.createScrollEvent());
+    if ((eventbits | Event.ONERROR) == Event.ONERROR)
+      dispatchEvent(document.createErrorEvent());
+    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));
+    return this;
+  }
+
+  /**
+   * Trigger a html event in all matched elements.
+   * 
+   * @param htmlEvent
+   *    An string representing the html event desired 
+   */
+  public Events triggerHtmlEvent(String htmlEvent) {
+    dispatchEvent(document.createHtmlEvent(htmlEvent, false, false));
+    return this;
+  }
+  
+  /**
+   * Removes all handlers, that matches the events bits passed, from each
+   * element.
+   * 
+   * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER)
+   */
+  public Events unbind(int eventbits) {
+    for (Element e : elements()) {
+      EventsListener.getInstance(e).unbind(eventbits);
+    }
+    return this;
+  }
+  
+  private void dispatchEvent(NativeEvent evt) {
+    for (Element e : elements()) {
+      e.dispatchEvent(evt);
+    }
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java
new file mode 100644 (file)
index 0000000..94beabb
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins;
+
+import com.google.gwt.core.client.Duration;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.JsObjectArray;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventListener;
+
+/**
+ * This class implements an event queue instance for one Element. The queue
+ * instance is configured as the default event listener in GWT.
+ * 
+ * The reference to this queue is stored as a unique variable in the element's
+ * DOM
+ * 
+ * The class takes care of calling the appropriate functions for each browser
+ * event and it also calls sinkEvents method.
+ */
+class EventsListener implements EventListener {
+
+  private static class BindFunction {
+
+    Object data;
+
+    Function function;
+
+    int times = -1;
+
+    int type;
+
+    BindFunction(int t, Function f, Object d) {
+      type = t;
+      function = f;
+      data = d;
+    }
+
+    BindFunction(int t, Function f, Object d, int times) {
+      this(t, f, d);
+      this.times = times;
+    }
+
+    public boolean fire(Event event) {
+      if (times != 0) {
+        times--;
+        return function.f(event, data);
+      }
+      return true;
+    }
+
+    public boolean hasEventType(int etype) {
+      return (type | etype) == type;
+    }
+  }
+
+  public static EventsListener getInstance(Element e) {
+    EventsListener ret = getGQueryEventLinstener(e);
+    return ret != null ? ret : new EventsListener(e);
+  }
+
+  private static native EventsListener getGQueryEventLinstener(Element elem) /*-{
+    return elem.__gqueryevent;
+  }-*/;
+
+  private static native EventListener getOriginalEventListener(Element elem) /*-{
+    return elem.__listener;
+  }-*/;
+
+  private static native void setFocusable(Element elem) /*-{
+    elem.tabIndex = 0;
+  }-*/;
+
+  private static native void setGQueryEventListener(Element elem,
+      EventsListener gqevent) /*-{
+    elem.__gqueryevent = gqevent;
+  }-*/;
+
+  private Element element;
+
+  private JsObjectArray<EventsListener.BindFunction> elementEvents = JsObjectArray
+      .createArray().cast();
+  private EventListener originalEventListener;
+
+  private EventsListener(Element element) {
+    this.element = element;
+    originalEventListener = getOriginalEventListener(element);
+    setGQueryEventListener(element, this);
+    DOM.setEventListener((com.google.gwt.user.client.Element) element, this);
+  }
+
+  public void bind(int eventbits, final Object data, Function...funcs) {
+    for (Function function: funcs) {
+      bind(eventbits, data, function, -1);
+    }
+  }
+
+  public void bind(int eventbits, final Object data, final Function function,
+      int times) {
+    if (function == null) {
+      unbind(eventbits);
+    } else {
+      DOM.sinkEvents((com.google.gwt.user.client.Element) element, eventbits
+          | DOM.getEventsSunk((com.google.gwt.user.client.Element) element));
+
+      if ((eventbits | Event.FOCUSEVENTS) == Event.FOCUSEVENTS) {
+        setFocusable(element);
+      }
+
+      elementEvents.add(new EventsListener.BindFunction(eventbits, function,
+          data, times));
+    }
+  }
+
+  double lastEvnt=0;
+  int lastType=0;
+  
+  public void onBrowserEvent(Event event) {
+    // Workaround for Issue_20
+    if (lastType == event.getTypeInt()
+        && lastEvnt - Duration.currentTimeMillis() < 10
+        && "body".equalsIgnoreCase(element.getTagName())) {
+      return;
+    }
+    lastEvnt = Duration.currentTimeMillis();
+    lastType = event.getTypeInt();
+
+    if (originalEventListener != null) {
+      originalEventListener.onBrowserEvent(event);
+    }
+
+    int etype = DOM.eventGetType(event);
+    for (int i = 0; i < elementEvents.length(); i++) {
+      EventsListener.BindFunction listener = elementEvents.get(i);
+      if (listener.hasEventType(etype)) {
+        if (!listener.fire(event)) {
+          event.stopPropagation();
+          event.preventDefault();
+        }
+      }
+    }
+  }
+
+  public void unbind(int eventbits) {
+    JsObjectArray<EventsListener.BindFunction> newList = JsObjectArray
+        .createArray().cast();
+    for (int i = 0; i < elementEvents.length(); i++) {
+      EventsListener.BindFunction listener = elementEvents.get(i);
+      if (!listener.hasEventType(eventbits)) {
+        newList.add(listener);
+      }
+    }
+    elementEvents = newList;
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/GQueryQueue.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/GQueryQueue.java
new file mode 100644 (file)
index 0000000..2989838
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.JSArray;
+
+/**
+ * Class used in plugins which need a queue system.
+ */
+public abstract class GQueryQueue extends GQuery {
+  
+  public GQueryQueue(Element element) {
+    super(element);
+  }
+
+  public GQueryQueue(GQuery gq) {
+    super(gq);
+  }
+
+  public GQueryQueue(JSArray elements) {
+    super(elements);
+  }
+
+  public GQueryQueue(NodeList<Element> list) {
+    super(list);
+  }
+
+  /**
+   * Removes a queued function from the front of the queue and executes it.
+   */
+  public GQueryQueue dequeue() {
+    for (Element e : elements()) {
+      dequeue(e);
+    }
+    return this;
+  }
+
+
+  /**
+   * Adds a new function, to be executed, onto the end of the queue of all
+   * matched elements.
+   */
+  public GQueryQueue queue(Function func) {
+    for (Element e : elements()) {
+      queue(e, func);
+    }
+    return this;
+  }
+
+  /**
+   * Replaces the current queue with the given queue on all matched elements.
+   */
+  public GQueryQueue queue(Queue<?> queue) {
+    for (Element e : elements()) {
+      replacequeue(e, queue);
+    }
+    return this;
+  }
+
+  protected String getQueueType() {
+    return "GQueryQueue_" + this.getClass().getName(); 
+  }
+
+  private void dequeue(Element elem) {
+    Queue<?> q = queue(elem, null);
+    if (q != null) {
+      q.poll();
+      Object f = q.peek();
+      if (f != null) {
+        if (f instanceof Function) {
+          ((Function)f).f(elem);
+        }
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private <S> Queue<S> queue(Element elem, S func) {
+    if (elem != null) {
+      Queue<S> q = (Queue<S>) data(elem, getQueueType(), null);
+      if (q == null) {
+        q = (Queue<S>) data(elem, getQueueType(), new LinkedList<S>());
+      }
+      if (func != null) {
+        q.add(func);
+      }
+      if (q.size() == 1 && func != null) {
+        if (func instanceof Function) {
+          ((Function)func).f(elem);
+        }
+      }
+      return q;
+    }
+    return null;
+  }
+  
+  private void replacequeue(Element elem, Queue<?> queue) {
+    if (elem != null) {
+      data(elem, getQueueType(), queue);
+    }
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java
new file mode 100644 (file)
index 0000000..1b037f9
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.JSArray;
+import com.google.gwt.query.client.Plugin;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.plugins.ClipAnimation.Action;
+import com.google.gwt.query.client.plugins.ClipAnimation.Direction;
+import com.google.gwt.query.client.plugins.PropertiesAnimation.Easing;
+import com.google.gwt.query.client.LazyBase;
+
+public interface LazyEffects<T> extends LazyBase<T>{
+
+  /**
+   * The animate() method allows us to create animation effects on any numeric CSS property. 
+   * The only required parameter is a map of CSS properties. 
+   * This map is similar to the one that can be sent to the .css() method, 
+   * except that the range of properties is more restrictive.
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. 
+   * (For example, width, height, or left can be animated but background-color cannot be.) 
+   * Property values are treated as a number of pixels unless otherwise specified.
+   *  The units em and % can be specified where applicable.
+   *  
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. 
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= 
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number 
+   *  from the current value of the property.
+   */  
+  LazyEffects<T> animate(Properties p, int duration, Easing easing, Function... funcs);
+
+  /**
+   * The animate() method allows us to create animation effects on any numeric CSS property. 
+   * The only required parameter is a map of CSS properties. 
+   * This map is similar to the one that can be sent to the .css() method, 
+   * except that the range of properties is more restrictive.
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. 
+   * (For example, width, height, or left can be animated but background-color cannot be.) 
+   * Property values are treated as a number of pixels unless otherwise specified.
+   *  The units em and % can be specified where applicable.
+   *  
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. 
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= 
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number 
+   *  from the current value of the property.
+   */
+  LazyEffects<T> animate(String prop, Function... funcs);
+
+  /**
+   * The animate() method allows us to create animation effects on any numeric CSS property. 
+   * The only required parameter is a map of CSS properties. 
+   * This map is similar to the one that can be sent to the .css() method, 
+   * except that the range of properties is more restrictive.
+   * All animated properties should be numeric, non-numeric cannot be animated using basic functionality. 
+   * (For example, width, height, or left can be animated but background-color cannot be.) 
+   * Property values are treated as a number of pixels unless otherwise specified.
+   *  The units em and % can be specified where applicable.
+   *  
+   *  In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. 
+   *  These shortcuts allow for custom hiding and showing animations that take into account the display type of the element.
+   *  Animated properties can also be relative. If a value is supplied with a leading += or -= 
+   *  sequence of characters, then the target value is computed by adding or subtracting the given number 
+   *  from the current value of the property.
+   */  
+  LazyEffects<T> animate(String prop, int duration, Function... funcs);
+
+  /**
+   * Animate the set of matched elements using the clip property.
+   * It is possible to show or hide a set of elements, 
+   * specify the direction of the animation and the start corner of the effect.
+   * Finally it executes the set of functions passed as arguments.
+   */
+  LazyEffects<T> clip(ClipAnimation.Action a, ClipAnimation.Corner c, ClipAnimation.Direction d, Function... f);
+
+  /**
+   * Animate the set of matched elements using the clip property.
+   * It is possible to show or hide a set of elements, 
+   * specify the direction of the animation and the start corner of the effect.
+   * Finally it executes the set of functions passed as arguments.
+   */
+  LazyEffects<T> clip(ClipAnimation.Action a, ClipAnimation.Corner c, ClipAnimation.Direction d, int duration, Function... f);
+
+  /**
+   * Animate the set of matched elements using the clip property.
+   * It is possible to show or hide a set of elements, 
+   * specify the direction of the animation and the start corner of the effect.
+   * Finally it executes the set of functions passed as arguments.
+   */
+  LazyEffects<T> clip(ClipAnimation.Action a, ClipAnimation.Corner c, Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the center to the perimeter.
+   */
+  LazyEffects<T> clipAppear(Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the center to the perimeter.
+   */
+  LazyEffects<T> clipAppear(int millisecs, Function... f);
+
+  /**
+   * Hide all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the perimeter to the center.
+   */
+  LazyEffects<T> clipDisappear(Function... f);
+
+  /**
+   * Hide all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the perimeter to the center.
+   */
+  LazyEffects<T> clipDisappear(int millisecs, Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the top to the bottom.
+   */
+  LazyEffects<T> clipDown(Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the top to the bottom.
+   */
+  LazyEffects<T> clipDown(int millisecs, Function... f);
+
+  /**
+   * Hide all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the bottom to the top.
+   */
+  LazyEffects<T> clipUp(Function... f);
+
+  /**
+   * Hide all matched elements by adjusting the clip property firing an
+   * optional callback after completion.
+   * The effect goes from the bottom to the top.
+   */
+  LazyEffects<T> clipUp(int millisecs, Function... f);
+
+  /**
+   * Fade in all matched elements by adjusting their opacity and firing an
+   * optional callback after completion. Only the opacity is adjusted for this
+   * animation, meaning that all of the matched elements should already have
+   * some form of height and width associated with them.
+   */  
+  LazyEffects<T> fadeIn(Function... f);
+
+  /**
+   * Fade in all matched elements by adjusting their opacity and firing an
+   * optional callback after completion. Only the opacity is adjusted for this
+   * animation, meaning that all of the matched elements should already have
+   * some form of height and width associated with them.
+   */
+  LazyEffects<T> fadeIn(int millisecs, Function... f);
+
+  /**
+   * Fade out all matched elements by adjusting their opacity to 0, then setting
+   * display to "none" and firing an optional callback after completion. Only
+   * the opacity is adjusted for this animation, meaning that all of the matched
+   * elements should already have some form of height and width associated with
+   * them.
+   */  
+  LazyEffects<T> fadeOut(Function... f);
+
+  /**
+   * Fade out all matched elements by adjusting their opacity to 0, then setting
+   * display to "none" and firing an optional callback after completion. Only
+   * the opacity is adjusted for this animation, meaning that all of the matched
+   * elements should already have some form of height and width associated with
+   * them.
+   */  
+  LazyEffects<T> fadeOut(int millisecs, Function... f);
+
+  /**
+   * Fade the opacity of all matched elements to a specified opacity and firing
+   * an optional callback after completion. Only the opacity is adjusted for
+   * this animation, meaning that all of the matched elements should already
+   * have some form of height and width associated with them.
+   */
+  LazyEffects<T> fadeTo(int millisecs, double opacity, Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting their height and firing an
+   * optional callback after completion.
+   */
+  LazyEffects<T> slideDown(Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting their height and firing an
+   * optional callback after completion.
+   */
+  LazyEffects<T> slideDown(int millisecs, Function... f);
+
+  /**
+   * Hide all matched elements by adjusting their width and firing an optional
+   * callback after completion.
+   */
+  LazyEffects<T> slideLeft(Function... f);
+
+  /**
+   * Hide all matched elements by adjusting their width and firing an optional
+   * callback after completion.
+   */
+  LazyEffects<T> slideLeft(int millisecs, Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting their width and firing an
+   * optional callback after completion.
+   */
+  LazyEffects<T> slideRight(Function... f);
+
+  /**
+   * Reveal all matched elements by adjusting their width and firing an
+   * optional callback after completion.
+   */
+  LazyEffects<T> slideRight(int millisecs, Function... f);
+
+  /**
+   * Toggle the visibility of all matched elements by adjusting their height and
+   * firing an optional callback after completion. Only the height is adjusted
+   * for this animation, causing all matched elements to be hidden or shown in a
+   * "sliding" manner
+   */  
+  LazyEffects<T> slideToggle(int millisecs, Function... f);
+
+  /**
+   * Hide all matched elements by adjusting their height and firing an optional
+   * callback after completion.
+   */
+  LazyEffects<T> slideUp(Function... f);
+
+  /**
+   * Hide all matched elements by adjusting their height and firing an optional
+   * callback after completion.
+   */
+  LazyEffects<T> slideUp(int millisecs, Function... f);
+
+  /**
+   * Toggle displaying each of the set of matched elements.
+   */
+  LazyEffects<T> toggle();
+
+  /**
+   * Toggle displaying each of the set of matched elements.
+   */
+  LazyEffects<T> toggle(int millisecs, Function... f);
+
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java
new file mode 100644 (file)
index 0000000..71e7950
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.plugins;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.JSArray;
+import com.google.gwt.query.client.Plugin;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.query.client.LazyBase;
+
+public interface LazyEvents<T> extends LazyBase<T>{
+
+  /**
+   * Binds a set of handlers to a particular Event for each matched element.
+   * 
+   * The event handlers are passed as Functions that you can use to prevent
+   * default behavior. To stop both default action and event bubbling, the
+   * function event handler has to return false.
+   * 
+   * You can pass an additional Object data to your Function as the second
+   * parameter
+   * 
+   */
+  LazyEvents<T> bind(int eventbits, Object data, Function...funcs);
+
+  /**
+   * Binds a handler to a particular Event (like Event.ONCLICK) for each matched
+   * element. The handler is executed only once for each element.
+   *
+   * The event handler is passed as a Function that you can use to prevent
+   * default behavior. To stop both default action and event bubbling, the
+   * function event handler has to return false.
+   *
+   * You can pass an additional Object data to your Function as the second
+   * parameter
+   */  
+  LazyEvents<T> one(int eventbits, Object data, Function f);
+
+  /**
+   * Execute all handlers and behaviors attached to the matched elements for the given event types.
+   * 
+   * Different event types can be passed joining these using the or bit wise operator.
+   * 
+   * For keyboard events you can pass a second parameter which represents 
+   * the key-code of the pushed key. 
+   * 
+   * Example: fire(Event.ONCLICK | Event.ONFOCUS)
+   * Example: fire(Event.ONKEYDOWN. 'a');
+   */
+  LazyEvents<T> trigger(int eventbits, int... keys);
+
+  /**
+   * Trigger a html event in all matched elements.
+   * 
+   * @param htmlEvent
+   *    An string representing the html event desired 
+   */
+  LazyEvents<T> triggerHtmlEvent(String htmlEvent);
+
+  /**
+   * Removes all handlers, that matches the events bits passed, from each
+   * element.
+   * 
+   * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER)
+   */
+  LazyEvents<T> unbind(int eventbits);
+
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/PropertiesAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/PropertiesAnimation.java
new file mode 100755 (executable)
index 0000000..08e048a
--- /dev/null
@@ -0,0 +1,166 @@
+/*\r
+ * Copyright 2009 Google Inc.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.client.plugins;\r
+\r
+import java.util.ArrayList;\r
+\r
+import com.google.gwt.animation.client.Animation;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.query.client.Function;\r
+import com.google.gwt.query.client.JSArray;\r
+import com.google.gwt.query.client.Properties;\r
+import com.google.gwt.query.client.Regexp;\r
+\r
+/**\r
+ *  Animation effects on any numeric CSS property. \r
+ */\r
+public class PropertiesAnimation extends Animation {\r
+\r
+  /**\r
+   * Easing method to use.\r
+   */\r
+  public enum Easing {\r
+    LINEAR, SWING\r
+  }\r
+  \r
+  private static class Effect {\r
+    private static Regexp nonPx = new Regexp(\r
+        "z-?index|font-?weight|opacity|zoom|line-?height", "i");\r
+\r
+    public String attr;\r
+    public double end;\r
+    public String old;\r
+    public double start;\r
+    public String unit;\r
+    public String value;\r
+\r
+    Effect(String attr, String value, String old, double start, double end,\r
+        String unit) {\r
+      this.attr = attr;\r
+      this.value = value;\r
+      this.old = old;\r
+      this.start = start;\r
+      this.end = end;\r
+      this.unit = nonPx.test(attr) ? "" : unit == null ? "px" : unit;\r
+    }\r
+\r
+    public String getVal(double progress) {\r
+      double ret = (start + ((end - start) * progress));\r
+      return ("px".equals(unit) ? ((int) ret) : ret) + unit;\r
+    }\r
+  }\r
+\r
+  private static final String[] attrsToSave = new String[] { "overflow",\r
+      "visivility", "white-space" };\r
+  private Element e;\r
+  private Easing easing = Easing.SWING;\r
+  private ArrayList<Effect> effects = new ArrayList<Effect>();\r
+  private Function[] funcs;\r
+  private Effects g;\r
+\r
+  private Properties prps;\r
+\r
+  public PropertiesAnimation(Easing easing, Element elem, Properties p,\r
+      Function... funcs) {\r
+    this.easing = easing;\r
+    this.e = elem;\r
+    this.funcs = funcs;\r
+    this.prps = p;\r
+    g = Effects.$(e).as(Effects.Effects);\r
+  }\r
+\r
+  @Override\r
+  public void onCancel() {\r
+    onComplete();\r
+  }\r
+\r
+  @Override\r
+  public void onComplete() {\r
+    super.onComplete();\r
+    g.restoreCssAttrs(attrsToSave);\r
+    for (Effect l : effects) {\r
+      if ("hide".equals(l.value)) {\r
+        g.hide();\r
+        g.css(l.attr, l.old);\r
+      } else if ("show".equals(l.value)) {\r
+        g.show();\r
+        g.css(l.attr, l.old);\r
+      }\r
+    }\r
+    g.each(funcs);\r
+    g.dequeue();\r
+  }\r
+\r
+  @Override\r
+  public void onStart() {\r
+    boolean hidden = !g.visible();\r
+    g.show();\r
+    for (String key : prps.keys()) {\r
+      String val = prps.get(key);\r
+      if ("toggle".equals(val)) {\r
+        val = hidden ? "show" : "hide";\r
+      }\r
+      if (("top".equals(key) || "left".equals(key))\r
+          && !"absolute".equalsIgnoreCase(g.css("position"))) {\r
+        g.css("position", "relative");\r
+      }\r
+\r
+      JSArray parts = new Regexp("^([+-]=)?([0-9+-.]+)(.*)?$").match(val);\r
+      String unit = parts != null ? parts.getStr(3) : "";\r
+      double start = Effects.cur(e, key);\r
+      double end = start;\r
+      if (parts != null) {\r
+        end = Double.parseDouble(parts.getStr(2));\r
+        if (parts.getStr(1) != null) {\r
+          end = (("-=".equals(parts.getStr(1)) ? -1 : 1) * end) + start;\r
+        }\r
+      } else if ("show".equals(val)) {\r
+        if (!hidden) {\r
+          return;\r
+        }\r
+        start = 0;\r
+      } else if ("hide".equals(val)) {\r
+        if (hidden) {\r
+          return;\r
+        }\r
+        end = 0;\r
+      }\r
+      effects.add(new Effect(key, val, g.css(key), start, end, unit));\r
+    }\r
+    g.saveCssAttrs(attrsToSave);\r
+    g.css("overflow", "hidden");\r
+    g.css("visivility", "visible");\r
+    g.css("white-space", "nowrap");\r
+    super.onStart();\r
+  }\r
+\r
+  @Override\r
+  public void onUpdate(double progress) {\r
+    for (Effect fx : effects) {\r
+      g.css(fx.attr, fx.getVal(progress));\r
+    }\r
+  }\r
+\r
+  @Override\r
+  protected double interpolate(double progress) {\r
+    if (easing == Easing.SWING) {\r
+      return super.interpolate(progress);\r
+    } else {\r
+      return progress;\r
+    }\r
+  }\r
+\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java
deleted file mode 100644 (file)
index ae8aa91..0000000
+++ /dev/null
@@ -1,527 +0,0 @@
-package com.google.gwt.query.client.plugins;
-
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.query.client.Function;
-import com.google.gwt.query.client.GQuery;
-import com.google.gwt.query.client.JSArray;
-import com.google.gwt.query.client.Plugin;
-import com.google.gwt.query.client.Properties;
-import com.google.gwt.query.client.Regexp;
-import com.google.gwt.query.client.SelectorEngine;
-import com.google.gwt.user.client.Event;
-
-/**
- * Star Rating plugin.
- */
-public class Ratings extends GQuery {
-
-  private static int calls;
-
-  /**
-   * Used to register the plugin.
-   */
-  private static class RatingsPlugin implements Plugin<Ratings> {
-
-    public Ratings init(GQuery gq) {
-      return new Ratings(gq.get());
-    }
-  }
-
-  public static final Class<Ratings> Ratings = Ratings.class;
-
-  static {
-    GQuery.registerPlugin(Ratings.class, new RatingsPlugin());
-  }
-
-  public Ratings(Element element) {
-    super(element);
-  }
-
-  public Ratings(JSArray elements) {
-    super(elements);
-  }
-
-  public Ratings(NodeList<Element> list) {
-    super(list);
-  }
-
-  public Ratings rating() {
-    if (size() == 0) {
-      return this;
-    }
-    calls++;
-    not(".star-rating-applied").addClass("star-rating-applied");
-    Control control = null;
-    for (Element e : elements()) {
-      GQuery input = $(e);
-      String eid = SelectorEngine
-          .or(e.getPropertyString("name"), "unnamed-rating")
-          .replaceAll("\\[|\\]", "_").replaceAll("^\\_+|\\_$", "");
-      GQuery context = $(getContext(e));
-      Raters raters = (Raters) context.data("rating");
-      if (raters == null || raters.getCalls() != calls) {
-        raters = new Raters(0, calls);
-      }
-      GQuery rater = raters.get(eid);
-      if (rater != null) {
-        control = (Control) rater.data("rating");
-      }
-      if (rater != null && control != null) {
-        control.bumpCount();
-      } else {
-        control = new Control();
-        control.setSerial(raters.bumpCount());
-        Properties metadata = getMetaData(input.get(0).getClassName());
-        if (metadata != null && metadata.defined("split")) {
-          control.setSplit(metadata.getInt("split"));
-        }
-        // create rating element
-        rater = $("<span class=\"star-rating-control\"/>");
-        input.before(rater);
-
-        // Mark element for initialization (once all stars are ready)
-        rater.addClass("rating-to-be-drawn");
-
-        // Accept readOnly setting from 'disabled' property
-        if (SelectorEngine.truth(input.attr("disabled"))) {
-          control.setReadOnly(true);
-        }
-
-        // Create 'cancel' button
-        GQuery query = $(
-            "<div class=\"rating-cancel\"><a title=\"" + control.cancel + "\">"
-                + control.cancelValue + "</a></div>").
-            mouseover(new Function() {
-              @Override
-              public boolean f(Event e) {
-                $(e).as(Ratings).drain();
-                $(e).addClass("star-rating-hover");
-                return true;
-              }
-            }).
-            mouseout(new Function() {
-              @Override
-              public boolean f(Event e) {
-                $(e).as(Ratings).draw();
-                $(e).removeClass("star-rating-hover");
-                return true;
-              }
-            }).
-            click(new Function() {
-              @Override
-              public boolean f(Event e) {
-                $(e).as(Ratings).selectStar();
-                return true;
-              }
-            });
-        control.cancelButton = query;
-        query.data("rating", control);
-        rater.append(query);
-      }
-      // insert rating star
-      GQuery star = $("<div class=\"star-rating rater-" + control.getSerial()
-          + "\"><a title=\""
-          + (SelectorEngine.or(e.getTitle(), e.getPropertyString("value")))
-          + "\">" + e.getPropertyString("value") + "</a></div>");
-      rater.append(star);
-
-      // inherit attributes from input element
-      if (e.getId() != null) {
-        star.attr("id", e.getId());
-      }
-      if (e.getClassName() != null) {
-        star.addClass(e.getClassName());
-      }
-
-      // Half-stars?
-      if (control.isHalf()) {
-        control.setSplit(2);
-      }
-
-      // Prepare division control
-      if (control.getSplit() > 0) {
-        int stw = star.width();
-        if (stw == 0) {
-          stw = control.getStarWidth();
-        }
-
-        int spi = (control.getCount() % control.getSplit());
-        int spw = (int) Math.floor(stw / control.getSplit());
-
-        star.width(spw).find("a").css("margin-left", "-" + (spi * spw) + "px");
-      }
-      ;
-
-      // readOnly?
-      if (control.isReadOnly())//{ //save a byte!
-      // Mark star as readOnly so user can customize display
-      {
-        star.addClass("star-rating-readonly");
-      }
-      //}  //save a byte!
-      else//{ //save a byte!
-      // Enable hover css effects
-      {
-        star.addClass("star-rating-live")
-            // Attach mouse events
-            .mouseover(new Function() {
-              @Override
-              public boolean f(Event e) {
-                $(e).as(Ratings).fill();
-                $(e).as(Ratings).focusStar();
-                return true;
-              }
-            }).mouseout(new Function() {
-          @Override
-          public boolean f(Event e) {
-            $(e).as(Ratings).draw();
-            $(e).as(Ratings).blurStar();
-
-            return true;
-          }
-        }).click(new Function() {
-          @Override
-          public boolean f(Event e) {
-            $(e).as(Ratings).selectStar();
-            return true;
-          }
-        });
-      }
-      // set current selection
-      if (e.getPropertyBoolean("checked")) {
-        control.setCurrent(star);
-      }
-
-      // hide input element
-      input.hide();
-
-      // backward compatibility, form element to plugin
-      input.change(new Function() {
-        @Override
-        public boolean f(Event e) {
-          $(e).as(Ratings).selectStar();
-          return true;
-        }
-      });
-
-      // attach reference to star to input element and vice-versa
-      star.data("rating.input", input.data("rating.star", star));
-
-      // store control information in form (or body when form not available)
-      control.addStar(star.get(0));
-      control.addInput(input.get(0));
-      control.setRater(rater);
-      raters.put(eid, rater);
-      control.setContext(context);
-
-      input.data("rating", control);
-      rater.data("rating", control);
-      star.data("rating", control);
-      context.data("rating", raters);
-    }
-    // Initialize ratings (first draw)
-    $(".rating-to-be-drawn").as(Ratings).draw()
-        .removeClass("rating-to-be-drawn");
-
-    return this;
-  }
-
-  private Properties getMetaData(String className) {
-    if (className.indexOf("{") == -1) {
-      return Properties.createObject().cast();
-    }
-    Regexp re = new Regexp("{(.*)}");
-    JSArray match = re.exec(className);
-    if (match != null && match.size() > 1) {
-      return Properties.create(match.getStr(1));
-    }
-    return Properties.createObject().cast();
-  }
-
-  public Ratings blurStar() {
-    return this;
-  }
-
-  public Ratings focusStar() {
-    Control control = (Control) this.data("rating");
-    if (control == null) {
-      return this;
-    }
-//   GQuery input = data("rating.input");
-    return this;
-  }
-
-  public Ratings fill() {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-
-      // Reset all stars and highlight them up to this element
-      self.as(Ratings).drain();
-      self.prevAll().andSelf().filter(".rater-" + control.getSerial())
-          .addClass("star-rating-hover");
-
-    }
-
-    return this;
-  }
-
-  public Ratings draw() {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-
-      // Clear all stars
-      self.as(Ratings).drain();
-      // Set control value
-      if (control.getCurrent() != null) {
-        ((GQuery) control.current.data("rating.input"))
-            .attr("checked", "checked");
-        control.current.prevAll().andSelf().filter(".rater-" + control.serial)
-            .addClass("star-rating-on");
-      } else {
-        $(control.getInputs()).removeAttr("checked");
-      }
-
-      // Show/hide 'cancel' button
-//                     control.cancel[control.readOnly || control.required?'hide':'show']();
-      // Add/remove read-only classes to remove hand pointer
-      self.siblings().toggleClass("star-rating-readonly", control.isReadOnly());
-    }
-
-    return this;
-  }
-
-  public Ratings selectStar(int value) {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-
-      control.setCurrent(null);
-      $(control.getStar(value)).as(Ratings).selectStar();
-    }
-    return this;
-  }
-
-  public Ratings selectStar() {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-
-      control.current = self.get(0).getTagName().equalsIgnoreCase("INPUT")
-          ? (GQuery) self.data("rating.star")
-          : self.is(".rater-" + control.getSerial()) ? this : null;
-
-      // Update rating control state
-      self.data("rating", control);
-      // Update display
-      self.as(Ratings).draw();
-      // find data for event
-      GQuery input = $(control.current != null ? (GQuery) control.current
-          .data("rating.input") : null);
-      // click callback, as requested here: http://plugins.jquery.com/node/1655
-//                     if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
-    }
-
-    return this;
-  }
-
-  private Control nullControlIfShouldSkipStar(GQuery q) {
-    Control control = (Control) q.data("rating");
-    if (control == null) {
-      return null;
-    }
-    // do not execute when control is in read-only mode
-    if (control.isReadOnly()) {
-      return null;
-    }
-    return control;
-  }
-
-  public Ratings selectStar(String value) {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-      control.setCurrent(null);
-      NodeList<Element> stars = control.getStars();
-      for (int i = 0; i < stars.getLength(); i++) {
-        String val = ((GQuery) $(stars.getItem(i)).data("rating.input")).val();
-        if (val != null && val.equals(value)) {
-          $(stars.getItem(i)).as(Ratings).selectStar();
-        }
-      }
-    }
-    return this;
-  }
-
-  public Ratings drain() {
-    for (Element e : elements()) {
-      GQuery self = $(e);
-      Control control = nullControlIfShouldSkipStar(self);
-      if (control == null) {
-        continue;
-      }
-      control.rater.children().filter(".rater-" + control.getSerial())
-          .removeClass("star-rating-on").removeClass("star-rating-hover");
-    }
-    return this;
-  }
-
-  public static class Control {
-
-    private int count;
-
-    private String cancel = "Cancel Rating";
-
-    private String cancelValue = "";
-
-    private int split = 0;
-
-    private int starWidth = 16;
-
-    private int serial;
-
-    private boolean readOnly;
-
-    private boolean half;
-
-    private GQuery current;
-
-    private GQuery context;
-
-    private JsArray<Element> stars = JsArray.createArray().cast();
-
-    private JsArray<Element> inputs = JsArray.createArray().cast();
-
-    private GQuery rater;
-
-    public GQuery cancelButton;
-
-    public int bumpCount() {
-      return count++;
-    }
-
-    public void setSerial(int serial) {
-      this.serial = serial;
-    }
-
-    public void setReadOnly(boolean readOnly) {
-      this.readOnly = readOnly;
-    }
-
-    public int getSerial() {
-      return serial;
-    }
-
-    public boolean isHalf() {
-      return half;
-    }
-
-    public void setSplit(int split) {
-      this.split = split;
-    }
-
-    public int getSplit() {
-      return split;
-    }
-
-    public int getStarWidth() {
-      return starWidth;
-    }
-
-    public int getCount() {
-      return count;
-    }
-
-    public boolean isReadOnly() {
-      return readOnly;
-    }
-
-    public void setCurrent(GQuery current) {
-      this.current = current;
-    }
-
-    public void setContext(GQuery context) {
-      this.context = context;
-    }
-
-    public void addStar(Element element) {
-      stars.set(stars.length(), element);
-    }
-
-    public void addInput(Element element) {
-      inputs.set(inputs.length(), element);
-    }
-
-    public void setRater(GQuery rater) {
-      this.rater = rater;
-    }
-
-    public Object getCurrent() {
-      return current;
-    }
-
-    public NodeList<Element> getInputs() {
-      return inputs.cast();
-    }
-
-    public Element getStar(int value) {
-      return stars.get(value);
-    }
-
-    public NodeList<Element> getStars() {
-      return stars.cast();
-    }
-  }
-
-  public static class Raters {
-
-    private int calls;
-
-    private int count;
-
-    private GQuery.DataCache cache = GQuery.DataCache.createObject().cast();
-
-    public Raters(int count, int calls) {
-      this.count = count;
-      this.calls = calls;
-    }
-
-    public int getCalls() {
-      return calls;
-    }
-
-    public GQuery get(String eid) {
-      return (GQuery) cache.getObject(eid);
-    }
-
-    public void put(String eid, GQuery q) {
-      cache.put(eid, q);
-    }
-
-    public int bumpCount() {
-      return count++;
-    }
-  }
-
-  private static native Element getContext(Element e) /*-{
-    return this.form || $doc.body;
-  }-*/;
-}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Widgets.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Widgets.java
deleted file mode 100644 (file)
index 377497c..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.google.gwt.query.client.plugins;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.query.client.GQuery;
-import com.google.gwt.query.client.JSArray;
-import com.google.gwt.query.client.Plugin;
-import com.google.gwt.user.client.ui.Button;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Experimental Gwt Query plugin for integrating Gwt Widgets.
- */
-public class Widgets extends GQuery {
-
-  /**
-   * Used to register the plugin.
-   */
-  private static class WidgetsPlugin implements Plugin<Widgets> {
-
-    public Widgets init(GQuery gq) {
-      return new Widgets(gq.get());
-    }
-  }
-
-  public static final Class<Widgets> Widgets = Widgets.class;
-
-  static {
-    GQuery.registerPlugin(Widgets.class, new WidgetsPlugin());
-  }
-
-  public Widgets(Element element) {
-    super(element);
-  }
-
-  public Widgets(JSArray elements) {
-    super(elements);
-  }
-
-  public Widgets(NodeList list) {
-    super(list);
-  }
-
-  /**
-   * Create a builder capable of instantiating a GWT Button object over every
-   * matched element. Call end() to execute builder and return to the current
-   * query object.
-   *
-   * @return a ButtonBuilder
-   */
-  public ButtonBuilder button() {
-    return new ButtonBuilder("*");
-  }
-
-  public class ButtonBuilder {
-
-    private String selector;
-
-    private String label = null;
-
-    private String labelSelector = null;
-
-    private Collection<ClickHandler> handlers = new ArrayList<ClickHandler>();
-
-    public ButtonBuilder(String selector) {
-      this.selector = selector;
-    }
-
-    public ButtonBuilder labelQuery(String label) {
-      this.labelSelector = label;
-      return this;
-    }
-
-    public ButtonBuilder label(String label) {
-      this.label = label;
-      return this;
-    }
-
-    public ButtonBuilder addClickHandler(ClickHandler handler) {
-      handlers.add(handler);
-      return this;
-    }
-
-    public Widgets end() {
-      for (Element e : elements()) {
-        Button b = null;
-        if ("button".equalsIgnoreCase(e.getTagName())) {
-          b = Button.wrap(e);
-        } else {
-          Element bElt = $("<button name='button' value='Click Me'>").get(0);
-          $(e).hide().before(bElt);
-          b = Button.wrap(bElt);
-        }
-
-        b.setText(label != null ? label
-            : (labelSelector == null ? $(e) : $(labelSelector, e)).text());
-        for (ClickHandler handler : handlers) {
-          b.addClickHandler(handler);
-        }
-      }
-      return Widgets.this;
-    }
-  }
-}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/public/delete.gif b/gwtquery-core/src/main/java/com/google/gwt/query/public/delete.gif
deleted file mode 100644 (file)
index 43c6ca8..0000000
Binary files a/gwtquery-core/src/main/java/com/google/gwt/query/public/delete.gif and /dev/null differ
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css b/gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css
deleted file mode 100644 (file)
index deb7d06..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */
-div.rating-cancel,div.star-rating{float:left;width:17px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden}
-div.rating-cancel,div.rating-cancel a{background:url(delete.gif) no-repeat 0 -16px}
-div.star-rating,div.star-rating a{background:url(star.gif) no-repeat 0 0px}
-div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0}
-div.star-rating-on a{background-position:0 -16px!important}
-div.star-rating-hover a{background-position:0 -32px}
-/* Read Only CSS */
-div.star-rating-readonly a{cursor:default !important}
-/* Partial Star CSS */
-div.star-rating{background:transparent!important;overflow:hidden!important}
-/* END jQuery.Rating Plugin CSS */
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/public/star.gif b/gwtquery-core/src/main/java/com/google/gwt/query/public/star.gif
deleted file mode 100644 (file)
index d0948a7..0000000
Binary files a/gwtquery-core/src/main/java/com/google/gwt/query/public/star.gif and /dev/null differ
index 82ec76946e5a63802555b537e9a15809acc32441..c1d240b6c8938fb32ee6d50c9d5a56f82e741d61 100644 (file)
@@ -588,4 +588,33 @@ public class GQueryCoreTest extends GWTTestCase {
     assertHtmlEquals(expected, $(e).html());
   }
   
+  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"));
+    sectB.hide();
+    assertEquals("none", sectB.css("display"));
+    
+    // show()
+    sectA.show();
+    assertEquals("inline", sectA.css("display"));
+    sectB.show();
+    assertEquals("", sectB.css("display"));
+    
+    // toggle()
+    assertEquals("", sectC.css("display"));
+    sectC.toggle();
+    assertEquals("none", sectC.css("display"));
+    sectC.toggle();
+    assertEquals("block", sectC.css("display"));
+  }
+  
 }
index 333092c10cf4071fe55b5870299cb3bae1cc8daf..d670627e32dd4f42f057f9cb0c652cdb8682be4c 100644 (file)
  */
 package com.google.gwt.query.client;
 
-import static com.google.gwt.query.client.Effects.Effects;
-import static com.google.gwt.query.client.Effects.Easing.LINEAR;
 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.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;
@@ -51,31 +51,16 @@ public class GQueryEffectsTest extends GWTTestCase {
     }
   }
 
-  public void testEffects() {
+  public void testFade() {
     $(e)
-        .html(
-            "<p id='id1'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
+    .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"));
-
-    // show()
-    sectB.show();
-    assertEquals("", sectB.css("display"));
-
-    // toggle()
-    assertEquals("", sectC.css("display"));
-    sectC.toggle();
-    assertEquals("none", sectC.css("display"));
-    sectC.toggle();
-    assertEquals("", sectC.css("display"));
-
+    
     // fadeIn() & fadeOut() are tested with delayed assertions
+    sectA.hide();
     sectA.fadeIn(2000);
     sectB.fadeOut(2000);
 
@@ -98,7 +83,7 @@ public class GQueryEffectsTest extends GWTTestCase {
     };
     Timer timerMidTime = new Timer() {
       public void run() {
-        assertEquals("", sectA.css("display"));
+        assertEquals("inline", sectA.css("display"));
         assertEquals("", sectB.css("display"));
         double o = Double.valueOf(sectA.css("opacity"));
         assertTrue(
@@ -112,30 +97,30 @@ public class GQueryEffectsTest extends GWTTestCase {
     };
     Timer timerLongTime = new Timer() {
       public void run() {
-        assertEquals("", sectA.css("display"));
+        assertEquals("inline", sectA.css("display"));
         assertEquals("none", sectB.css("display"));
         // 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);
-  }
+    timerLongTime.schedule(2200);    
+  }  
 
   public void testEffectsShouldBeQueued() {
     $(e).html("<p id='idtest'>Content 1</p></p>");
 
     final GQuery g = $("#idtest").css("position", "absolute");
     final Offset o = g.offset();
-    g.as(Effects).
-        animate($$("left: '+=100'"), 400, LINEAR, null).
-        animate($$("top: '+=100'"), 400, LINEAR, null).
-        animate($$("left: '-=100'"), 400, LINEAR, null).
-        animate($$("top: '-=100'"), 400, LINEAR, null);
-
+    g.as(Effects.Effects).
+        animate($$("left: '+=100'"), 400, Easing.LINEAR).
+        animate($$("top: '+=100'"), 400, Easing.LINEAR).
+        animate($$("left: '-=100'"), 400, Easing.LINEAR).
+        animate($$("top: '-=100'"), 400, Easing.LINEAR);
     
     // Configure the max duration for this test
     delayTestFinish(400 * 4);
@@ -143,26 +128,26 @@ public class GQueryEffectsTest extends GWTTestCase {
     // each timer calls the next one
     final Timer timer1 = new Timer() {
       public void run() {
-        assertPosition(g, o.add(99, 0), o.add(1, 0));
+        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(100, 99), o.add(100, 1));
+        assertPosition(g, o.add(99, 100), o.add(1, 100));
         timer1.schedule(400);
       }
     };
     final Timer timer3 = new Timer() {
       public void run() {
-        assertPosition(g, o.add(1, 100), o.add(99, 100));
+        assertPosition(g, o.add(100, 1), o.add(100, 99));
         timer2.schedule(400);
       }
     };
     final Timer timer4 = new Timer() {
       public void run() {
-        assertPosition(g, o.add(0, 1), o.add(0, 99));
+        assertPosition(g, o.add(1, 0), o.add(99, 0));
         timer3.schedule(400);
       }
     };
index a5b2f366ac23a0b87c6552909576fc3fe0e24c55..d65b8125d6a55c3c512907c2b0da4cd196cd99df 100644 (file)
@@ -25,6 +25,7 @@ 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.plugins.Events;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.HTML;
index 86b9fb2ec3cb51a33d1fb266444f20c9540e518a..8cdc995bfd6f9622703080fc866f556a40348f2b 100644 (file)
@@ -17,10 +17,10 @@ package gwtquery.plugins.collapser;
 
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.query.client.Effects;
 import com.google.gwt.query.client.Function;
 import com.google.gwt.query.client.GQuery;
 import com.google.gwt.query.client.Plugin;
+import com.google.gwt.query.client.plugins.Effects;
 import com.google.gwt.user.client.Event;
 
 /**
index e6f38a1913288a9e8ecd02efb08d4551b8c041d1..cbaca98de41d9c6faee657cabdb522fe66032af1 100644 (file)
                     <logLevel>${gwt.loglevel}</logLevel>
                     <style>${gwt.outputstyle}</style>
                     <gwtVersion>${gwtversion}</gwtVersion>
+                    <soyc>true</soyc>
                     <modules>
-                        <module>
-                            gwtquery.samples.GwtQuerySample
-                        </module>
-                        <module>
-                            gwtquery.samples.GwtQueryBench
-                        </module>
-                        <module>
-                            gwtquery.samples.GwtQueryDemo
-                        </module>
-                        <module>
-                            gwtquery.samples.GwtQueryPlugin
-                        </module>
-                        <module>
-                            gwtquery.samples.GwtQueryWidgets
-                        </module>
-                        <module>
-                            gwtquery.samples.GwtQueryEffects
-                        </module>
+                        <module>gwtquery.samples.GwtQueryEffects</module>
+                        <module>gwtquery.samples.GwtQuerySample</module>
+                        <module>gwtquery.samples.GwtQueryBench</module>
+                        <module>gwtquery.samples.GwtQueryDemo</module>
+                        <module>gwtquery.samples.GwtQueryPlugin</module>
+                        <module>gwtquery.samples.GwtQueryWidgets</module>
                     </modules>
                 </configuration>
                 <executions>
                     </execution>
                 </executions>
             </plugin>
-
+            <plugin>
+              <artifactId>maven-clean-plugin</artifactId>
+              <configuration>
+                <filesets>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQueryBench</directory></fileset>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQueryDemo</directory></fileset>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQueryEffects</directory></fileset>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQueryPlugin</directory></fileset>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQuerySample</directory></fileset>
+                  <fileset><directory>src/main/webapp/gwtquery.samples.GwtQueryWidgets</directory></fileset>
+                  <fileset><directory>src/main/webapp/WEB-INF/classes</directory></fileset>
+                  <fileset><directory>tomcat</directory></fileset>
+                  <fileset><directory>www-test</directory></fileset>
+                  <fileset><directory>.gwt-tmp</directory></fileset>
+                </filesets>
+              </configuration>
+            </plugin>
         </plugins>
     </build>
 
index 056618e518f40a74f735f51c011b61ab51acb9c2..c1b76429be98be7c72c747d71d9fb513bad7d13a 100644 (file)
@@ -23,7 +23,7 @@ public class GwtQueryBenchModule implements EntryPoint {
 \r
   private static final String JQUERY = "jquery";\r
 \r
-  private static final String GDYNAMIC = "gwt";\r
+  private static final String GDYNAMIC = "dgwt";\r
 \r
   private static final String DOJO = "dojo";\r
 \r
@@ -34,13 +34,13 @@ public class GwtQueryBenchModule implements EntryPoint {
 \r
     final DeferredGQuery dg[] = m.getAllSelectors();\r
     HTML h = HTML.wrap(Document.get().getElementById("startrace"));\r
-    initResultsTable(dg, "GQuery", GCOMPILED, "jQuery"\r
+    initResultsTable(dg, "GQuery", GCOMPILED, "DGQuery", GDYNAMIC, "jQuery"\r
         /*"DOMAssistant 2.7" */, JQUERY, "Dojo", DOJO, "Prototype", PROTOTYPE);\r
 \r
     h.addClickHandler(new ClickHandler() {\r
       public void onClick(ClickEvent clickEvent) {\r
 \r
-        runBenchmarks(dg, new GQueryDynamicBenchmark(), new JQueryBenchmark(),\r
+        runBenchmarks(dg,new GQueryDynamicBenchmark(), new GQueryCompiledBenchmark(), new JQueryBenchmark(),\r
             new DojoBenchmark(), new PrototypeBenchmark());\r
       }\r
     });\r
index ac2679df2ed4439d9e7fc1d289b24c37ec5af3d5..20baa2ae2867ff6753b829aa74149480467a663d 100644 (file)
@@ -1,11 +1,9 @@
 package gwtquery.samples.client;\r
 \r
-import static com.google.gwt.query.client.Effects.Effects;\r
 import static com.google.gwt.query.client.GQuery.$;\r
 \r
 import com.google.gwt.core.client.EntryPoint;\r
 import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.dom.client.Document;\r
 import com.google.gwt.dom.client.Element;\r
 import com.google.gwt.dom.client.Node;\r
 import com.google.gwt.dom.client.NodeList;\r
@@ -13,6 +11,7 @@ import com.google.gwt.query.client.Function;
 import com.google.gwt.query.client.GQuery;\r
 import com.google.gwt.query.client.Selector;\r
 import com.google.gwt.query.client.Selectors;\r
+import com.google.gwt.query.client.plugins.Effects;\r
 import com.google.gwt.user.client.Event;\r
 \r
 /**\r
@@ -39,30 +38,30 @@ public class GwtQueryDemoModule implements EntryPoint {
   public void onModuleLoad() {\r
     // Ask GWT compiler to generate our interface\r
     final Slide s = GWT.create(Slide.class);\r
+    final GQuery slides = $(s.allSlides());\r
 \r
-    $(s.allSlides()).hide().eq(0).show();\r
-\r
-    // we initially hide all bullets\r
+    // we initially hide all slides and bullets\r
+    slides.hide().eq(0).as(Effects.Effects).clipAppear();\r
     $(s.allSlideBullets()).hide();\r
 \r
+\r
     // add onclick handler to body element\r
-    $(Document.get().getBody()).click(new Function() {\r
+    $(slides).click(new Function() {\r
       // two state variables to note current slide being shown\r
       // and current bullet\r
       int curSlide = 0;\r
       int curBullets = 0;\r
 \r
-      // query and store all slides, and bullets of current slide\r
-      GQuery slides = $(s.allSlides());\r
+      // query and store all bullets of current slide\r
       GQuery bullets = $(s.slideBulletsCtx(slides.get(curSlide)));\r
+      \r
       public boolean f(Event e) {\r
         // onclick, if not all bullets shown, show a bullet and increment\r
         if (curBullets < bullets.size()) {\r
-          bullets.eq(curBullets++).fadeIn();\r
+          bullets.eq(curBullets++).show();\r
         } else {\r
           // all bullets shown, hide them and current slide\r
           bullets.hide();\r
-          slides.eq(curSlide).as(Effects).hide();\r
           // move to next slide, checking for wrap around\r
           curSlide++;\r
           if (curSlide == slides.size()) {\r
@@ -71,7 +70,11 @@ public class GwtQueryDemoModule implements EntryPoint {
           curBullets = 0;\r
           // query for new set of bullets, and show next slide\r
           bullets = $(s.slideBulletsCtx(slides.get(curSlide)));\r
-          slides.eq(curSlide).show();\r
+          slides.eq(curSlide - 1).as(Effects.Effects).slideLeft(new Function() {\r
+            public void f(Element e) {\r
+              slides.eq(curSlide).as(Effects.Effects).clipAppear();\r
+            }\r
+          });\r
         }\r
         return true;\r
       }\r
index c393514c59e656f971dbac119dd26aea7c5eccf8..ca695fdb862ecdbfd5445cce503221dee9691bcd 100644 (file)
@@ -1,38 +1,97 @@
 package gwtquery.samples.client;\r
 \r
-import com.google.gwt.core.client.EntryPoint;\r
-import static com.google.gwt.query.client.Effects.Easing.LINEAR;\r
-import static com.google.gwt.query.client.Effects.Effects;\r
-import com.google.gwt.query.client.Function;\r
 import static com.google.gwt.query.client.GQuery.$;\r
 import static com.google.gwt.query.client.GQuery.$$;\r
 import static com.google.gwt.query.client.GQuery.lazy;\r
+\r
+import com.google.gwt.core.client.EntryPoint;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.query.client.Function;\r
+import com.google.gwt.query.client.plugins.Effects;\r
+import com.google.gwt.query.client.plugins.PropertiesAnimation.Easing;\r
 import com.google.gwt.user.client.Event;\r
 \r
 public class GwtQueryEffectsModule implements EntryPoint {\r
 \r
   public void onModuleLoad() {\r
-\r
-    $("div > div").\r
-        css("color", "blue").\r
-        hover(lazy().\r
-            css("color", "red").\r
-            done(), lazy().\r
-            css("color", "blue").\r
-            done());\r
+    $("div > div").css("color", "blue")\r
+    .hover(lazy().css("color", "red").done(),\r
+           lazy().css("color", "blue").done());\r
 \r
     $("div.outer > div").css("position", "relative").dblclick(new Function() {\r
       public boolean f(Event e) {\r
-        $("div.outer > div").as(Effects).\r
-            animate($$("left: '+=100'"), 400, LINEAR, null).\r
-            animate($$("top: '+=100'"), 400, LINEAR, null).\r
-            animate($$("left: '-=100'"), 400, LINEAR, null).\r
-            animate($$("top: '-=100'"), 400, LINEAR, null);\r
-\r
+         $("div.outer > div").as(Effects.Effects).\r
+         animate($$("left: '+=100'"), 400, Easing.LINEAR).\r
+         animate($$("top: '+=100'"), 400, Easing.LINEAR).\r
+         animate($$("left: '-=100'"), 400, Easing.LINEAR).\r
+         animate($$("top: '-=100'"), 400, Easing.LINEAR);\r
         return true;\r
       }\r
     });\r
     $(".note").click(lazy().fadeOut().done());\r
     $(".note").append(" Hello");\r
+    \r
+    final Effects a = $(".a, .b > div:nth-child(2)").as(Effects.Effects);\r
+    \r
+    $("#b1").toggle(new Function() {\r
+      public void f(Element e) {\r
+        $("#i1").as(Effects.Effects).animate(" width: '70%', opacity: '0.4', marginLeft: '0.6in', fontSize: '3em', borderWidth: '10px'");\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        $("#i1").as(Effects.Effects).animate(" width: '0%', opacity: '1', marginLeft: '0', fontSize: '1em', borderWidth: '5px'");\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.fadeOut();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.fadeIn();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.slideUp();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.slideDown();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.slideLeft();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.slideRight();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.animate("left: '+=25%', width: 'hide'");\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.animate("left: '-=25%', width: 'show'");\r
+      }\r
+    });\r
+    \r
+    $("#b2").toggle(new Function() {\r
+      public void f(Element e) {\r
+        a.as(Effects.Effects).clipUp();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.as(Effects.Effects).clipDown();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.as(Effects.Effects).clipDisappear();\r
+      }\r
+    }, new Function() {\r
+      public void f(Element e) {\r
+        a.as(Effects.Effects).clipAppear();\r
+      }\r
+    });\r
+    \r
   }\r
 }
\ No newline at end of file
index 0efad537a7de2ae74b9add31c5dc44ecb0976d86..2bbffad16e69a4bc8192ee2a403f06e70b3fed29 100644 (file)
@@ -10,10 +10,8 @@ import com.google.gwt.query.client.Selectors;
  */
 public interface MySelectors extends Selectors {
 
-//  @Selector("h1[id]:contains(Selectors)")
-//  NodeList<Element> h1IdContainsSelectors();
-
-  //  
+  @Selector("h1[id]:contains(Selectors)")
+  NodeList<Element> h1IdContainsSelectors();
 
   @Selector("a[href][lang][class]")
   NodeList<Element> aHrefLangClass();
@@ -36,8 +34,6 @@ public interface MySelectors extends Selectors {
 //    @Selector("*:first")
 //    NodeList<Element> allFirst();
 
-  //    
-
   @Selector("div:not(.example)")
   NodeList<Element> divNotExample();
 
@@ -71,9 +67,8 @@ public interface MySelectors extends Selectors {
   @Selector("div[class=example]")
   NodeList<Element> divWithClassExample();
 
-//    @Selector("div[class!=madeup]")
-//    NodeList<Element> divWithClassNotContainsMadeup();
-//    
+  @Selector("div[class!=madeup]")
+  NodeList<Element> divWithClassNotContainsMadeup();
 
   @Selector("div[class~=dialog]")
   NodeList<Element> divWithClassListContainsDialog();
@@ -96,8 +91,8 @@ public interface MySelectors extends Selectors {
   @Selector("p:last-child")
   NodeList<Element> lastChild();
 
-//  @Selector("div, p a")
-//  NodeList<Element> divCommaPA();
+  @Selector("div, p a")
+  NodeList<Element> divCommaPA();
 
   @Selector(".note")
   NodeList<Element> note();
@@ -111,8 +106,8 @@ public interface MySelectors extends Selectors {
   @Selector("p:nth-child(2n+1)")
   NodeList<Element> nThChild2nPlus1();
 
-//    @Selector("p:contains(selectors)")
-//    NodeList<Element> pContainsSelectors();
+  @Selector("p:contains(selectors)")
+  NodeList<Element> pContainsSelectors();
 
   @Selector("p:nth-child(even)")
   NodeList<Element> nThChildEven();
index 8cf52b2580b8770aa9b8357054c1264ee91e5ac2..90b79b2875fbc4fe81135812549b71f554e05851 100644 (file)
@@ -3,8 +3,21 @@
     <title>GQuery Demo</title>\r
     <script language="javascript"\r
             src="gwtquery.samples.GwtQueryEffects.nocache.js"></script>\r
-    <link href='gquery-star-ratings.css' type="text/css" rel="stylesheet"/>\r
-\r
+       <style type="text/css">\r
+       .box {\r
+          border-style: groove;\r
+          border-color: green;\r
+          border-width: 5px;\r
+       }\r
+       .a {\r
+          border-style: solid;\r
+          border-color: black;\r
+          border-width: 7px;\r
+          background: pink;\r
+          width: 50%;\r
+          padding: 10px;\r
+       }\r
+       </style>\r
 </head>\r
 <body>\r
 <div class="outer">\r
     <div>Foo <span class="note">bar</span> <span class="xyz">baz</span></div>\r
     <div>Foo <span class="note">bar</span> <span class="xyz">baz</span></div>\r
 </div>\r
+<br/>\r
+<button id="b1">Toggle Animate effects</button>\r
+<button id="b2">Toggle Clip effects</button>\r
+<br/>\r
+<br/>\r
+<div class="a">\r
+<span id="i1" class="box">Span 1</span>\r
+<span id="i2" class="box">Span 2</span>\r
+<span id="i3" class="box">Span 3</span>\r
+</div>\r
+<br/>\r
+<div class="b">\r
+<div class="box">Div 1</div>\r
+<div class="box">Div 2</div>\r
+<div class="box">Div 3</div>\r
+<div class="box">Div 4</div>\r
+</div>\r
+\r
+<script src="jquery-1.3.1.js"></script>\r
+<script>\r
+// $("#b1").click(function(){\r
+// $("#i1").animate(({width: '70%', opacity: '0.4', marginLeft: '0.6in', fontSize: '3em', borderWidth: '10px'}));\r
+// });\r
+</script>\r
 \r
 \r
 </body>\r
index 46fdc5417dc68dd926381a67ca5f5fbd258f0ba2..3ed9adab5b78b159b7dfa3efd8ea8b7b854672df 100644 (file)
     </script>
     <style type="text/css">
         img.himg {
-            width: 124px;
-            height: 73px;
+            height: 55px;
+        }
+        img.logo {
+            max-width: 100px; 
         }
 
         .horse {
 <div id="racefield"
      style="width:790px; background-image: url(grass-texture-small.jpg); background-repeat: repeat;">
     <div id="gwthorse" class="horse">
-        <nobr><img class="himg" src="horse.gif"><img src="gwt-logo-cs.gif">
+        <nobr><img class="himg" src="horse.gif"><img class="logo" src="gwt-logo-cs.gif">
+        </nobr>
+    </div>
+    <div id="dgwthorse" class="horse">
+        <nobr><img class="himg" src="horse.gif"><img class="logo" src="gwt-logo-cs.gif">
         </nobr>
     </div>
     <div id="jqueryhorse" class="horse">
-        <nobr><img class="himg" src="horse.gif"><img src="logo_jquery.gif">
+        <nobr><img class="himg" src="horse.gif"><img class="logo" src="logo_jquery.gif">
         </nobr>
     </div>
     <div id="dojohorse" class="horse">
 
-        <img class="himg" src="horse.gif"><img src="dojo-logo-text.gif"></nobr>
+        <img class="himg" src="horse.gif"><img class="logo" src="dojo-logo-text.gif"></nobr>
     </div>
     <div id="prototypehorse" class="horse">
 
-        <img class="himg" src="horse.gif"><img src="prototype_logo.gif"></nobr>
+        <img class="himg" src="horse.gif"><img class="logo" src="prototype_logo.gif"></nobr>
     </div>
 
 </div>