]> source.dussan.org Git - gwtquery.git/commitdiff
Refactored to com.google.gwt.query
authorRay Cromwell <cromwellian@gmail.com>
Thu, 30 Apr 2009 21:43:29 +0000 (21:43 +0000)
committerRay Cromwell <cromwellian@gmail.com>
Thu, 30 Apr 2009 21:43:29 +0000 (21:43 +0000)
Fixup javadocs
Add tests

65 files changed:
gwtquery-core/pom.xml
gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/$.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/DeferredGQuery.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Events.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/EventsListener.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/JSArray.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Plugin.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Regexp.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Selector.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/SelectorEngine.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/Selectors.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImpl.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImplIE.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineImpl.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJS.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJSIE.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineNative.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineXPath.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorBase.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJS.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJSOptimal.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorNative.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorXPath.java [new file with mode: 0644]
gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml [deleted file]
gwtquery-core/src/main/java/gwtquery/client/$.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/DeferredGQuery.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Effects.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Function.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/GQuery.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/JSArray.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Plugin.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Predicate.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Properties.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Regexp.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Selector.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/Selectors.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineImpl.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJS.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJSIE.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineNative.java [deleted file]
gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineXPath.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorBase.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorJS.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorNative.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorXPath.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorJSGEBCN.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorNativeGEBCN.java [deleted file]
gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorXPathGEBCN.java [deleted file]
gwtquery-core/src/test/java/com/google/gwt/query/client/GwtQueryCoreTest.java [new file with mode: 0644]
gwtquery-core/src/test/java/gwtquery/client/GwtQueryCoreTest.java [deleted file]
pom.xml
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/GwtQuerySampleModule.java
samples/src/main/java/gwtquery/samples/client/MySelectors.java

index 5af705a856f50848093e444218611ccfb4266f53..9c4b662220b2f33f90f79085281bb766e9247e92 100644 (file)
@@ -1,14 +1,14 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>gwtquery</groupId>
+    <groupId>com.google.gwt</groupId>
     <artifactId>gwtquery-project</artifactId>
     <version>1.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>gwtquery</artifactId>
   <packaging>jar</packaging>
-  <name>GwtQuery Core API</name>
+  <name>Gwt Query Core API</name>
   <url>http://gwtquery.com</url>
   <dependencies>
     <dependency>
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml b/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml
new file mode 100644 (file)
index 0000000..a09eeaf
--- /dev/null
@@ -0,0 +1,81 @@
+<module>\r
+    <inherits name='com.google.gwt.user.User'/>\r
+\r
+    <!--<define-property name="selectorCapability" values="native,xpath,js"/>-->\r
+      <!-- enable for native getClassByName shortcut acceleration -->\r
+    <define-property name="selectorCapability"\r
+                     values="native,js"/>\r
+    <property-provider name="selectorCapability">\r
+        <![CDATA[\r
+   // useful for benchmarking tests when you want to force non-accelerated queries\r
+   //if(window.location.href.indexOf("_selector_force_js") != -1) return "js"; \r
+   if(document.querySelectorAll && /native/.test(document.querySelectorAll.toString())) {\r
+      return "native";\r
+   }\r
+   return "js"\r
+     ]]>\r
+    </property-provider>\r
+\r
+    <generate-with class="com.google.gwt.query.rebind.SelectorGeneratorJS">\r
+        <when-type-assignable class="com.google.gwt.query.client.Selectors"/>\r
+        <any>\r
+            <when-property-is name="user.agent" value="gecko"/>\r
+            <when-property-is name="user.agent" value="ie6"/>\r
+        </any>\r
+\r
+    </generate-with>\r
+\r
+    <generate-with class="com.google.gwt.query.rebind.SelectorGeneratorXPath">\r
+        <when-type-assignable class="com.google.gwt.query.client.Selectors"/>\r
+        <any>\r
+            <when-property-is name="user.agent" value="gecko1_8"/>\r
+            <when-property-is name="user.agent" value="opera"/>\r
+            <all>\r
+                <when-property-is name="selectorCapability" value="js"/>\r
+                <when-property-is name="user.agent" value="safari"/>\r
+            </all>\r
+        </any>\r
+    </generate-with>\r
+\r
+  \r
+    <replace-with class="com.google.gwt.query.client.impl.DocumentStyleImpl">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.DocumentStyleImpl"/>\r
+    </replace-with>\r
+\r
+    <replace-with class="com.google.gwt.query.client.impl.DocumentStyleImplIE">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.DocumentStyleImpl"/>\r
+        <when-property-is name="user.agent" value="ie6"/>\r
+    </replace-with>\r
+\r
+\r
+    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineJS">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
+        <when-property-is name="user.agent" value="gecko"/>\r
+    </replace-with>\r
+\r
+    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineJSIE">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
+        <when-property-is name="user.agent" value="ie6"/>\r
+    </replace-with>\r
+\r
+    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineXPath">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
+        <any>\r
+            <when-property-is name="user.agent" value="gecko1_8"/>\r
+            <when-property-is name="user.agent" value="opera"/>\r
+            <all>\r
+                <when-property-is name="selectorCapability" value="js"/>\r
+                <when-property-is name="user.agent" value="safari"/>\r
+            </all>\r
+        </any>\r
+    </replace-with>\r
+\r
+    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineNative">\r
+        <when-type-assignable class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
+        <all>\r
+            <when-property-is name="user.agent" value="safari"/>\r
+            <when-property-is name="selectorCapability" value="native"/>\r
+        </all>\r
+    </replace-with>\r
+\r
+</module>
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/$.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/$.java
new file mode 100644 (file)
index 0000000..1648783
--- /dev/null
@@ -0,0 +1,82 @@
+package com.google.gwt.query.client;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+
+/**
+ * A facade class of forwarding functions which allow end users to refer to
+ * the GQuery class as '$' if they desire.
+ */
+public class $ {
+
+  public static GQuery $(String selectorOrHtml) {
+    return GQuery.$(selectorOrHtml);
+  }
+
+  public static <T extends GQuery> T $(T gq) {
+    return GQuery.$(gq);
+  }
+
+  /**
+   * This function accepts a string containing a CSS selector which is then used
+   * to match a set of elements, or it accepts raw HTML creating a GQuery
+   * element containing those elements. The second parameter is is a class
+   * reference to a plugin to be used.
+   */
+  public static <T extends GQuery> T $(String selector, Class<T> plugin) {
+    return GQuery.$(selector, plugin);
+  }
+
+  /**
+   * This function accepts a string containing a CSS selector which is then used
+   * to match a set of elements, or it accepts raw HTML creating a GQuery
+   * element containing those elements. The second parameter is the context to
+   * use for the selector.
+   */
+  public static GQuery $(String selector, Node context) {
+    return GQuery.$(selector, context);
+  }
+
+  /**
+   * This function accepts a string containing a CSS selector which is then used
+   * to match a set of elements, or it accepts raw HTML creating a GQuery
+   * element containing those elements. The second parameter is the context to
+   * use for the selector. The third parameter is the class plugin to use.
+   */
+  public static <T extends GQuery> GQuery $(String selector, Node context,
+      Class<T> plugin) {
+    return GQuery.$(selector, context, plugin);
+  }
+
+  /**
+   * Wrap a GQuery around  existing Elements.
+   */
+  public static GQuery $(NodeList<Element> elements) {
+    return GQuery.$(elements);
+  }
+
+  /**
+   * Wrap a GQuery around an existing Element.
+   */
+  public static GQuery $(Element element) {
+    return GQuery.$(element);
+  }
+
+  /**
+   * Wrap a JSON object
+   */
+  public static Properties $$(String properties) {
+    return GQuery.$$(properties);
+  }
+
+  /**
+   * Registers a GQuery plugin
+   * @param plugin
+   * @param pluginFactory
+   */
+  public static void registerPlugin(Class<? extends GQuery> plugin,
+      Plugin<? extends GQuery> pluginFactory) {
+    GQuery.registerPlugin(plugin, pluginFactory);
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/DeferredGQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/DeferredGQuery.java
new file mode 100644 (file)
index 0000000..28bb99e
--- /dev/null
@@ -0,0 +1,33 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.dom.client.Node;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.dom.client.NodeList;\r
+\r
+/**\r
+ * A compiled selector that can be lazily turned into a GQuery.\r
+ */\r
+public interface DeferredGQuery {\r
+\r
+  /**\r
+   * The selector which was compiled.\r
+   * @return\r
+   */\r
+    String getSelector();\r
+\r
+  /**\r
+   * Evaluate the compiled selector with the given DOM node as a context.\r
+   * Returns the result as a GQuery object.\r
+   * @param ctx\r
+   * @return\r
+   */\r
+    GQuery eval(Node ctx);\r
+\r
+  /**\r
+   * Evaluate the compiled selector with the given DOM node as a context.\r
+   * Returns a NodeList as a result.\r
+   * @param ctx\r
+   * @return\r
+   */\r
+    NodeList<Element> array(Node ctx);\r
+}\r
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
new file mode 100644 (file)
index 0000000..ac69eb6
--- /dev/null
@@ -0,0 +1,109 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.animation.client.Animation;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.dom.client.NodeList;\r
+\r
+public class Effects extends GQuery {\r
+\r
+  static {\r
+    GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
+  }\r
+\r
+  public static final Class<Effects> Effects = Effects.class;\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 hide() {\r
+    this.css("display", "none");\r
+    return this;\r
+  }\r
+\r
+  public Effects show() {\r
+    this.css("display", "");\r
+    return this;\r
+  }\r
+\r
+  public boolean visible() {\r
+    return !"none".equalsIgnoreCase(this.css("display"));\r
+  }\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 Effects fadeOut() {\r
+    Animation a = new Animation() {\r
+\r
+      public void onCancel() {\r
+      }\r
+\r
+      public void onComplete() {\r
+        for (int i = 0; i < elements.getLength(); i++) {\r
+          elements.getItem(i).getStyle().setProperty("opacity", "0");\r
+          elements.getItem(i).getStyle().setProperty("display", "none");\r
+        }\r
+      }\r
+\r
+      public void onStart() {\r
+      }\r
+\r
+      public void onUpdate(double progress) {\r
+        for (int i = 0; i < elements.getLength(); i++) {\r
+          elements.getItem(i).getStyle()\r
+              .setProperty("opacity", String.valueOf(1.0 - progress));\r
+        }\r
+      }\r
+    };\r
+    a.run(1000);\r
+    return this;\r
+  }\r
+\r
+  public Effects fadeIn() {\r
+    Animation a = new Animation() {\r
+\r
+      public void onCancel() {\r
+      }\r
+\r
+      public void onComplete() {\r
+      }\r
+\r
+      public void onStart() {\r
+      }\r
+\r
+      public void onUpdate(double progress) {\r
+        for (int i = 0; i < elements.getLength(); i++) {\r
+          elements.getItem(i).getStyle()\r
+              .setProperty("opacity", String.valueOf(progress));\r
+        }\r
+      }\r
+    };\r
+    a.run(1000);\r
+    return this;\r
+  }\r
+\r
+  public static class EffectsPlugin implements Plugin<Effects> {\r
+\r
+    public Effects init(GQuery gq) {\r
+      return new Effects(gq.get());\r
+    }\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
new file mode 100644 (file)
index 0000000..14025ea
--- /dev/null
@@ -0,0 +1,172 @@
+package com.google.gwt.query.client;
+
+import com.google.gwt.dom.client.Element;
+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 {
+
+  static {
+    GQuery.registerPlugin(Events.class, new Plugin<Events>() {
+      public Events init(GQuery gq) {
+        return new Events(gq.get());
+      }
+    });
+  }
+
+  public static final Class<Events> Events = Events.class;
+
+  public Events(Element element) {
+    super(element);
+  }
+
+  public Events(JSArray elements) {
+    super(elements);
+  }
+
+  public Events(NodeList<Element> list) {
+    super(list);
+  }
+
+  /**
+   * Binds a handler to a particular Event for each matched 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
+   * 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, final Object data, final Function f) {
+    for (Element e : elements()) {
+      EventsListener.getInstance(e).bind(eventbits, data, f);
+    }
+    return this;
+  }
+
+  /**
+   * Fires an event on each matched element.
+   *
+   * Example: fire(Event.ONCLICK)
+   */
+  public GQuery fire(int eventbits, int... keys) {
+    for (Element e : elements()) {
+      EventsListener.getInstance(e).fire(eventbits, keys);
+    }
+    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;
+  }
+}
+
+/**
+ * Just a class with static methods for firing element events on demand
+ */
+class FireEvents {
+
+  private native static Event createMouseEventImpl(String type) /*-{
+   var event = $doc.createEvent('MouseEvents');
+    event.initEvent(type, true, true);
+    return event;
+  }-*/;
+
+  private native static Event createKeyEventImpl(String type, int keycode) /*-{
+   var event;
+     if( $wnd.KeyEvent ) {
+        event = $doc.createEvent('KeyEvents');
+       event.initKeyEvent( type, true, true, $wnd, false, false, false, false, keycode, 0 );
+     } else {
+        event = $doc.createEvent('UIEvents');
+       event.initUIEvent( type, true, true, $wnd, 1 );
+       event.keyCode = keycode;
+     }
+    return event;
+  }-*/;
+
+  private native static Event createHtmlEventImpl(String type) /*-{
+   var event = $doc.createEvent('HTMLEvents');
+   event.initEvent( type, true, true);
+   return event;
+  }-*/;
+
+  private native static void dispatchEvent(Element elem, Event event) /*-{
+    elem.dispatchEvent(event);
+    if (event.type == 'focus' && elem.focus)
+      elem.focus();
+    else if (event.type == 'blur' && elem.focus)  
+      elem.blur();
+  }-*/;
+
+  private static String getEventTypeStr(int type) {
+    switch (type) {
+      case Event.ONBLUR:
+        return "blur";
+      case Event.ONCHANGE:
+        return "change";
+      case Event.ONCLICK:
+        return "click";
+      case Event.ONDBLCLICK:
+        return "dblclick";
+      case Event.ONFOCUS:
+        return "focus";
+      case Event.ONKEYDOWN:
+        return "keydown";
+      case Event.ONKEYPRESS:
+        return "keypress";
+      case Event.ONKEYUP:
+        return "keyup";
+      case Event.ONLOSECAPTURE:
+        return "losecapture";
+      case Event.ONMOUSEDOWN:
+        return "mousedown";
+      case Event.ONMOUSEMOVE:
+        return "mousemove";
+      case Event.ONMOUSEOUT:
+        return "mouseout";
+      case Event.ONMOUSEOVER:
+        return "mouseover";
+      case Event.ONMOUSEUP:
+        return "mouseup";
+      case Event.ONSCROLL:
+        return "scroll";
+      case Event.ONERROR:
+        return "error";
+      case Event.ONMOUSEWHEEL:
+        return "mousewheel";
+      default:
+        return "";
+    }
+  }
+
+  public static void fire(Element element, int eventbits, int... keys) {
+    Event event = null;
+
+    String type = getEventTypeStr(eventbits);
+
+    if ((eventbits & Event.MOUSEEVENTS) != 0
+        || (eventbits | Event.ONCLICK) == Event.ONCLICK) {
+      event = createMouseEventImpl(type);
+    } else if ((eventbits & Event.KEYEVENTS) != 0) {
+      event = createKeyEventImpl(type, keys[0]);
+    } else if ((eventbits & Event.FOCUSEVENTS) != 0) {
+      event = createHtmlEventImpl(type);
+    }
+
+    dispatchEvent(element, event);
+  }
+}
\ No newline at end of file
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
new file mode 100644 (file)
index 0000000..37adcf6
--- /dev/null
@@ -0,0 +1,124 @@
+package com.google.gwt.query.client;
+
+import com.google.gwt.user.client.EventListener;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.dom.client.Element;
+
+import java.util.List;
+import java.util.ArrayList;
+
+
+/**
+ * This class implements an event queue instance for one element.
+ * This queue instance is configured as the default event listener in GWT.
+ * 
+ * The reference to this queue is stored as a uniq variable in the element's DOM
+ * 
+ * The class takes care of calling the appropiate functions for each browser event
+ * and also calls sinkEvents methods.
+ * 
+ */
+class EventsListener implements EventListener {
+
+  private class BindFunction {
+    int type;
+    Function function;
+    Object data;
+    int times = -1;
+
+    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 hasEventType(int etype) {
+      return (type | etype) == type;
+    }
+
+    public boolean fire(Event event) {
+      if (times != 0) {
+        times--;
+        return function.f(event, data);
+      }
+      return true;
+    }
+  }
+  
+  private native static EventsListener getWidgetElementImpl(
+      Element elem) /*-{
+    return elem.__gqueryevent;
+  }-*/;
+
+  private native static void setWidgetElementImpl(Element elem, EventsListener gqevent) /*-{
+    elem.__gqueryevent = gqevent;
+  }-*/;
+
+  private native static void setFocusable(Element elem) /*-{
+    elem.tabIndex = 0;
+  }-*/;
+
+
+  private List<EventsListener.BindFunction> elementEvents = new ArrayList<EventsListener.BindFunction>();
+  private Element element;
+
+  private EventsListener(Element e) {
+    element = e;
+    setWidgetElementImpl(element, this);
+    DOM.setEventListener((com.google.gwt.user.client.Element) e, this);
+  }
+
+  public static EventsListener getInstance(Element e) {
+    EventsListener ret = getWidgetElementImpl(e);
+    return ret != null ? ret : new EventsListener(e);
+  }
+
+  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));
+    }
+  }
+
+  public void bind(int eventbits, final Object data, final Function function) {
+    bind(eventbits, data, function, -1);
+  }
+
+  public void fire(int eventbits, int... keys) {
+    FireEvents.fire(element, eventbits, keys);
+  }
+
+  public void onBrowserEvent(Event event) {
+    int etype = DOM.eventGetType(event);
+    for (EventsListener.BindFunction listener : elementEvents) {
+      if (listener.hasEventType(etype)) {
+        if (!listener.fire(event)) {
+          event.cancelBubble(true);
+          event.preventDefault();
+        }
+      }
+    }
+  }
+
+  public void unbind(int eventbits) {
+    ArrayList<EventsListener.BindFunction> newList = new ArrayList<EventsListener.BindFunction>();
+    for (EventsListener.BindFunction listener : elementEvents)
+      if (!listener.hasEventType(eventbits))
+        newList.add(listener);
+    elementEvents = newList;
+  }
+
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java
new file mode 100644 (file)
index 0000000..d9c093e
--- /dev/null
@@ -0,0 +1,50 @@
+package com.google.gwt.query.client;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.Event;
+
+/**
+   * Extend this class to implement functions callbacks.
+ */
+public abstract class Function {
+
+  /**
+   * Override this for GQuery methods which loop over matched elements and
+   * invoke a callback on each element.
+   * @param e
+   * @param i
+   * @return
+   */
+  public String f(Element e,  int i) {
+    return "";  
+  }
+
+  /**
+   * Override this for GQuery methods which take a callback, but do not expect
+   * a return value, apply to a single element only.
+   * @param e
+   */
+  public void f(Element e) {
+  }
+
+  /**
+   * Override this method for bound event handlers if you wish to deal with
+   * per-handler user data.
+   * @param e
+   * @param data
+   * @return
+   */
+  public boolean f(Event e, Object data) {
+    return f(e);
+  }
+
+  /**
+   * Override this method for bound event handlers.
+   * @param e
+   * @return
+   */
+  public boolean f(Event e) {
+    f(e.getCurrentTarget());
+    return true;
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
new file mode 100644 (file)
index 0000000..74cc5b8
--- /dev/null
@@ -0,0 +1,2479 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.JavaScriptObject;\r
+import com.google.gwt.dom.client.BodyElement;\r
+import com.google.gwt.dom.client.ButtonElement;\r
+import com.google.gwt.dom.client.Document;\r
+import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.dom.client.IFrameElement;\r
+import com.google.gwt.dom.client.InputElement;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.dom.client.Node;\r
+import com.google.gwt.dom.client.NodeList;\r
+import com.google.gwt.dom.client.OptionElement;\r
+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 static com.google.gwt.query.client.Effects.Effects;\r
+import static com.google.gwt.query.client.Events.Events;\r
+import com.google.gwt.query.client.impl.DocumentStyleImpl;\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
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ *\r
+ */\r
+public class GQuery {\r
+\r
+  public static class Offset {\r
+\r
+    public int top;\r
+\r
+    public int left;\r
+\r
+    Offset(int left, int top) {\r
+      this.left = left;\r
+      this.top = top;\r
+    }\r
+  }\r
+\r
+  private static final class DataCache extends JavaScriptObject {\r
+\r
+    protected DataCache() {\r
+    }\r
+\r
+    public native void delete(String name) /*-{\r
+      delete this[name];\r
+    }-*/;\r
+\r
+    public native void delete(int name) /*-{\r
+      delete this[name];\r
+    }-*/;\r
+\r
+    public native boolean exists(int id) /*-{\r
+      return !!this[id];\r
+    }-*/;\r
+\r
+    public native JavaScriptObject get(String id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native JavaScriptObject get(int id) /*-{\r
+      return this[id];\r
+    }-*/; /*-{\r
+      delete this[name];\r
+    }-*/\r
+\r
+    public DataCache getCache(int id) {\r
+      return get(id).cast();\r
+    }\r
+\r
+    public native double getDouble(String id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native double getDouble(int id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native int getInt(String id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native int getInt(int id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native String getString(String id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native String getString(int id) /*-{\r
+      return this[id];\r
+    }-*/;\r
+\r
+    public native boolean isEmpty() /*-{\r
+        var foo = "";\r
+        for(foo in this) break;\r
+        return !foo;\r
+    }-*/;\r
+\r
+    public native void put(String id, Object obj) /*-{\r
+      return this[id]=obj;\r
+    }-*/;\r
+\r
+    public native void put(int id, Object obj) /*-{\r
+      return this[id]=obj;\r
+    }-*/;\r
+  }\r
+\r
+  private static final class FastSet extends JavaScriptObject {\r
+\r
+    public static FastSet create() {\r
+      return JavaScriptObject.createObject().cast();\r
+    }\r
+\r
+    protected FastSet() {\r
+    }\r
+\r
+    public void add(Object o) {\r
+      add0(o.hashCode());\r
+    }\r
+\r
+    public boolean contains(Object o) {\r
+      return contains0(o.hashCode());\r
+    }\r
+\r
+    public void remove(Object o) {\r
+      remove0(o.hashCode());\r
+    }\r
+\r
+    private native void add0(int hc) /*-{\r
+      this[hc]=true;\r
+    }-*/;\r
+\r
+    private native boolean contains0(int hc) /*-{\r
+      return this[hc] || false;\r
+    }-*/;\r
+\r
+    private native void remove0(int hc) /*-{\r
+      delete this[hc];\r
+    }-*/;\r
+  }\r
+\r
+  private static final class Queue<T> extends JavaScriptObject {\r
+\r
+    public static Queue newInstance() {\r
+      return createArray().cast();\r
+    }\r
+\r
+    protected Queue() {\r
+    }\r
+\r
+    public native T dequeue() /*-{\r
+       return this.shift();\r
+    }-*/;\r
+\r
+    public native void enqueue(T foo) /*-{\r
+       this.push(foo);\r
+     }-*/;\r
+\r
+    public native int length() /*-{\r
+       return this.length;\r
+    }-*/;\r
+\r
+    public native T peek(int i) /*-{\r
+      return this[i];\r
+    }-*/;\r
+  }\r
+\r
+  public static boolean fxOff = false;\r
+\r
+  private static Map<Class<? extends GQuery>, Plugin<? extends GQuery>> plugins;\r
+\r
+  private static Element windowData = null;\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
+  /**\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.trim().charAt(0) == '<') {\r
+      return innerHtml(selectorOrHtml);\r
+    }\r
+    return $(selectorOrHtml, Document.get());\r
+  }\r
+\r
+  public static <T extends GQuery> T $(T gq) {\r
+\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
+   * element containing those elements. The second parameter is is a class\r
+   * reference to a plugin to be used.\r
+   */\r
+  public static <T extends GQuery> T $(String selector, Class<T> plugin) {\r
+    try {\r
+      if (plugins != null) {\r
+        T gquery = (T) plugins.get(plugin).init($(selector, Document.get()));\r
+        return gquery;\r
+      }\r
+      throw new RuntimeException("No plugin for class " + plugin);\r
+    } catch (Exception e) {\r
+      throw new RuntimeException(e);\r
+    }\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. The second parameter is the context to\r
+   * use for the selector.\r
+   */\r
+  public static GQuery $(String selector, Node context) {\r
+    return new GQuery(select(selector, context));\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. The second parameter is the context to\r
+   * use for the selector. The third parameter is the class plugin to use.\r
+   */\r
+  public static <T extends GQuery> GQuery $(String selector, Node context,\r
+      Class<T> plugin) {\r
+    try {\r
+      if (plugins != null) {\r
+        T gquery = (T) plugins.get(plugin)\r
+            .init(new GQuery(select(selector, context)));\r
+        return gquery;\r
+      }\r
+      throw new RuntimeException("No plugin for class " + plugin);\r
+    } catch (Exception e) {\r
+      throw new RuntimeException(e);\r
+    }\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
+  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 JSON object\r
+   */\r
+  public static Properties $$(String properties) {\r
+    return Properties.create(properties);\r
+  }\r
+\r
+  public static <T extends Node> T[] asArray(NodeList<T> nl) {\r
+    if (GWT.isScript()) {\r
+      return reinterpretCast(nl);\r
+    } else {\r
+      Node[] elts = new Node[nl.getLength()];\r
+      for (int i = 0; i < elts.length; i++) {\r
+        elts[i] = nl.getItem(i);\r
+      }\r
+      return (T[]) elts;\r
+    }\r
+  }\r
+\r
+  public static native String camelize(String s)/*-{\r
+     return s.toLowerCase().replace(/-([a-z])/ig, function(a, c){return c.toUpperCase()} );\r
+   }-*/;\r
+\r
+  public static void registerPlugin(Class<? extends GQuery> plugin,\r
+      Plugin<? extends GQuery> pluginFactory) {\r
+    if (plugins == null) {\r
+      plugins = new HashMap();\r
+    }\r
+    plugins.put(plugin, pluginFactory);\r
+  }\r
+\r
+  /**\r
+   * Copied from UIObject *\r
+   */\r
+  protected static void setStyleName(Element elem, String style, boolean add) {\r
+\r
+    style = style.trim();\r
+\r
+    // Get the current style string.\r
+    String oldStyle = elem.getClassName();\r
+    int idx = oldStyle.indexOf(style);\r
+\r
+    // Calculate matching index.\r
+    while (idx != -1) {\r
+      if (idx == 0 || oldStyle.charAt(idx - 1) == ' ') {\r
+        int last = idx + style.length();\r
+        int lastPos = oldStyle.length();\r
+        if ((last == lastPos) || ((last < lastPos) && (oldStyle.charAt(last)\r
+            == ' '))) {\r
+          break;\r
+        }\r
+      }\r
+      idx = oldStyle.indexOf(style, idx + 1);\r
+    }\r
+\r
+    if (add) {\r
+      // Only add the style if it's not already present.\r
+      if (idx == -1) {\r
+        if (oldStyle.length() > 0) {\r
+          oldStyle += " ";\r
+        }\r
+        DOM.setElementProperty(elem.<com.google.gwt.user.client.Element>cast(),\r
+            "className", oldStyle + style);\r
+      }\r
+    } else {\r
+      // Don't try to remove the style if it's not there.\r
+      if (idx != -1) {\r
+        // Get the leading and trailing parts, without the removed name.\r
+        String begin = oldStyle.substring(0, idx).trim();\r
+        String end = oldStyle.substring(idx + style.length()).trim();\r
+\r
+        // Some contortions to make sure we don't leave extra spaces.\r
+        String newClassName;\r
+        if (begin.length() == 0) {\r
+          newClassName = end;\r
+        } else if (end.length() == 0) {\r
+          newClassName = begin;\r
+        } else {\r
+          newClassName = begin + " " + end;\r
+        }\r
+\r
+        DOM.setElementProperty(elem.<com.google.gwt.user.client.Element>cast(),\r
+            "className", newClassName);\r
+      }\r
+    }\r
+  }\r
+\r
+  private static String curCSS(Element elem, String name) {\r
+    Style s = elem.getStyle();\r
+    ensureStyleImpl();\r
+    name = styleImpl.getPropertyName(name);\r
+\r
+    if (SelectorEngine.truth(s.getProperty(name))) {\r
+      return s.getProperty(name);\r
+    }\r
+    return styleImpl.getCurrentStyle(elem, name);\r
+  }\r
+\r
+  private static void ensureStyleImpl() {\r
+    if (styleImpl == null) {\r
+      styleImpl = GWT.create(DocumentStyleImpl.class);\r
+    }\r
+  }\r
+\r
+  private static boolean hasClass(Element e, String clz) {\r
+    return ((" " + e.getClassName() + " ").matches(".*\\s" + clz + "\\s.*"));\r
+  }\r
+\r
+  private static GQuery innerHtml(String html) {\r
+    Element div = DOM.createDiv();\r
+    div.setInnerHTML(html);\r
+    return new GQuery((NodeList<Element>) (NodeList<?>) div.getChildNodes());\r
+  }\r
+\r
+  private static native <T extends Node> T[] reinterpretCast(NodeList<T> nl) /*-{\r
+        return nl;\r
+    }-*/;\r
+\r
+  private static NodeList select(String selector, Node context) {\r
+    return new SelectorEngine().select(selector, context);\r
+  }\r
+\r
+  protected NodeList<Element> elements = null;\r
+\r
+  private String selector;\r
+\r
+  private GQuery previousObject;\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
+   * 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. Add elements to the set\r
+   * of matched elements if they are not included yet.\r
+   */\r
+  public GQuery add(GQuery previousObject) {\r
+    return pushStack(unique(merge(elements, previousObject.elements)), "add",\r
+        getSelector() + "," + previousObject.getSelector());\r
+  }\r
+\r
+  /**\r
+   * Adds the specified classes to each matched element.\r
+   */\r
+  public GQuery addClass(String... classes) {\r
+    for (Element e : elements()) {\r
+      for (String clz : classes) {\r
+        setStyleName(e, clz, true);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Add the previous selection to the current selection. Useful for traversing\r
+   * elements, and then adding something that was matched before the last\r
+   * traversal.\r
+   */\r
+  public GQuery andSelf() {\r
+    return add(previousObject);\r
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * similar to doing an appendChild to all the specified elements, adding them\r
+   * into the document.\r
+   */\r
+  public GQuery append(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_APPEND);\r
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Append all of the matched elements to another, specified, set of elements.\r
+   * This operation is, essentially, the reverse of doing a regular\r
+   * $(A).append(B), in that instead of appending B to A, you're appending A to\r
+   * B.\r
+   */\r
+  public GQuery appendTo(GQuery other) {\r
+    return other.append(this);\r
+  }\r
+\r
+  /**\r
+   * Convert to Plugin interface provided by Class literal.\r
+   */\r
+  public <T extends GQuery> T as(Class<T> plugin) {\r
+    if (plugins != null) {\r
+      return (T) plugins.get(plugin).init(this);\r
+    }\r
+    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
+   * Example: $("img").attr(new Properties("src: 'test.jpg', alt: 'Test\r
+   * Image'"))\r
+   */\r
+  public GQuery attr(Properties properties) {\r
+    for (Element e : elements()) {\r
+      for (String name : properties.keys()) {\r
+        e.setAttribute(fixAttributeName(name), properties.get(name));\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Set a single property to a computed value, on all matched elements.\r
+   */\r
+  public GQuery attr(String key, Function closure) {\r
+    for (int i = 0; i < elements.getLength(); i++) {\r
+      Element e = elements.getItem(i);\r
+      e.setAttribute(fixAttributeName(key), closure.f(e, i));\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
+  }\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(GQuery query) {\r
+    return domManip(query.elements, FUNC_BEFORE);\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(String html) {\r
+    return domManip(html, FUNC_BEFORE);\r
+  }\r
+\r
+  /**\r
+   * Binds a handler to a particular Event (like Event.ONCLICK) for each matched\r
+   * 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
+   * 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 bind(int eventbits, final Object data, final Function f) {\r
+    return as(Events).bind(eventbits, data, f);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the blur event of each matched element.\r
+   */\r
+  public GQuery blur(Function f) {\r
+    return bind(Event.ONBLUR, null, f);\r
+  }\r
+\r
+  /**\r
+   * Trigger a blur event.\r
+   */\r
+  public GQuery blur() {\r
+    return trigger(Document.get().createBlurEvent(), null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the change event of each matched element.\r
+   */\r
+  public GQuery change(Function f) {\r
+    return bind(Event.ONCHANGE, null, f);\r
+  }\r
+\r
+  /**\r
+   * Trigger a change event.\r
+   */\r
+  public GQuery change() {\r
+    return trigger(Document.get().createChangeEvent(), null);\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
+   * 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
+   * at all ancestors, children() will only consider immediate child elements.\r
+   */\r
+  public GQuery children() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      allNextSiblingElements(e.getFirstChildElement(), result, null);\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Trigger a click event.\r
+   */\r
+  public GQuery click() {\r
+    return trigger(\r
+        Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false,\r
+            false), null);\r
+  }\r
+\r
+  /**\r
+   * Triggers the click event of each matched element. Causes all of the\r
+   * functions that have been bound to that click event to be executed.\r
+   */\r
+  public GQuery click(final Function f) {\r
+    return bind(Event.ONCLICK, null, f);\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
+   */\r
+  public GQuery clone() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      result.addNode(e.cloneNode(true));\r
+    }\r
+    return new GQuery(result);\r
+  }\r
+\r
+  /**\r
+   * Filter the set of elements to those that contain the specified text.\r
+   */\r
+  public GQuery contains(String text) {\r
+    JSArray array = JSArray.create();\r
+    for (Element e : elements()) {\r
+      if ($(e).text().contains(text)) {\r
+        array.addNode(e);\r
+      }\r
+    }\r
+    return $(array);\r
+  }\r
+\r
+  /**\r
+   * Find all the child nodes inside the matched elements (including text\r
+   * nodes), or the content document, if the element is an iframe.\r
+   */\r
+  public GQuery contents() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      NodeList children = e.getChildNodes();\r
+      for (int i = 0; i < children.getLength(); i++) {\r
+        Node n = children.getItem(i);\r
+        if (IFrameElement.is(n)) {\r
+          result.addNode(getContentDocument(n));\r
+        } else {\r
+          result.addNode(n);\r
+        }\r
+      }\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Return a style property on the first matched element.\r
+   */\r
+  public String css(String name) {\r
+    return curCSS(get(0), name);\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
+   */\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 a single style property to a value, on all matched elements.\r
+   */\r
+  public GQuery css(String prop, String val) {\r
+    for (Element e : elements()) {\r
+      String property = camelize(prop);\r
+      e.getStyle().setProperty(property, val);\r
+      if ("opacity".equals(property)) {\r
+        e.getStyle().setProperty("zoom", "1");\r
+        e.getStyle().setProperty("filter",\r
+            "alpha(opacity=" + (int) (Double.valueOf(val) * 100) + ")");\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Returns value at named data store for the element, as set by data(name,\r
+   * value).\r
+   */\r
+  public Object data(String name) {\r
+    return data(elements.getItem(0), name, null);\r
+  }\r
+\r
+  /**\r
+   * Returns value at named data store for the element, as set by data(name,\r
+   * value) with desired return type.\r
+   *\r
+   * @param clz return type class literal\r
+   */\r
+  public <T> T data(String name, Class<T> clz) {\r
+    return (T) data(elements.getItem(0), name, null);\r
+  }\r
+\r
+  /**\r
+   * Stores the value in the named spot with desired return type.\r
+   */\r
+  public void data(String name, String value) {\r
+    for (Element e : elements()) {\r
+      data(e, name, value);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Trigger a double click event.\r
+   */\r
+  public GQuery dblclick() {\r
+    return trigger(\r
+        Document.get().createDblClickEvent(0, 0, 0, 0, 0, false, false, false,\r
+            false), null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the dblclick event of each matched element.\r
+   */\r
+  public GQuery dblclick(Function f) {\r
+    return bind(Event.ONDBLCLICK, null, f);\r
+  }\r
+\r
+  /**\r
+   * Removes a queued function from the front of the queue and executes it.\r
+   */\r
+  public GQuery dequeue(String type) {\r
+    for (Element e : elements()) {\r
+      dequeue(e, type);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Removes a queued function from the front of the FX queue and executes it.\r
+   */\r
+  public GQuery dequeue() {\r
+    return dequeue("__FX");\r
+  }\r
+\r
+  /**\r
+   * Run one or more Functions over each element of the GQuery.\r
+   */\r
+  public GQuery each(Function... f) {\r
+    for (Function f1 : f) {\r
+      for (Element e : elements()) {\r
+        f1.f(e);\r
+      }\r
+    }\r
+    return this;\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
+   */\r
+  public Element[] elements() {\r
+    return asArray(elements);\r
+  }\r
+\r
+  /**\r
+   * Remove all child nodes from the set of matched elements.\r
+   */\r
+  public GQuery empty() {\r
+    //TODO: add memory leak cleanup, remove event handlers, and \r
+    // data caches\r
+    for (Element e : elements()) {\r
+      while (e.getFirstChild() != null) {\r
+        e.removeChild(e.getFirstChild());\r
+      }\r
+    }\r
+\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Revert the most recent 'destructive' operation, changing the set of matched\r
+   * elements to its previous state (right before the destructive operation).\r
+   */\r
+  public GQuery end() {\r
+    return previousObject != null ? previousObject : new GQuery();\r
+  }\r
+\r
+  /**\r
+   * Reduce GQuery to element in the specified position.\r
+   */\r
+  public GQuery eq(int pos) {\r
+    return $(elements.getItem(pos));\r
+  }\r
+\r
+  /**\r
+   * Trigger an error event.\r
+   */\r
+  public GQuery error() {\r
+    return trigger(Document.get().createErrorEvent(), null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the error event of each matched element.\r
+   */\r
+  public GQuery error(Function f) {\r
+    return bind(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
+  }\r
+\r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity.\r
+   */\r
+  public GQuery fadeOut(int millisecs) {\r
+    return $(as(Effects).fadeOut(millisecs));\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
+  }\r
+\r
+  /**\r
+   * Removes all elements from the set of matched elements that do not match the\r
+   * specified function. The function is called with a context equal to the\r
+   * current element. If the function returns false, then the element is removed\r
+   * - anything else and the element is kept.\r
+   */\r
+  public GQuery filter(Predicate filterFn) {\r
+    JSArray result = JSArray.create();\r
+    for (int i = 0; i < elements.getLength(); i++) {\r
+      Element e = elements.getItem(i);\r
+      if (filterFn.f(e, i)) {\r
+        result.addNode(e);\r
+      }\r
+    }\r
+    return pushStack(result, "filter", selector);\r
+  }\r
+\r
+  /**\r
+   * Removes all elements from the set of matched elements that do not pass the\r
+   * specified css expression. This method is used to narrow down the results of\r
+   * a search. Provide a comma-separated list of expressions to apply multiple\r
+   * filters at once.\r
+   */\r
+  public GQuery filter(String... filters) {\r
+    JSArray array = JSArray.create();\r
+    for (String f : filters) {\r
+      for (Element e : elements()) {\r
+        for (Element c : $(f, e.getParentNode()).elements()) {\r
+          if (c == e) {\r
+            array.addNode(c);\r
+            break;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    return $(unique(array));\r
+  }\r
+\r
+  /**\r
+   * Searches for all elements that match the specified css expression. This\r
+   * method is a good way to find additional descendant elements with which to\r
+   * process.\r
+   *\r
+   * Provide a comma-separated list of expressions to apply multiple filters at\r
+   * once.\r
+   */\r
+  public GQuery find(String... filters) {\r
+    JSArray array = JSArray.create();\r
+    for (String selector : filters) {\r
+      for (Element e : elements()) {\r
+        for (Element c : $(selector, e).elements()) {\r
+          array.addNode(c);\r
+        }\r
+      }\r
+    }\r
+    return $(unique(array));\r
+  }\r
+\r
+  /**\r
+   * Trigger a focus event.\r
+   */\r
+  public GQuery focus() {\r
+    return trigger(Document.get().createFocusEvent(), null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the focus event of each matched element.\r
+   */\r
+\r
+  public GQuery focus(Function f) {\r
+    return bind(Event.ONFOCUS, null, f);\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
+   */\r
+  public NodeList<Element> get() {\r
+    return elements;\r
+  }\r
+\r
+  /**\r
+   * Return the ith element matched.\r
+   */\r
+  public Element get(int i) {\r
+    return elements.getItem(i);\r
+  }\r
+\r
+  /**\r
+   * Return the previous set of matched elements prior to the last destructive\r
+   * operation (e.g. query)\r
+   */\r
+  public GQuery getPreviousObject() {\r
+    return previousObject;\r
+  }\r
+\r
+  /**\r
+   * Return the selector representing the current set of matched elements.\r
+   */\r
+  public String getSelector() {\r
+    return selector;\r
+  }\r
+\r
+  /**\r
+   * Returns true any of the specified classes are present on any of the matched\r
+   * Reduce the set of matched elements to all elements after a given position.\r
+   * The position of the element in the set of matched elements starts at 0 and\r
+   * goes to length - 1.\r
+   */\r
+  public GQuery gt(int pos) {\r
+    return $(slice(pos + 1, -1));\r
+  }\r
+\r
+  /**\r
+   * Returns true any of the specified classes are present on any of the matched\r
+   * elements.\r
+   */\r
+  public boolean hasClass(String... classes) {\r
+    for (Element e : elements()) {\r
+      for (String clz : classes) {\r
+        if (hasClass(e, clz)) {\r
+          return true;\r
+        }\r
+      }\r
+    }\r
+    return false;\r
+  }\r
+\r
+  /**\r
+   * Set the height of every element in the matched set.\r
+   */\r
+  public GQuery height(int height) {\r
+    for (Element e : elements()) {\r
+      e.getStyle().setPropertyPx("height", height);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Set the height style property of every matched element. It's useful for\r
+   * using 'percent' or 'em' units Example: $(".a").width("100%")\r
+   */\r
+  public GQuery height(String height) {\r
+    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
+  }\r
+\r
+  /**\r
+   * Bind a function to the mouseover event of each matched element. A method\r
+   * for simulating hovering (moving the mouse on, and off, an object). This is\r
+   * a custom method which provides an 'in' to a frequent task. Whenever the\r
+   * mouse cursor is moved over a matched element, the first specified function\r
+   * is fired. Whenever the mouse moves off of the element, the second specified\r
+   * function fires.\r
+   */\r
+  public GQuery hover(Function fover, Function fout) {\r
+    return bind(Event.ONMOUSEOVER, null, fover)\r
+        .bind(Event.ONMOUSEOUT, null, fout);\r
+  }\r
+\r
+  /**\r
+   * Get the innerHTML of the first matched element.\r
+   */\r
+  public String html() {\r
+    return get(0).getInnerHTML();\r
+  }\r
+\r
+  /**\r
+   * Set the innerHTML of every matched element.\r
+   */\r
+  public GQuery html(String html) {\r
+    for (Element e : elements()) {\r
+      e.setInnerHTML(html);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Find the index of the specified Element\r
+   */\r
+  public int index(Element element) {\r
+    for (int i = 0; i < elements.getLength(); i++) {\r
+      if (elements.getItem(i) == element) {\r
+        return i;\r
+      }\r
+    }\r
+    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
+   */\r
+  public GQuery insertAfter(Element elem) {\r
+    return insertAfter($(elem));\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements after another, specified, set of\r
+   * elements.\r
+   */\r
+  public GQuery insertAfter(GQuery query) {\r
+    for (Element e : elements()) {\r
+      query.after(e);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(Element item) {\r
+    return insertBefore($(item));\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(GQuery query) {\r
+    for (Element e : elements()) {\r
+      query.before(e);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(String selector) {\r
+    return insertBefore($(selector));\r
+  }\r
+\r
+  /**\r
+   * Checks the current selection against an expression and returns true, if at\r
+   * least one element of the selection fits the given expression. Does return\r
+   * false, if no element fits or the expression is not valid.\r
+   */\r
+  public boolean is(String... filters) {\r
+    return filter(filters).size() > 0;\r
+  }\r
+\r
+  /**\r
+   * Trigger a keydown event.\r
+   */\r
+  public GQuery keydown() {\r
+    return trigger(\r
+        Document.get().createKeyDownEvent(false, false, false, false, 0, 0),\r
+        null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the keydown event of each matched element.\r
+   */\r
+  public GQuery keydown(Function f) {\r
+    return bind(Event.ONKEYDOWN, null, f);\r
+  }\r
+\r
+  /**\r
+   * Trigger a keypress event.\r
+   */\r
+  public GQuery keypress() {\r
+    return trigger(\r
+        Document.get().createKeyPressEvent(false, false, false, false, 0, 0),\r
+        null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the keypress event of each matched element.\r
+   */\r
+  public GQuery keypressed(Function f) {\r
+    return bind(Event.ONKEYPRESS, null, f);\r
+  }\r
+\r
+  /**\r
+   * Trigger a keyup event.\r
+   */\r
+  public GQuery keyup() {\r
+    return trigger(\r
+        Document.get().createKeyUpEvent(false, false, false, false, 0, 0),\r
+        null);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the keyup event of each matched element.\r
+   */\r
+  public GQuery keyup(Function f) {\r
+    return bind(Event.ONKEYUP, null, f);\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
+   * 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
+   * Reduce the set of matched elements to all elements before a given position.\r
+   * The position of the element in the set of matched elements starts at 0 and\r
+   * goes to length - 1.\r
+   */\r
+  public GQuery lt(int pos) {\r
+    return $(slice(0, pos));\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the mousedown event of each matched element.\r
+   */\r
+  public GQuery mousedown(Function f) {\r
+    return bind(Event.ONMOUSEDOWN, null, f);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the mousemove event of each matched element.\r
+   */\r
+  public GQuery mousemove(Function f) {\r
+    return bind(Event.ONMOUSEMOVE, null, f);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the mouseout event of each matched element.\r
+   */\r
+  public GQuery mouseout(Function f) {\r
+    return bind(Event.ONMOUSEOUT, null, f);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the mouseover event of each matched element.\r
+   */\r
+  public GQuery mouseover(Function f) {\r
+    return bind(Event.ONMOUSEOVER, null, f);\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the mouseup event of each matched element.\r
+   */\r
+  public GQuery mouseup(Function f) {\r
+    return bind(Event.ONMOUSEUP, null, f);\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique next siblings of each of the\r
+   * given set of elements. next only returns the very next sibling for each\r
+   * element, not all next siblings see {#nextAll}.\r
+   */\r
+  public GQuery next() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      Element next = e.getNextSiblingElement();\r
+      if (next != null) {\r
+        result.addNode(next);\r
+      }\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique next siblings of each of the\r
+   * given set of elements filtered by 1 or more selectors. next only returns\r
+   * the very next sibling for each element, not all next siblings see\r
+   * {#nextAll}.\r
+   */\r
+  public GQuery next(String... selectors) {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      Element next = e.getNextSiblingElement();\r
+      if (next != null) {\r
+        result.addNode(next);\r
+      }\r
+    }\r
+    return new GQuery(unique(result)).filter(selectors);\r
+  }\r
+\r
+  /**\r
+   * Find all sibling elements after the current element.\r
+   */\r
+  public GQuery nextAll() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      allNextSiblingElements(e.getNextSiblingElement(), result, null);\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Removes the specified Element from the set of matched elements. This method\r
+   * is used to remove a single Element from a jQuery object.\r
+   */\r
+  public GQuery not(Element elem) {\r
+    JSArray array = JSArray.create();\r
+    for (Element e : elements()) {\r
+      if (e != elem) {\r
+        array.addNode(e);\r
+      }\r
+    }\r
+    return $(array);\r
+  }\r
+\r
+  /**\r
+   * Removes any elements inside the passed set of elements from the set of\r
+   * matched elements.\r
+   */\r
+  public GQuery not(GQuery gq) {\r
+    GQuery ret = this;\r
+    for (Element e : gq.elements()) {\r
+      ret = ret.not(e);\r
+    }\r
+    return ret;\r
+  }\r
+\r
+  /**\r
+   * Removes elements matching the specified expression from the set of matched\r
+   * elements.\r
+   */\r
+  public GQuery not(String... filters) {\r
+    GQuery ret = this;\r
+    for (String f : filters) {\r
+      ret = ret.not($(f));\r
+    }\r
+    return ret;\r
+  }\r
+\r
+  public Offset offset() {\r
+    return new Offset(get(0).getOffsetLeft(), get(0).getOffsetTop());\r
+  }\r
+\r
+  /**\r
+   * Returns a GQuery collection with the positioned parent of the first matched\r
+   * element. This is the first parent of the element that has position (as in\r
+   * relative or absolute). This method only works with visible elements.\r
+   */\r
+  public GQuery offsetParent() {\r
+    Element offParent = SelectorEngine\r
+        .or(elements.getItem(0).getOffsetParent(), Document.get().getBody());\r
+    while (offParent != null && !"body".equalsIgnoreCase(offParent.getTagName())\r
+        && !"html".equalsIgnoreCase(offParent.getTagName()) && "static"\r
+        .equals(curCSS(offParent, "position"))) {\r
+      offParent = offParent.getOffsetParent();\r
+    }\r
+    return new GQuery(offParent);\r
+  }\r
+\r
+  /**\r
+   * Binds a handler to a particular Event (like Event.ONCLICK) for each matched\r
+   * 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
+   * 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
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique parents of the matched set of\r
+   * elements.\r
+   */\r
+  public GQuery parent() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      result.addNode(e.getParentElement());\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique parents of the matched set of\r
+   * elements. You may use an optional expressions to filter the set of parent\r
+   * elements that will match one of them.\r
+   */\r
+  public GQuery parent(String... filters) {\r
+    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
+   */\r
+  public GQuery parents() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      Node par = e.getParentNode();\r
+      while (par != null && par != Document.get()) {\r
+        result.addNode(par);\r
+        par = par.getParentNode();\r
+      }\r
+    }\r
+    return new GQuery(unique(result));\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
+\r
+    if (size() > 0) {\r
+      GQuery offsetParent = offsetParent();\r
+      Offset offset = offset();\r
+      Element e = offsetParent.get(0);\r
+\r
+      Offset parentOffset = BodyElement.is(e) || "html".equals(e.getTagName())\r
+          ? new Offset(0, 0) : offsetParent.offset();\r
+      offset.top -= num(this, "marginTop");\r
+      offset.left -= num(this, "marginLeft");\r
+      parentOffset.top += num(offsetParent, "borderTopWidth");\r
+      parentOffset.left += num(offsetParent, "borderLeftWidth");\r
+      return new Offset(offset.top - parentOffset.top,\r
+          offset.left - parentOffset.left);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * 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
+  }\r
+\r
+  /**\r
+   * Prepend all of the matched elements to another, specified, set of elements.\r
+   * This operation is, essentially, the reverse of doing a regular\r
+   * $(A).prepend(B), in that instead of prepending B to A, you're prepending A\r
+   * to B.\r
+   */\r
+  public GQuery prependTo(GQuery elms) {\r
+    return elms.prepend(this);\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique previous siblings of each of\r
+   * the matched set of elements. Only the immediately previous sibling is\r
+   * returned, not all previous siblings.\r
+   */\r
+  public GQuery prev() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      Element next = getPreviousSiblingElement(e);\r
+      if (next != null) {\r
+        result.addNode(next);\r
+      }\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing the unique previous siblings of each of\r
+   * the matched set of elements filtered by selector. Only the immediately\r
+   * previous sibling is returned, not all previous siblings.\r
+   */\r
+  public GQuery prev(String... selectors) {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      Element next = getPreviousSiblingElement(e);\r
+      if (next != null) {\r
+        result.addNode(next);\r
+      }\r
+    }\r
+    return new GQuery(unique(result)).filter(selectors);\r
+  }\r
+\r
+  /**\r
+   * Find all sibling elements in front of the current element.\r
+   */\r
+  public GQuery prevAll() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      allPreviousSiblingElements(getPreviousSiblingElement(e), result);\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Returns a reference to the first element's queue (which is an array of\r
+   * functions).\r
+   */\r
+  public Queue<Function> queue(String type) {\r
+    return queue(elements.getItem(0), type, null);\r
+  }\r
+\r
+  /**\r
+   * Returns a reference to the FX queue.\r
+   */\r
+  public Queue<Function> queue() {\r
+    return queue(elements.getItem(0), "__FX", null);\r
+  }\r
+\r
+  /**\r
+   * Adds a new function, to be executed, onto the end of the queue of all\r
+   * matched elements.\r
+   */\r
+  public GQuery queue(String type, Function data) {\r
+    for (Element e : elements()) {\r
+      queue(e, type, data);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Replaces the current queue with the given queue on all matched elements.\r
+   */\r
+  public GQuery queue(String type, Queue data) {\r
+    for (Element e : elements()) {\r
+      replacequeue(e, type, data);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Adds a new function, to be executed, onto the end of the queue of all\r
+   * matched elements in the FX queue.\r
+   */\r
+  public GQuery queue(Function data) {\r
+    return queue("__FX", data);\r
+  }\r
+\r
+  /**\r
+   * Removes all matched elements from the DOM.\r
+   */\r
+  public GQuery remove() {\r
+    for (Element e : elements()) {\r
+      //TODO: cleanup event bindings\r
+      removeData(e, null);\r
+      if (e.getParentNode() != null) {\r
+        e.getParentNode().removeChild(e);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Remove the named attribute from every element in the matched set.\r
+   */\r
+  public GQuery removeAttr(String key) {\r
+    for (Element e : elements()) {\r
+      e.removeAttribute(key);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Removes the specified classes to each matched element.\r
+   */\r
+  public GQuery removeClass(String... classes) {\r
+    for (Element e : elements()) {\r
+      for (String clz : classes) {\r
+        setStyleName(e, clz, false);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Removes named data store from an element.\r
+   */\r
+  public GQuery removeData(String name) {\r
+    for (Element e : elements()) {\r
+      removeData(e, name);\r
+    }\r
+    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(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).replaceWith(query);\r
+    }\r
+    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(String html) {\r
+    return replaceAll($(html));\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 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 replaceWith(GQuery query) {\r
+    return after(query).remove();\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
+   * from the DOM.\r
+   */\r
+  public GQuery replaceWith(String html) {\r
+    return replaceWith($(html));\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
+   * from the DOM.\r
+   */\r
+  public GQuery replaceWith(Element elem) {\r
+    return replaceWith($(elem));\r
+  }\r
+\r
+  /**\r
+   * Bind a function to the scroll event of each matched element.\r
+   */\r
+  public GQuery scroll(Function f) {\r
+    return bind(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.get()) {\r
+        Window.scrollTo(left, $(e).scrollTop());\r
+      } else {\r
+        e.setPropertyInt("scrollLeft", left);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Gets the scroll left offset of the first matched element. This method works\r
+   * for both visible and hidden elements.\r
+   */\r
+  public int scrollLeft() {\r
+    Element e = get(0);\r
+    if (e == window()) {\r
+      return Window.getScrollLeft();\r
+    } else if (e == (Node) Document.get()) {\r
+      return Document.get().getScrollLeft();\r
+    } else {\r
+      return e.getScrollLeft();\r
+    }\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.get()) {\r
+        Window.scrollTo($(e).scrollLeft(), top);\r
+      } else {\r
+        e.setPropertyInt("scrollTop", top);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Gets the scroll top offset of the first matched element. This method works\r
+   * for both visible and hidden elements.\r
+   */\r
+  public int scrollTop() {\r
+    Element e = get(0);\r
+    if (e == window()) {\r
+      return Window.getScrollTop();\r
+    } else if (e == (Node) Document.get()) {\r
+      return Document.get().getScrollTop();\r
+    } else {\r
+      return e.getScrollTop();\r
+    }\r
+  }\r
+\r
+  public GQuery select() {\r
+    return trigger(Document.get().createHtmlEvent("select", false, false),\r
+        null);\r
+  }\r
+\r
+  public void setPreviousObject(GQuery previousObject) {\r
+    this.previousObject = previousObject;\r
+  }\r
+\r
+  public void setSelector(String selector) {\r
+    this.selector = selector;\r
+  }\r
+\r
+  /**\r
+   * Return the number of elements in the matched set. Make visible all mached\r
+   * elements\r
+   */\r
+  public GQuery show() {\r
+    return $(as(Effects).show());\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing all of the unique siblings of each of the\r
+   * matched set of elements.\r
+   */\r
+  public GQuery siblings() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      allNextSiblingElements(e.getParentElement().getFirstChildElement(),\r
+          result, e);\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
+  /**\r
+   * Get a set of elements containing all of the unique siblings of each of the\r
+   * matched set of elements filtered by the provided set of selectors.\r
+   */\r
+  public GQuery siblings(String... selectors) {\r
+    return siblings().filter(selectors);\r
+  }\r
+\r
+  /**\r
+   * Return the number of elements in the matched set.\r
+   */\r
+  public int size() {\r
+    return elements.getLength();\r
+  }\r
+\r
+  /**\r
+   * Selects a subset of the matched elements.\r
+   */\r
+  public GQuery slice(int start, int end) {\r
+    JSArray slice = JSArray.create();\r
+    if (end == -1 || end > elements.getLength()) {\r
+      end = elements.getLength();\r
+    }\r
+    for (int i = start; i < end; i++) {\r
+      slice.addNode(elements.getItem(i));\r
+    }\r
+    return new GQuery(slice);\r
+  }\r
+\r
+  public GQuery submit() {\r
+    return trigger(Document.get().createHtmlEvent("submit", false, false),\r
+        null);\r
+  }\r
+\r
+  /**\r
+   * Return the text contained in the first matched element.\r
+   */\r
+  public String text() {\r
+    String result="";\r
+    for(Element e : elements()) {\r
+      result += e.getInnerText();\r
+    }\r
+    return result;\r
+  }\r
+\r
+  /**\r
+   * Set the innerText of every matched element.\r
+   */\r
+  public GQuery text(String txt) {\r
+    for (Element e : asArray(elements)) {\r
+      e.setInnerText(txt);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Toggle among two or more function calls every other click.\r
+   */\r
+  public GQuery toggle(final Function... fn) {\r
+    return click(new Function() {\r
+      int click = 0;\r
+\r
+      @Override\r
+      public boolean f(Event e) {\r
+        return fn[(click++ % fn.length)].f(e);\r
+      }\r
+    });\r
+  }\r
+\r
+  /**\r
+   * Adds or removes the specified classes to each matched element.\r
+   */\r
+  public GQuery toggleClass(String... classes) {\r
+    for (Element e : elements()) {\r
+      for (String clz : classes) {\r
+        if (hasClass(e, clz)) {\r
+          setStyleName(e, clz, false);\r
+        } else {\r
+          setStyleName(e, clz, true);\r
+        }\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Adds or removes the specified classes to each matched element.\r
+   */\r
+  public GQuery toggleClass(String clz, boolean sw) {\r
+    for (Element e : elements()) {\r
+      setStyleName(e, clz, sw);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Produces a string representation of the matched elements\r
+   */\r
+  public String toString() {\r
+    return toString(false);\r
+  }\r
+\r
+  /**\r
+   * Produces a string representation of the matched elements\r
+   */\r
+  public String toString(boolean pretty) {\r
+    String r = "";\r
+    for (Element e : elements()) {\r
+      r += (pretty && r.length() > 0 ? "\n " : "") + e.getString();\r
+    }\r
+    return r;\r
+  }\r
+\r
+  /**\r
+   * Trigger an event of type eventbits on every matched element.\r
+   */\r
+  public GQuery trigger(int eventbits, int... keys) {\r
+    return as(Events).fire(eventbits, keys);\r
+  }\r
+\r
+  /**\r
+   * Removes all events that match the eventbits\r
+   */\r
+  public GQuery unbind(int eventbits) {\r
+    return as(Events).unbind(eventbits);\r
+  }\r
+\r
+  /**\r
+   * Remove all duplicate elements from an array of elements. Note that this\r
+   * only works on arrays of DOM elements, not strings or numbers.\r
+   */\r
+  public JSArray unique(JSArray result) {\r
+    FastSet f = FastSet.create();\r
+    JSArray ret = JSArray.create();\r
+    for (int i = 0; i < result.getLength(); i++) {\r
+      Element e = result.getElement(i);\r
+      if (!f.contains(e)) {\r
+        f.add(e);\r
+        ret.addNode(e);\r
+      }\r
+    }\r
+    return ret;\r
+  }\r
+\r
+  /**\r
+   * Gets the content of the value attribute of the first matched element,\r
+   * returns only the first value even if it is a multivalued element. To get an\r
+   * array of all values in multivalues elements use vals()\r
+   *\r
+   * When the first element is a radio-button and is not checked, then it looks\r
+   * for a the first checked radio-button that has the same name in the list of\r
+   * matched elements.\r
+   */\r
+  public String val() {\r
+    String[] v = vals();\r
+    return (v != null && v.length > 0) ? v[0] : "";\r
+  }\r
+\r
+  /**\r
+   * Sets the value attribute of every matched element In the case of multivalue\r
+   * elements, all values are setted for other elements, only the first value is\r
+   * considered.\r
+   */\r
+  public GQuery val(String... values) {\r
+    for (Element e : elements()) {\r
+      String name = e.getNodeName();\r
+      if ("select".equalsIgnoreCase(name)) {\r
+        SelectElement s = SelectElement.as(e);\r
+        if (values.length > 1 && s.isMultiple()) {\r
+          s.setSelectedIndex(-1);\r
+          for (String v : values) {\r
+            for (int i = 0; i < s.getOptions().getLength(); i++) {\r
+              if (v.equals(s.getOptions().getItem(i).getValue())) {\r
+                s.getOptions().getItem(i).setSelected(true);\r
+              }\r
+            }\r
+          }\r
+        } else {\r
+          s.setValue(values[0]);\r
+        }\r
+      } else if ("input".equalsIgnoreCase(name)) {\r
+        InputElement ie = InputElement.as(e);\r
+        String type = ie.getType();\r
+        if ("radio".equalsIgnoreCase((type)) || "checkbox"\r
+            .equalsIgnoreCase(type)) {\r
+          if ("checkbox".equalsIgnoreCase(type)) {\r
+            for (String val : values) {\r
+              if (ie.getValue().equals(val)) {\r
+                ie.setChecked(true);\r
+              } else {\r
+                ie.setChecked(false);\r
+              }\r
+            }\r
+          } else if (values[0].equals(ie.getValue())) {\r
+            ie.setChecked(true);\r
+          }\r
+        } else {\r
+          ie.setValue(values[0]);\r
+        }\r
+      } else if ("textarea".equalsIgnoreCase(name)) {\r
+        TextAreaElement.as(e).setValue(values[0]);\r
+      } else if ("button".equalsIgnoreCase(name)) {\r
+        ButtonElement.as(e).setValue(values[0]);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Gets the content of the value attribute of the first matched element,\r
+   * returns more than one value if it is a multiple select.\r
+   *\r
+   * When the first element is a radio-button and is not checked, then it looks\r
+   * for a the first checked radio-button that has the same name in the list of\r
+   * matched elements.\r
+   *\r
+   * This method always returns an array. If no valid value can be determined\r
+   * the array will be empty, otherwise it will contain one or more values.\r
+   */\r
+  public String[] vals() {\r
+    if (size() > 0) {\r
+      Element e = get(0);\r
+      if (e.getNodeName().equalsIgnoreCase("select")) {\r
+        SelectElement se = SelectElement.as(e);\r
+        if (se.isMultiple()) {\r
+          List<String> result = new ArrayList<String>();\r
+          for (OptionElement oe : asArray(se.getOptions())) {\r
+            if (oe.isSelected()) {\r
+              result.add(oe.getValue());\r
+            }\r
+          }\r
+          return result.toArray(new String[0]);\r
+        } else if (se.getSelectedIndex() >= 0) {\r
+          return new String[]{\r
+              se.getOptions().getItem(se.getSelectedIndex()).getValue()};\r
+        }\r
+      } else if (e.getNodeName().equalsIgnoreCase("input")) {\r
+        InputElement ie = InputElement.as(e);\r
+        if ("radio".equalsIgnoreCase(ie.getType())) {\r
+          for (Element e2 : elements()) {\r
+            if ("input".equalsIgnoreCase(e2.getNodeName())) {\r
+              InputElement ie2 = InputElement.as(e2);\r
+              if ("radio".equalsIgnoreCase(ie2.getType()) && ie2.isChecked()\r
+                  && ie.getName().equals(ie2.getName())) {\r
+                return new String[]{ie2.getValue()};\r
+              }\r
+            }\r
+          }\r
+        } else if ("checkbox".equalsIgnoreCase(ie.getType())) {\r
+          if (ie.isChecked()) {\r
+            return new String[]{ie.getValue()};\r
+          }\r
+        } else {\r
+          return new String[]{ie.getValue()};\r
+        }\r
+      } else if (e.getNodeName().equalsIgnoreCase("textarea")) {\r
+        return new String[]{TextAreaElement.as(e).getValue()};\r
+      } else if (e.getNodeName().equalsIgnoreCase("button")) {\r
+        return new String[]{ButtonElement.as(e).getValue()};\r
+      }\r
+    }\r
+    return new String[0];\r
+  }\r
+\r
+  /**\r
+   * Return true if the first element is visible.\r
+   */\r
+  public boolean visible() {\r
+    return as(Effects).visible();\r
+  }\r
+\r
+  /**\r
+   * Set the width of every matched element.\r
+   */\r
+  public GQuery width(int width) {\r
+    for (Element e : elements()) {\r
+      e.getStyle().setPropertyPx("width", width);\r
+    }\r
+    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
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * 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
+  }\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
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * 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
+  }\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
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * within its structure -- it is that element that will enwrap everything\r
+   * else.\r
+   */\r
+  public GQuery wrap(String html) {\r
+    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
+   * 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(Element elem) {\r
+    return wrapAll($(elem));\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(GQuery query) {\r
+    GQuery wrap = query.clone();\r
+    if (elements.getItem(0).getParentNode() != null) {\r
+      wrap.insertBefore(elements.getItem(0));\r
+    }\r
+    for (Element e : wrap.elements()) {\r
+      Node n = e;\r
+      while (n.getFirstChild() != null) {\r
+        n = n.getFirstChild();\r
+        $((Element) n).append(this);\r
+      }\r
+    }\r
+    return this;\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
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * 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
+  }\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
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * 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
+  }\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
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * 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
+  }\r
+\r
+  protected GQuery pushStack(JSArray elts, String name, String selector) {\r
+    GQuery g = new GQuery(elts);\r
+    g.setPreviousObject(this);\r
+    g.setSelector(selector);\r
+    return g;\r
+  }\r
+\r
+  private void allNextSiblingElements(Element firstChildElement, JSArray result,\r
+      Element elem) {\r
+    while (firstChildElement != null) {\r
+      if (firstChildElement != elem) {\r
+        result.addNode(firstChildElement);\r
+      }\r
+      firstChildElement = firstChildElement.getNextSiblingElement();\r
+    }\r
+  }\r
+\r
+  private void allPreviousSiblingElements(Element firstChildElement,\r
+      JSArray result) {\r
+    while (firstChildElement != null) {\r
+      result.addNode(firstChildElement);\r
+      firstChildElement = getPreviousSiblingElement(firstChildElement);\r
+    }\r
+  }\r
+\r
+  private 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.get().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
+  private <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
+    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 ? value : id;\r
+  }\r
+\r
+  private void dequeue(Element elem, String type) {\r
+    Queue<Function> q = queue(elem, type, null);\r
+    Function f = q.dequeue();\r
+\r
+    if (q != null) {\r
+      if (SelectorEngine.eq(type, "__FX")) {\r
+        f = q.peek(0);\r
+      }\r
+      if (f != null) {\r
+        f.f(elem);\r
+      }\r
+    }\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
+    for (Element e : elements()) {\r
+      for (int i = 0; i < nodes.getLength(); i++) {\r
+        Node n = nodes.getItem(i);\r
+        if(size() > 1) n=n.cloneNode(true);\r
+        \r
+        switch (func) {\r
+          case FUNC_PREPEND:\r
+            e.insertBefore(n, e.getFirstChild());\r
+            break;\r
+          case FUNC_APPEND:\r
+            e.appendChild(n);\r
+            break;\r
+          case FUNC_AFTER:\r
+            e.getParentNode().insertBefore(n, e.getNextSibling());\r
+            break;\r
+          case FUNC_BEFORE:\r
+            e.getParentNode().insertBefore(n, e);\r
+            break;\r
+        }\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  private String fixAttributeName(String key) {\r
+    return key;\r
+  }\r
+\r
+  private native Document getContentDocument(Node n) /*-{\r
+    return n.contentDocument || n.contentWindow.document;\r
+  }-*/;\r
+\r
+  private native Element getPreviousSiblingElement(Element elem)  /*-{\r
+    var sib = elem.previousSibling;\r
+    while (sib && sib.nodeType != 1)\r
+      sib = sib.previousSibling;\r
+    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 = JSArray.create();\r
+    for (int i = 0; i < first.getLength(); i++) {\r
+      res.addNode(first.getItem(i));\r
+    }\r
+    for (int i = 0; i < second.getLength(); i++) {\r
+      res.addNode(second.getItem(i));\r
+    }\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
+    }\r
+    return 0;\r
+  }\r
+\r
+  private Queue<Function> queue(Element elem, String type, Function data) {\r
+    if (elem != null) {\r
+      type = type + "queue";\r
+      Object q = (Queue) data(elem, type, null);\r
+      if (q == null) {\r
+        q = data(elem, type, Queue.newInstance());\r
+      }\r
+      Queue<Function> qq = (Queue<Function>) q;\r
+      if (data != null) {\r
+        qq.enqueue(data);\r
+      }\r
+      if (SelectorEngine.eq(type, "__FX") && qq.length() == 1) {\r
+        data.f(elem);\r
+      }\r
+      return qq;\r
+    }\r
+    return null;\r
+  }\r
+\r
+  private void removeData(Element item, String name) {\r
+    if (dataCache == null) {\r
+      windowData = JavaScriptObject.createObject().cast();\r
+      dataCache = JavaScriptObject.createObject().cast();\r
+    }\r
+    item = item == window() ? windowData : item;\r
+    int id = item.hashCode();\r
+    if (name != null) {\r
+      if (!dataCache.exists(id)) {\r
+        dataCache.getCache(id).delete(name);\r
+      }\r
+      if (dataCache.getCache(id).isEmpty()) {\r
+        removeData(item, null);\r
+      }\r
+    } else {\r
+      dataCache.delete(id);\r
+    }\r
+  }\r
+\r
+  private void replacequeue(Element elem, String type, Queue data) {\r
+    if (elem != null) {\r
+      type = type + "queue";\r
+      Object q = (Queue) data(elem, type, null);\r
+      data(elem, type, data);\r
+    }\r
+  }\r
+\r
+  private GQuery trigger(NativeEvent event, Object o) {\r
+    for (Element e : elements()) {\r
+      e.dispatchEvent(event);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  private native Element window() /*-{\r
+    return $wnd;\r
+  }-*/;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/JSArray.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/JSArray.java
new file mode 100644 (file)
index 0000000..87242f5
--- /dev/null
@@ -0,0 +1,72 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.core.client.JavaScriptObject;\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
+\r
+/**\r
+ */\r
+public class JSArray extends NodeList<Element> {\r
+\r
+  public static JSArray create() {\r
+    return (JSArray) JavaScriptObject.createArray();\r
+  }\r
+\r
+  public static native JSArray create(Node node) /*-{\r
+    return [node];\r
+  }-*/;\r
+\r
+  public static native JSArray create(NodeList nl) /*-{\r
+    var r = [], len=nl.length;\r
+    for(var i=0; i<len; i++) {\r
+      r.push(nl[i]);\r
+    }\r
+    return r;\r
+  }-*/;\r
+\r
+  protected JSArray() {\r
+  }\r
+\r
+  public final native void addInt(int i) /*-{\r
+       this[this.length]=i;\r
+  }-*/;\r
+\r
+  public final native void addNode(Node n) /*-{\r
+     this[this.length]=n;\r
+  }-*/;\r
+\r
+  public final native void addNode(Node ci, int i) /*-{\r
+       this[i]=ci;\r
+    }-*/;\r
+\r
+  public final native void concat(JSArray ary) /*-{\r
+     this.concat(ary);\r
+  }-*/;\r
+\r
+  public final native Element getElement(int i) /*-{\r
+        return this[i];\r
+    }-*/;\r
+\r
+  public final native int getInt(int i) /*-{\r
+    return this[i]  || 0;\r
+  }-*/;\r
+\r
+  public final native Node getNode(int i) /*-{\r
+        return this[i];\r
+  }-*/;\r
+\r
+  public final native String getStr(int i) /*-{\r
+     return this[i] || null;\r
+  }-*/;\r
+\r
+  public final void pushAll(JSArray prevElem) {\r
+    for (int i = 0, ilen = prevElem.size(); i < ilen; i++) {\r
+      addNode(prevElem.getNode(i));\r
+    }\r
+  }\r
+\r
+  public final native int size() /*-{\r
+     return this.length;\r
+  }-*/;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Plugin.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Plugin.java
new file mode 100644 (file)
index 0000000..64b92af
--- /dev/null
@@ -0,0 +1,16 @@
+package com.google.gwt.query.client;\r
+\r
+/**\r
+ * A GQuery plugin. All GQuery plugins must implement this interface.\r
+ */\r
+public interface Plugin<T extends GQuery> {\r
+\r
+  /**\r
+   * Called by the GQuery.as() method in order to pass the current matched\r
+   * set. Typically a plugin will want to call a super class copy constructor\r
+   * in order to copy the internal matched set of elements.\r
+   * @param gQuery\r
+   * @return\r
+   */\r
+     T init(GQuery gQuery);\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java
new file mode 100644 (file)
index 0000000..89d78f2
--- /dev/null
@@ -0,0 +1,10 @@
+package com.google.gwt.query.client;
+
+import com.google.gwt.dom.client.Element;
+
+/**
+ * A predicate function used by some GQuery methods.
+ */
+public interface Predicate {
+    boolean f(Element e, int index);
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java
new file mode 100644 (file)
index 0000000..c2954a4
--- /dev/null
@@ -0,0 +1,51 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.core.client.JavaScriptObject;\r
+import com.google.gwt.core.client.JsArrayString;\r
+\r
+/**\r
+ * JSO for accessing Javascript objective literals used by GwtQuery functions.\r
+ */\r
+public class Properties extends JavaScriptObject {\r
+\r
+  protected Properties() {\r
+  }\r
+\r
+  public static Properties create(String properties) {\r
+    String s = properties.replaceFirst("^[({]*(.*)[})]*$", "({$1})");\r
+    return (Properties) createImpl(s);\r
+  }\r
+\r
+  public final native static JavaScriptObject createImpl(String properties) /*-{\r
+      return eval(properties);\r
+    }-*/;\r
+\r
+  public final native String get(String name) /*-{\r
+    return this[name];\r
+  }-*/;\r
+\r
+  public final native int getInt(String name) /*-{\r
+    return this[name];\r
+  }-*/;\r
+\r
+  public final native float getFloat(String name) /*-{\r
+    return this[name];\r
+  }-*/;\r
+\r
+  public final String[] keys() {\r
+    JsArrayString a = keysImpl();\r
+    String[] ret = new String[a.length()];\r
+    for (int i = 0; i < a.length(); i++) {\r
+      ret[i] = "" + a.get(i);\r
+    }\r
+    return ret;\r
+  }\r
+\r
+  public final native JsArrayString keysImpl() /*-{\r
+    var key, keys=[];\r
+    for(key in this) {\r
+      keys.push("" + key); \r
+    }\r
+    return keys;\r
+  }-*/;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Regexp.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Regexp.java
new file mode 100644 (file)
index 0000000..8a33ffd
--- /dev/null
@@ -0,0 +1,56 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.core.client.JavaScriptObject;\r
+\r
+/**\r
+ * A wrapper around Javascript Regexps.\r
+ */\r
+public class Regexp {\r
+\r
+  private final JavaScriptObject regexp;\r
+\r
+  public Regexp(String pattern) {\r
+    this.regexp = compile(pattern);\r
+  }\r
+\r
+  public Regexp(String pat, String flags) {\r
+    this.regexp = compileFlags(pat, flags);\r
+  }\r
+\r
+  public static  native JavaScriptObject compile(String pat) /*-{\r
+     return new RegExp(pat);\r
+  }-*/;\r
+  \r
+   public static  native JavaScriptObject compileFlags(String pat, String flags) /*-{\r
+     return new RegExp(pat, flags);\r
+  }-*/;\r
+  \r
+   public JSArray exec(String str) {\r
+     return exec0(regexp, str);\r
+   }\r
+\r
+  \r
+  private static native JSArray exec0(JavaScriptObject regexp, String str) /*-{\r
+    return regexp.exec(str);\r
+  }-*/;\r
+\r
+  public JSArray match(String currentRule) {\r
+    return match0(regexp, currentRule);\r
+  }\r
+\r
+  private native JSArray match0(JavaScriptObject regexp, String currentRule)/*-{\r
+    return currentRule.match(regexp);\r
+  }-*/;\r
+\r
+  public boolean test(String rule) {\r
+    return test0(regexp, rule);\r
+  }\r
+\r
+  private native boolean test0(JavaScriptObject regexp, String rule) /*-{\r
+    return regexp.test(rule);\r
+  }-*/;\r
+\r
+  public static JSArray match(String regexp, String flags, String string) {\r
+    return new Regexp(regexp, flags).match(string);\r
+  }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Selector.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Selector.java
new file mode 100644 (file)
index 0000000..23eae98
--- /dev/null
@@ -0,0 +1,15 @@
+package com.google.gwt.query.client;\r
+\r
+import java.lang.annotation.Target;\r
+import java.lang.annotation.Retention;\r
+import java.lang.annotation.RetentionPolicy;\r
+import static java.lang.annotation.ElementType.METHOD;\r
+\r
+/**\r
+ * Used to pass a CSS Selector to a generator at compile time\r
+ */\r
+@Target({METHOD})\r
+@Retention(RetentionPolicy.RUNTIME)\r
+public @interface Selector {\r
+   String value();\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/SelectorEngine.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/SelectorEngine.java
new file mode 100644 (file)
index 0000000..ebe3624
--- /dev/null
@@ -0,0 +1,97 @@
+package com.google.gwt.query.client;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.JavaScriptObject;\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
+import com.google.gwt.query.client.impl.SelectorEngineImpl;\r
+\r
+\r
+/**\r
+ *  Core Selector engine functions, and native JS utility functions.\r
+ */\r
+public class SelectorEngine {\r
+\r
+  private SelectorEngineImpl impl;\r
+\r
+  public SelectorEngine() {\r
+    impl = (SelectorEngineImpl) GWT.create(SelectorEngineImpl.class);\r
+  }\r
+\r
+  public static native boolean eq(String s1, String s2) /*-{\r
+       return s1 == s2;\r
+    }-*/;\r
+\r
+  public static native NodeList<Element> getElementsByClassName(String clazz,\r
+      Node ctx) /*-{\r
+        return ctx.getElementsByClassName(clazz);\r
+    }-*/;\r
+\r
+  public  static native <T> T or(T s1, T s2) /*-{\r
+       return s1 || s2;\r
+    }-*/;\r
+\r
+  public static native NodeList<Element> querySelectorAll(String selector) /*-{\r
+      return $doc.querySelectorAll(selector);\r
+  }-*/;\r
+\r
+  public static native NodeList<Element> querySelectorAll(String selector,\r
+      Node ctx) /*-{\r
+      return ctx.querySelectorAll(selector);\r
+  }-*/;\r
+\r
+  public NodeList<Element> select(String selector, Node ctx) {\r
+    return impl.select(selector, ctx);\r
+  }\r
+\r
+  public static boolean truth(String a) {\r
+    return GWT.isScript() ? truth0(a) : a != null && !"".equals(a);\r
+  }\r
+\r
+  public static boolean truth(JavaScriptObject a) {\r
+    return GWT.isScript() ? truth0(a) : a != null;\r
+  }\r
+\r
+  public static NodeList<Element> xpathEvaluate(String selector, Node ctx) {\r
+    return xpathEvaluate(selector, ctx, JSArray.create());\r
+  }\r
+\r
+  public static native NodeList<Element> xpathEvaluate(String selector,\r
+      Node ctx, JSArray r) /*-{\r
+      var node;\r
+      var result = $doc.evaluate(selector, ctx, null, 0, null);\r
+      while ((node = result.iterateNext())) {\r
+          r.push(node);\r
+      }\r
+      return r;\r
+  }-*/;\r
+\r
+  private static native boolean truth0(String a) /*-{\r
+       return a;\r
+    }-*/;\r
+\r
+  private static native boolean truth0(JavaScriptObject a) /*-{\r
+         return a;\r
+      }-*/;\r
+\r
+  protected JSArray veryQuickId(Node context, String id) {\r
+    JSArray r = JSArray.create();\r
+    if (context.getNodeType() == Node.DOCUMENT_NODE) {\r
+      r.addNode(((Document) context).getElementById(id));\r
+      return r;\r
+    } else {\r
+      r.addNode(context.getOwnerDocument().getElementById(id));\r
+      return r;\r
+    }\r
+  }\r
+\r
+  public static native Node getNextSibling(Node n) /*-{\r
+       return n.nextSibling || null; \r
+    }-*/;\r
+\r
+  public static native Node getPreviousSibling(Node n) /*-{\r
+       return n.previousSibling || null; \r
+    }-*/;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Selectors.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Selectors.java
new file mode 100644 (file)
index 0000000..062df40
--- /dev/null
@@ -0,0 +1,8 @@
+package com.google.gwt.query.client;\r
+\r
+/**\r
+ * Tagging interface used to generate compile time selectors.\r
+ */\r
+public interface Selectors {\r
+    DeferredGQuery[] getAllSelectors();\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImpl.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImpl.java
new file mode 100644 (file)
index 0000000..eb3aa74
--- /dev/null
@@ -0,0 +1,41 @@
+package com.google.gwt.query.client.impl;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.SelectorEngine;
+import com.google.gwt.query.client.GQuery;
+
+/**
+ * A helper class to get computed CSS styles for elements.
+ */
+public class DocumentStyleImpl {
+
+  public String getPropertyName(String name) {
+    if ("float".equals(name)) {
+      return "cssFloat";
+    } else if ("class".equals(name)) {
+      return "className";
+    } else if ("for".equals(name)) {
+      return "htmlFor";
+    }
+    return GQuery.camelize(name);
+  }
+
+  public String getCurrentStyle(Element elem, String name) {
+    name = hyphenize(name);
+    String propVal = getComputedStyle(elem, name, null);
+    if ("opacity".equals(name)) {
+      propVal = SelectorEngine.or(propVal, "1");
+    }
+    return propVal;
+  }
+
+  protected native String hyphenize(String name) /*-{
+      return name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+  }-*/;
+
+  private native String getComputedStyle(Element elem, String name,
+      String pseudo) /*-{
+       var cStyle = $doc.defaultView.getComputedStyle( elem, pseudo );
+        return cStyle ? cStyle.getPropertyValue( name ) : null;
+  }-*/;
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImplIE.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/DocumentStyleImplIE.java
new file mode 100644 (file)
index 0000000..1445024
--- /dev/null
@@ -0,0 +1,56 @@
+package com.google.gwt.query.client.impl;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.SelectorEngine;
+
+/**
+ * A helper class to get computed CSS styles for elements on IE6.
+ */
+public class DocumentStyleImplIE extends DocumentStyleImpl {
+
+  public String getPropertyName(String name) {
+    if ("float".equals(name)) {
+      return "styleFloat";
+    } else if ("class".equals(name)) {
+      return "className";
+    } else if ("for".equals(name)) {
+      return "htmlFor";
+    }
+    return name;
+  }
+
+  public String getCurrentStyle(Element elem, String name) {
+    name = hyphenize(name);
+    String propVal = getComputedStyle(elem, name, null);
+    if ("opacity".equals(name)) {
+      propVal = SelectorEngine.or(propVal, "1");
+    }
+    return propVal;
+  }
+
+  // code lifted from jQuery
+  private native String getComputedStyle(Element elem, String name,
+      String pseudo) /*-{
+    var style = elem.style;
+    var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+                               return letter.toUpperCase();
+                       });
+    var ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+       // From the awesome hack by Dean Edwards
+        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+        // If we're not dealing with a regular pixel number
+       // but a number that has a weird ending, we need to convert it to pixels
+       if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+               // Remember the original values
+               var left = style.left, rsLeft = elem.runtimeStyle.left;
+               // Put in the new values to get a computed value out
+               elem.runtimeStyle.left = elem.currentStyle.left;
+               style.left = ret || 0;
+               ret = style.pixelLeft + "px";
+                // Revert the changed values
+               style.left = left;
+               elem.runtimeStyle.left = rsLeft;
+    }  
+    return ret;
+  }-*/;
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineImpl.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineImpl.java
new file mode 100644 (file)
index 0000000..d42e7fa
--- /dev/null
@@ -0,0 +1,106 @@
+package com.google.gwt.query.client.impl;\r
+\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
+import com.google.gwt.query.client.JSArray;\r
+import com.google.gwt.query.client.Regexp;\r
+import com.google.gwt.query.client.SelectorEngine;\r
+\r
+/**\r
+ * Base/Utility class for runtime selector engine implementations.\r
+ */\r
+public abstract class SelectorEngineImpl {\r
+\r
+  public abstract NodeList<Element> select(String selector, Node ctx);\r
+\r
+  protected static Sequence getSequence(String expression) {\r
+    int start = 0, add = 2, max = -1, modVal = -1;\r
+    Regexp expressionRegExp = new Regexp(\r
+        "^((odd|even)|([1-9]\\d*)|((([1-9]\\d*)?)n((\\+|\\-)(\\d+))?)|(\\-(([1-9]\\d*)?)n\\+(\\d+)))$");\r
+    JSArray pseudoValue = expressionRegExp.exec(expression);\r
+    if (!SelectorEngine.truth(pseudoValue)) {\r
+      return null;\r
+    } else {\r
+      if (SelectorEngine.truth(pseudoValue.getStr(2))) {        // odd or even\r
+        start = (SelectorEngine.eq(pseudoValue.getStr(2), "odd")) ? 1 : 2;\r
+        modVal = (start == 1) ? 1 : 0;\r
+      } else if (SelectorEngine\r
+          .truth(pseudoValue.getStr(3))) {        // single digit\r
+        start = Integer.parseInt(pseudoValue.getStr(3), 10);\r
+        add = 0;\r
+        max = start;\r
+      } else if (SelectorEngine.truth(pseudoValue.getStr(4))) {        // an+b\r
+        add = SelectorEngine.truth(pseudoValue.getStr(6)) ? Integer\r
+            .parseInt(pseudoValue.getStr(6), 10) : 1;\r
+        start = SelectorEngine.truth(pseudoValue.getStr(7)) ? Integer.parseInt(\r
+            (pseudoValue.getStr(8).charAt(0) == '+' ? ""\r
+                : pseudoValue.getStr(8)) + pseudoValue.getStr(9), 10) : 0;\r
+        while (start < 1) {\r
+          start += add;\r
+        }\r
+        modVal = (start > add) ? (start - add) % add\r
+            : ((start == add) ? 0 : start);\r
+      } else if (SelectorEngine.truth(pseudoValue.getStr(10))) {        // -an+b\r
+        add = SelectorEngine.truth(pseudoValue.getStr(12)) ? Integer\r
+            .parseInt(pseudoValue.getStr(12), 10) : 1;\r
+        start = max = Integer.parseInt(pseudoValue.getStr(13), 10);\r
+        while (start > add) {\r
+          start -= add;\r
+        }\r
+        modVal = (max > add) ? (max - add) % add : ((max == add) ? 0 : max);\r
+      }\r
+    }\r
+    Sequence s = new Sequence();\r
+    s.start = start;\r
+    s.add = add;\r
+    s.max = max;\r
+    s.modVal = modVal;\r
+    return s;\r
+  }\r
+\r
+  public static class Sequence {\r
+\r
+    public int start;\r
+\r
+    public int max;\r
+\r
+    public int add;\r
+\r
+    public int modVal;\r
+  }\r
+\r
+  public static class SplitRule {\r
+\r
+    public String tag;\r
+\r
+    public String id;\r
+\r
+    public String allClasses;\r
+\r
+    public String allAttr;\r
+\r
+    public String allPseudos;\r
+\r
+    public String tagRelation;\r
+\r
+    public SplitRule(String tag, String id, String allClasses, String allAttr,\r
+        String allPseudos) {\r
+      this.tag = tag;\r
+      this.id = id;\r
+      this.allClasses = allClasses;\r
+      this.allAttr = allAttr;\r
+      this.allPseudos = allPseudos;\r
+    }\r
+\r
+    public SplitRule(String tag, String id, String allClasses, String allAttr,\r
+        String allPseudos, String tagRelation) {\r
+      this.tag = tag;\r
+      this.id = id;\r
+      this.allClasses = allClasses;\r
+      this.allAttr = allAttr;\r
+      this.allPseudos = allPseudos;\r
+      this.tagRelation = tagRelation;\r
+    }\r
+  }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJS.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJS.java
new file mode 100644 (file)
index 0000000..6c46e4d
--- /dev/null
@@ -0,0 +1,689 @@
+package com.google.gwt.query.client.impl;\r
+\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
+import com.google.gwt.query.client.SelectorEngine;\r
+import com.google.gwt.query.client.Regexp;\r
+import com.google.gwt.query.client.JSArray;\r
+\r
+/**\r
+ * Runtime selector engine implementation with no-XPath/native support based\r
+ * on DOMAssistant.\r
+ */\r
+public class SelectorEngineJS extends SelectorEngineImpl {\r
+    private Regexp cssSelectorRegExp;\r
+    private Regexp selectorSplitRegExp;\r
+    private Regexp childOrSiblingRefRegExp;\r
+\r
+\r
+    public SelectorEngineJS() {\r
+        selectorSplitRegExp = new Regexp("[^\\s]+", "g");\r
+        childOrSiblingRefRegExp = new Regexp("^(>|\\+|~)$");\r
+        cssSelectorRegExp = new Regexp(\r
+                "^(\\w+)?(#[\\w\\u00C0-\\uFFFF\\-\\_]+|(\\*))?((\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[\\w\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[\\w\\u00C0-\\uFFFF\\-_]+|((\\w*\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[\\w\\-]*))\\))?)*)?");\r
+    }\r
+\r
+    public static void clearAdded(JSArray a) {\r
+        for (int i = 0, len = a.size(); i < len; i++) {\r
+            clearAdded(a.getNode(i));\r
+        }\r
+    }\r
+\r
+    public static native void clearAdded(Node node) /*-{\r
+      node.added = null;\r
+    }-*/;\r
+\r
+    public static native NodeList<Element> getElementsByClassName(String clazz,\r
+                                                                  Node ctx) /*-{\r
+      return ctx.getElementsByClassName(clazz);\r
+  }-*/;\r
+\r
+    public static native boolean isAdded(Node prevRef) /*-{\r
+      return prevRef.added || false;\r
+    }-*/;\r
+\r
+    public static native void setAdded(Node prevRef, boolean added) /*-{\r
+      prevRef.added = added;\r
+    }-*/;\r
+\r
+    public static native void setSkipTag(JSArray prevElem, boolean skip) /*-{\r
+      prevElem.skipTag = skip;\r
+    }-*/;\r
+\r
+    private static String attrToRegExp(String attrVal, String op) {\r
+        if (SelectorEngine.eq("^", op)) {\r
+            return "^" + attrVal;\r
+        }\r
+        if (SelectorEngine.eq("$", op)) {\r
+            return attrVal + "$";\r
+        }\r
+        if (SelectorEngine.eq("*", op)) {\r
+            return attrVal;\r
+        }\r
+        if (SelectorEngine.eq("|", op)) {\r
+            return "(^" + attrVal + "(\\-\\w+)*$)";\r
+        }\r
+        if (SelectorEngine.eq("~", op)) {\r
+            return "\\b" + attrVal + "\\b";\r
+        }\r
+        return SelectorEngine.truth(attrVal) ? "^" + attrVal + "$" : null;\r
+    }\r
+\r
+    private static void clearChildElms(JSArray prevParents) {\r
+        for (int n = 0, nl = prevParents.size(); n < nl; n++) {\r
+            setHasChildElms(prevParents.getNode(n), false);\r
+        }\r
+    }\r
+\r
+    protected String getAttr(Element current, String name) {\r
+        return current.getAttribute(name);\r
+    }\r
+\r
+    private static void getDescendantNodes(JSArray matchingElms,\r
+                                           String nextTagStr, Node prevRef) {\r
+        NodeList<Element> children = getElementsByTagName(nextTagStr, prevRef);\r
+        for (int k = 0, klen = children.getLength(); k < klen; k++) {\r
+            Node child = children.getItem(k);\r
+            if (child.getParentNode() == prevRef) {\r
+                matchingElms.addNode(child);\r
+            }\r
+        }\r
+    }\r
+\r
+    private JSArray getElementsByPseudo(JSArray previousMatch, String pseudoClass,\r
+                                        String pseudoValue) {\r
+        JSArray prevParents = JSArray.create();\r
+        boolean previousDir = pseudoClass.startsWith("first") ? true : false;\r
+        JSArray matchingElms = JSArray.create();\r
+        Node prev, next, previous;\r
+        if (SelectorEngine.eq("first-child", pseudoClass) || SelectorEngine\r
+                .eq("last-child", pseudoClass)) {\r
+            getFirstChildPseudo(previousMatch, previousDir, matchingElms);\r
+        } else if (SelectorEngine.eq("only-child", pseudoClass)) {\r
+            getOnlyChildPseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("nth-child", pseudoClass)) {\r
+            matchingElms = getNthChildPseudo(previousMatch, pseudoValue, prevParents,\r
+                    matchingElms);\r
+        } else if (SelectorEngine.eq("first-of-type", pseudoClass) || SelectorEngine\r
+                .eq("last-of-type", pseudoClass)) {\r
+            getFirstOfTypePseudo(previousMatch, previousDir, matchingElms);\r
+        } else if (SelectorEngine.eq("only-of-type", pseudoClass)) {\r
+            getOnlyOfTypePseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("nth-of-type", pseudoClass)) {\r
+            matchingElms = getNthOfTypePseudo(previousMatch, pseudoValue, prevParents,\r
+                    matchingElms);\r
+        } else if (SelectorEngine.eq("empty", pseudoClass)) {\r
+            getEmptyPseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("enabled", pseudoClass)) {\r
+            getEnabledPseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("disabled", pseudoClass)) {\r
+            getDisabledPseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("checked", pseudoClass)) {\r
+            getCheckedPseudo(previousMatch, matchingElms);\r
+        } else if (SelectorEngine.eq("contains", pseudoClass)) {\r
+            getContainsPseudo(previousMatch, pseudoValue, matchingElms);\r
+        } else if (SelectorEngine.eq("not", pseudoClass)) {\r
+            matchingElms = getNotPseudo(previousMatch, pseudoValue, matchingElms);\r
+        } else {\r
+            getDefaultPseudo(previousMatch, pseudoClass, pseudoValue, matchingElms);\r
+        }\r
+        return matchingElms;\r
+    }\r
+\r
+    private void getDefaultPseudo(JSArray previousMatch, String pseudoClass,\r
+                                  String pseudoValue, JSArray matchingElms) {\r
+        Node previous;\r
+        for (int w = 0, wlen = previousMatch.size(); w < wlen; w++) {\r
+            previous = previousMatch.getElement(w);\r
+            if (SelectorEngine\r
+                    .eq(((Element) previous).getAttribute(pseudoClass), pseudoValue)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private JSArray getNotPseudo(JSArray previousMatch, String pseudoValue,\r
+                                 JSArray matchingElms) {\r
+        if (new Regexp("(:\\w+[\\w\\-]*)$").test(pseudoValue)) {\r
+            matchingElms = subtractArray(previousMatch,\r
+                    getElementsByPseudo(previousMatch, pseudoValue.substring(1), ""));\r
+        } else {\r
+            pseudoValue = pseudoValue\r
+                    .replace("^\\[#([\\w\\u00C0-\\uFFFF\\-\\_]+)\\]$", "[id=$1]");\r
+            JSArray notTag = new Regexp("^(\\w+)").exec(pseudoValue);\r
+            JSArray notClass = new Regexp("^\\.([\\w\u00C0-\uFFFF\\-_]+)")\r
+                    .exec(pseudoValue);\r
+            JSArray notAttr = new Regexp(\r
+                    "\\[(\\w+)(\\^|\\$|\\*|\\||~)?=?([\\w\\u00C0-\\uFFFF\\s\\-_\\.]+)?\\]")\r
+                    .exec(pseudoValue);\r
+            Regexp notRegExp = new Regexp(\r
+                    "(^|\\s)" + (SelectorEngine.truth(notTag) ? notTag\r
+                            .getStr(1)\r
+                            : SelectorEngine.truth(notClass) ? notClass.getStr(1) : "")\r
+                            + "(\\s|$)", "i");\r
+            if (SelectorEngine.truth(notAttr)) {\r
+                String notAttribute = SelectorEngine.truth(notAttr.getStr(3)) ? notAttr\r
+                        .getStr(3)\r
+                        .replace("\\.", "\\.") : null;\r
+                String notMatchingAttrVal = attrToRegExp(notAttribute,\r
+                        notAttr.getStr(2));\r
+                notRegExp = new Regexp(notMatchingAttrVal, "i");\r
+            }\r
+            for (int v = 0, vlen = previousMatch.size(); v < vlen; v++) {\r
+                Element notElm = previousMatch.getElement(v);\r
+                Element addElm = null;\r
+                if (SelectorEngine.truth(notTag) && !notRegExp\r
+                        .test(notElm.getNodeName())) {\r
+                    addElm = notElm;\r
+                } else if (SelectorEngine.truth(notClass) && !notRegExp\r
+                        .test(notElm.getClassName())) {\r
+                    addElm = notElm;\r
+                } else if (SelectorEngine.truth(notAttr)) {\r
+                    String att = getAttr(notElm, notAttr.getStr(1));\r
+                    if (!SelectorEngine.truth(att) || !notRegExp.test(att)) {\r
+                        addElm = notElm;\r
+                    }\r
+                }\r
+                if (SelectorEngine.truth(addElm) && !isAdded(addElm)) {\r
+                    setAdded(addElm, true);\r
+                    matchingElms.addNode(addElm);\r
+                }\r
+            }\r
+        }\r
+        return matchingElms;\r
+    }\r
+\r
+    private void getContainsPseudo(JSArray previousMatch, String pseudoValue,\r
+                                   JSArray matchingElms) {\r
+        Node previous;\r
+        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
+            previous = previousMatch.getNode(q);\r
+            if (!isAdded(previous)) {\r
+                if (((Element) previous).getInnerText().indexOf(pseudoValue) != -1) {\r
+                    setAdded(previous, true);\r
+                    matchingElms.addNode(previous);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getCheckedPseudo(JSArray previousMatch, JSArray matchingElms) {\r
+        Node previous;\r
+        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
+            previous = previousMatch.getNode(q);\r
+            if (checked(previous)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getDisabledPseudo(JSArray previousMatch, JSArray matchingElms) {\r
+        Node previous;\r
+        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
+            previous = previousMatch.getNode(q);\r
+            if (!enabled(previous)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getEnabledPseudo(JSArray previousMatch, JSArray matchingElms) {\r
+        Node previous;\r
+        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
+            previous = previousMatch.getNode(q);\r
+            if (enabled(previous)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getEmptyPseudo(JSArray previousMatch, JSArray matchingElms) {\r
+        Node previous;\r
+        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
+            previous = previousMatch.getNode(q);\r
+            if (!previous.hasChildNodes()) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private JSArray getNthOfTypePseudo(JSArray previousMatch, String pseudoValue,\r
+                                       JSArray prevParents, JSArray matchingElms) {\r
+        Node previous;\r
+        if (pseudoValue.startsWith("n")) {\r
+            matchingElms = previousMatch;\r
+        } else {\r
+            Sequence sequence = getSequence(pseudoValue);\r
+            if (sequence != null) {\r
+                for (int p = 0, plen = previousMatch.size(); p < plen; p++) {\r
+                    previous = previousMatch.getNode(p);\r
+                    Node prevParent = previous.getParentNode();\r
+                    if (!hasChildElms(prevParent)) {\r
+                        int iteratorNext = sequence.start;\r
+                        int childCount = 0;\r
+                        Node childElm = prevParent.getFirstChild();\r
+                        while (SelectorEngine.truth(childElm) && (sequence.max < 0\r
+                                || iteratorNext <= sequence.max)) {\r
+                            if (SelectorEngine\r
+                                    .eq(childElm.getNodeName(), previous.getNodeName())) {\r
+                                if (++childCount == iteratorNext) {\r
+                                    matchingElms.addNode(childElm);\r
+                                    iteratorNext += sequence.add;\r
+                                }\r
+                            }\r
+                            childElm = SelectorEngine.getNextSibling(childElm);\r
+                        }\r
+                        setHasChildElms(prevParent, true);\r
+                        prevParents.addNode(prevParent);\r
+                    }\r
+                }\r
+                clearChildElms(prevParents);\r
+            }\r
+        }\r
+        return matchingElms;\r
+    }\r
+\r
+    private void getOnlyOfTypePseudo(JSArray previousMatch,\r
+                                     JSArray matchingElms) {\r
+        Node previous;\r
+        Node next;\r
+        Node prev;\r
+        Node oParent = null;\r
+        for (int o = 0, olen = previousMatch.size(); o < olen; o++) {\r
+            prev = next = previous = previousMatch.getNode(o);\r
+            Node prevParent = previous.getParentNode();\r
+            if (prevParent != oParent) {\r
+                while (\r
+                        SelectorEngine.truth(prev = SelectorEngine.getPreviousSibling(prev))\r
+                                && !SelectorEngine\r
+                                .eq(prev.getNodeName(), previous.getNodeName())) {\r
+                }\r
+                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
+                        && !SelectorEngine.eq(next.getNodeName(), previous.getNodeName())) {\r
+                }\r
+                if (!SelectorEngine.truth(prev) && !SelectorEngine.truth(next)) {\r
+                    matchingElms.addNode(previous);\r
+                }\r
+                oParent = prevParent;\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getFirstOfTypePseudo(JSArray previousMatch, boolean previousDir,\r
+                                      JSArray matchingElms) {\r
+        Node previous;\r
+        Node next;\r
+        for (int n = 0, nlen = previousMatch.size(); n < nlen; n++) {\r
+            next = previous = previousMatch.getNode(n);\r
+\r
+            if (previousDir) {\r
+                while (\r
+                        SelectorEngine.truth(next = SelectorEngine.getPreviousSibling(next))\r
+                                && !SelectorEngine\r
+                                .eq(next.getNodeName(), previous.getNodeName())) {\r
+                }\r
+            } else {\r
+                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
+                        && !SelectorEngine.eq(next.getNodeName(), previous.getNodeName())) {\r
+                }\r
+            }\r
+\r
+            if (!SelectorEngine.truth(next)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private JSArray getNthChildPseudo(JSArray previousMatch, String pseudoValue,\r
+                                      JSArray prevParents, JSArray matchingElms) {\r
+        Node previous;\r
+        if (SelectorEngine.eq(pseudoValue, "n")) {\r
+            matchingElms = previousMatch;\r
+        } else {\r
+            Sequence sequence = getSequence(pseudoValue);\r
+            if (sequence != null) {\r
+                for (int l = 0, llen = previousMatch.size(); l < llen; l++) {\r
+                    previous = previousMatch.getNode(l);\r
+                    Node prevParent = previous.getParentNode();\r
+                    if (!hasChildElms(prevParent)) {\r
+                        int iteratorNext = sequence.start;\r
+                        int childCount = 0;\r
+                        Node childElm = prevParent.getFirstChild();\r
+                        while (childElm != null && (sequence.max < 0\r
+                                || iteratorNext <= sequence.max)) {\r
+                            if (childElm.getNodeType() == Node.ELEMENT_NODE) {\r
+                                if (++childCount == iteratorNext) {\r
+                                    if (SelectorEngine\r
+                                            .eq(childElm.getNodeName(), previous.getNodeName())) {\r
+                                        matchingElms.addNode(childElm);\r
+                                    }\r
+                                    iteratorNext += sequence.add;\r
+                                }\r
+                            }\r
+                            childElm = SelectorEngine.getNextSibling(childElm);\r
+                        }\r
+                        setHasChildElms(prevParent, true);\r
+                        prevParents.addNode(prevParent);\r
+                    }\r
+                }\r
+                clearChildElms(prevParents);\r
+            }\r
+        }\r
+        return matchingElms;\r
+    }\r
+\r
+    private void getOnlyChildPseudo(JSArray previousMatch, JSArray matchingElms) {\r
+        Node previous;\r
+        Node next;\r
+        Node prev;\r
+        Node kParent = null;\r
+        for (int k = 0, klen = previousMatch.size(); k < klen; k++) {\r
+            prev = next = previous = previousMatch.getNode(k);\r
+            Node prevParent = previous.getParentNode();\r
+            if (prevParent != kParent) {\r
+                while (\r
+                        SelectorEngine.truth(prev = SelectorEngine.getPreviousSibling(prev))\r
+                                && prev.getNodeType() != Node.ELEMENT_NODE) {\r
+                }\r
+                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
+                        && next.getNodeType() != Node.ELEMENT_NODE) {\r
+                }\r
+                if (!SelectorEngine.truth(prev) && !SelectorEngine.truth(next)) {\r
+                    matchingElms.addNode(previous);\r
+                }\r
+                kParent = prevParent;\r
+            }\r
+        }\r
+    }\r
+\r
+    private void getFirstChildPseudo(JSArray previousMatch, boolean previousDir,\r
+                                     JSArray matchingElms) {\r
+        Node next;\r
+        Node previous;\r
+        for (int j = 0, jlen = previousMatch.size(); j < jlen; j++) {\r
+            previous = next = previousMatch.getElement(j);\r
+            if (previousDir) {\r
+                while (SelectorEngine\r
+                        .truth((next = SelectorEngine.getPreviousSibling(next)))\r
+                        && next.getNodeType() != Node.ELEMENT_NODE) {\r
+                }\r
+            } else {\r
+                while (\r
+                        SelectorEngine.truth((next = SelectorEngine.getNextSibling(next)))\r
+                                && next.getNodeType() != Node.ELEMENT_NODE) {\r
+                }\r
+            }\r
+            if (!SelectorEngine.truth(next)) {\r
+                matchingElms.addNode(previous);\r
+            }\r
+        }\r
+    }\r
+\r
+    private static native boolean checked(Node previous) /*-{\r
+    return previous.checked || false;\r
+  }-*/;\r
+\r
+    private static native boolean enabled(Node node) /*-{\r
+    return !node.disabled;\r
+  }-*/;\r
+\r
+    private static NodeList<Element> getElementsByTagName(String tag, Node ctx) {\r
+        return ((Element) ctx).getElementsByTagName(tag);\r
+    }\r
+\r
+    private static void getGeneralSiblingNodes(JSArray matchingElms,\r
+                                               JSArray nextTag, Regexp nextRegExp, Node prevRef) {\r
+        while (\r
+                SelectorEngine.truth((prevRef = SelectorEngine.getNextSibling(prevRef)))\r
+                        && !isAdded(prevRef)) {\r
+            if (!SelectorEngine.truth(nextTag) || nextRegExp\r
+                    .test(prevRef.getNodeName())) {\r
+                setAdded(prevRef, true);\r
+                matchingElms.addNode(prevRef);\r
+            }\r
+        }\r
+    }\r
+\r
+    private static void getSiblingNodes(JSArray matchingElms, JSArray nextTag,\r
+                                        Regexp nextRegExp, Node prevRef) {\r
+        while (\r
+                SelectorEngine.truth(prevRef = SelectorEngine.getNextSibling(prevRef))\r
+                        && prevRef.getNodeType() != Node.ELEMENT_NODE) {\r
+        }\r
+        if (SelectorEngine.truth(prevRef)) {\r
+            if (!SelectorEngine.truth(nextTag) || nextRegExp\r
+                    .test(prevRef.getNodeName())) {\r
+                matchingElms.addNode(prevRef);\r
+            }\r
+        }\r
+    }\r
+\r
+    private static native boolean hasChildElms(Node prevParent) /*-{\r
+      return prevParent.childElms || false;\r
+    }-*/;\r
+\r
+    private static native boolean isSkipped(JSArray prevElem) /*-{\r
+       return prevElem.skipTag || false;\r
+    }-*/;\r
+\r
+    private static native void setHasChildElms(Node prevParent, boolean bool) /*-{\r
+      prevParent.childElms = bool ? bool : null;\r
+    }-*/;\r
+\r
+    private static native JSArray subtractArray(JSArray previousMatch,\r
+                                                JSArray elementsByPseudo) /*-{\r
+      for (var i=0, src1; (src1=arr1[i]); i++) {\r
+        var found = false;\r
+        for (var j=0, src2; (src2=arr2[j]); j++) {\r
+          if (src2 === src1) {\r
+        found = true;\r
+            break;\r
+          }\r
+        }\r
+        if (found) {\r
+          arr1.splice(i--, 1);\r
+        }\r
+      }\r
+      return arr;\r
+    }-*/;\r
+\r
+    public NodeList<Element> select(String sel, Node ctx) {\r
+        String selectors[] = sel.replace("\\s*(,)\\s*", "$1").split(",");\r
+        boolean identical = false;\r
+        JSArray elm = JSArray.create();\r
+        for (int a = 0, len = selectors.length; a < len; a++) {\r
+            if (a > 0) {\r
+                identical = false;\r
+                for (int b = 0, bl = a; b < bl; b++) {\r
+                    if (SelectorEngine.eq(selectors[a], selectors[b])) {\r
+                        identical = true;\r
+                        break;\r
+                    }\r
+                }\r
+                if (identical) {                          \r
+                    continue;\r
+                }\r
+            }\r
+            String currentRule = selectors[a];\r
+            JSArray cssSelectors = selectorSplitRegExp.match(currentRule);\r
+            JSArray prevElem = JSArray.create(ctx);\r
+            for (int i = 0, slen = cssSelectors.size(); i < slen; i++) {\r
+                JSArray matchingElms = JSArray.create();\r
+                String rule = cssSelectors.getStr(i);\r
+                if (i > 0 && childOrSiblingRefRegExp.test(rule)) {\r
+                    JSArray childOrSiblingRef = childOrSiblingRefRegExp.exec(rule);\r
+                    if (SelectorEngine.truth(childOrSiblingRef)) {\r
+                        JSArray nextTag = new Regexp("^\\w+")\r
+                                .exec(cssSelectors.getStr(i + 1));\r
+                        Regexp nextRegExp = null;\r
+                        String nextTagStr = null;\r
+                        if (SelectorEngine.truth(nextTag)) {\r
+                            nextTagStr = nextTag.getStr(0);\r
+                            nextRegExp = new Regexp("(^|\\s)" + nextTagStr + "(\\s|$)", "i");\r
+                        }\r
+                        for (int j = 0, jlen = prevElem.size(); j < jlen; j++) {\r
+                            Node prevRef = prevElem.getNode(j);\r
+                            String ref = childOrSiblingRef.getStr(0);\r
+                            if (SelectorEngine.eq(">", ref)) {\r
+                                getDescendantNodes(matchingElms, nextTagStr, prevRef);\r
+                            } else if (SelectorEngine.eq("+", ref)) {\r
+                                getSiblingNodes(matchingElms, nextTag, nextRegExp, prevRef);\r
+                            } else if (SelectorEngine.eq("~", ref)) {\r
+                                getGeneralSiblingNodes(matchingElms, nextTag, nextRegExp,\r
+                                        prevRef);\r
+                            }\r
+                        }\r
+                        prevElem = matchingElms;\r
+                        clearAdded(prevElem);\r
+                        rule = cssSelectors.getStr(++i);\r
+                        if (new Regexp("^\\w+$").test(rule)) {\r
+                            continue;\r
+                        }\r
+                        setSkipTag(prevElem, true);\r
+                    }\r
+                }\r
+                JSArray cssSelector = cssSelectorRegExp.exec(rule);\r
+                SplitRule splitRule = new SplitRule(\r
+                        !SelectorEngine.truth(cssSelector.getStr(1)) || SelectorEngine\r
+                                .eq(cssSelector.getStr(3), "*") ? "*" : cssSelector.getStr(1),\r
+                        !SelectorEngine.eq(cssSelector.getStr(3), "*") ? cssSelector\r
+                                .getStr(2) : null, cssSelector.getStr(4), cssSelector.getStr(6),\r
+                        cssSelector.getStr(10));\r
+                if (SelectorEngine.truth(splitRule.id)) {\r
+                    Element domelem = Document.get()\r
+                            .getElementById(splitRule.id.substring(1));\r
+                    if (SelectorEngine.truth(domelem)) {\r
+                        matchingElms = JSArray.create(domelem);\r
+                    }\r
+                    prevElem = matchingElms;\r
+                } else if (SelectorEngine.truth(splitRule.tag) && !isSkipped(prevElem)) {\r
+                    if (i == 0 && matchingElms.size() == 0 && prevElem.size() == 1) {\r
+                        prevElem = matchingElms = JSArray.create(\r
+                                getElementsByTagName(splitRule.tag, prevElem.getNode(0)));\r
+                    } else {\r
+                        NodeList<Element> tagCollectionMatches;\r
+                        for (int l = 0, ll = prevElem.size(); l < ll; l++) {\r
+                            tagCollectionMatches = getElementsByTagName(splitRule.tag,\r
+                                    prevElem.getNode(l));\r
+                            for (int m = 0, mlen = tagCollectionMatches.getLength(); m < mlen;\r
+                                 m++) {\r
+                                Node tagMatch = tagCollectionMatches.getItem(m);\r
+\r
+                                if (!isAdded(tagMatch)) {\r
+                                    setAdded(tagMatch, true);\r
+                                    matchingElms.addNode(tagMatch);\r
+                                }\r
+                            }\r
+                        }\r
+                        prevElem = matchingElms;\r
+                        clearAdded(prevElem);\r
+                    }\r
+                    if (matchingElms.size() == 0) {\r
+                        break;\r
+                    }\r
+                    setSkipTag(prevElem, false);\r
+                    if (SelectorEngine.truth(splitRule.allClasses)) {\r
+                        String[] allClasses = splitRule.allClasses.replaceFirst("^\\.", "")\r
+                                .split("\\.");\r
+                        Regexp[] regExpClassNames = new Regexp[allClasses.length];\r
+                        for (int n = 0, nl = allClasses.length; n < nl; n++) {\r
+                            regExpClassNames[n] = new Regexp(\r
+                                    "(^|\\s)" + allClasses[n] + "(\\s|$)");\r
+                        }\r
+                        JSArray matchingClassElms = JSArray.create();\r
+                        for (int o = 0, olen = prevElem.size(); o < olen; o++) {\r
+                            Element current = prevElem.getElement(o);\r
+                            String elmClass = current.getClassName();\r
+                            boolean addElm = false;\r
+                            if (SelectorEngine.truth(elmClass) && !isAdded(current)) {\r
+                                for (int p = 0, pl = regExpClassNames.length; p < pl; p++) {\r
+                                    addElm = regExpClassNames[p].test(elmClass);\r
+                                    if (!addElm) {\r
+                                        break;\r
+                                    }\r
+                                }\r
+                                if (addElm) {\r
+                                    setAdded(current, true);\r
+                                    matchingClassElms.addNode(current);\r
+                                }\r
+                            }\r
+                        }\r
+                        clearAdded(prevElem);\r
+                        prevElem = matchingElms = matchingClassElms;\r
+                    }\r
+                    if (SelectorEngine.truth(splitRule.allAttr)) {\r
+                        JSArray allAttr = Regexp\r
+                                .match("\\[[^\\]]+\\]", "g", splitRule.allAttr);\r
+                        Regexp[] regExpAttributes = new Regexp[allAttr.size()];\r
+                        String[] regExpAttributesStr = new String[allAttr.size()];\r
+                        Regexp attributeMatchRegExp = new Regexp(\r
+                                "(\\w+)(\\^|\\$|\\*|\\||~)?=?([\\w\u00C0-\uFFFF\\s\\-_\\.]+)?");\r
+                        for (int q = 0, ql = allAttr.size(); q < ql; q++) {\r
+                            JSArray attributeMatch = attributeMatchRegExp\r
+                                    .exec(allAttr.getStr(q));\r
+                            String attributeValue =\r
+                                    SelectorEngine.truth(attributeMatch.getStr(3))\r
+                                            ? attributeMatch.getStr(3).replaceAll("\\.", "\\.")\r
+                                            : null;\r
+                            String attrVal = attrToRegExp(attributeValue,\r
+                                    (SelectorEngine.or(attributeMatch.getStr(2), null)));\r
+                            regExpAttributes[q] = (SelectorEngine.truth(attrVal) ? new Regexp(\r
+                                    attrVal) : null);\r
+                            regExpAttributesStr[q] = attributeMatch.getStr(1);                                     \r
+                        }\r
+                        JSArray matchingAttributeElms = JSArray.create();\r
+\r
+                        for (int r = 0, rlen = matchingElms.size(); r < rlen; r++) {\r
+                            Element current = matchingElms.getElement(r);\r
+                            boolean addElm = false;\r
+                            for (int s = 0, sl = regExpAttributes.length, attributeRegExp;\r
+                                 s < sl; s++) {\r
+                                addElm = false;\r
+                                Regexp attributeRegExp2 = regExpAttributes[s];\r
+                                String currentAttr = getAttr(current, regExpAttributesStr[s]);\r
+                                if (SelectorEngine.truth(currentAttr)\r
+                                        && currentAttr.length() != 0) {\r
+                                    if (attributeRegExp2 == null || attributeRegExp2\r
+                                            .test(currentAttr)) {\r
+                                        addElm = true;\r
+                                    }\r
+                                }\r
+                                if (!addElm) {\r
+                                    break;\r
+                                }\r
+                            }\r
+                            if (addElm) {\r
+                                matchingAttributeElms.addNode(current);\r
+                            }\r
+                        }\r
+                        prevElem = matchingElms = matchingAttributeElms;\r
+                    }\r
+                    if (SelectorEngine.truth(splitRule.allPseudos)) {\r
+                        Regexp pseudoSplitRegExp = new Regexp(\r
+                                ":(\\w[\\w\\-]*)(\\(([^\\)]+)\\))?");\r
+\r
+                        JSArray allPseudos = Regexp.match(\r
+                                "(:\\w+[\\w\\-]*)(\\([^\\)]+\\))?", "g", splitRule.allPseudos);\r
+                        for (int t = 0, tl = allPseudos.size(); t < tl; t++) {\r
+                            JSArray pseudo = pseudoSplitRegExp.match(allPseudos.getStr(t));\r
+                            String pseudoClass = SelectorEngine.truth(pseudo.getStr(1))\r
+                                    ? pseudo.getStr(1)\r
+                                    .toLowerCase() : null;\r
+                            String pseudoValue = SelectorEngine.truth(pseudo.getStr(3))\r
+                                    ? pseudo.getStr(3) : null;\r
+                            matchingElms = getElementsByPseudo(matchingElms, pseudoClass,\r
+                                    pseudoValue);\r
+                            clearAdded(matchingElms);\r
+                        }\r
+                        prevElem = matchingElms;\r
+                    }\r
+                }\r
+            }\r
+            elm.pushAll(prevElem);\r
+        }\r
+\r
+        return elm;\r
+    }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJSIE.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJSIE.java
new file mode 100644 (file)
index 0000000..e2a2cf1
--- /dev/null
@@ -0,0 +1,21 @@
+package com.google.gwt.query.client.impl;\r
+\r
+import com.google.gwt.dom.client.Element;\r
+\r
+/**\r
+ * Runtime implementaton of non-XPath/native for IE that fixes some \r
+ * DOM operation incompatibilities.\r
+ */\r
+public class SelectorEngineJSIE extends SelectorEngineJS {\r
+    public native String getAttr(Element elm, String attr) /*-{\r
+       switch (attr) {\r
+                       case "id":\r
+                       return elm.id;\r
+                       case "for":\r
+                               return elm.htmlFor;\r
+                       case "class":\r
+                               return elm.className;\r
+               }\r
+               return elm.getAttribute(attr, 2);\r
+   }-*/;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineNative.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineNative.java
new file mode 100644 (file)
index 0000000..130142b
--- /dev/null
@@ -0,0 +1,17 @@
+package com.google.gwt.query.client.impl;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.dom.client.Node;
+
+import com.google.gwt.query.client.SelectorEngine;
+
+/**
+ * Runtime selector engine implementation for browsers with native 
+ * querySelectorAll support.
+ */
+public class SelectorEngineNative extends SelectorEngineImpl {
+  public NodeList<Element> select(String selector, Node ctx) {
+    return SelectorEngine.querySelectorAll(selector, ctx);
+  }
+}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineXPath.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineXPath.java
new file mode 100644 (file)
index 0000000..4fa316f
--- /dev/null
@@ -0,0 +1,229 @@
+package com.google.gwt.query.client.impl;\r
+\r
+import com.google.gwt.core.client.GWT;\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
+import com.google.gwt.query.client.Regexp;\r
+\r
+import com.google.gwt.query.client.JSArray;\r
+import com.google.gwt.query.client.SelectorEngine;\r
+import static com.google.gwt.query.client.SelectorEngine.eq;\r
+import static com.google.gwt.query.client.SelectorEngine.truth;\r
+\r
+/**\r
+ * Runtime selector engine implementation which translates selectors to XPath\r
+ * and delegates to document.evaluate().\r
+ */\r
+public class SelectorEngineXPath extends SelectorEngineImpl {\r
+    private Regexp cssSelectorRegExp;\r
+    private Regexp selectorSplitRegExp;\r
+    private Regexp COMBINATOR;\r
+\r
+    public SelectorEngineXPath() {\r
+    }\r
+\r
+    private void init() {\r
+        if (cssSelectorRegExp == null) {\r
+            cssSelectorRegExp = new Regexp(\r
+                    "^(\\w+)?(#[\\w\\u00C0-\\uFFFF\\-\\_]+|(\\*))?((\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[\\w\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[\\w\\u00C0-\\uFFFF\\-_]+|((\\w*\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[\\w\\-]*))\\))?)*)?(>|\\+|~)?");\r
+            selectorSplitRegExp = new Regexp("[^\\s]+", "g");\r
+            COMBINATOR = new Regexp("(>|\\+|~)");\r
+        }\r
+    }\r
+\r
+\r
+    public NodeList<Element> select(String sel, Node ctx) {\r
+        init();\r
+        String selectors[] = sel.replaceAll("\\s*(,)\\s*", "$1").split(",");\r
+        boolean identical = false;\r
+        JSArray elm = JSArray.create();\r
+        for (int a = 0, len = selectors.length; a < len; a++) {\r
+            if (a > 0) {\r
+                identical = false;\r
+                for (int b = 0, bl = a; b < bl; b++) {\r
+                    if (eq(selectors[a], selectors[b])) {\r
+                        identical = true;\r
+                        break;\r
+                    }\r
+                }\r
+                if (identical) {\r
+                    continue;\r
+                }\r
+            }\r
+            String currentRule = selectors[a];\r
+            JSArray cssSelectors = selectorSplitRegExp.match(currentRule);\r
+            String xPathExpression = ".";\r
+            for (int i = 0, slen = cssSelectors.size(); i < slen; i++) {\r
+                String rule = cssSelectors.getStr(i);\r
+                JSArray cssSelector = cssSelectorRegExp.exec(rule);\r
+                SplitRule splitRule = new SplitRule(!truth(cssSelector.getStr(1)) || eq(\r
+                        cssSelector.getStr(3), "*") ? "*" : cssSelector.getStr(1),\r
+                        !eq(cssSelector.getStr(3), "*") ? cssSelector.getStr(2) : null,\r
+                        cssSelector.getStr(4), cssSelector.getStr(6),\r
+                        cssSelector.getStr(10), cssSelector.getStr(22));\r
+                if (truth(splitRule.tagRelation)) {\r
+                    if (eq(">", splitRule.tagRelation)) {\r
+                        xPathExpression += "/child::";\r
+                    } else if (eq("+", splitRule.tagRelation)) {\r
+                        xPathExpression += "/following-sibling::*[1]/self::";\r
+                    } else if (eq("~", splitRule.tagRelation)) {\r
+                        xPathExpression += "/following-sibling::";\r
+                    }\r
+                } else {\r
+                    xPathExpression +=\r
+                            (i > 0 && COMBINATOR.test(cssSelectors.getStr(i - 1)))\r
+                                    ? splitRule.tag : ("/descendant::" + splitRule.tag);\r
+                }\r
+                if (truth(splitRule.id)) {\r
+                    xPathExpression += "[@id = '" + splitRule.id.replaceAll("^#", "")\r
+                            + "']";\r
+                }\r
+                if (truth(splitRule.allClasses)) {\r
+                    xPathExpression += splitRule.allClasses.replaceAll(\r
+                            "\\.([\\w\\u00C0-\\uFFFF\\-_]+)",\r
+                            "[contains(concat(' ', @class, ' '), ' $1 ')]");\r
+                }\r
+                if (truth(splitRule.allAttr)) {\r
+                    GWT.log("AllAttr is " + splitRule.allAttr, null);\r
+                    xPathExpression += replaceAttr(\r
+                            SelectorEngine.or(splitRule.allAttr, ""));\r
+                }\r
+                if (truth(splitRule.allPseudos)) {\r
+                    Regexp pseudoSplitRegExp = new Regexp(\r
+                            ":(\\w[\\w\\-]*)(\\(([^\\)]+)\\))?");\r
+                    Regexp pseudoMatchRegExp = new Regexp(\r
+                            "(:\\w+[\\w\\-]*)(\\([^\\)]+\\))?", "g");\r
+                    JSArray allPseudos = pseudoMatchRegExp.match(splitRule.allPseudos);\r
+                    for (int k = 0, kl = allPseudos.size(); k < kl; k++) {\r
+                        JSArray pseudo = pseudoSplitRegExp.match(allPseudos.getStr(k));\r
+                        String pseudoClass = truth(pseudo.getStr(1)) ? pseudo.getStr(1)\r
+                                .toLowerCase() : null;\r
+                        String pseudoValue = truth(pseudo.getStr(3)) ? pseudo.getStr(3)\r
+                                : null;\r
+                        String xpath = pseudoToXPath(splitRule.tag, pseudoClass,\r
+                                pseudoValue);\r
+                        if (xpath.length() > 0) {\r
+                            xPathExpression += "[" + xpath + "]";\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            SelectorEngine.xpathEvaluate(xPathExpression, ctx, elm);\r
+        }\r
+        return elm;\r
+    }\r
+\r
+    private String pseudoToXPath(String tag, String pseudoClass,\r
+                                 String pseudoValue) {\r
+        String xpath = "";\r
+        if (eq("first-child", pseudoClass)) {\r
+            xpath = "not(preceding-sibling::*)";\r
+        } else if (eq("first-of-type", pseudoClass)) {\r
+            xpath = "not(preceding-sibling::" + tag + ")";\r
+        } else if (eq("last-child", pseudoClass)) {\r
+            xpath = "not(following-sibling::*)";\r
+        } else if (eq("last-of-type", pseudoClass)) {\r
+            xpath = "not(following-sibling::" + tag + ")";\r
+        } else if (eq("only-child", pseudoClass)) {\r
+            xpath = "not(preceding-sibling::* or following-sibling::*)";\r
+        } else if (eq("only-of-type", pseudoClass)) {\r
+            xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag\r
+                    + ")";\r
+        } else if (eq("nth-child", pseudoClass)) {\r
+            if (!eq("n", pseudoClass)) {\r
+                Sequence sequence = getSequence(pseudoValue);\r
+                if (sequence != null) {\r
+                    if (sequence.start == sequence.max) {\r
+                        xpath = "count(preceding-sibling::*) = " + (sequence.start - 1);\r
+                    } else {\r
+                        xpath = "(count(preceding-sibling::*) + 1) mod " + sequence.add\r
+                                + " = " + sequence.modVal + ((sequence.start > 1) ?\r
+                                " and count(preceding-sibling::*) >= " + (sequence.start - 1)\r
+                                : "") + ((sequence.max > 0) ?\r
+                                " and count(preceding-sibling::*) <= " + (sequence.max - 1)\r
+                                : "");\r
+                    }\r
+                }\r
+            }\r
+        } else if (eq("nth-of-type", pseudoClass)) {\r
+            if (!pseudoValue.startsWith("n")) {\r
+                Sequence sequence = getSequence(pseudoValue);\r
+                if (sequence != null) {\r
+                    if (sequence.start == sequence.max) {\r
+                        xpath = pseudoValue;\r
+                    } else {\r
+                        xpath = "position() mod " + sequence.add + " = " + sequence.modVal\r
+                                + ((sequence.start > 1) ? " and position() >= " + sequence\r
+                                .start : "") + ((sequence.max > 0) ? " and position() <= "\r
+                                + sequence.max : "");\r
+                    }\r
+                }\r
+            }\r
+        } else if (eq("empty", pseudoClass)) {\r
+            xpath = "count(child::*) = 0 and string-length(text()) = 0";\r
+        } else if (eq("contains", pseudoClass)) {\r
+            xpath = "contains(., '" + pseudoValue + "')";\r
+        } else if (eq("enabled", pseudoClass)) {\r
+            xpath = "not(@disabled)";\r
+        } else if (eq("disabled", pseudoClass)) {\r
+            xpath = "@disabled";\r
+        } else if (eq("checked", pseudoClass)) {\r
+            xpath = "@checked='checked'"; // Doesn't work in Opera 9.24\r
+        } else if (eq("not", pseudoClass)) {\r
+            if (new Regexp("^(:\\w+[\\w\\-]*)$").test(pseudoValue)) {\r
+                xpath = "not(" + pseudoToXPath(tag, pseudoValue.substring(1), "") + ")";\r
+            } else {\r
+\r
+                pseudoValue = pseudoValue\r
+                        .replaceFirst("^\\[#([\\w\\u00C0-\\uFFFF\\-\\_]+)\\]$", "[id=$1]");\r
+                String notSelector = pseudoValue\r
+                        .replaceFirst("^(\\w+)", "self::$1");\r
+                notSelector = notSelector.replaceAll("^\\.([\\w\\u00C0-\\uFFFF\\-_]+)",\r
+                        "contains(concat(' ', @class, ' '), ' $1 ')");\r
+                notSelector = replaceAttr2(notSelector);\r
+                xpath = "not(" + notSelector + ")";\r
+            }\r
+        } else {\r
+            xpath = "@" + pseudoClass + "='" + pseudoValue + "'";\r
+        }\r
+\r
+        return xpath;\r
+    }\r
+\r
+    private static String attrToXPath(String match, String p1, String p2,\r
+                                      String p3) {\r
+        if (eq("^", p2)) {\r
+            return "starts-with(@" + p1 + ", '" + p3 + "')";\r
+        }\r
+        if (eq("$", p2)) {\r
+            return "substring(@" + p1 + ", (string-length(@" + p1 + ") - "\r
+                    + (p3.length() - 1) + "), " + p3.length() + ") = '" + p3 + "'";\r
+        }\r
+        if (eq("*", p2)) {\r
+            return "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')";\r
+        }\r
+        if (eq("|", p2)) {\r
+            return "(@" + p1 + "='" + p3 + "' or starts-with(@" + p1 + ", '" + p3\r
+                    + "-'))";\r
+        }\r
+        if (eq("~", p2)) {\r
+            return "contains(concat(' ', @" + p1 + ", ' '), ' " + p3 + " ')";\r
+        }\r
+        return "@" + p1 + (truth(p3) ? "='" + p3 + "'" : "");\r
+    }\r
+\r
+    private native String replaceAttr(String allAttr) /*-{\r
+        if(!allAttr) return "";\r
+        return allAttr.replace(/(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?/g, \r
+            function(a,b,c,d) {\r
+              return @gwtquery.client.impl.SelectorEngineXPath::attrToXPath(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)(a,b || "",c || "",d || "");\r
+            });\r
+            \r
+    }-*/;\r
+\r
+    private native String replaceAttr2(String allAttr) /*-{\r
+        if(!allAttr) return "";\r
+        return allAttr.replace(/\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/g, @com.google.gwt.query.client.impl.SelectorEngineXPath::attrToXPath(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));\r
+    }-*/;\r
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorBase.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorBase.java
new file mode 100644 (file)
index 0000000..e19d9b4
--- /dev/null
@@ -0,0 +1,191 @@
+package com.google.gwt.query.rebind;\r
+\r
+import com.google.gwt.core.ext.Generator;\r
+import com.google.gwt.core.ext.GeneratorContext;\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JClassType;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.core.ext.typeinfo.JParameter;\r
+import com.google.gwt.core.ext.typeinfo.TypeOracle;\r
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+import com.google.gwt.query.client.Selector;\r
+\r
+import java.io.PrintWriter;\r
+\r
+/**\r
+ * Base class for compile time selector generators.\r
+ */\r
+public abstract class SelectorGeneratorBase extends Generator {\r
+\r
+  private TreeLogger treeLogger;\r
+\r
+  protected JClassType NODE_TYPE = null;\r
+\r
+  public String generate(TreeLogger treeLogger,\r
+      GeneratorContext generatorContext, String requestedClass)\r
+      throws UnableToCompleteException {\r
+    this.treeLogger = treeLogger;\r
+    TypeOracle oracle = generatorContext.getTypeOracle();\r
+    NODE_TYPE = oracle.findType("com.google.gwt.dom.client.Node");\r
+\r
+    JClassType selectorType = oracle.findType(requestedClass);\r
+    SourceWriter sw = getSourceWriter(treeLogger, generatorContext,\r
+        selectorType.getPackage().getName(),\r
+        selectorType.getSimpleSourceName() + getImplSuffix(), requestedClass);\r
+    if (sw != null) {\r
+      for (JMethod method : selectorType.getMethods()) {\r
+        generateMethod(sw, method, treeLogger);\r
+      }\r
+      genGetAllMethod(sw, selectorType.getMethods(), treeLogger);\r
+      sw.commit(treeLogger);\r
+    }\r
+\r
+    return selectorType.getPackage().getName() + "."\r
+        + selectorType.getSimpleSourceName() + getImplSuffix();\r
+  }\r
+\r
+  protected String getImplSuffix() {\r
+    return "Impl";\r
+  }\r
+\r
+  // used by benchmark harness\r
+  private void genGetAllMethod(SourceWriter sw, JMethod[] methods,\r
+      TreeLogger treeLogger) {\r
+    sw.println("public DeferredGQuery[] getAllSelectors() {");\r
+    sw.indent();\r
+    sw.println(\r
+        "DeferredGQuery[] dg = new DeferredGQuery[" + (methods.length) + "];");\r
+    int i = 0;\r
+    for (JMethod m : methods) {\r
+      Selector selectorAnnotation = m.getAnnotation(Selector.class);\r
+      if(selectorAnnotation == null) continue;\r
+      String selector = selectorAnnotation.value();\r
+\r
+      sw.println("dg[" + i + "]=new DeferredGQuery() {");\r
+      sw.indent();\r
+      sw.println(\r
+          "public String getSelector() { return \"" + selector + "\"; }");\r
+      sw.println("public GQuery eval(Node ctx) { return " + wrapJS(m, m.getName()\r
+          + (m.getParameters().length == 0 ? "()" : "(ctx)")+"") + " ;}");\r
+      sw.println("public NodeList<Element> array(Node ctx) { return "+("NodeList".equals(m.getReturnType().getSimpleSourceName()) ?\r
+        (m.getName()\r
+          + (m.getParameters().length == 0 ? "(); " : "(ctx); ")) : \r
+          "eval"+(m.getParameters().length == 0 ? "(null).get(); " : "(ctx).get(); "))+"}");\r
+      \r
+      i++;\r
+      sw.outdent();\r
+      sw.println("};");\r
+    }\r
+    sw.println("return dg;");\r
+    sw.outdent();\r
+    sw.println("}");\r
+  }\r
+\r
+  public void generateMethod(SourceWriter sw, JMethod method, TreeLogger logger)\r
+      throws UnableToCompleteException {\r
+      Selector selectorAnnotation = method.getAnnotation(Selector.class);\r
+    if(selectorAnnotation == null) return;\r
+\r
+    String selector = selectorAnnotation.value();\r
+    JParameter[] params = method.getParameters();\r
+\r
+    sw.indent();\r
+    String retType = method.getReturnType().getParameterizedQualifiedSourceName();\r
+    sw.print("public final "+retType+" "+method.getName());\r
+    boolean hasContext = false;\r
+    if (params.length == 0) {\r
+      sw.print("()");\r
+    } else if (params.length == 1) {\r
+      JClassType type = params[0].getType().isClassOrInterface();\r
+      if (type != null && type.isAssignableTo(NODE_TYPE)) {\r
+        sw.print("(Node root)");\r
+        hasContext = true;\r
+      }\r
+    }\r
+    sw.println(" {");\r
+    sw.indent();\r
+    Selector sel = method.getAnnotation(Selector.class);\r
+\r
+    // short circuit #foo\r
+    if (sel != null && sel.value().matches("^#\\w+$")) {\r
+      sw.println("return "+wrap(method, "JSArray.create(((Document)" + (hasContext ? "root" : "(Node)Document.get()")\r
+          + ").getElementById(\"" + sel.value().substring(1) + "\"))")+";");\r
+    }\r
+    // short circuit FOO\r
+    else if (sel != null && sel.value().matches("^\\w+$")) {\r
+      sw.println("return "+wrap(method, "JSArray.create(((Element)"+(hasContext ? "root" : "(Node)Document.get()")\r
+          + ").getElementsByTagName(\"" + sel.value() + "\"))")+";");\r
+    } // short circuit .foo for browsers with native getElementsByClassName \r
+    else if (sel != null && sel.value().matches("^\\.\\w+$")\r
+        && hasGetElementsByClassName()) {\r
+      sw.println("return "+wrap(method, "JSArray.create(getElementsByClassName(\""\r
+          + sel.value().substring(1) + "\", " + (hasContext ? "root" : "(Node)Document.get()")\r
+          + "))")+";");\r
+    } else {\r
+      generateMethodBody(sw, method, logger, hasContext);\r
+    }\r
+    sw.outdent();\r
+    sw.println("}");\r
+    sw.outdent();\r
+  }\r
+\r
+  protected boolean hasGetElementsByClassName() {\r
+    return false;\r
+  }\r
+\r
+  protected void debug(String s) {\r
+//    System.err.println(s);\r
+    treeLogger.log(TreeLogger.DEBUG, s, null);\r
+  }\r
+\r
+  protected boolean notNull(String s) {\r
+    return s != null && !"".equals(s);\r
+  }\r
+\r
+  protected SourceWriter getSourceWriter(TreeLogger logger,\r
+      GeneratorContext context, String packageName, String className,\r
+      String... interfaceNames) {\r
+    PrintWriter printWriter = context.tryCreate(logger, packageName, className);\r
+    if (printWriter == null) {\r
+      return null;\r
+    }\r
+    ClassSourceFileComposerFactory composerFactory\r
+        = new ClassSourceFileComposerFactory(packageName, className);\r
+    composerFactory.setSuperclass("com.google.gwt.query.client.SelectorEngine");\r
+    composerFactory.addImport("com.google.gwt.core.client.GWT");\r
+    composerFactory.addImport("gwtquery.client.*");\r
+//    composerFactory.addImport("com.google.gwt.query.client.JSArray");\r
+\r
+    composerFactory.addImport("com.google.gwt.dom.client.*");\r
+    for (String interfaceName : interfaceNames) {\r
+      composerFactory.addImplementedInterface(interfaceName);\r
+    }\r
+\r
+    return composerFactory.createSourceWriter(context, printWriter);\r
+  }\r
+\r
+  protected String wrap(JMethod method, String expr) {\r
+    if("NodeList".equals(method.getReturnType().getSimpleSourceName())) {\r
+      return expr;\r
+    }\r
+    else {\r
+      return "new GQuery("+expr+")";\r
+    }\r
+    \r
+  }\r
+  \r
+  protected String wrapJS(JMethod method, String expr) {\r
+    if("GQuery".equals(method.getReturnType().getSimpleSourceName())) {\r
+      return expr;\r
+    }\r
+    else {\r
+      return "new GQuery("+expr+")";\r
+    }\r
+    \r
+  }\r
+  \r
+  protected abstract void generateMethodBody(SourceWriter sw, JMethod method,\r
+      TreeLogger logger, boolean hasContext) throws UnableToCompleteException;\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJS.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJS.java
new file mode 100644 (file)
index 0000000..67162e6
--- /dev/null
@@ -0,0 +1,31 @@
+package com.google.gwt.query.rebind;\r
+\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.query.client.Selector;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+\r
+/**\r
+ * An implementaton of pure-JS compile time selectors. This implementation\r
+ * simply defers to the runtime selector engine.\r
+ */\r
+public class SelectorGeneratorJS extends SelectorGeneratorBase {\r
+\r
+  protected String getImplSuffix() {\r
+    return "JS" + super.getImplSuffix();\r
+  }\r
+\r
+  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
+      TreeLogger treeLogger, boolean hasContext)\r
+      throws UnableToCompleteException {\r
+\r
+    String selector = method.getAnnotation(Selector.class).value();\r
+    if (!hasContext) {\r
+      sw.println("Node root = Document.get();");\r
+    }\r
+\r
+    sw.println("return " + wrap(method,\r
+        "new SelectorEngine().select(\"" + selector + "\", root)") + ";");\r
+  }\r
+}\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJSOptimal.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorJSOptimal.java
new file mode 100644 (file)
index 0000000..782b2d6
--- /dev/null
@@ -0,0 +1,174 @@
+package com.google.gwt.query.rebind;\r
+\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+\r
+import java.util.regex.Pattern;\r
+\r
+import com.google.gwt.query.client.Selector;\r
+\r
+/**\r
+ *\r
+ */\r
+public class SelectorGeneratorJSOptimal extends SelectorGeneratorBase {\r
+\r
+  protected static Pattern nonSpace = Pattern.compile("\\S/");\r
+\r
+  private static final String trimReStr = "^\\s+|\\s+$";\r
+\r
+  protected static Pattern trimRe = Pattern.compile(trimReStr);\r
+\r
+  protected static Pattern tplRe = Pattern.compile("\\{(\\d+)\\}");\r
+\r
+  protected static Pattern modeRe = Pattern\r
+      .compile("^(\\s?[\\/>+~]\\s?|\\s|$)");\r
+\r
+  protected static Pattern tagTokenRe = Pattern\r
+      .compile("^(#)?([a-zA-Z_0-9-\\*]+)");\r
+\r
+  protected static Pattern nthRe = Pattern.compile("(\\d*)n\\+?(\\d*)");\r
+\r
+  protected static Pattern nthRe2 = Pattern.compile("\\D");\r
+\r
+  protected static RuleMatcher[] matchers = new RuleMatcher[]{new RuleMatcher(\r
+      "^\\.([a-zA-Z_0-9-]+)", "n = byClassName(n, null, \"{0}\");"),\r
+      new RuleMatcher("^\\:([a-zA-Z_0-9-]+)(?:\\(((?:[^ >]*|.*?))\\))?",\r
+          "n = byPseudo(n, \"{0}\", \"{1}\");"), new RuleMatcher(\r
+      "^(?:([\\[\\{])(?:@)?([a-zA-Z_0-9-]+)\\s?(?:(=|.=)\\s?['\"]?(.*?)[\"']?)?[\\]\\}])",\r
+      "n = byAttribute(n, \"{1}\", \"{3}\", \"{2}\", \"{0}\");"),\r
+      new RuleMatcher("^#([a-zA-Z_0-9-]+)", "n = byId(n, null, \"{0}\");")};\r
+\r
+  protected String getImplSuffix() {\r
+    return "JS"+super.getImplSuffix();\r
+  }\r
+\r
+  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
+      TreeLogger treeLogger, boolean hasContext) throws UnableToCompleteException {\r
+\r
+    String selector = method.getAnnotation(Selector.class).value();\r
+    if(!hasContext) sw.println("Node root = Document.get();");\r
+    \r
+    sw.println("return "+wrap(method, "new SelectorEngine().select(\""+selector+"\", root)")+";");\r
+//    sw.println("JSArray n = JSArray.create();");\r
+//    if(!hasContext) { \r
+//      sw.println("Node root = Document.get();");\r
+//    }\r
+//\r
+//    // add root node as context. \r
+//    // TODO: support any context\r
+//    sw.println("n.addNode(root);");\r
+//    String q = selector, lq = null;\r
+//    Matcher lmode = modeRe.matcher(q);\r
+//    Matcher mm = null;\r
+//    String mode = "";\r
+//    if (lmode.lookingAt() && notNull(lmode.group(1))) {\r
+//      mode = lmode.group(1).replaceAll(trimReStr, "").trim();\r
+//      q = q.replaceFirst("\\Q" + lmode.group(1) + "\\E", "");\r
+//    }\r
+//\r
+//    while (notNull(q) && !q.equals(lq)) {\r
+//      debug("Doing q=" + q);\r
+//\r
+//      lq = q;\r
+//      Matcher tm = tagTokenRe.matcher(q);\r
+//      if (tm.lookingAt()) {\r
+//        if ("#".equals(tm.group(1))) {\r
+//          sw.println("n = quickId(n, \"" + mode + "\", root, \"" + tm.group(2)\r
+//              + "\");");\r
+//        } else {\r
+//          String tagName = tm.group(2);\r
+//          tagName = "".equals(tagName) ? "*" : tagName;\r
+//     //     sw.println("if (n.size() == 0) { n=JSArray.create(); }");\r
+//          String func = "";\r
+//          if ("".equals(mode)) {\r
+//            func = "getDescendentNodes";\r
+//          } else if (">".equals(mode)) {\r
+//            func = "getChildNodes";\r
+//          } else if ("+".equals(mode)) {\r
+//            func = "getSiblingNodes";\r
+//          } else if ("~".equals(mode)) {\r
+//            func = "getGeneralSiblingNodes";\r
+//          } else {\r
+//            treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "\r
+//                + mode + " not recognized in " + selector, null);\r
+//            throw new UnableToCompleteException();\r
+//          }\r
+//          sw.println("n = " + func + "(n, \"" + tagName + "\");");\r
+//        }\r
+//        debug("replacing in q, the value " + tm.group(0));\r
+//        q = q.replaceFirst("\\Q" + tm.group(0) + "\\E", "");\r
+//      } else {\r
+//        String func = "";\r
+//        String tagName = "*";\r
+//        if ("".equals(mode)) {\r
+//          func = "getDescendentNodes";\r
+//        } else if (">".equals(mode)) {\r
+//          func = "getChildNodes";\r
+//        } else if ("+".equals(mode)) {\r
+//          func = "getSiblingNodes";\r
+//        } else if ("~".equals(mode)) {\r
+//          func = "getGeneralSiblingNodes";\r
+//        } else {\r
+//          treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "\r
+//              + mode + " not recognized in " + selector, null);\r
+//          throw new UnableToCompleteException();\r
+//        }\r
+//        sw.println("n = " + func + "(n, \"" + tagName + "\");");\r
+//      }\r
+//\r
+//      while (!(mm = modeRe.matcher(q)).lookingAt()) {\r
+//        debug("Looking at " + q);\r
+//        boolean matched = false;\r
+//        for (RuleMatcher rm : matchers) {\r
+//          Matcher rmm = rm.re.matcher(q);\r
+//          if (rmm.lookingAt()) {\r
+//            String res[] = new String[rmm.groupCount()];\r
+//            for (int i = 1; i <= rmm.groupCount(); i++) {\r
+//              res[i - 1] = rmm.group(i);\r
+//              debug("added param " + res[i - 1]);\r
+//            }\r
+//            Object[] r = res;\r
+//            // inline enum, perhaps type-tightening will allow inlined eval() \r
+//            // call\r
+//            if (rm.fnTemplate.indexOf("byPseudo") != -1) {\r
+//              sw.println("n = Pseudo."+res[0].toUpperCase().replace("-", "_") +\r
+//                  ".eval(n, \""+res[1]+"\");");\r
+//            } else {\r
+//              sw.println(MessageFormat.format(rm.fnTemplate, r));\r
+//            }\r
+//            q = q.replaceFirst("\\Q" + rmm.group(0) + "\\E", "");\r
+//            matched = true;\r
+//            break;\r
+//          }\r
+//        }\r
+//        if (!matched) {\r
+//          treeLogger\r
+//              .log(TreeLogger.ERROR, "Error parsing selector at " + q, null);\r
+//          throw new UnableToCompleteException();\r
+//        }\r
+//      }\r
+//\r
+//      if (notNull(mm.group(1))) {\r
+//        mode = mm.group(1).replaceAll(trimReStr, "");\r
+//        debug("replacing q=" + q + " this part:" + mm.group(1));\r
+//        q = q.replaceFirst("\\Q" + mm.group(1) + "\\E", "");\r
+//      }\r
+//    }\r
+//    sw.println("return "+wrap(method, "nodup(n)")+";");\r
+  }\r
+\r
\r
+  static class RuleMatcher {\r
+\r
+    public Pattern re;\r
+\r
+    public String fnTemplate;\r
+\r
+    RuleMatcher(String pat, String fnT) {\r
+      this.re = Pattern.compile(pat);\r
+      this.fnTemplate = fnT;\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorNative.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorNative.java
new file mode 100644 (file)
index 0000000..5688085
--- /dev/null
@@ -0,0 +1,32 @@
+package com.google.gwt.query.rebind;\r
+\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+import com.google.gwt.query.client.Selector;\r
+\r
+/**\r
+ * Compile time selector generator which delegates to native browser\r
+ * methods.\r
+ */\r
+public class SelectorGeneratorNative extends SelectorGeneratorBase {\r
+\r
+  protected String getImplSuffix() {\r
+    return "Native" + super.getImplSuffix();\r
+  }\r
+\r
+  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
+      TreeLogger treeLogger, boolean hasContext)\r
+      throws UnableToCompleteException {\r
+    String selector = method.getAnnotation(Selector.class).value();\r
+    if (!hasContext) {\r
+      sw.println("return "\r
+          + wrap(method, "querySelectorAll(\"" + selector + "\"") + ");");\r
+    } else {\r
+      sw.println("return "\r
+          + wrap(method, "querySelectorAll(\"" + selector + "\", root)")\r
+          + ");");\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorXPath.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/SelectorGeneratorXPath.java
new file mode 100644 (file)
index 0000000..e38b6df
--- /dev/null
@@ -0,0 +1,319 @@
+package com.google.gwt.query.rebind;\r
+\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.query.client.Selector;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+\r
+import java.util.ArrayList;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+/**\r
+ * Compile time selector generator which translates selector into XPath at\r
+ * compile time.\r
+ */\r
+public class SelectorGeneratorXPath extends SelectorGeneratorBase {\r
+\r
+  private static Pattern cssSelectorRegExp = Pattern.compile(\r
+      "^(\\w+)?(#[a-zA-Z_0-9\u00C0-\uFFFF\\-\\_]+|(\\*))?((\\.[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[a-zA-Z_0-9\u00C0-\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[a-zA-Z_0-9\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+|((\\w*\\.[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[a-zA-Z_0-9\u00C0-\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[a-zA-Z_0-9\\-]*))\\))?)*)?(>|\\+|~)?");\r
+\r
+  private static Pattern selectorSplitRegExp = Pattern\r
+      .compile("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]");\r
+\r
+  private String prefix = "";\r
+\r
+  static class SplitRule {\r
+\r
+    public String tag;\r
+\r
+    public String id;\r
+\r
+    public String allClasses;\r
+\r
+    public String allAttr;\r
+\r
+    public String allPseudos;\r
+\r
+    public String tagRelation;\r
+  }\r
+\r
+  protected String getImplSuffix() {\r
+    return "XPath" + super.getImplSuffix();\r
+  }\r
+\r
+  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
+      TreeLogger treeLogger, boolean hasContext)\r
+      throws UnableToCompleteException {\r
+\r
+    String selector = method.getAnnotation(Selector.class).value();\r
+    String[] cssRules = selector.replaceAll("\\s*(,)\\s*", "$1").split(",");\r
+    String currentRule;\r
+    boolean identical = false;\r
+    String xPathExpression = ".";\r
+\r
+    for (int i = 0; i < cssRules.length; i++) {\r
+      currentRule = cssRules[i];\r
+\r
+      if (i > 0) {\r
+        identical = false;\r
+        for (int x = 0, xl = i; x < xl; x++) {\r
+          if (cssRules[i].equals(cssRules[x])) {\r
+            identical = true;\r
+            break;\r
+          }\r
+        }\r
+        if (identical) {\r
+          continue;\r
+        }\r
+      }\r
+\r
+      ArrayList<String> cssSelectors = new ArrayList<String>();\r
+      Matcher selm = selectorSplitRegExp.matcher(currentRule);\r
+      while (selm.find()) {\r
+        cssSelectors.add(selm.group(0));\r
+      }\r
+\r
+      Matcher cssSelector;\r
+      for (int j = 0, jl = cssSelectors.size(); j < jl; j++) {\r
+        cssSelector = cssSelectorRegExp.matcher(cssSelectors.get(j));\r
+        if (cssSelector.matches()) {\r
+\r
+          SplitRule splitRule = new SplitRule();\r
+          splitRule.tag = prefix + ((!notNull(cssSelector.group(1)) || "*"\r
+              .equals(cssSelector.group(3))) ? "*" : cssSelector.group(1));\r
+          splitRule.id = (!"*".equals(cssSelector.group(3))) ? cssSelector\r
+              .group(2) : null;\r
+          splitRule.allClasses = cssSelector.group(4);\r
+          splitRule.allAttr = cssSelector.group(6);\r
+          splitRule.allPseudos = cssSelector.group(10);\r
+          splitRule.tagRelation = cssSelector.group(22);\r
+          if (notNull(splitRule.tagRelation)) {\r
+            if (">".equals(splitRule.tagRelation)) {\r
+              xPathExpression += "/child::";\r
+            } else if ("+".equals(splitRule.tagRelation)) {\r
+              xPathExpression += "/following-sibling::*[1]/self::";\r
+            } else if ("~".equals(splitRule.tagRelation)) {\r
+              xPathExpression += "/following-sibling::";\r
+            }\r
+          } else {\r
+            xPathExpression +=\r
+                (j > 0 && cssSelectors.get(j - 1).matches("(>|\\+|~)"))\r
+                    ? splitRule.tag : ("/descendant::" + splitRule.tag);\r
+          }\r
+\r
+          if (notNull(splitRule.id)) {\r
+            xPathExpression += "[@id = '" + splitRule.id.replaceAll("^#", "")\r
+                + "']";\r
+          }\r
+          if (notNull(splitRule.allClasses)) {\r
+            xPathExpression += splitRule.allClasses\r
+                .replaceAll("\\.([a-zA-Z_0-9\u00C0 -\uFFFF\\-_]+)",\r
+                    "[contains(concat(' ', @class, ' '), ' $1 ')]");\r
+          }\r
+          if (notNull(splitRule.allAttr)) {\r
+            xPathExpression += attrToXPath(splitRule.allAttr,\r
+                "(\\w+)(\\^|\\$|\\*|\\||~)?=?([a-zA-Z_0-9\u00C0-\uFFFF\\s\\-_\\.]+)?");\r
+          }\r
+          if (notNull(splitRule.allPseudos)) {\r
+            Pattern pseudoSplitRegExp = Pattern\r
+                .compile(":(\\w[a-zA-Z_0-9\\-]*)(\\(([^\\)]+)\\))?");\r
+            Matcher m = Pattern\r
+                .compile("(:\\w+[a-zA-Z_0-9\\-]*)(\\([^\\)]+\\))?")\r
+                .matcher(splitRule.allPseudos);\r
+            while (m.find()) {\r
+              String str = m.group(0);\r
+              Matcher pseudo = pseudoSplitRegExp\r
+                  .matcher(str == null ? "" : str);\r
+              if (pseudo.matches()) {\r
+                String pseudoClass = notNull(pseudo.group(1)) ? pseudo.group(1)\r
+                    .toLowerCase() : null;\r
+                String pseudoValue = notNull(pseudo.group(3)) ? pseudo.group(3)\r
+                    : null;\r
+                String xpath = pseudoToXPath(splitRule.tag, pseudoClass,\r
+                    pseudoValue);\r
+                if (notNull(xpath)) {\r
+                  xPathExpression += "[" + xpath + "]";\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    if (!hasContext) {\r
+      sw.println("Node root = Document.get();");\r
+    }\r
+    sw.println("return " + wrap(method,\r
+        "SelectorEngine.xpathEvaluate(\"" + xPathExpression + "\", root)")\r
+        + ";");\r
+  }\r
+\r
+  static class Sequence {\r
+\r
+    public int start;\r
+\r
+    public int max;\r
+\r
+    public int add;\r
+\r
+    public int modVal;\r
+  }\r
+\r
+  private String pseudoToXPath(String tag, String pseudoClass,\r
+      String pseudoValue) {\r
+    tag = pseudoClass.matches(".*\\-child$") ? "*" : tag;\r
+    String xpath = "";\r
+    String pseudo[] = pseudoClass.split("-");\r
+    if ("first".equals(pseudo[0])) {\r
+      xpath = "not(preceding-sibling::" + tag + ")";\r
+    } else if ("last".equals(pseudo[0])) {\r
+      xpath = "not(following-sibling::" + tag + ")";\r
+    } else if ("only".equals(pseudo[0])) {\r
+      xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag\r
+          + ")";\r
+    } else if ("nth".equals(pseudo[0])) {\r
+      if (!pseudoValue.matches("^n$")) {\r
+        String position =\r
+            (("last".equals(pseudo[1])) ? "(count(following-sibling::"\r
+                : "(count(preceding-sibling::") + tag + ") + 1)";\r
+        Sequence sequence = getSequence(pseudoValue);\r
+        if (sequence != null) {\r
+          if (sequence.start == sequence.max) {\r
+            xpath = position + " = " + sequence.start;\r
+          } else {\r
+            xpath = position + " mod " + sequence.add + " = " + sequence.modVal\r
+                + ((sequence.start > 1) ? " and " + position + " >= "\r
+                + sequence.start : "") + ((sequence.max > 0) ? " and "\r
+                + position + " <= " + sequence.max : "");\r
+          }\r
+        }\r
+      }\r
+    } else if ("empty".equals(pseudo[0])) {\r
+      xpath = "count(child::*) = 0 and string-length(text()) = 0";\r
+    } else if ("contains".equals(pseudo[0])) {\r
+      xpath = "contains(., '" + pseudoValue + "')";\r
+    } else if ("enabled".equals(pseudo[0])) {\r
+      xpath = "not(@disabled)";\r
+    } else if ("disabled".equals(pseudo[0])) {\r
+      xpath = "@disabled";\r
+    } else if ("checked".equals(pseudo[0])) {\r
+      xpath = "@checked='checked'"; // Doesn't work in Opera 9.24\r
+    } else if ("not".equals(pseudo[0])) {\r
+      if (pseudoValue.matches("^(:a-zA-Z_0-9+[a-zA-Z_0-9\\-]*)$")) {\r
+        xpath = "not(" + pseudoToXPath(tag, pseudoValue.substring(1), "") + ")";\r
+      } else {\r
+        pseudoValue = pseudoValue\r
+            .replaceAll("^\\[#([a-zA-Z_0-9\u00C0-\uFFFF\\-\\_]+)\\]$",\r
+                "[id=$1]");\r
+        String notSelector = pseudoValue\r
+            .replaceFirst("^(a-zA-Z_0-9+)", "self::$1");\r
+        notSelector = notSelector\r
+            .replaceAll("^\\.([a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)",\r
+                "contains(concat(' ', @class, ' '), ' $1 ')");\r
+        notSelector = attrToXPath(notSelector,\r
+            "\\[(a-zA-Z_0-9+)(\\^|\\$|\\*|\\||~)?=?([a-zA-Z_0-9\u00C0-\uFFFF\\s\\-_\\.]+)?\\]");\r
+        xpath = "not(" + notSelector + ")";\r
+      }\r
+    } else {\r
+      xpath = "@" + pseudoClass + "='" + pseudoValue + "'";\r
+    }\r
+    return xpath;\r
+  }\r
+\r
+  private String attrToXPath(String notSelector, String pattern) {\r
+    Pattern p = Pattern.compile(pattern);\r
+    Matcher m = p.matcher(notSelector);\r
+    m.reset();\r
+    boolean result = m.find();\r
+    if (result) {\r
+      StringBuffer sb = new StringBuffer();\r
+      do {\r
+        String replacement;\r
+        String p1 = m.group(1);\r
+        String p2 = m.group(2);\r
+        String p3 = m.group(3);\r
+        if ("^".equals(p2)) {\r
+          replacement = "starts-with(@" + p1 + ", '" + p3 + "')";\r
+        } else if ("$".equals(p2)) {\r
+          replacement = "substring(@" + p1 + ", (string-length(@" + p1 + ") - "\r
+              + (p3.length() - 1) + "), " + p3.length() + ") = '" + p3 + "'";\r
+        } else if ("*".equals(p2)) {\r
+          replacement = "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')";\r
+        } else if ("|".equals(p2)) {\r
+          replacement = "(@" + p1 + "='" + p3 + "' or starts-with(@" + p1\r
+              + ", '" + p3 + "-'))";\r
+        } else if ("~".equals(p2)) {\r
+          replacement = "contains(concat(' ', @" + p1 + ", ' '), ' " + p3\r
+              + " ')";\r
+        } else {\r
+          replacement = "@" + p1 + (notNull(p3) ? "='" + p3 + "'" : "");\r
+        }\r
+        debug("p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " replacement is "\r
+            + replacement);\r
+        m.appendReplacement(sb, replacement.replace("$", "\\$"));\r
+        result = m.find();\r
+      } while (result);\r
+      m.appendTail(sb);\r
+      return sb.toString();\r
+    }\r
+    return notSelector;\r
+  }\r
+\r
+  private Sequence getSequence(String expression) {\r
+    int start = 0, add = 2, max = -1, modVal = -1;\r
+    Pattern expressionRegExp = Pattern.compile(\r
+        "^((odd|even)|([1-9]\\d*)|((([1-9]\\d*)?)n([\\+\\-]\\d+)?)|(\\-(([1-9]\\d*)?)n\\+(\\d+)))$");\r
+    Matcher pseudoValue = expressionRegExp.matcher(expression);\r
+    if (!pseudoValue.matches()) {\r
+      return null;\r
+    } else {\r
+      if (notNull(pseudoValue.group(2))) {   // odd or even\r
+        start = ("odd".equals(pseudoValue.group(2))) ? 1 : 2;\r
+        modVal = (start == 1) ? 1 : 0;\r
+      } else if (notNull(pseudoValue.group(3))) {      // single digit\r
+        start = Integer.parseInt(pseudoValue.group(3), 10);\r
+        add = 0;\r
+        max = start;\r
+      } else if (notNull(pseudoValue.group(4))) {      // an+b\r
+        add = notNull(pseudoValue.group(6)) ? getInt(pseudoValue.group(6), 1)\r
+            : 1;\r
+        start = notNull(pseudoValue.group(7)) ? getInt(pseudoValue.group(7), 0)\r
+            : 0;\r
+        while (start < 1) {\r
+          start += add;\r
+        }\r
+        modVal = (start > add) ? (start - add) % add\r
+            : ((start == add) ? 0 : start);\r
+      } else if (notNull(pseudoValue.group(8))) {      // -an+b\r
+        add = notNull(pseudoValue.group(10)) ? Integer\r
+            .parseInt(pseudoValue.group(10), 10) : 1;\r
+        start = max = Integer.parseInt(pseudoValue.group(10), 10);\r
+        while (start > add) {\r
+          start -= add;\r
+        }\r
+        modVal = (max > add) ? (max - add) % add : ((max == add) ? 0 : max);\r
+      }\r
+    }\r
+    Sequence s = new Sequence();\r
+    s.start = start;\r
+    s.add = add;\r
+    s.max = max;\r
+    s.modVal = modVal;\r
+    return s;\r
+  }\r
+\r
+  private int getInt(String s, int i) {\r
+    try {\r
+      if (s.startsWith("+")) {\r
+        s = s.substring(1);\r
+      }\r
+      return Integer.parseInt(s);\r
+    } catch (Exception e) {\r
+      debug("error parsing Integer " + s);\r
+      return i;\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml b/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml
deleted file mode 100644 (file)
index 8cfabdb..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<module>\r
-    <inherits name='com.google.gwt.user.User'/>\r
-\r
-    <!--<define-property name="selectorCapability" values="native,xpath,js"/>-->\r
-      <!-- enable for native getClassByName shortcut acceleration -->\r
-    <define-property name="selectorCapability"\r
-                     values="native,js"/>\r
-    <property-provider name="selectorCapability">\r
-        <![CDATA[\r
-   // useful for benchmarking tests when you want to force non-accelerated queries\r
-   //if(window.location.href.indexOf("_selector_force_js") != -1) return "js"; \r
-   if(document.querySelectorAll && /native/.test(document.querySelectorAll.toString())) {\r
-      return "native";\r
-   }\r
-   return "js"\r
-     ]]>\r
-    </property-provider>\r
-\r
-    <generate-with class="gwtquery.rebind.SelectorGeneratorJS">\r
-        <when-type-assignable class="gwtquery.client.Selectors"/>\r
-        <any>\r
-            <when-property-is name="user.agent" value="gecko"/>\r
-            <when-property-is name="user.agent" value="ie6"/>\r
-        </any>\r
-\r
-    </generate-with>\r
-\r
-    <generate-with class="gwtquery.rebind.SelectorGeneratorXPath">\r
-        <when-type-assignable class="gwtquery.client.Selectors"/>\r
-        <any>\r
-            <when-property-is name="user.agent" value="gecko1_8"/>\r
-            <when-property-is name="user.agent" value="opera"/>\r
-            <all>\r
-                <when-property-is name="selectorCapability" value="js"/>\r
-                <when-property-is name="user.agent" value="safari"/>\r
-            </all>\r
-        </any>\r
-    </generate-with>\r
-\r
-    <generate-with class="gwtquery.rebind.gebcn.SelectorGeneratorNativeGEBCN">\r
-        <when-type-assignable class="gwtquery.client.Selectors"/>\r
-        <all>\r
-            <when-property-is name="selectorCapability" value="native"/>\r
-            <when-property-is name="user.agent" value="safari"/>\r
-        </all>\r
-    </generate-with>\r
-\r
-    <!--versions which handle native getElementsByClassName -->\r
-    <!--<generate-with class="gwtquery.rebind.gebcn.SelectorGeneratorJSGEBCN">-->\r
-    <!--<when-type-assignable class="gwtquery.client.Selectors"/>-->\r
-    <!--<when-property-is name="selectorCapability" value="js_gebcn"/>-->\r
-    <!--</generate-with>-->\r
-\r
-    <!--<generate-with class="gwtquery.rebind.gebcn.SelectorGeneratorXPathGEBCN">-->\r
-    <!--<when-type-assignable class="gwtquery.client.Selectors"/>-->\r
-    <!--<when-property-is name="selectorCapability" value="xpath_gebcn"/>-->\r
-    <!--</generate-with>-->\r
-\r
-    <!--<generate-with class="gwtquery.rebind.gebcn.SelectorGeneratorNativeGEBCN">-->\r
-    <!--<when-type-assignable class="gwtquery.client.Selectors"/>-->\r
-    <!--<when-property-is name="selectorCapability" value="native_gebcn"/>-->\r
-    <!--</generate-with>-->\r
-\r
-\r
-    <replace-with class="gwtquery.client.impl.DocumentStyleImpl">\r
-        <when-type-assignable class="gwtquery.client.impl.DocumentStyleImpl"/>\r
-    </replace-with>\r
-\r
-    <replace-with class="gwtquery.client.impl.DocumentStyleImplIE">\r
-        <when-type-assignable class="gwtquery.client.impl.DocumentStyleImpl"/>\r
-        <when-property-is name="user.agent" value="ie6"/>\r
-    </replace-with>\r
-\r
-\r
-    <replace-with class="gwtquery.client.impl.SelectorEngineJS">\r
-        <when-type-assignable class="gwtquery.client.impl.SelectorEngineImpl"/>\r
-        <when-property-is name="user.agent" value="gecko"/>\r
-    </replace-with>\r
-\r
-    <replace-with class="gwtquery.client.impl.SelectorEngineJSIE">\r
-        <when-type-assignable class="gwtquery.client.impl.SelectorEngineImpl"/>\r
-        <when-property-is name="user.agent" value="ie6"/>\r
-    </replace-with>\r
-\r
-    <replace-with class="gwtquery.client.impl.SelectorEngineXPath">\r
-        <when-type-assignable class="gwtquery.client.impl.SelectorEngineImpl"/>\r
-        <any>\r
-            <when-property-is name="user.agent" value="gecko1_8"/>\r
-            <when-property-is name="user.agent" value="opera"/>\r
-            <all>\r
-                <when-property-is name="selectorCapability" value="js"/>\r
-                <when-property-is name="user.agent" value="safari"/>\r
-            </all>\r
-        </any>\r
-    </replace-with>\r
-\r
-    <replace-with class="gwtquery.client.impl.SelectorEngineNative">\r
-        <when-type-assignable class="gwtquery.client.impl.SelectorEngineImpl"/>\r
-        <all>\r
-            <when-property-is name="user.agent" value="safari"/>\r
-            <when-property-is name="selectorCapability" value="native"/>\r
-        </all>\r
-    </replace-with>\r
-\r
-</module>
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/client/$.java b/gwtquery-core/src/main/java/gwtquery/client/$.java
deleted file mode 100644 (file)
index 273c951..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-package gwtquery.client;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
-
-/**
- *
- */
-public class $ {
-
-  public static GQuery $(String selectorOrHtml) {
-    return GQuery.$(selectorOrHtml);
-  }
-
-  public static <T extends GQuery> T $(T gq) {
-    return GQuery.$(gq);
-  }
-
-  /**
-   * This function accepts a string containing a CSS selector which is then used
-   * to match a set of elements, or it accepts raw HTML creating a GQuery
-   * element containing those elements. The second parameter is is a class
-   * reference to a plugin to be used.
-   */
-  public static <T extends GQuery> T $(String selector, Class<T> plugin) {
-    return GQuery.$(selector, plugin);
-  }
-
-  /**
-   * This function accepts a string containing a CSS selector which is then used
-   * to match a set of elements, or it accepts raw HTML creating a GQuery
-   * element containing those elements. The second parameter is the context to
-   * use for the selector.
-   */
-  public static GQuery $(String selector, Node context) {
-    return GQuery.$(selector, context);
-  }
-
-  /**
-   * This function accepts a string containing a CSS selector which is then used
-   * to match a set of elements, or it accepts raw HTML creating a GQuery
-   * element containing those elements. The second parameter is the context to
-   * use for the selector. The third parameter is the class plugin to use.
-   */
-  public static <T extends GQuery> GQuery $(String selector, Node context,
-      Class<T> plugin) {
-    return GQuery.$(selector, context, plugin);
-  }
-
-  /**
-   * Wrap a GQuery around  existing Elements.
-   */
-  public static GQuery $(NodeList<Element> elements) {
-    return GQuery.$(elements);
-  }
-
-  /**
-   * Wrap a GQuery around an existing Element.
-   */
-  public static GQuery $(Element element) {
-    return GQuery.$(element);
-  }
-
-  /**
-   * Wrap a JSON object
-   */
-  public static Properties $$(String properties) {
-    return GQuery.$$(properties);
-  }
-
-  /**
-   * Registers a GQuery plugin
-   * @param plugin
-   * @param pluginFactory
-   */
-  public static void registerPlugin(Class<? extends GQuery> plugin,
-      Plugin<? extends GQuery> pluginFactory) {
-    GQuery.registerPlugin(plugin, pluginFactory);
-  }
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/client/DeferredGQuery.java b/gwtquery-core/src/main/java/gwtquery/client/DeferredGQuery.java
deleted file mode 100644 (file)
index fe1165a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.dom.client.Node;\r
-import com.google.gwt.dom.client.Element;\r
-import com.google.gwt.dom.client.NodeList;\r
-\r
-/**\r
- * A compiled selector that can be lazily turned into a GQuery\r
- */\r
-public interface DeferredGQuery {\r
-    String getSelector();\r
-    GQuery eval(Node ctx);\r
-    NodeList<Element> array(Node ctx);\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Effects.java b/gwtquery-core/src/main/java/gwtquery/client/Effects.java
deleted file mode 100644 (file)
index 21fabb8..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.dom.client.Element;\r
-import com.google.gwt.dom.client.NodeList;\r
-import com.google.gwt.animation.client.Animation;\r
-\r
-public class Effects extends GQuery {\r
-\r
-  static {\r
-    GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
-  }\r
-\r
-  public static final Class<Effects> Effects = Effects.class;\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
-  /**\r
-   * function( prop, speed, easing, callback ) {\r
-               var optall = jQuery.speed(speed, easing, callback);\r
-\r
-               return this[ optall.queue === false ? "each" : "queue" ](function(){\r
-               \r
-                       var opt = jQuery.extend({}, optall), p,\r
-                               hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),\r
-                               self = this;\r
-       \r
-                       for ( p in prop ) {\r
-                               if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )\r
-                                       return opt.complete.call(this);\r
-\r
-                               if ( ( p == "height" || p == "width" ) && this.style ) {\r
-                                       // Store display property\r
-                                       opt.display = jQuery.css(this, "display");\r
-\r
-                                       // Make sure that nothing sneaks out\r
-                                       opt.overflow = this.style.overflow;\r
-                               }\r
-                       }\r
-\r
-                       if ( opt.overflow != null )\r
-                               this.style.overflow = "hidden";\r
-\r
-                       opt.curAnim = jQuery.extend({}, prop);\r
-\r
-                       jQuery.each( prop, function(name, val){\r
-                               var e = new jQuery.fx( self, opt, name );\r
-\r
-                               if ( /toggle|show|hide/.test(val) )\r
-                                       e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );\r
-                               else {\r
-                                       var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),\r
-                                               start = e.cur(true) || 0;\r
-\r
-                                       if ( parts ) {\r
-                                               var end = parseFloat(parts[2]),\r
-                                                       unit = parts[3] || "px";\r
-\r
-                                               // We need to compute starting value\r
-                                               if ( unit != "px" ) {\r
-                                                       self.style[ name ] = (end || 1) + unit;\r
-                                                       start = ((end || 1) / e.cur(true)) * start;\r
-                                                       self.style[ name ] = start + unit;\r
-                                               }\r
-\r
-                                               // If a +=/-= token was provided, we're doing a relative animation\r
-                                               if ( parts[1] )\r
-                                                       end = ((parts[1] == "-=" ? -1 : 1) * end) + start;\r
-\r
-                                               e.custom( start, end, unit );\r
-                                       } else\r
-                                               e.custom( start, val, "" );\r
-                               }\r
-                       });\r
-\r
-                       // For JS strict compliance\r
-                       return true;\r
-               });\r
-       },\r
-   * @return\r
-   */\r
-  public Effects animate(Properties props, String speed, String easing,\r
-      Function callback) {\r
-    return this;\r
-  }\r
-  \r
-  public Effects fadeOut() {\r
-    Animation a = new Animation() {\r
-\r
-      public void onCancel() {\r
-      }\r
-\r
-      public void onComplete() {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle().setProperty("opacity", "0");\r
-          elements.getItem(i).getStyle().setProperty("display", "none");\r
-        }\r
-      }\r
-\r
-      public void onStart() {\r
-      }\r
-\r
-      public void onUpdate(double progress) {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle()\r
-              .setProperty("opacity", String.valueOf(1.0 - progress));\r
-        }\r
-      }\r
-    };\r
-    a.run(1000);\r
-    return this;\r
-  }\r
-\r
-  public Effects fadeIn() {\r
-    Animation a = new Animation() {\r
-\r
-      public void onCancel() {\r
-      }\r
-\r
-      public void onComplete() {\r
-      }\r
-\r
-      public void onStart() {\r
-      }\r
-\r
-      public void onUpdate(double progress) {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle()\r
-              .setProperty("opacity", String.valueOf(progress));\r
-        }\r
-      }\r
-    };\r
-    a.run(1000);\r
-    return this;\r
-  }\r
-\r
-  public static class EffectsPlugin implements Plugin<Effects> {\r
-\r
-    public Effects init(GQuery gq) {\r
-      return new Effects(gq.get());\r
-    }\r
-  }\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Function.java b/gwtquery-core/src/main/java/gwtquery/client/Function.java
deleted file mode 100644 (file)
index f9d70a4..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package gwtquery.client;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.user.client.Event;
-
-/**
-   * Extend this class to implement functions.
- */
-public abstract class Function {
-
-  public String f(Element e,  int i) {
-    return "";  
-  }
-  
-  public void f(Element e) {
-  }
-
-  public boolean f(Event e, Object data) {
-    return f(e);
-  }
-
-  public boolean f(Event e) {
-    f(e.getCurrentTarget());
-    return true;
-  }
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/client/GQuery.java b/gwtquery-core/src/main/java/gwtquery/client/GQuery.java
deleted file mode 100644 (file)
index 3354bba..0000000
+++ /dev/null
@@ -1,1950 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.core.client.JavaScriptObject;\r
-import com.google.gwt.dom.client.BodyElement;\r
-import com.google.gwt.dom.client.ButtonElement;\r
-import com.google.gwt.dom.client.Document;\r
-import com.google.gwt.dom.client.Element;\r
-import com.google.gwt.dom.client.IFrameElement;\r
-import com.google.gwt.dom.client.InputElement;\r
-import com.google.gwt.dom.client.NativeEvent;\r
-import com.google.gwt.dom.client.Node;\r
-import com.google.gwt.dom.client.NodeList;\r
-import com.google.gwt.dom.client.OptionElement;\r
-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.user.client.DOM;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.EventListener;\r
-import com.google.gwt.user.client.Window;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import gwtquery.client.impl.DocumentStyleImpl;\r
-\r
-/**\r
- *\r
- */\r
-public class GQuery {\r
-\r
-  public static class Offset {\r
-\r
-    public int top;\r
-\r
-    public int left;\r
-\r
-    Offset(int left, int top) {\r
-      this.left = left;\r
-      this.top = top;\r
-    }\r
-  }\r
-\r
-  private static class DataCache extends JavaScriptObject {\r
-\r
-    protected DataCache() {\r
-    }\r
-\r
-    public native void delete(String name) /*-{\r
-      delete this[name];\r
-    }-*/;\r
-\r
-    public native void delete(int name) /*-{\r
-      delete this[name];\r
-    }-*/;\r
-\r
-    public native boolean exists(int id) /*-{\r
-      return !!this[id];\r
-    }-*/;\r
-\r
-    public native JavaScriptObject get(String id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native JavaScriptObject get(int id) /*-{\r
-      return this[id];\r
-    }-*/; /*-{\r
-      delete this[name];\r
-    }-*/\r
-\r
-    public DataCache getCache(int id) {\r
-      return get(id).cast();\r
-    }\r
-\r
-    public native double getDouble(String id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native double getDouble(int id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native int getInt(String id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native int getInt(int id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native String getString(String id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native String getString(int id) /*-{\r
-      return this[id];\r
-    }-*/;\r
-\r
-    public native boolean isEmpty() /*-{\r
-        var foo = "";\r
-        for(foo in this) break;\r
-        return !foo;\r
-    }-*/;\r
-\r
-    public native void put(String id, Object obj) /*-{\r
-      return this[id]=obj;\r
-    }-*/;\r
-\r
-    public native void put(int id, Object obj) /*-{\r
-      return this[id]=obj;\r
-    }-*/;\r
-  }\r
-\r
-  private static class FastSet extends JavaScriptObject {\r
-\r
-    public static FastSet create() {\r
-      return JavaScriptObject.createObject().cast();\r
-    }\r
-\r
-    protected FastSet() {\r
-    }\r
-\r
-    public void add(Object o) {\r
-      add0(o.hashCode());\r
-    }\r
-\r
-    public boolean contains(Object o) {\r
-      return contains0(o.hashCode());\r
-    }\r
-\r
-    public void remove(Object o) {\r
-      remove0(o.hashCode());\r
-    }\r
-\r
-    private native void add0(int hc) /*-{\r
-      this[hc]=true;\r
-    }-*/;\r
-\r
-    private native boolean contains0(int hc) /*-{\r
-      return this[hc];\r
-    }-*/;\r
-\r
-    private native void remove0(int hc) /*-{\r
-      delete this[hc];\r
-    }-*/;\r
-  }\r
-\r
-  private static class Queue<T> extends JavaScriptObject {\r
-\r
-    public static Queue newInstance() {\r
-      return createArray().cast();\r
-    }\r
-\r
-    protected Queue() {\r
-    }\r
-\r
-    public native T dequeue() /*-{\r
-       return this.shift();\r
-    }-*/;\r
-\r
-    public native void enqueue(T foo) /*-{\r
-       this.push(foo);\r
-     }-*/;\r
-\r
-    public native int length() /*-{\r
-       return this.length;\r
-    }-*/;\r
-\r
-    public native T peek(int i) /*-{\r
-      return this[i];\r
-    }-*/;\r
-  }\r
-\r
-  public static boolean fxOff = false;\r
-\r
-  private static Map<Class<? extends GQuery>, Plugin<? extends GQuery>> plugins;\r
-\r
-  private static Element windowData = null;\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
-  /**\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.trim().charAt(0) == '<') {\r
-      return innerHtml(selectorOrHtml);\r
-    }\r
-    return $(selectorOrHtml, Document.get());\r
-  }\r
-\r
-  public static <T extends GQuery> T $(T gq) {\r
-\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
-   * element containing those elements. The second parameter is is a class\r
-   * reference to a plugin to be used.\r
-   */\r
-  public static <T extends GQuery> T $(String selector, Class<T> plugin) {\r
-    try {\r
-      if (plugins != null) {\r
-        T gquery = (T) plugins.get(plugin).init($(selector, Document.get()));\r
-        return gquery;\r
-      }\r
-      throw new RuntimeException("No plugin for class " + plugin);\r
-    } catch (Exception e) {\r
-      throw new RuntimeException(e);\r
-    }\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. The second parameter is the context to\r
-   * use for the selector.\r
-   */\r
-  public static GQuery $(String selector, Node context) {\r
-    return new GQuery(select(selector, context));\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. The second parameter is the context to\r
-   * use for the selector. The third parameter is the class plugin to use.\r
-   */\r
-  public static <T extends GQuery> GQuery $(String selector, Node context,\r
-      Class<T> plugin) {\r
-    try {\r
-      if (plugins != null) {\r
-        T gquery = (T) plugins.get(plugin)\r
-            .init(new GQuery(select(selector, context)));\r
-        return gquery;\r
-      }\r
-      throw new RuntimeException("No plugin for class " + plugin);\r
-    } catch (Exception e) {\r
-      throw new RuntimeException(e);\r
-    }\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
-  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 JSON object\r
-   */\r
-  public static Properties $$(String properties) {\r
-    return Properties.create(properties);\r
-  }\r
-\r
-  public static <T extends Node> T[] asArray(NodeList<T> nl) {\r
-    if (GWT.isScript()) {\r
-      return reinterpretCast(nl);\r
-    } else {\r
-      Node[] elts = new Node[nl.getLength()];\r
-      for (int i = 0; i < elts.length; i++) {\r
-        elts[i] = nl.getItem(i);\r
-      }\r
-      return (T[]) elts;\r
-    }\r
-  }\r
-\r
-  public static void registerPlugin(Class<? extends GQuery> plugin,\r
-      Plugin<? extends GQuery> pluginFactory) {\r
-    if (plugins == null) {\r
-      plugins = new HashMap();\r
-    }\r
-    plugins.put(plugin, pluginFactory);\r
-  }\r
-\r
-  /**\r
-   * Copied from UIObject *\r
-   */\r
-  protected static void setStyleName(Element elem, String style, boolean add) {\r
-\r
-    style = style.trim();\r
-\r
-    // Get the current style string.\r
-    String oldStyle = elem.getClassName();\r
-    int idx = oldStyle.indexOf(style);\r
-\r
-    // Calculate matching index.\r
-    while (idx != -1) {\r
-      if (idx == 0 || oldStyle.charAt(idx - 1) == ' ') {\r
-        int last = idx + style.length();\r
-        int lastPos = oldStyle.length();\r
-        if ((last == lastPos) || ((last < lastPos) && (oldStyle.charAt(last)\r
-            == ' '))) {\r
-          break;\r
-        }\r
-      }\r
-      idx = oldStyle.indexOf(style, idx + 1);\r
-    }\r
-\r
-    if (add) {\r
-      // Only add the style if it's not already present.\r
-      if (idx == -1) {\r
-        if (oldStyle.length() > 0) {\r
-          oldStyle += " ";\r
-        }\r
-        DOM.setElementProperty(elem.<com.google.gwt.user.client.Element>cast(),\r
-            "className", oldStyle + style);\r
-      }\r
-    } else {\r
-      // Don't try to remove the style if it's not there.\r
-      if (idx != -1) {\r
-        // Get the leading and trailing parts, without the removed name.\r
-        String begin = oldStyle.substring(0, idx).trim();\r
-        String end = oldStyle.substring(idx + style.length()).trim();\r
-\r
-        // Some contortions to make sure we don't leave extra spaces.\r
-        String newClassName;\r
-        if (begin.length() == 0) {\r
-          newClassName = end;\r
-        } else if (end.length() == 0) {\r
-          newClassName = begin;\r
-        } else {\r
-          newClassName = begin + " " + end;\r
-        }\r
-\r
-        DOM.setElementProperty(elem.<com.google.gwt.user.client.Element>cast(),\r
-            "className", newClassName);\r
-      }\r
-    }\r
-  }\r
-\r
-  private static String curCSS(Element elem, String name) {\r
-    Style s = elem.getStyle();\r
-    ensureStyleImpl();\r
-    name = styleImpl.getPropertyName(name);\r
-\r
-    if (SelectorEngine.truth(s.getProperty(name))) {\r
-      return s.getProperty(name);\r
-    }\r
-    return styleImpl.getCurrentStyle(elem, name);\r
-  }\r
-\r
-  private static void ensureStyleImpl() {\r
-    if (styleImpl != null) {\r
-      styleImpl = GWT.create(DocumentStyleImpl.class);\r
-    }\r
-  }\r
-\r
-  private static boolean hasClass(Element e, String clz) {\r
-    return e.getClassName().matches("\\s" + clz + "\\s");\r
-  }\r
-\r
-  private static GQuery innerHtml(String html) {\r
-    Element div = DOM.createDiv();\r
-    div.setInnerHTML(html);\r
-    return new GQuery((NodeList<Element>) (NodeList<?>) div.getChildNodes());\r
-  }\r
-\r
-  private static native <T extends Node> T[] reinterpretCast(NodeList<T> nl) /*-{\r
-        return nl;\r
-    }-*/;\r
-\r
-  private static NodeList select(String selector, Node context) {\r
-    return new SelectorEngine().select(selector, context);\r
-  }\r
-\r
-  protected NodeList<Element> elements = null;\r
-\r
-  private String selector;\r
-\r
-  private GQuery previousObject;\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
-  public GQuery add(String selector) {\r
-    return add($(selector));\r
-  }\r
-\r
-  /**\r
-   * Adds the specified classes to each matched element.\r
-   */\r
-  public GQuery addClass(String... classes) {\r
-    for (Element e : elements()) {\r
-      for (String clz : classes) {\r
-        setStyleName(e, clz, true);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Insert content after each of the matched elements. The elements must\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Insert content after each of the matched elements. The elements must\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Insert content after each of the matched elements. The elements must\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Add the previous selection to the current selection. Useful for traversing\r
-   * elements, and then adding something that was matched before the last\r
-   * traversal.\r
-   */\r
-  public GQuery andSelf() {\r
-    return add(previousObject);\r
-  }\r
-\r
-  /**\r
-   * Append content to the inside of every matched element. This operation is\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Append content to the inside of every matched element. This operation is\r
-   * similar to doing an appendChild to all the specified elements, adding them\r
-   * into the document.\r
-   */\r
-  public GQuery append(Node n) {\r
-    return domManip(JSArray.create(n), FUNC_APPEND);\r
-  }\r
-\r
-  /**\r
-   * Append content to the inside of every matched element. This operation is\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Convert to Plugin interface provided by Class literal.\r
-   */\r
-  public <T extends GQuery> T as(Class<T> plugin) {\r
-    if (plugins != null) {\r
-      return (T) plugins.get(plugin).init(this);\r
-    }\r
-    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(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
-    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
-  public GQuery attr(Properties properties) {\r
-    for (Element e : elements()) {\r
-      for (String name : properties.keys()) {\r
-        e.setAttribute(name, properties.get(name));\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Set a single property to a computed value, on all matched elements.\r
-   */\r
-  public GQuery attr(String key, Function closure) {\r
-    for (int i = 0; i < elements.getLength(); i++) {\r
-      Element e = elements.getItem(i);\r
-      e.setAttribute(key, closure.f(e, i));\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_AFTER);\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(GQuery query) {\r
-    return domManip(query.elements, FUNC_AFTER);\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(String html) {\r
-    return domManip(html, FUNC_AFTER);\r
-  }\r
-\r
-  /**\r
-   * Binds a handler to one or more events (like click) for each matched\r
-   * element.\r
-   */\r
-  public GQuery bind(int eventbits, final Object data, final Function f) {\r
-    EventListener listener = new EventListener() {\r
-      public void onBrowserEvent(Event event) {\r
-        if (!f.f(event, data)) {\r
-          event.cancelBubble(true);\r
-          event.preventDefault();\r
-        }\r
-      }\r
-    };\r
-    for (Element e : elements()) {\r
-      DOM.sinkEvents((com.google.gwt.user.client.Element) e, eventbits);\r
-      DOM.setEventListener((com.google.gwt.user.client.Element) e, listener);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  public GQuery blur(Function f) {\r
-    return bind(Event.ONBLUR, null, f);\r
-  }\r
-\r
-  public GQuery blur() {\r
-    return trigger(Document.get().createBlurEvent(), null);\r
-  }\r
-\r
-  public GQuery change(Function f) {\r
-    return bind(Event.ONCHANGE, null, f);\r
-  }\r
-\r
-  public GQuery change() {\r
-    return trigger(Document.get().createChangeEvent(), null);\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
-   * at all ancestors, children() will only consider immediate child elements.\r
-   */\r
-  public GQuery children() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      allNextSiblingElements(e.getFirstChildElement(), result);\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  public GQuery click() {\r
-    return trigger(\r
-        Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false,\r
-            false), null);\r
-  }\r
-\r
-  /**\r
-   * Triggers the click event of each matched element. Causes all of the\r
-   * functions that have been bound to that click event to be executed.\r
-   */\r
-  public GQuery click(final Function f) {\r
-    return bind(Event.ONCLICK, null, f);\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
-   */\r
-  public GQuery clone() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      result.addNode(e.cloneNode(true));\r
-    }\r
-    return new GQuery(result);\r
-  }\r
-\r
-  /**\r
-   * Find all the child nodes inside the matched elements (including text\r
-   * nodes), or the content document, if the element is an iframe.\r
-   */\r
-  public GQuery contents() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      NodeList children = e.getChildNodes();\r
-      for (int i = 0; i < children.getLength(); i++) {\r
-        Node n = children.getItem(i);\r
-        if (IFrameElement.is(n)) {\r
-          result.addNode(getContentDocument(n));\r
-        } else {\r
-          result.addNode(n);\r
-        }\r
-      }\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  /**\r
-   * Return a style property on the first matched element.\r
-   */\r
-  public String css(String name) {\r
-    return curCSS(get(0), name);\r
-  }\r
-\r
-  /**\r
-   * Set a key/value object as style properties to all matched elements. This is\r
-   * the best way to set several style properties on all matched elements. Be\r
-   * aware, however, that when the key contains a hyphen, such as\r
-   * "background-color," it must either be placed within quotation marks or be\r
-   * written in camel case like so: backgroundColor. As "float" and "class" are\r
-   * reserved words in JavaScript, it's recommended to always surround those\r
-   * terms with quotes. gQuery normalizes the "opacity" property in Internet\r
-   * Explorer.\r
-   */\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 a single style property to a value on all matched elements. If a number\r
-   * is provided, it is automatically converted into a pixel value.\r
-   */\r
-  public GQuery css(String prop, String val) {\r
-    for (Element e : elements()) {\r
-      e.getStyle().setProperty(prop, val);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Returns value at named data store for the element, as set by data(name,\r
-   * value).\r
-   */\r
-  public Object data(String name) {\r
-    return data(elements.getItem(0), name, null);\r
-  }\r
-\r
-  /**\r
-   * Returns value at named data store for the element, as set by data(name,\r
-   * value) with desired return type.\r
-   *\r
-   * @param clz return type class literal\r
-   */\r
-  public <T> T data(String name, Class<T> clz) {\r
-    return (T) data(elements.getItem(0), name, null);\r
-  }\r
-\r
-  /**\r
-   * Stores the value in the named spot with desired return type.\r
-   */\r
-  public void data(String name, String value) {\r
-    for (Element e : elements()) {\r
-      data(e, name, value);\r
-    }\r
-  }\r
-\r
-  public GQuery dblclick() {\r
-    return trigger(\r
-        Document.get().createDblClickEvent(0, 0, 0, 0, 0, false, false, false,\r
-            false), null);\r
-  }\r
-\r
-  public GQuery dblclick(Function f) {\r
-    return bind(Event.ONDBLCLICK, null, f);\r
-  }\r
-\r
-  /**\r
-   * Removes a queued function from the front of the queue and executes it.\r
-   */\r
-  public GQuery dequeue(String type) {\r
-    for (Element e : elements()) {\r
-      dequeue(e, type);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Removes a queued function from the front of the FX queue and executes it.\r
-   */\r
-  public GQuery dequeue() {\r
-    return dequeue("__FX");\r
-  }\r
-\r
-  /**\r
-   * Run one or more Functions over each element of the GQuery.\r
-   */\r
-  public GQuery each(Function... f) {\r
-    for (Function f1 : f) {\r
-      for (Element e : elements()) {\r
-        f1.f(e);\r
-      }\r
-    }\r
-    return this;\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
-   */\r
-  public Element[] elements() {\r
-    return asArray(elements);\r
-  }\r
-\r
-  /**\r
-   * Remove all child nodes from the set of matched elements.\r
-   */\r
-  public GQuery empty() {\r
-    //TODO: add memory leak cleanup, remove event handlers, and \r
-    // data caches\r
-    for (Element e : elements()) {\r
-      while (e.getFirstChild() != null) {\r
-        e.removeChild(e.getFirstChild());\r
-      }\r
-    }\r
-\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Revert the most recent 'destructive' operation, changing the set of matched\r
-   * elements to its previous state (right before the destructive operation).\r
-   */\r
-  public GQuery end() {\r
-    return previousObject != null ? previousObject : new GQuery();\r
-  }\r
-\r
-  /**\r
-   * Reduce GQuery to element in the specified position.\r
-   */\r
-  public GQuery eq(int pos) {\r
-    return $(elements.getItem(pos));\r
-  }\r
-\r
-  public GQuery error() {\r
-    return trigger(Document.get().createErrorEvent(), null);\r
-  }\r
-\r
-  public GQuery error(Function f) {\r
-    return bind(Event.ONERROR, null, f);\r
-  }\r
-\r
-  /**\r
-   * Removes all elements from the set of matched elements that do not match the\r
-   * specified function. The function is called with a context equal to the\r
-   * current element. If the function returns false, then the element is removed\r
-   * - anything else and the element is kept.\r
-   */\r
-  public GQuery filter(Predicate filterFn) {\r
-    JSArray result = JSArray.create();\r
-    for (int i = 0; i < elements.getLength(); i++) {\r
-      Element e = elements.getItem(i);\r
-      if (filterFn.f(e, i)) {\r
-        result.addNode(e);\r
-      }\r
-    }\r
-    return pushStack(result, "filter", selector);\r
-  }\r
-\r
-  public GQuery focus() {\r
-    return trigger(Document.get().createFocusEvent(), null);\r
-  }\r
-\r
-  public GQuery focus(Function f) {\r
-    return bind(Event.ONFOCUS, null, f);\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
-   */\r
-  public NodeList<Element> get() {\r
-    return elements;\r
-  }\r
-\r
-  /**\r
-   * Return the ith element matched.\r
-   */\r
-  public Element get(int i) {\r
-    return elements.getItem(i);\r
-  }\r
-\r
-  public GQuery getPreviousObject() {\r
-    return previousObject;\r
-  }\r
-\r
-  public String getSelector() {\r
-    return selector;\r
-  }\r
-\r
-  /**\r
-   * Returns true any of the specified classes are present on any of the matched\r
-   * elements.\r
-   */\r
-  public boolean hasClass(String... classes) {\r
-    for (Element e : elements()) {\r
-      for (String clz : classes) {\r
-        if (hasClass(e, clz)) {\r
-          return true;\r
-        }\r
-      }\r
-    }\r
-    return false;\r
-  }\r
-\r
-  /**\r
-   * Set the height of every element in the matched set.\r
-   */\r
-  public GQuery height(int height) {\r
-    for (Element e : elements()) {\r
-      e.getStyle().setPropertyPx("height", height);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Get the innerHTML of the first matched element.\r
-   */\r
-  public String html() {\r
-    return get(0).getInnerHTML();\r
-  }\r
-\r
-  /**\r
-   * Set the innerHTML of every matched element.\r
-   */\r
-  public GQuery html(String html) {\r
-    for (Element e : elements()) {\r
-      e.setInnerHTML(html);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Find the index of the specified Element\r
-   */\r
-  public int index(Element element) {\r
-    for (int i = 0; i < elements.getLength(); i++) {\r
-      if (elements.getItem(i) == element) {\r
-        return i;\r
-      }\r
-    }\r
-    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
-   */\r
-  public GQuery insertAfter(Element elem) {\r
-    return insertAfter($(elem));\r
-  }\r
-\r
-  /**\r
-   * Insert all of the matched elements after another, specified, set of\r
-   * elements.\r
-   */\r
-  public GQuery insertAfter(GQuery query) {\r
-    for (Element e : elements()) {\r
-      query.after(e);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Insert all of the matched elements before another, specified, set of\r
-   * elements.\r
-   *\r
-   * The elements must already be inserted into the document (you can't insert\r
-   * an element after another if it's not in the page).\r
-   */\r
-  public GQuery insertBefore(Element item) {\r
-    return insertBefore($(item));\r
-  }\r
-\r
-  /**\r
-   * Insert all of the matched elements before another, specified, set of\r
-   * elements.\r
-   *\r
-   * The elements must already be inserted into the document (you can't insert\r
-   * an element after another if it's not in the page).\r
-   */\r
-  public GQuery insertBefore(GQuery query) {\r
-    for (Element e : elements()) {\r
-      query.before(e);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Insert all of the matched elements before another, specified, set of\r
-   * elements.\r
-   *\r
-   * The elements must already be inserted into the document (you can't insert\r
-   * an element after another if it's not in the page).\r
-   */\r
-  public GQuery insertBefore(String selector) {\r
-    return insertBefore($(selector));\r
-  }\r
-\r
-  public GQuery keydown() {\r
-    return trigger(\r
-        Document.get().createKeyDownEvent(false, false, false, false, 0, 0),\r
-        null);\r
-  }\r
-\r
-  public GQuery keydown(Function f) {\r
-    return bind(Event.ONKEYDOWN, null, f);\r
-  }\r
-\r
-  public GQuery keypress() {\r
-    return trigger(\r
-        Document.get().createKeyPressEvent(false, false, false, false, 0, 0),\r
-        null);\r
-  }\r
-\r
-  public GQuery keypressed(Function f) {\r
-    return bind(Event.ONKEYPRESS, null, f);\r
-  }\r
-\r
-  public GQuery keyup() {\r
-    return trigger(\r
-        Document.get().createKeyUpEvent(false, false, false, false, 0, 0),\r
-        null);\r
-  }\r
-\r
-  public GQuery keyup(Function f) {\r
-    return bind(Event.ONKEYUP, null, f);\r
-  }\r
-\r
-  public GQuery load(Function f) {\r
-    return bind(Event.ONLOAD, null, f);\r
-  }\r
-\r
-  public GQuery mousedown(Function f) {\r
-    return bind(Event.ONMOUSEDOWN, null, f);\r
-  }\r
-\r
-  public GQuery mousemove(Function f) {\r
-    return bind(Event.ONMOUSEMOVE, null, f);\r
-  }\r
-\r
-  public GQuery mouseout(Function f) {\r
-    return bind(Event.ONMOUSEOUT, null, f);\r
-  }\r
-\r
-  public GQuery mouseover(Function f) {\r
-    return bind(Event.ONMOUSEOVER, null, f);\r
-  }\r
-\r
-  public GQuery mouseup(Function f) {\r
-    return bind(Event.ONMOUSEUP, null, f);\r
-  }\r
-\r
-  /**\r
-   * Get a set of elements containing the unique next siblings of each of the\r
-   * given set of elements. next only returns the very next sibling for each\r
-   * element, not all next siblings see {#nextAll}.\r
-   */\r
-  public GQuery next() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      Element next = e.getNextSiblingElement();\r
-      if (next != null) {\r
-        result.addNode(next);\r
-      }\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  /**\r
-   * Find all sibling elements after the current element.\r
-   */\r
-  public GQuery nextAll() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      allNextSiblingElements(e.getNextSiblingElement(), result);\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  public Offset offset() {\r
-    return new Offset(get(0).getOffsetLeft(), get(0).getOffsetTop());\r
-  }\r
-\r
-  /**\r
-   * Returns a GQuery collection with the positioned parent of the first matched\r
-   * element. This is the first parent of the element that has position (as in\r
-   * relative or absolute). This method only works with visible elements.\r
-   */\r
-  public GQuery offsetParent() {\r
-    Element offParent = SelectorEngine\r
-        .or(elements.getItem(0).getOffsetParent(), Document.get().getBody());\r
-    while (offParent != null && !"body".equalsIgnoreCase(offParent.getTagName())\r
-        && !"html".equalsIgnoreCase(offParent.getTagName()) && "static"\r
-        .equals(curCSS(offParent, "position"))) {\r
-      offParent = offParent.getOffsetParent();\r
-    }\r
-    return new GQuery(offParent);\r
-  }\r
-\r
-  /**\r
-   * Get a set of elements containing the unique parents of the matched set of\r
-   * elements.\r
-   */\r
-  public GQuery parent() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      result.addNode(e.getParentElement());\r
-    }\r
-    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).\r
-   */\r
-  public GQuery parents() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      Node par = e.getParentNode();\r
-      while (par != null && par != Document.get()) {\r
-        result.addNode(par);\r
-        par = par.getParentNode();\r
-      }\r
-    }\r
-    return new GQuery(unique(result));\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
-\r
-    if (size() > 0) {\r
-      GQuery offsetParent = offsetParent();\r
-      Offset offset = offset();\r
-      Element e = offsetParent.get(0);\r
-\r
-      Offset parentOffset = BodyElement.is(e) || "html".equals(e.getTagName())\r
-          ? new Offset(0, 0) : offsetParent.offset();\r
-      offset.top -= num(this, "marginTop");\r
-      offset.left -= num(this, "marginLeft");\r
-      parentOffset.top += num(offsetParent, "borderTopWidth");\r
-      parentOffset.left += num(offsetParent, "borderLeftWidth");\r
-      return new Offset(offset.top - parentOffset.top,\r
-          offset.left - parentOffset.left);\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * Prepend content to the inside of every matched element. This operation is\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Prepend content to the inside of every matched element. This operation is\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Prepend content to the inside of every matched element. This operation is\r
-   * 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
-  }\r
-\r
-  /**\r
-   * Get a set of elements containing the unique previous siblings of each of\r
-   * the matched set of elements. Only the immediately previous sibling is\r
-   * returned, not all previous siblings.\r
-   */\r
-  public GQuery prev() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      Element next = getPreviousSiblingElement(e);\r
-      if (next != null) {\r
-        result.addNode(next);\r
-      }\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  /**\r
-   * Find all sibling elements in front of the current element.\r
-   */\r
-  public GQuery prevAll() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      allPreviousSiblingElements(getPreviousSiblingElement(e), result);\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  /**\r
-   * Returns a reference to the first element's queue (which is an array of\r
-   * functions).\r
-   */\r
-  public Queue<Function> queue(String type) {\r
-    return queue(elements.getItem(0), type, null);\r
-  }\r
-\r
-  /**\r
-   * Returns a reference to the FX queue.\r
-   */\r
-  public Queue<Function> queue() {\r
-    return queue(elements.getItem(0), "__FX", null);\r
-  }\r
-\r
-  /**\r
-   * Adds a new function, to be executed, onto the end of the queue of all\r
-   * matched elements.\r
-   */\r
-  public GQuery queue(String type, Function data) {\r
-    for (Element e : elements()) {\r
-      queue(e, type, data);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Replaces the current queue with the given queue on all matched elements.\r
-   */\r
-  public GQuery queue(String type, Queue data) {\r
-    for (Element e : elements()) {\r
-      replacequeue(e, type, data);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Adds a new function, to be executed, onto the end of the queue of all\r
-   * matched elements in the FX queue.\r
-   */\r
-  public GQuery queue(Function data) {\r
-    return queue("__FX", data);\r
-  }\r
-\r
-  /**\r
-   * Removes all matched elements from the DOM.\r
-   */\r
-  public GQuery remove() {\r
-    for (Element e : elements()) {\r
-      //TODO: cleanup event bindings\r
-      removeData(e, null);\r
-      if (e.getParentNode() != null) {\r
-        e.getParentNode().removeChild(e);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Remove the named attribute from every element in the matched set.\r
-   */\r
-  public GQuery removeAttr(String key) {\r
-    for (Element e : elements()) {\r
-      e.removeAttribute(key);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Removes the specified classes to each matched element.\r
-   */\r
-  public GQuery removeClass(String... classes) {\r
-    for (Element e : elements()) {\r
-      for (String clz : classes) {\r
-        setStyleName(e, clz, false);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Removes named data store from an element.\r
-   */\r
-  public GQuery removeData(String name) {\r
-    for (Element e : elements()) {\r
-      removeData(e, name);\r
-    }\r
-    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(GQuery query) {\r
-    for (Element e : elements()) {\r
-      $(e).replaceWith(query);\r
-    }\r
-    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(String html) {\r
-    return replaceAll($(html));\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 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 replaceWith(GQuery query) {\r
-    return after(query).remove();\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
-   * from the DOM.\r
-   */\r
-  public GQuery replaceWith(String html) {\r
-    return replaceWith($(html));\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
-   * from the DOM.\r
-   */\r
-  public GQuery replaceWith(Element elem) {\r
-    return replaceWith($(elem));\r
-  }\r
-\r
-  public GQuery scroll(Function f) {\r
-    return bind(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.get()) {\r
-        Window.scrollTo(left, $(e).scrollTop());\r
-      } else {\r
-        e.setPropertyInt("scrollLeft", left);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Gets the scroll left offset of the first matched element. This method works\r
-   * for both visible and hidden elements.\r
-   */\r
-  public int scrollLeft() {\r
-    Element e = get(0);\r
-    if (e == window()) {\r
-      return Window.getScrollLeft();\r
-    } else if (e == (Node) Document.get()) {\r
-      return Document.get().getScrollLeft();\r
-    } else {\r
-      return e.getScrollLeft();\r
-    }\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.get()) {\r
-        Window.scrollTo($(e).scrollLeft(), top);\r
-      } else {\r
-        e.setPropertyInt("scrollTop", top);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Gets the scroll top offset of the first matched element. This method works\r
-   * for both visible and hidden elements.\r
-   */\r
-  public int scrollTop() {\r
-    Element e = get(0);\r
-    if (e == window()) {\r
-      return Window.getScrollTop();\r
-    } else if (e == (Node) Document.get()) {\r
-      return Document.get().getScrollTop();\r
-    } else {\r
-      return e.getScrollTop();\r
-    }\r
-  }\r
-\r
-  public GQuery select() {\r
-    return trigger(Document.get().createHtmlEvent("select", false, false),\r
-        null);\r
-  }\r
-\r
-  public void setPreviousObject(GQuery previousObject) {\r
-    this.previousObject = previousObject;\r
-  }\r
-\r
-  public void setSelector(String selector) {\r
-    this.selector = selector;\r
-  }\r
-\r
-  /**\r
-   * Get a set of elements containing all of the unique siblings of each of the\r
-   * matched set of elements.\r
-   */\r
-  public GQuery siblings() {\r
-    JSArray result = JSArray.create();\r
-    for (Element e : elements()) {\r
-      allNextSiblingElements(e.getParentElement().getFirstChildElement(),\r
-          result);\r
-    }\r
-    return new GQuery(unique(result));\r
-  }\r
-\r
-  /**\r
-   * Return the number of elements in the matched set.\r
-   */\r
-  public int size() {\r
-    return elements.getLength();\r
-  }\r
-\r
-  /**\r
-   * Selects a subset of the matched elements.\r
-   */\r
-  public GQuery slice(int start, int end) {\r
-    JSArray slice = JSArray.create();\r
-    if (end == -1 || end > elements.getLength()) {\r
-      end = elements.getLength();\r
-    }\r
-    for (int i = start; i < elements.getLength(); i++) {\r
-      slice.addNode(elements.getItem(i));\r
-    }\r
-    return new GQuery(slice);\r
-  }\r
-\r
-  public GQuery submit() {\r
-    return trigger(Document.get().createHtmlEvent("submit", false, false),\r
-        null);\r
-  }\r
-\r
-  /**\r
-   * Return the text contained in the first matched element.\r
-   */\r
-  public String text() {\r
-    return elements.getItem(0).getInnerText();\r
-  }\r
-\r
-  /**\r
-   * Set the innerText of every matched element.\r
-   */\r
-  public GQuery text(String txt) {\r
-    for (Element e : asArray(elements)) {\r
-      e.setInnerText(txt);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Adds or removes the specified classes to each matched element.\r
-   */\r
-  public GQuery toggleClass(String... classes) {\r
-    for (Element e : elements()) {\r
-      for (String clz : classes) {\r
-        if (hasClass(e, clz)) {\r
-          setStyleName(e, clz, false);\r
-        } else {\r
-          setStyleName(e, clz, true);\r
-        }\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Adds or removes the specified classes to each matched element.\r
-   */\r
-  public GQuery toggleClass(String clz, boolean sw) {\r
-    for (Element e : elements()) {\r
-      setStyleName(e, clz, sw);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Remove all duplicate elements from an array of elements. Note that this\r
-   * only works on arrays of DOM elements, not strings or numbers.\r
-   */\r
-  public JSArray unique(JSArray result) {\r
-    FastSet f = FastSet.create();\r
-    JSArray ret = JSArray.create();\r
-    for (int i = 0; i < result.getLength(); i++) {\r
-      Element e = result.getElement(i);\r
-      if (!f.contains(e)) {\r
-        f.add(e);\r
-        ret.addNode(e);\r
-      }\r
-    }\r
-    return ret;\r
-  }\r
-\r
-  /**\r
-   * Get the content of the value attribute of the first matched element,\r
-   * returns more than one value if it is a multiple select.\r
-   */\r
-  public String[] val() {\r
-    if (size() > 0) {\r
-      Element e = get(0);\r
-      if (e.getNodeName().equals("select")) {\r
-        SelectElement se = SelectElement.as(e);\r
-        if (se.getMultiple() != null) {\r
-          NodeList<OptionElement> oel = se.getOptions();\r
-          int count = 0;\r
-          for (OptionElement oe : asArray(oel)) {\r
-            if (oe.isSelected()) {\r
-              count++;\r
-            }\r
-          }\r
-          String result[] = new String[count];\r
-          count = 0;\r
-          for (OptionElement oe : asArray(oel)) {\r
-            if (oe.isSelected()) {\r
-              result[count++] = oe.getValue();\r
-            }\r
-          }\r
-\r
-          return result;\r
-        } else {\r
-          int index = se.getSelectedIndex();\r
-          if (index != -1) {\r
-            return new String[]{se.getOptions().getItem(index).getValue()};\r
-          }\r
-        }\r
-      } else if (e.getNodeName().equals("input")) {\r
-        InputElement ie = InputElement.as(e);\r
-        return new String[]{ie.getValue()};\r
-      }\r
-    }\r
-    return new String[0];\r
-  }\r
-\r
-  public GQuery val(String... values) {\r
-    for (Element e : elements()) {\r
-      String name = e.getNodeName();\r
-      if ("select".equals(name)) {\r
-\r
-      } else if ("input".equals(name)) {\r
-        InputElement ie = InputElement.as(e);\r
-        String type = ie.getType();\r
-        if ("radio".equals((type)) || "checkbox".equals(type)) {\r
-          if ("checkbox".equals(type)) {\r
-            for (String val : values) {\r
-              if (ie.getValue().equals(val)) {\r
-                ie.setChecked(true);\r
-              } else if (ie.getValue().equals(val)) {\r
-                ie.setChecked(true);\r
-              }\r
-            }\r
-          }\r
-        } else {\r
-          ie.setValue(values[0]);\r
-        }\r
-      } else if ("textarea".equals(name)) {\r
-        TextAreaElement.as(e).setValue(values[0]);\r
-      } else if ("button".equals(name)) {\r
-        ButtonElement.as(e).setValue(values[0]);\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Set the width of every matched element.\r
-   */\r
-  public GQuery width(int width) {\r
-    for (Element e : elements()) {\r
-      e.getStyle().setPropertyPx("width", width);\r
-    }\r
-    return this;\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
-   * without ruining the original semantic qualities of a document. This works\r
-   * by going through the first element provided (which is generated, on the\r
-   * fly, from the provided HTML) and finds the deepest descendant element\r
-   * 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
-  }\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
-   * without ruining the original semantic qualities of a document. This works\r
-   * by going through the first element provided (which is generated, on the\r
-   * fly, from the provided HTML) and finds the deepest descendant element\r
-   * 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
-  }\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
-   * without ruining the original semantic qualities of a document. This works\r
-   * by going through the first element provided (which is generated, on the\r
-   * fly, from the provided HTML) and finds the deepest descendant element\r
-   * within its structure -- it is that element that will enwrap everything\r
-   * else.\r
-   */\r
-  public GQuery wrap(String html) {\r
-    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
-   * 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(Element elem) {\r
-    return wrapAll($(elem));\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(GQuery query) {\r
-    GQuery wrap = query.clone();\r
-    if (elements.getItem(0).getParentNode() != null) {\r
-      wrap.insertBefore(elements.getItem(0));\r
-    }\r
-    for (Element e : wrap.elements()) {\r
-      Node n = e;\r
-      while (n.getFirstChild() != null) {\r
-        n = n.getFirstChild();\r
-        $((Element) n).append(this);\r
-      }\r
-    }\r
-    return this;\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
-   * injecting additional structure into a document, without ruining the\r
-   * original semantic qualities of a document. This works by going through the\r
-   * first element provided (which is generated, on the fly, from the provided\r
-   * 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
-  }\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
-   * injecting additional structure into a document, without ruining the\r
-   * original semantic qualities of a document. This works by going through the\r
-   * first element provided (which is generated, on the fly, from the provided\r
-   * 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
-  }\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
-   * injecting additional structure into a document, without ruining the\r
-   * original semantic qualities of a document. This works by going through the\r
-   * first element provided (which is generated, on the fly, from the provided\r
-   * 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
-  }\r
-\r
-  protected GQuery pushStack(JSArray elts, String name, String selector) {\r
-    GQuery g = new GQuery(elts);\r
-    g.setPreviousObject(this);\r
-    g.setSelector(selector);\r
-    return g;\r
-  }\r
-\r
-  private GQuery add(GQuery previousObject) {\r
-    return pushStack(unique(merge(elements, previousObject.elements)), "add",\r
-        getSelector() + "," + previousObject.getSelector());\r
-  }\r
-\r
-  private void allNextSiblingElements(Element firstChildElement,\r
-      JSArray result) {\r
-    while (firstChildElement != null) {\r
-      result.addNode(firstChildElement);\r
-      firstChildElement = firstChildElement.getNextSiblingElement();\r
-    }\r
-  }\r
-\r
-  private void allPreviousSiblingElements(Element firstChildElement,\r
-      JSArray result) {\r
-    while (firstChildElement != null) {\r
-      result.addNode(firstChildElement);\r
-      firstChildElement = getPreviousSiblingElement(firstChildElement);\r
-    }\r
-  }\r
-\r
-  private 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("<leg")) {\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.get().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 JSArray.create(n);\r
-  }\r
-\r
-  private <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
-    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 ? value : id;\r
-  }\r
-\r
-  private void dequeue(Element elem, String type) {\r
-    Queue<Function> q = queue(elem, type, null);\r
-    Function f = q.dequeue();\r
-\r
-    if (q != null) {\r
-      if (SelectorEngine.eq(type, "__FX")) {\r
-        f = q.peek(0);\r
-      }\r
-      if (f != null) {\r
-        f.f(elem);\r
-      }\r
-    }\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
-    for (Element e : elements()) {\r
-      for (int i = 0; i < nodes.getLength(); i++) {\r
-        Node n = nodes.getItem(i).cloneNode(true);\r
-        switch (func) {\r
-          case FUNC_PREPEND:\r
-            e.insertBefore(n, e.getFirstChild());\r
-            break;\r
-          case FUNC_APPEND:\r
-            e.appendChild(n);\r
-            break;\r
-          case FUNC_AFTER:\r
-            e.getParentNode().insertBefore(n, e.getNextSibling());\r
-            break;\r
-          case FUNC_BEFORE:\r
-            e.getParentNode().insertBefore(n, e);\r
-            break;\r
-        }\r
-      }\r
-    }\r
-    return this;\r
-  }\r
-\r
-  private native Document getContentDocument(Node n) /*-{\r
-    return n.contentDocument || n.contentWindow.document;\r
-  }-*/;\r
-\r
-  private native Element getPreviousSiblingElement(Element elem)  /*-{\r
-    var sib = elem.previousSibling;\r
-    while (sib && sib.nodeType != 1)\r
-      sib = sib.previousSibling;\r
-    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 = JSArray.create();\r
-    for (int i = 0; i < first.getLength(); i++) {\r
-      res.addNode(first.getItem(i));\r
-    }\r
-    for (int i = 0; i < second.getLength(); i++) {\r
-      res.addNode(second.getItem(i));\r
-    }\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
-    }\r
-    return 0;\r
-  }\r
-\r
-  private Queue<Function> queue(Element elem, String type, Function data) {\r
-    if (elem != null) {\r
-      type = type + "queue";\r
-      Object q = (Queue) data(elem, type, null);\r
-      if (q == null) {\r
-        q = data(elem, type, Queue.newInstance());\r
-      }\r
-      Queue<Function> qq = (Queue<Function>) q;\r
-      if (data != null) {\r
-        qq.enqueue(data);\r
-      }\r
-      if (SelectorEngine.eq(type, "__FX") && qq.length() == 1) {\r
-        data.f(elem);\r
-      }\r
-      return qq;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  private void removeData(Element item, String name) {\r
-    if (dataCache == null) {\r
-      windowData = JavaScriptObject.createObject().cast();\r
-      dataCache = JavaScriptObject.createObject().cast();\r
-    }\r
-    item = item == window() ? windowData : item;\r
-    int id = item.hashCode();\r
-    if (name != null) {\r
-      if (!dataCache.exists(id)) {\r
-        dataCache.getCache(id).delete(name);\r
-      }\r
-      if (dataCache.getCache(id).isEmpty()) {\r
-        removeData(item, null);\r
-      }\r
-    } else {\r
-      dataCache.delete(id);\r
-    }\r
-  }\r
-\r
-  private void replacequeue(Element elem, String type, Queue data) {\r
-    if (elem != null) {\r
-      type = type + "queue";\r
-      Object q = (Queue) data(elem, type, null);\r
-      data(elem, type, data);\r
-    }\r
-  }\r
-\r
-  private GQuery trigger(NativeEvent event, Object o) {\r
-    for (Element e : elements()) {\r
-      e.dispatchEvent(event);\r
-    }\r
-    return this;\r
-  }\r
-\r
-  private native Element window() /*-{\r
-    return $wnd;\r
-  }-*/;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/JSArray.java b/gwtquery-core/src/main/java/gwtquery/client/JSArray.java
deleted file mode 100644 (file)
index a804934..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.core.client.JavaScriptObject;\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
-\r
-/**\r
- */\r
-public class JSArray extends NodeList<Element> {\r
-\r
-  public static JSArray create() {\r
-    return (JSArray) JavaScriptObject.createArray();\r
-  }\r
-\r
-  public static native JSArray create(Node node) /*-{\r
-    return [node];\r
-  }-*/;\r
-\r
-  public static native JSArray create(NodeList nl) /*-{\r
-    var r = [], len=nl.length;\r
-    for(var i=0; i<len; i++) {\r
-      r.push(nl[i]);\r
-    }\r
-    return r;\r
-  }-*/;\r
-\r
-  protected JSArray() {\r
-  }\r
-\r
-  public final native void addInt(int i) /*-{\r
-       this[this.length]=i;\r
-  }-*/;\r
-\r
-  public final native void addNode(Node n) /*-{\r
-     this[this.length]=n;\r
-  }-*/;\r
-\r
-  public final native void addNode(Node ci, int i) /*-{\r
-       this[i]=ci;\r
-    }-*/;\r
-\r
-  public final native void concat(JSArray ary) /*-{\r
-     this.concat(ary);\r
-  }-*/;\r
-\r
-  public final native Element getElement(int i) /*-{\r
-        return this[i];\r
-    }-*/;\r
-\r
-  public final native int getInt(int i) /*-{\r
-    return this[i]  || 0;\r
-  }-*/;\r
-\r
-  public final native Node getNode(int i) /*-{\r
-        return this[i];\r
-  }-*/;\r
-\r
-  public final native String getStr(int i) /*-{\r
-     return this[i] || null;\r
-  }-*/;\r
-\r
-  public final void pushAll(JSArray prevElem) {\r
-    for (int i = 0, ilen = prevElem.size(); i < ilen; i++) {\r
-      addNode(prevElem.getNode(i));\r
-    }\r
-  }\r
-\r
-  public final native int size() /*-{\r
-     return this.length;\r
-  }-*/;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Plugin.java b/gwtquery-core/src/main/java/gwtquery/client/Plugin.java
deleted file mode 100644 (file)
index 9f7864d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package gwtquery.client;\r
-\r
-/**\r
- * A GQuery plugin\r
- */\r
-public interface Plugin<T extends GQuery> {\r
-     T init(GQuery gq);\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Predicate.java b/gwtquery-core/src/main/java/gwtquery/client/Predicate.java
deleted file mode 100644 (file)
index feb7b64..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package gwtquery.client;
-
-import com.google.gwt.dom.client.Element;
-
-/**
- * A predicate function used by some GQuery methods.
- */
-public interface Predicate {
-    boolean f(Element e, int index);
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Properties.java b/gwtquery-core/src/main/java/gwtquery/client/Properties.java
deleted file mode 100644 (file)
index 2003092..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.core.client.JavaScriptObject;\r
-\r
-/**\r
- *\r
- */\r
-public class Properties extends JavaScriptObject {\r
-\r
-  protected Properties() { }\r
-  public native static Properties create(String properties) /*-{\r
-    return eval(properties);\r
-  }-*/;\r
-  \r
-  public final native String get(String name) /*-{\r
-    return this[name];\r
-  }-*/;\r
-  \r
-  public final native int getInt(String name) /*-{\r
-    return this[name];\r
-  }-*/;\r
-  \r
-  public final native float getFloat(String name) /*-{\r
-    return this[name];\r
-  }-*/;\r
-  \r
-  public final native String[] keys() /*-{\r
-    var key, keys=[];\r
-    \r
-    for(key in this) {\r
-      keys.push(key); \r
-    }\r
-    return keys;\r
-  }-*/;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Regexp.java b/gwtquery-core/src/main/java/gwtquery/client/Regexp.java
deleted file mode 100644 (file)
index 5eae1c1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.core.client.JavaScriptObject;\r
-\r
-/**\r
- */\r
-public class Regexp {\r
-\r
-  private final JavaScriptObject regexp;\r
-\r
-  public Regexp(String pattern) {\r
-    this.regexp = compile(pattern);\r
-  }\r
-\r
-  public Regexp(String pat, String flags) {\r
-    this.regexp = compileFlags(pat, flags);\r
-  }\r
-\r
-  public static  native JavaScriptObject compile(String pat) /*-{\r
-     return new RegExp(pat);\r
-  }-*/;\r
-  \r
-   public static  native JavaScriptObject compileFlags(String pat, String flags) /*-{\r
-     return new RegExp(pat, flags);\r
-  }-*/;\r
-  \r
-   public JSArray exec(String str) {\r
-     return exec0(regexp, str);\r
-   }\r
-\r
-  \r
-  private static native JSArray exec0(JavaScriptObject regexp, String str) /*-{\r
-    return regexp.exec(str);\r
-  }-*/;\r
-\r
-  public JSArray match(String currentRule) {\r
-    return match0(regexp, currentRule);\r
-  }\r
-\r
-  private native JSArray match0(JavaScriptObject regexp, String currentRule)/*-{\r
-    return currentRule.match(regexp);\r
-  }-*/;\r
-\r
-  public boolean test(String rule) {\r
-    return test0(regexp, rule);\r
-  }\r
-\r
-  private native boolean test0(JavaScriptObject regexp, String rule) /*-{\r
-    return regexp.test(rule);\r
-  }-*/;\r
-\r
-  public static JSArray match(String regexp, String flags, String string) {\r
-    return new Regexp(regexp, flags).match(string);\r
-  }\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Selector.java b/gwtquery-core/src/main/java/gwtquery/client/Selector.java
deleted file mode 100644 (file)
index 0ec58e5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package gwtquery.client;\r
-\r
-import java.lang.annotation.Target;\r
-import java.lang.annotation.Retention;\r
-import java.lang.annotation.RetentionPolicy;\r
-import static java.lang.annotation.ElementType.METHOD;\r
-\r
-/**\r
- * Used to pass a CSS Selector to a generator at compile time\r
- */\r
-@Target({METHOD})\r
-@Retention(RetentionPolicy.RUNTIME)\r
-public @interface Selector {\r
-   String value();\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java b/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java
deleted file mode 100644 (file)
index 167a675..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-package gwtquery.client;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.core.client.JavaScriptObject;\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
-\r
-import gwtquery.client.impl.SelectorEngineImpl;\r
-\r
-/**\r
- *\r
- */\r
-public class SelectorEngine {\r
-\r
-  private SelectorEngineImpl impl;\r
-\r
-  public SelectorEngine() {\r
-    impl = (SelectorEngineImpl) GWT.create(SelectorEngineImpl.class);\r
-  }\r
-\r
-  public static native boolean eq(String s1, String s2) /*-{\r
-       return s1 == s2;\r
-    }-*/;\r
-\r
-  public static native NodeList<Element> getElementsByClassName(String clazz,\r
-      Node ctx) /*-{\r
-        return ctx.getElementsByClassName(clazz);\r
-    }-*/;\r
-\r
-  public  static native <T> T or(T s1, T s2) /*-{\r
-       return s1 || s2;\r
-    }-*/;\r
-\r
-  public static native NodeList<Element> querySelectorAll(String selector) /*-{\r
-      return $doc.querySelectorAll(selector);\r
-  }-*/;\r
-\r
-  public static native NodeList<Element> querySelectorAll(String selector,\r
-      Node ctx) /*-{\r
-      return ctx.querySelectorAll(selector);\r
-  }-*/;\r
-\r
-  public NodeList<Element> select(String selector, Node ctx) {\r
-    return impl.select(selector, ctx);\r
-  }\r
-\r
-  public static boolean truth(String a) {\r
-    return GWT.isScript() ? truth0(a) : a != null && !"".equals(a);\r
-  }\r
-\r
-  public static boolean truth(JavaScriptObject a) {\r
-    return GWT.isScript() ? truth0(a) : a != null;\r
-  }\r
-\r
-  public static NodeList<Element> xpathEvaluate(String selector, Node ctx) {\r
-    return xpathEvaluate(selector, ctx, JSArray.create());\r
-  }\r
-\r
-  public static native NodeList<Element> xpathEvaluate(String selector,\r
-      Node ctx, JSArray r) /*-{\r
-      var node;\r
-      var result = $doc.evaluate(selector, ctx, null, 0, null);\r
-      while ((node = result.iterateNext())) {\r
-          r.push(node);\r
-      }\r
-      return r;\r
-  }-*/;\r
-\r
-  private static native boolean truth0(String a) /*-{\r
-       return a;\r
-    }-*/;\r
-\r
-  private static native boolean truth0(JavaScriptObject a) /*-{\r
-         return a;\r
-      }-*/;\r
-\r
-  protected JSArray veryQuickId(Node context, String id) {\r
-    JSArray r = JSArray.create();\r
-    if (context.getNodeType() == Node.DOCUMENT_NODE) {\r
-      r.addNode(((Document) context).getElementById(id));\r
-      return r;\r
-    } else {\r
-      r.addNode(context.getOwnerDocument().getElementById(id));\r
-      return r;\r
-    }\r
-  }\r
-\r
-  public static native Node getNextSibling(Node n) /*-{\r
-       return n.nextSibling || null; \r
-    }-*/;\r
-\r
-  public static native Node getPreviousSibling(Node n) /*-{\r
-       return n.previousSibling || null; \r
-    }-*/;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/Selectors.java b/gwtquery-core/src/main/java/gwtquery/client/Selectors.java
deleted file mode 100644 (file)
index 6ebd501..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package gwtquery.client;\r
-\r
-/**\r
- */\r
-public interface Selectors {\r
-    DeferredGQuery[] getAllSelectors();\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java
deleted file mode 100644 (file)
index c61a88b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package gwtquery.client.impl;
-
-import com.google.gwt.dom.client.Element;
-
-import gwtquery.client.SelectorEngine;
-
-/**
- *
- */
-public class DocumentStyleImpl {
-
-  public String getPropertyName(String name) {
-    if ("float".equals(name)) {
-      return "cssFloat";
-    } else if ("class".equals(name)) {
-      return "className";
-    } else if ("for".equals(name)) {
-      return "htmlFor";
-    }
-    return name;
-  }
-
-  public String getCurrentStyle(Element elem, String name) {
-    name = hyphenize(name);
-    String propVal = getComputedStyle(elem, name, null);
-    if ("opacity".equals(name)) {
-      propVal = SelectorEngine.or(propVal, "1");
-    }
-    return propVal;
-  }
-
-  protected native String hyphenize(String name) /*-{
-      return name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-  }-*/;
-
-  private native String getComputedStyle(Element elem, String name,
-      String pseudo) /*-{
-       var cStyle = $doc.defaultView.getComputedStyle( elem, pseudo );
-        return cStyle ? cStyle.getPropertyValue( name ) : null;
-  }-*/;
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java
deleted file mode 100644 (file)
index b9d95bc..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-package gwtquery.client.impl;
-
-import com.google.gwt.dom.client.Element;
-
-import gwtquery.client.SelectorEngine;
-
-/**
- *
- */
-public class DocumentStyleImplIE extends DocumentStyleImpl {
-
-  public String getPropertyName(String name) {
-    if ("float".equals(name)) {
-      return "styleFloat";
-    } else if ("class".equals(name)) {
-      return "className";
-    } else if ("for".equals(name)) {
-      return "htmlFor";
-    }
-    return name;
-  }
-
-  public String getCurrentStyle(Element elem, String name) {
-    name = hyphenize(name);
-    String propVal = getComputedStyle(elem, name, null);
-    if ("opacity".equals(name)) {
-      propVal = SelectorEngine.or(propVal, "1");
-    }
-    return propVal;
-  }
-
-  // code lifted from jQuery
-  private native String getComputedStyle(Element elem, String name,
-      String pseudo) /*-{
-    var style = elem.style;
-    var camelCase = name.replace(/\-(\w)/g, function(all, letter){
-                               return letter.toUpperCase();
-                       });
-    var ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-       // From the awesome hack by Dean Edwards
-        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-        // If we're not dealing with a regular pixel number
-       // but a number that has a weird ending, we need to convert it to pixels
-       if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
-               // Remember the original values
-               var left = style.left, rsLeft = elem.runtimeStyle.left;
-               // Put in the new values to get a computed value out
-               elem.runtimeStyle.left = elem.currentStyle.left;
-               style.left = ret || 0;
-               ret = style.pixelLeft + "px";
-                // Revert the changed values
-               style.left = left;
-               elem.runtimeStyle.left = rsLeft;
-    }  
-    return ret;
-  }-*/;
-}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineImpl.java b/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineImpl.java
deleted file mode 100644 (file)
index 18774d0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-package gwtquery.client.impl;\r
-\r
-import gwtquery.client.Regexp;\r
-import gwtquery.client.JSArray;\r
-import gwtquery.client.SelectorEngine;\r
-import com.google.gwt.dom.client.*;\r
-\r
-/**\r
- * Copyright 2007 Timepedia.org\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * @author Ray Cromwell <ray@timepedia.log>\r
- */\r
-public abstract class SelectorEngineImpl {\r
-\r
-    public abstract NodeList<Element> select(String selector, Node ctx);\r
-\r
-    protected static Sequence getSequence(String expression) {\r
-        int start = 0, add = 2, max = -1, modVal = -1;\r
-        Regexp expressionRegExp = new Regexp(\r
-                "^((odd|even)|([1-9]\\d*)|((([1-9]\\d*)?)n((\\+|\\-)(\\d+))?)|(\\-(([1-9]\\d*)?)n\\+(\\d+)))$");\r
-        JSArray pseudoValue = expressionRegExp.exec(expression);\r
-        if (!SelectorEngine.truth(pseudoValue)) {\r
-            return null;\r
-        } else {\r
-            if (SelectorEngine.truth(pseudoValue.getStr(2))) {        // odd or even\r
-                start = (SelectorEngine.eq(pseudoValue.getStr(2), "odd")) ? 1 : 2;\r
-                modVal = (start == 1) ? 1 : 0;\r
-            } else if (SelectorEngine.truth(pseudoValue.getStr(3))) {        // single digit\r
-                start = Integer.parseInt(pseudoValue.getStr(3), 10);\r
-                add = 0;\r
-                max = start;\r
-            } else if (SelectorEngine.truth(pseudoValue.getStr(4))) {        // an+b\r
-                add = SelectorEngine.truth(pseudoValue.getStr(6)) ? Integer\r
-                        .parseInt(pseudoValue.getStr(6), 10) : 1;\r
-                start = SelectorEngine.truth(pseudoValue.getStr(7)) ? Integer\r
-                        .parseInt((pseudoValue.getStr(8).charAt(0) == '+' ? "" : pseudoValue.getStr(8)) + pseudoValue.getStr(9), 10) : 0;\r
-                while (start < 1) {\r
-                    start += add;\r
-                }\r
-                modVal = (start > add) ? (start - add) % add\r
-                        : ((start == add) ? 0 : start);\r
-            } else if (SelectorEngine.truth(pseudoValue.getStr(10))) {        // -an+b\r
-                add = SelectorEngine.truth(pseudoValue.getStr(12)) ? Integer\r
-                        .parseInt(pseudoValue.getStr(12), 10) : 1;\r
-                start = max = Integer.parseInt(pseudoValue.getStr(13), 10);\r
-                while (start > add) {\r
-                    start -= add;\r
-                }\r
-                modVal = (max > add) ? (max - add) % add : ((max == add) ? 0 : max);\r
-            }\r
-        }\r
-        Sequence s = new Sequence();\r
-        s.start = start;\r
-        s.add = add;\r
-        s.max = max;\r
-        s.modVal = modVal;\r
-        return s;\r
-    }\r
-\r
-    public static class Sequence {\r
-        public int start;\r
-        public int max;\r
-        public int add;\r
-        public int modVal;\r
-    }\r
-\r
-    public static class SplitRule {\r
-\r
-        public String tag;\r
-        public String id;\r
-        public String allClasses;\r
-        public String allAttr;\r
-        public String allPseudos;\r
-        public String tagRelation;\r
-\r
-        public SplitRule(String tag, String id, String allClasses, String allAttr,\r
-                         String allPseudos) {\r
-            this.tag = tag;\r
-            this.id = id;\r
-            this.allClasses = allClasses;\r
-            this.allAttr = allAttr;\r
-            this.allPseudos = allPseudos;\r
-        }\r
-\r
-        public SplitRule(String tag, String id, String allClasses, String allAttr,\r
-                         String allPseudos, String tagRelation) {\r
-            this.tag = tag;\r
-            this.id = id;\r
-            this.allClasses = allClasses;\r
-            this.allAttr = allAttr;\r
-            this.allPseudos = allPseudos;\r
-            this.tagRelation = tagRelation;\r
-        }\r
-    }\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJS.java b/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJS.java
deleted file mode 100644 (file)
index a65e1cd..0000000
+++ /dev/null
@@ -1,698 +0,0 @@
-package gwtquery.client.impl;\r
-\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
-\r
-import gwtquery.client.JSArray;\r
-import gwtquery.client.Regexp;\r
-import gwtquery.client.SelectorEngine;\r
-\r
-/**\r
- * Copyright 2007 Timepedia.org Licensed under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with the\r
- * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0\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
- * @author Ray Cromwell <ray@timepedia.log>\r
- */\r
-public class SelectorEngineJS extends SelectorEngineImpl {\r
-    private Regexp cssSelectorRegExp;\r
-    private Regexp selectorSplitRegExp;\r
-    private Regexp childOrSiblingRefRegExp;\r
-\r
-\r
-    public SelectorEngineJS() {\r
-        selectorSplitRegExp = new Regexp("[^\\s]+", "g");\r
-        childOrSiblingRefRegExp = new Regexp("^(>|\\+|~)$");\r
-        cssSelectorRegExp = new Regexp(\r
-                "^(\\w+)?(#[\\w\\u00C0-\\uFFFF\\-\\_]+|(\\*))?((\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[\\w\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[\\w\\u00C0-\\uFFFF\\-_]+|((\\w*\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[\\w\\-]*))\\))?)*)?");\r
-    }\r
-\r
-    public static void clearAdded(JSArray a) {\r
-        for (int i = 0, len = a.size(); i < len; i++) {\r
-            clearAdded(a.getNode(i));\r
-        }\r
-    }\r
-\r
-    public static native void clearAdded(Node node) /*-{\r
-      node.added = null;\r
-    }-*/;\r
-\r
-    public static native NodeList<Element> getElementsByClassName(String clazz,\r
-                                                                  Node ctx) /*-{\r
-      return ctx.getElementsByClassName(clazz);\r
-  }-*/;\r
-\r
-    public static native boolean isAdded(Node prevRef) /*-{\r
-      return prevRef.added || false;\r
-    }-*/;\r
-\r
-    public static native void setAdded(Node prevRef, boolean added) /*-{\r
-      prevRef.added = added;\r
-    }-*/;\r
-\r
-    public static native void setSkipTag(JSArray prevElem, boolean skip) /*-{\r
-      prevElem.skipTag = skip;\r
-    }-*/;\r
-\r
-    private static String attrToRegExp(String attrVal, String op) {\r
-        if (SelectorEngine.eq("^", op)) {\r
-            return "^" + attrVal;\r
-        }\r
-        if (SelectorEngine.eq("$", op)) {\r
-            return attrVal + "$";\r
-        }\r
-        if (SelectorEngine.eq("*", op)) {\r
-            return attrVal;\r
-        }\r
-        if (SelectorEngine.eq("|", op)) {\r
-            return "(^" + attrVal + "(\\-\\w+)*$)";\r
-        }\r
-        if (SelectorEngine.eq("~", op)) {\r
-            return "\\b" + attrVal + "\\b";\r
-        }\r
-        return SelectorEngine.truth(attrVal) ? "^" + attrVal + "$" : null;\r
-    }\r
-\r
-    private static void clearChildElms(JSArray prevParents) {\r
-        for (int n = 0, nl = prevParents.size(); n < nl; n++) {\r
-            setHasChildElms(prevParents.getNode(n), false);\r
-        }\r
-    }\r
-\r
-    protected String getAttr(Element current, String name) {\r
-        return current.getAttribute(name);\r
-    }\r
-\r
-    private static void getDescendantNodes(JSArray matchingElms,\r
-                                           String nextTagStr, Node prevRef) {\r
-        NodeList<Element> children = getElementsByTagName(nextTagStr, prevRef);\r
-        for (int k = 0, klen = children.getLength(); k < klen; k++) {\r
-            Node child = children.getItem(k);\r
-            if (child.getParentNode() == prevRef) {\r
-                matchingElms.addNode(child);\r
-            }\r
-        }\r
-    }\r
-\r
-    private JSArray getElementsByPseudo(JSArray previousMatch, String pseudoClass,\r
-                                        String pseudoValue) {\r
-        JSArray prevParents = JSArray.create();\r
-        boolean previousDir = pseudoClass.startsWith("first") ? true : false;\r
-        JSArray matchingElms = JSArray.create();\r
-        Node prev, next, previous;\r
-        if (SelectorEngine.eq("first-child", pseudoClass) || SelectorEngine\r
-                .eq("last-child", pseudoClass)) {\r
-            getFirstChildPseudo(previousMatch, previousDir, matchingElms);\r
-        } else if (SelectorEngine.eq("only-child", pseudoClass)) {\r
-            getOnlyChildPseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("nth-child", pseudoClass)) {\r
-            matchingElms = getNthChildPseudo(previousMatch, pseudoValue, prevParents,\r
-                    matchingElms);\r
-        } else if (SelectorEngine.eq("first-of-type", pseudoClass) || SelectorEngine\r
-                .eq("last-of-type", pseudoClass)) {\r
-            getFirstOfTypePseudo(previousMatch, previousDir, matchingElms);\r
-        } else if (SelectorEngine.eq("only-of-type", pseudoClass)) {\r
-            getOnlyOfTypePseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("nth-of-type", pseudoClass)) {\r
-            matchingElms = getNthOfTypePseudo(previousMatch, pseudoValue, prevParents,\r
-                    matchingElms);\r
-        } else if (SelectorEngine.eq("empty", pseudoClass)) {\r
-            getEmptyPseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("enabled", pseudoClass)) {\r
-            getEnabledPseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("disabled", pseudoClass)) {\r
-            getDisabledPseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("checked", pseudoClass)) {\r
-            getCheckedPseudo(previousMatch, matchingElms);\r
-        } else if (SelectorEngine.eq("contains", pseudoClass)) {\r
-            getContainsPseudo(previousMatch, pseudoValue, matchingElms);\r
-        } else if (SelectorEngine.eq("not", pseudoClass)) {\r
-            matchingElms = getNotPseudo(previousMatch, pseudoValue, matchingElms);\r
-        } else {\r
-            getDefaultPseudo(previousMatch, pseudoClass, pseudoValue, matchingElms);\r
-        }\r
-        return matchingElms;\r
-    }\r
-\r
-    private void getDefaultPseudo(JSArray previousMatch, String pseudoClass,\r
-                                  String pseudoValue, JSArray matchingElms) {\r
-        Node previous;\r
-        for (int w = 0, wlen = previousMatch.size(); w < wlen; w++) {\r
-            previous = previousMatch.getElement(w);\r
-            if (SelectorEngine\r
-                    .eq(((Element) previous).getAttribute(pseudoClass), pseudoValue)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private JSArray getNotPseudo(JSArray previousMatch, String pseudoValue,\r
-                                 JSArray matchingElms) {\r
-        if (new Regexp("(:\\w+[\\w\\-]*)$").test(pseudoValue)) {\r
-            matchingElms = subtractArray(previousMatch,\r
-                    getElementsByPseudo(previousMatch, pseudoValue.substring(1), ""));\r
-        } else {\r
-            pseudoValue = pseudoValue\r
-                    .replace("^\\[#([\\w\\u00C0-\\uFFFF\\-\\_]+)\\]$", "[id=$1]");\r
-            JSArray notTag = new Regexp("^(\\w+)").exec(pseudoValue);\r
-            JSArray notClass = new Regexp("^\\.([\\w\u00C0-\uFFFF\\-_]+)")\r
-                    .exec(pseudoValue);\r
-            JSArray notAttr = new Regexp(\r
-                    "\\[(\\w+)(\\^|\\$|\\*|\\||~)?=?([\\w\\u00C0-\\uFFFF\\s\\-_\\.]+)?\\]")\r
-                    .exec(pseudoValue);\r
-            Regexp notRegExp = new Regexp(\r
-                    "(^|\\s)" + (SelectorEngine.truth(notTag) ? notTag\r
-                            .getStr(1)\r
-                            : SelectorEngine.truth(notClass) ? notClass.getStr(1) : "")\r
-                            + "(\\s|$)", "i");\r
-            if (SelectorEngine.truth(notAttr)) {\r
-                String notAttribute = SelectorEngine.truth(notAttr.getStr(3)) ? notAttr\r
-                        .getStr(3)\r
-                        .replace("\\.", "\\.") : null;\r
-                String notMatchingAttrVal = attrToRegExp(notAttribute,\r
-                        notAttr.getStr(2));\r
-                notRegExp = new Regexp(notMatchingAttrVal, "i");\r
-            }\r
-            for (int v = 0, vlen = previousMatch.size(); v < vlen; v++) {\r
-                Element notElm = previousMatch.getElement(v);\r
-                Element addElm = null;\r
-                if (SelectorEngine.truth(notTag) && !notRegExp\r
-                        .test(notElm.getNodeName())) {\r
-                    addElm = notElm;\r
-                } else if (SelectorEngine.truth(notClass) && !notRegExp\r
-                        .test(notElm.getClassName())) {\r
-                    addElm = notElm;\r
-                } else if (SelectorEngine.truth(notAttr)) {\r
-                    String att = getAttr(notElm, notAttr.getStr(1));\r
-                    if (!SelectorEngine.truth(att) || !notRegExp.test(att)) {\r
-                        addElm = notElm;\r
-                    }\r
-                }\r
-                if (SelectorEngine.truth(addElm) && !isAdded(addElm)) {\r
-                    setAdded(addElm, true);\r
-                    matchingElms.addNode(addElm);\r
-                }\r
-            }\r
-        }\r
-        return matchingElms;\r
-    }\r
-\r
-    private void getContainsPseudo(JSArray previousMatch, String pseudoValue,\r
-                                   JSArray matchingElms) {\r
-        Node previous;\r
-        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
-            previous = previousMatch.getNode(q);\r
-            if (!isAdded(previous)) {\r
-                if (((Element) previous).getInnerText().indexOf(pseudoValue) != -1) {\r
-                    setAdded(previous, true);\r
-                    matchingElms.addNode(previous);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getCheckedPseudo(JSArray previousMatch, JSArray matchingElms) {\r
-        Node previous;\r
-        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
-            previous = previousMatch.getNode(q);\r
-            if (checked(previous)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getDisabledPseudo(JSArray previousMatch, JSArray matchingElms) {\r
-        Node previous;\r
-        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
-            previous = previousMatch.getNode(q);\r
-            if (!enabled(previous)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getEnabledPseudo(JSArray previousMatch, JSArray matchingElms) {\r
-        Node previous;\r
-        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
-            previous = previousMatch.getNode(q);\r
-            if (enabled(previous)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getEmptyPseudo(JSArray previousMatch, JSArray matchingElms) {\r
-        Node previous;\r
-        for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) {\r
-            previous = previousMatch.getNode(q);\r
-            if (!previous.hasChildNodes()) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private JSArray getNthOfTypePseudo(JSArray previousMatch, String pseudoValue,\r
-                                       JSArray prevParents, JSArray matchingElms) {\r
-        Node previous;\r
-        if (pseudoValue.startsWith("n")) {\r
-            matchingElms = previousMatch;\r
-        } else {\r
-            Sequence sequence = getSequence(pseudoValue);\r
-            if (sequence != null) {\r
-                for (int p = 0, plen = previousMatch.size(); p < plen; p++) {\r
-                    previous = previousMatch.getNode(p);\r
-                    Node prevParent = previous.getParentNode();\r
-                    if (!hasChildElms(prevParent)) {\r
-                        int iteratorNext = sequence.start;\r
-                        int childCount = 0;\r
-                        Node childElm = prevParent.getFirstChild();\r
-                        while (SelectorEngine.truth(childElm) && (sequence.max < 0\r
-                                || iteratorNext <= sequence.max)) {\r
-                            if (SelectorEngine\r
-                                    .eq(childElm.getNodeName(), previous.getNodeName())) {\r
-                                if (++childCount == iteratorNext) {\r
-                                    matchingElms.addNode(childElm);\r
-                                    iteratorNext += sequence.add;\r
-                                }\r
-                            }\r
-                            childElm = SelectorEngine.getNextSibling(childElm);\r
-                        }\r
-                        setHasChildElms(prevParent, true);\r
-                        prevParents.addNode(prevParent);\r
-                    }\r
-                }\r
-                clearChildElms(prevParents);\r
-            }\r
-        }\r
-        return matchingElms;\r
-    }\r
-\r
-    private void getOnlyOfTypePseudo(JSArray previousMatch,\r
-                                     JSArray matchingElms) {\r
-        Node previous;\r
-        Node next;\r
-        Node prev;\r
-        Node oParent = null;\r
-        for (int o = 0, olen = previousMatch.size(); o < olen; o++) {\r
-            prev = next = previous = previousMatch.getNode(o);\r
-            Node prevParent = previous.getParentNode();\r
-            if (prevParent != oParent) {\r
-                while (\r
-                        SelectorEngine.truth(prev = SelectorEngine.getPreviousSibling(prev))\r
-                                && !SelectorEngine\r
-                                .eq(prev.getNodeName(), previous.getNodeName())) {\r
-                }\r
-                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
-                        && !SelectorEngine.eq(next.getNodeName(), previous.getNodeName())) {\r
-                }\r
-                if (!SelectorEngine.truth(prev) && !SelectorEngine.truth(next)) {\r
-                    matchingElms.addNode(previous);\r
-                }\r
-                oParent = prevParent;\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getFirstOfTypePseudo(JSArray previousMatch, boolean previousDir,\r
-                                      JSArray matchingElms) {\r
-        Node previous;\r
-        Node next;\r
-        for (int n = 0, nlen = previousMatch.size(); n < nlen; n++) {\r
-            next = previous = previousMatch.getNode(n);\r
-\r
-            if (previousDir) {\r
-                while (\r
-                        SelectorEngine.truth(next = SelectorEngine.getPreviousSibling(next))\r
-                                && !SelectorEngine\r
-                                .eq(next.getNodeName(), previous.getNodeName())) {\r
-                }\r
-            } else {\r
-                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
-                        && !SelectorEngine.eq(next.getNodeName(), previous.getNodeName())) {\r
-                }\r
-            }\r
-\r
-            if (!SelectorEngine.truth(next)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private JSArray getNthChildPseudo(JSArray previousMatch, String pseudoValue,\r
-                                      JSArray prevParents, JSArray matchingElms) {\r
-        Node previous;\r
-        if (SelectorEngine.eq(pseudoValue, "n")) {\r
-            matchingElms = previousMatch;\r
-        } else {\r
-            Sequence sequence = getSequence(pseudoValue);\r
-            if (sequence != null) {\r
-                for (int l = 0, llen = previousMatch.size(); l < llen; l++) {\r
-                    previous = previousMatch.getNode(l);\r
-                    Node prevParent = previous.getParentNode();\r
-                    if (!hasChildElms(prevParent)) {\r
-                        int iteratorNext = sequence.start;\r
-                        int childCount = 0;\r
-                        Node childElm = prevParent.getFirstChild();\r
-                        while (childElm != null && (sequence.max < 0\r
-                                || iteratorNext <= sequence.max)) {\r
-                            if (childElm.getNodeType() == Node.ELEMENT_NODE) {\r
-                                if (++childCount == iteratorNext) {\r
-                                    if (SelectorEngine\r
-                                            .eq(childElm.getNodeName(), previous.getNodeName())) {\r
-                                        matchingElms.addNode(childElm);\r
-                                    }\r
-                                    iteratorNext += sequence.add;\r
-                                }\r
-                            }\r
-                            childElm = SelectorEngine.getNextSibling(childElm);\r
-                        }\r
-                        setHasChildElms(prevParent, true);\r
-                        prevParents.addNode(prevParent);\r
-                    }\r
-                }\r
-                clearChildElms(prevParents);\r
-            }\r
-        }\r
-        return matchingElms;\r
-    }\r
-\r
-    private void getOnlyChildPseudo(JSArray previousMatch, JSArray matchingElms) {\r
-        Node previous;\r
-        Node next;\r
-        Node prev;\r
-        Node kParent = null;\r
-        for (int k = 0, klen = previousMatch.size(); k < klen; k++) {\r
-            prev = next = previous = previousMatch.getNode(k);\r
-            Node prevParent = previous.getParentNode();\r
-            if (prevParent != kParent) {\r
-                while (\r
-                        SelectorEngine.truth(prev = SelectorEngine.getPreviousSibling(prev))\r
-                                && prev.getNodeType() != Node.ELEMENT_NODE) {\r
-                }\r
-                while (SelectorEngine.truth(next = SelectorEngine.getNextSibling(next))\r
-                        && next.getNodeType() != Node.ELEMENT_NODE) {\r
-                }\r
-                if (!SelectorEngine.truth(prev) && !SelectorEngine.truth(next)) {\r
-                    matchingElms.addNode(previous);\r
-                }\r
-                kParent = prevParent;\r
-            }\r
-        }\r
-    }\r
-\r
-    private void getFirstChildPseudo(JSArray previousMatch, boolean previousDir,\r
-                                     JSArray matchingElms) {\r
-        Node next;\r
-        Node previous;\r
-        for (int j = 0, jlen = previousMatch.size(); j < jlen; j++) {\r
-            previous = next = previousMatch.getElement(j);\r
-            if (previousDir) {\r
-                while (SelectorEngine\r
-                        .truth((next = SelectorEngine.getPreviousSibling(next)))\r
-                        && next.getNodeType() != Node.ELEMENT_NODE) {\r
-                }\r
-            } else {\r
-                while (\r
-                        SelectorEngine.truth((next = SelectorEngine.getNextSibling(next)))\r
-                                && next.getNodeType() != Node.ELEMENT_NODE) {\r
-                }\r
-            }\r
-            if (!SelectorEngine.truth(next)) {\r
-                matchingElms.addNode(previous);\r
-            }\r
-        }\r
-    }\r
-\r
-    private static native boolean checked(Node previous) /*-{\r
-    return previous.checked || false;\r
-  }-*/;\r
-\r
-    private static native boolean enabled(Node node) /*-{\r
-    return !node.disabled;\r
-  }-*/;\r
-\r
-    private static NodeList<Element> getElementsByTagName(String tag, Node ctx) {\r
-        return ((Element) ctx).getElementsByTagName(tag);\r
-    }\r
-\r
-    private static void getGeneralSiblingNodes(JSArray matchingElms,\r
-                                               JSArray nextTag, Regexp nextRegExp, Node prevRef) {\r
-        while (\r
-                SelectorEngine.truth((prevRef = SelectorEngine.getNextSibling(prevRef)))\r
-                        && !isAdded(prevRef)) {\r
-            if (!SelectorEngine.truth(nextTag) || nextRegExp\r
-                    .test(prevRef.getNodeName())) {\r
-                setAdded(prevRef, true);\r
-                matchingElms.addNode(prevRef);\r
-            }\r
-        }\r
-    }\r
-\r
-    private static void getSiblingNodes(JSArray matchingElms, JSArray nextTag,\r
-                                        Regexp nextRegExp, Node prevRef) {\r
-        while (\r
-                SelectorEngine.truth(prevRef = SelectorEngine.getNextSibling(prevRef))\r
-                        && prevRef.getNodeType() != Node.ELEMENT_NODE) {\r
-        }\r
-        if (SelectorEngine.truth(prevRef)) {\r
-            if (!SelectorEngine.truth(nextTag) || nextRegExp\r
-                    .test(prevRef.getNodeName())) {\r
-                matchingElms.addNode(prevRef);\r
-            }\r
-        }\r
-    }\r
-\r
-    private static native boolean hasChildElms(Node prevParent) /*-{\r
-      return prevParent.childElms || false;\r
-    }-*/;\r
-\r
-    private static native boolean isSkipped(JSArray prevElem) /*-{\r
-       return prevElem.skipTag || false;\r
-    }-*/;\r
-\r
-    private static native void setHasChildElms(Node prevParent, boolean bool) /*-{\r
-      prevParent.childElms = bool ? bool : null;\r
-    }-*/;\r
-\r
-    private static native JSArray subtractArray(JSArray previousMatch,\r
-                                                JSArray elementsByPseudo) /*-{\r
-      for (var i=0, src1; (src1=arr1[i]); i++) {\r
-        var found = false;\r
-        for (var j=0, src2; (src2=arr2[j]); j++) {\r
-          if (src2 === src1) {\r
-        found = true;\r
-            break;\r
-          }\r
-        }\r
-        if (found) {\r
-          arr1.splice(i--, 1);\r
-        }\r
-      }\r
-      return arr;\r
-    }-*/;\r
-\r
-    public NodeList<Element> select(String sel, Node ctx) {\r
-        String selectors[] = sel.replace("\\s*(,)\\s*", "$1").split(",");\r
-        boolean identical = false;\r
-        JSArray elm = JSArray.create();\r
-        for (int a = 0, len = selectors.length; a < len; a++) {\r
-            if (a > 0) {\r
-                identical = false;\r
-                for (int b = 0, bl = a; b < bl; b++) {\r
-                    if (SelectorEngine.eq(selectors[a], selectors[b])) {\r
-                        identical = true;\r
-                        break;\r
-                    }\r
-                }\r
-                if (identical) {                          \r
-                    continue;\r
-                }\r
-            }\r
-            String currentRule = selectors[a];\r
-            JSArray cssSelectors = selectorSplitRegExp.match(currentRule);\r
-            JSArray prevElem = JSArray.create(ctx);\r
-            for (int i = 0, slen = cssSelectors.size(); i < slen; i++) {\r
-                JSArray matchingElms = JSArray.create();\r
-                String rule = cssSelectors.getStr(i);\r
-                if (i > 0 && childOrSiblingRefRegExp.test(rule)) {\r
-                    JSArray childOrSiblingRef = childOrSiblingRefRegExp.exec(rule);\r
-                    if (SelectorEngine.truth(childOrSiblingRef)) {\r
-                        JSArray nextTag = new Regexp("^\\w+")\r
-                                .exec(cssSelectors.getStr(i + 1));\r
-                        Regexp nextRegExp = null;\r
-                        String nextTagStr = null;\r
-                        if (SelectorEngine.truth(nextTag)) {\r
-                            nextTagStr = nextTag.getStr(0);\r
-                            nextRegExp = new Regexp("(^|\\s)" + nextTagStr + "(\\s|$)", "i");\r
-                        }\r
-                        for (int j = 0, jlen = prevElem.size(); j < jlen; j++) {\r
-                            Node prevRef = prevElem.getNode(j);\r
-                            String ref = childOrSiblingRef.getStr(0);\r
-                            if (SelectorEngine.eq(">", ref)) {\r
-                                getDescendantNodes(matchingElms, nextTagStr, prevRef);\r
-                            } else if (SelectorEngine.eq("+", ref)) {\r
-                                getSiblingNodes(matchingElms, nextTag, nextRegExp, prevRef);\r
-                            } else if (SelectorEngine.eq("~", ref)) {\r
-                                getGeneralSiblingNodes(matchingElms, nextTag, nextRegExp,\r
-                                        prevRef);\r
-                            }\r
-                        }\r
-                        prevElem = matchingElms;\r
-                        clearAdded(prevElem);\r
-                        rule = cssSelectors.getStr(++i);\r
-                        if (new Regexp("^\\w+$").test(rule)) {\r
-                            continue;\r
-                        }\r
-                        setSkipTag(prevElem, true);\r
-                    }\r
-                }\r
-                JSArray cssSelector = cssSelectorRegExp.exec(rule);\r
-                SplitRule splitRule = new SplitRule(\r
-                        !SelectorEngine.truth(cssSelector.getStr(1)) || SelectorEngine\r
-                                .eq(cssSelector.getStr(3), "*") ? "*" : cssSelector.getStr(1),\r
-                        !SelectorEngine.eq(cssSelector.getStr(3), "*") ? cssSelector\r
-                                .getStr(2) : null, cssSelector.getStr(4), cssSelector.getStr(6),\r
-                        cssSelector.getStr(10));\r
-                if (SelectorEngine.truth(splitRule.id)) {\r
-                    Element domelem = Document.get()\r
-                            .getElementById(splitRule.id.substring(1));\r
-                    if (SelectorEngine.truth(domelem)) {\r
-                        matchingElms = JSArray.create(domelem);\r
-                    }\r
-                    prevElem = matchingElms;\r
-                } else if (SelectorEngine.truth(splitRule.tag) && !isSkipped(prevElem)) {\r
-                    if (i == 0 && matchingElms.size() == 0 && prevElem.size() == 1) {\r
-                        prevElem = matchingElms = JSArray.create(\r
-                                getElementsByTagName(splitRule.tag, prevElem.getNode(0)));\r
-                    } else {\r
-                        NodeList<Element> tagCollectionMatches;\r
-                        for (int l = 0, ll = prevElem.size(); l < ll; l++) {\r
-                            tagCollectionMatches = getElementsByTagName(splitRule.tag,\r
-                                    prevElem.getNode(l));\r
-                            for (int m = 0, mlen = tagCollectionMatches.getLength(); m < mlen;\r
-                                 m++) {\r
-                                Node tagMatch = tagCollectionMatches.getItem(m);\r
-\r
-                                if (!isAdded(tagMatch)) {\r
-                                    setAdded(tagMatch, true);\r
-                                    matchingElms.addNode(tagMatch);\r
-                                }\r
-                            }\r
-                        }\r
-                        prevElem = matchingElms;\r
-                        clearAdded(prevElem);\r
-                    }\r
-                    if (matchingElms.size() == 0) {\r
-                        break;\r
-                    }\r
-                    setSkipTag(prevElem, false);\r
-                    if (SelectorEngine.truth(splitRule.allClasses)) {\r
-                        String[] allClasses = splitRule.allClasses.replaceFirst("^\\.", "")\r
-                                .split("\\.");\r
-                        Regexp[] regExpClassNames = new Regexp[allClasses.length];\r
-                        for (int n = 0, nl = allClasses.length; n < nl; n++) {\r
-                            regExpClassNames[n] = new Regexp(\r
-                                    "(^|\\s)" + allClasses[n] + "(\\s|$)");\r
-                        }\r
-                        JSArray matchingClassElms = JSArray.create();\r
-                        for (int o = 0, olen = prevElem.size(); o < olen; o++) {\r
-                            Element current = prevElem.getElement(o);\r
-                            String elmClass = current.getClassName();\r
-                            boolean addElm = false;\r
-                            if (SelectorEngine.truth(elmClass) && !isAdded(current)) {\r
-                                for (int p = 0, pl = regExpClassNames.length; p < pl; p++) {\r
-                                    addElm = regExpClassNames[p].test(elmClass);\r
-                                    if (!addElm) {\r
-                                        break;\r
-                                    }\r
-                                }\r
-                                if (addElm) {\r
-                                    setAdded(current, true);\r
-                                    matchingClassElms.addNode(current);\r
-                                }\r
-                            }\r
-                        }\r
-                        clearAdded(prevElem);\r
-                        prevElem = matchingElms = matchingClassElms;\r
-                    }\r
-                    if (SelectorEngine.truth(splitRule.allAttr)) {\r
-                        JSArray allAttr = Regexp\r
-                                .match("\\[[^\\]]+\\]", "g", splitRule.allAttr);\r
-                        Regexp[] regExpAttributes = new Regexp[allAttr.size()];\r
-                        String[] regExpAttributesStr = new String[allAttr.size()];\r
-                        Regexp attributeMatchRegExp = new Regexp(\r
-                                "(\\w+)(\\^|\\$|\\*|\\||~)?=?([\\w\u00C0-\uFFFF\\s\\-_\\.]+)?");\r
-                        for (int q = 0, ql = allAttr.size(); q < ql; q++) {\r
-                            JSArray attributeMatch = attributeMatchRegExp\r
-                                    .exec(allAttr.getStr(q));\r
-                            String attributeValue =\r
-                                    SelectorEngine.truth(attributeMatch.getStr(3))\r
-                                            ? attributeMatch.getStr(3).replaceAll("\\.", "\\.")\r
-                                            : null;\r
-                            String attrVal = attrToRegExp(attributeValue,\r
-                                    (SelectorEngine.or(attributeMatch.getStr(2), null)));\r
-                            regExpAttributes[q] = (SelectorEngine.truth(attrVal) ? new Regexp(\r
-                                    attrVal) : null);\r
-                            regExpAttributesStr[q] = attributeMatch.getStr(1);                                     \r
-                        }\r
-                        JSArray matchingAttributeElms = JSArray.create();\r
-\r
-                        for (int r = 0, rlen = matchingElms.size(); r < rlen; r++) {\r
-                            Element current = matchingElms.getElement(r);\r
-                            boolean addElm = false;\r
-                            for (int s = 0, sl = regExpAttributes.length, attributeRegExp;\r
-                                 s < sl; s++) {\r
-                                addElm = false;\r
-                                Regexp attributeRegExp2 = regExpAttributes[s];\r
-                                String currentAttr = getAttr(current, regExpAttributesStr[s]);\r
-                                if (SelectorEngine.truth(currentAttr)\r
-                                        && currentAttr.length() != 0) {\r
-                                    if (attributeRegExp2 == null || attributeRegExp2\r
-                                            .test(currentAttr)) {\r
-                                        addElm = true;\r
-                                    }\r
-                                }\r
-                                if (!addElm) {\r
-                                    break;\r
-                                }\r
-                            }\r
-                            if (addElm) {\r
-                                matchingAttributeElms.addNode(current);\r
-                            }\r
-                        }\r
-                        prevElem = matchingElms = matchingAttributeElms;\r
-                    }\r
-                    if (SelectorEngine.truth(splitRule.allPseudos)) {\r
-                        Regexp pseudoSplitRegExp = new Regexp(\r
-                                ":(\\w[\\w\\-]*)(\\(([^\\)]+)\\))?");\r
-\r
-                        JSArray allPseudos = Regexp.match(\r
-                                "(:\\w+[\\w\\-]*)(\\([^\\)]+\\))?", "g", splitRule.allPseudos);\r
-                        for (int t = 0, tl = allPseudos.size(); t < tl; t++) {\r
-                            JSArray pseudo = pseudoSplitRegExp.match(allPseudos.getStr(t));\r
-                            String pseudoClass = SelectorEngine.truth(pseudo.getStr(1))\r
-                                    ? pseudo.getStr(1)\r
-                                    .toLowerCase() : null;\r
-                            String pseudoValue = SelectorEngine.truth(pseudo.getStr(3))\r
-                                    ? pseudo.getStr(3) : null;\r
-                            matchingElms = getElementsByPseudo(matchingElms, pseudoClass,\r
-                                    pseudoValue);\r
-                            clearAdded(matchingElms);\r
-                        }\r
-                        prevElem = matchingElms;\r
-                    }\r
-                }\r
-            }\r
-            elm.pushAll(prevElem);\r
-        }\r
-\r
-        return elm;\r
-    }\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJSIE.java b/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineJSIE.java
deleted file mode 100644 (file)
index e7aad62..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package gwtquery.client.impl;\r
-\r
-import com.google.gwt.dom.client.Element;\r
-\r
-/**\r
- * Fix some DOM ops for IE\r
- */\r
-public class SelectorEngineJSIE extends SelectorEngineJS {\r
-    public native String getAttr(Element elm, String attr) /*-{\r
-       switch (attr) {\r
-                       case "id":\r
-                       return elm.id;\r
-                       case "for":\r
-                               return elm.htmlFor;\r
-                       case "class":\r
-                               return elm.className;\r
-               }\r
-               return elm.getAttribute(attr, 2);\r
-   }-*/;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineNative.java b/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineNative.java
deleted file mode 100644 (file)
index b9e96bd..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package gwtquery.client.impl;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.dom.client.Node;
-
-import gwtquery.client.SelectorEngine;
-
-/**
- *
- */
-public class SelectorEngineNative extends SelectorEngineImpl {
-  public NodeList<Element> select(String selector, Node ctx) {
-    return SelectorEngine.querySelectorAll(selector, ctx);
-  }
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineXPath.java b/gwtquery-core/src/main/java/gwtquery/client/impl/SelectorEngineXPath.java
deleted file mode 100644 (file)
index cbc2ca3..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-package gwtquery.client.impl;\r
-\r
-import com.google.gwt.core.client.GWT;\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
-\r
-import gwtquery.client.JSArray;\r
-import gwtquery.client.Regexp;\r
-import gwtquery.client.SelectorEngine;\r
-import static gwtquery.client.SelectorEngine.eq;\r
-import static gwtquery.client.SelectorEngine.truth;\r
-\r
-/**\r
- * Copyright 2007 Timepedia.org Licensed under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with the\r
- * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0\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
- * @author Ray Cromwell <ray@timepedia.log>\r
- */\r
-public class SelectorEngineXPath extends SelectorEngineImpl {\r
-    private Regexp cssSelectorRegExp;\r
-    private Regexp selectorSplitRegExp;\r
-    private Regexp COMBINATOR;\r
-\r
-    public SelectorEngineXPath() {\r
-    }\r
-\r
-    private void init() {\r
-        if (cssSelectorRegExp == null) {\r
-            cssSelectorRegExp = new Regexp(\r
-                    "^(\\w+)?(#[\\w\\u00C0-\\uFFFF\\-\\_]+|(\\*))?((\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[\\w\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[\\w\\u00C0-\\uFFFF\\-_]+|((\\w*\\.[\\w\\u00C0-\\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[\\w\\u00C0-\\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[\\w\\-]*))\\))?)*)?(>|\\+|~)?");\r
-            selectorSplitRegExp = new Regexp("[^\\s]+", "g");\r
-            COMBINATOR = new Regexp("(>|\\+|~)");\r
-        }\r
-    }\r
-\r
-\r
-    public NodeList<Element> select(String sel, Node ctx) {\r
-        init();\r
-        String selectors[] = sel.replaceAll("\\s*(,)\\s*", "$1").split(",");\r
-        boolean identical = false;\r
-        JSArray elm = JSArray.create();\r
-        for (int a = 0, len = selectors.length; a < len; a++) {\r
-            if (a > 0) {\r
-                identical = false;\r
-                for (int b = 0, bl = a; b < bl; b++) {\r
-                    if (eq(selectors[a], selectors[b])) {\r
-                        identical = true;\r
-                        break;\r
-                    }\r
-                }\r
-                if (identical) {\r
-                    continue;\r
-                }\r
-            }\r
-            String currentRule = selectors[a];\r
-            JSArray cssSelectors = selectorSplitRegExp.match(currentRule);\r
-            String xPathExpression = ".";\r
-            for (int i = 0, slen = cssSelectors.size(); i < slen; i++) {\r
-                String rule = cssSelectors.getStr(i);\r
-                JSArray cssSelector = cssSelectorRegExp.exec(rule);\r
-                SplitRule splitRule = new SplitRule(!truth(cssSelector.getStr(1)) || eq(\r
-                        cssSelector.getStr(3), "*") ? "*" : cssSelector.getStr(1),\r
-                        !eq(cssSelector.getStr(3), "*") ? cssSelector.getStr(2) : null,\r
-                        cssSelector.getStr(4), cssSelector.getStr(6),\r
-                        cssSelector.getStr(10), cssSelector.getStr(22));\r
-                if (truth(splitRule.tagRelation)) {\r
-                    if (eq(">", splitRule.tagRelation)) {\r
-                        xPathExpression += "/child::";\r
-                    } else if (eq("+", splitRule.tagRelation)) {\r
-                        xPathExpression += "/following-sibling::*[1]/self::";\r
-                    } else if (eq("~", splitRule.tagRelation)) {\r
-                        xPathExpression += "/following-sibling::";\r
-                    }\r
-                } else {\r
-                    xPathExpression +=\r
-                            (i > 0 && COMBINATOR.test(cssSelectors.getStr(i - 1)))\r
-                                    ? splitRule.tag : ("/descendant::" + splitRule.tag);\r
-                }\r
-                if (truth(splitRule.id)) {\r
-                    xPathExpression += "[@id = '" + splitRule.id.replaceAll("^#", "")\r
-                            + "']";\r
-                }\r
-                if (truth(splitRule.allClasses)) {\r
-                    xPathExpression += splitRule.allClasses.replaceAll(\r
-                            "\\.([\\w\\u00C0-\\uFFFF\\-_]+)",\r
-                            "[contains(concat(' ', @class, ' '), ' $1 ')]");\r
-                }\r
-                if (truth(splitRule.allAttr)) {\r
-                    GWT.log("AllAttr is " + splitRule.allAttr, null);\r
-                    xPathExpression += replaceAttr(\r
-                            SelectorEngine.or(splitRule.allAttr, ""));\r
-                }\r
-                if (truth(splitRule.allPseudos)) {\r
-                    Regexp pseudoSplitRegExp = new Regexp(\r
-                            ":(\\w[\\w\\-]*)(\\(([^\\)]+)\\))?");\r
-                    Regexp pseudoMatchRegExp = new Regexp(\r
-                            "(:\\w+[\\w\\-]*)(\\([^\\)]+\\))?", "g");\r
-                    JSArray allPseudos = pseudoMatchRegExp.match(splitRule.allPseudos);\r
-                    for (int k = 0, kl = allPseudos.size(); k < kl; k++) {\r
-                        JSArray pseudo = pseudoSplitRegExp.match(allPseudos.getStr(k));\r
-                        String pseudoClass = truth(pseudo.getStr(1)) ? pseudo.getStr(1)\r
-                                .toLowerCase() : null;\r
-                        String pseudoValue = truth(pseudo.getStr(3)) ? pseudo.getStr(3)\r
-                                : null;\r
-                        String xpath = pseudoToXPath(splitRule.tag, pseudoClass,\r
-                                pseudoValue);\r
-                        if (xpath.length() > 0) {\r
-                            xPathExpression += "[" + xpath + "]";\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            SelectorEngine.xpathEvaluate(xPathExpression, ctx, elm);\r
-        }\r
-        return elm;\r
-    }\r
-\r
-    private String pseudoToXPath(String tag, String pseudoClass,\r
-                                 String pseudoValue) {\r
-        String xpath = "";\r
-        if (eq("first-child", pseudoClass)) {\r
-            xpath = "not(preceding-sibling::*)";\r
-        } else if (eq("first-of-type", pseudoClass)) {\r
-            xpath = "not(preceding-sibling::" + tag + ")";\r
-        } else if (eq("last-child", pseudoClass)) {\r
-            xpath = "not(following-sibling::*)";\r
-        } else if (eq("last-of-type", pseudoClass)) {\r
-            xpath = "not(following-sibling::" + tag + ")";\r
-        } else if (eq("only-child", pseudoClass)) {\r
-            xpath = "not(preceding-sibling::* or following-sibling::*)";\r
-        } else if (eq("only-of-type", pseudoClass)) {\r
-            xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag\r
-                    + ")";\r
-        } else if (eq("nth-child", pseudoClass)) {\r
-            if (!eq("n", pseudoClass)) {\r
-                Sequence sequence = getSequence(pseudoValue);\r
-                if (sequence != null) {\r
-                    if (sequence.start == sequence.max) {\r
-                        xpath = "count(preceding-sibling::*) = " + (sequence.start - 1);\r
-                    } else {\r
-                        xpath = "(count(preceding-sibling::*) + 1) mod " + sequence.add\r
-                                + " = " + sequence.modVal + ((sequence.start > 1) ?\r
-                                " and count(preceding-sibling::*) >= " + (sequence.start - 1)\r
-                                : "") + ((sequence.max > 0) ?\r
-                                " and count(preceding-sibling::*) <= " + (sequence.max - 1)\r
-                                : "");\r
-                    }\r
-                }\r
-            }\r
-        } else if (eq("nth-of-type", pseudoClass)) {\r
-            if (!pseudoValue.startsWith("n")) {\r
-                Sequence sequence = getSequence(pseudoValue);\r
-                if (sequence != null) {\r
-                    if (sequence.start == sequence.max) {\r
-                        xpath = pseudoValue;\r
-                    } else {\r
-                        xpath = "position() mod " + sequence.add + " = " + sequence.modVal\r
-                                + ((sequence.start > 1) ? " and position() >= " + sequence\r
-                                .start : "") + ((sequence.max > 0) ? " and position() <= "\r
-                                + sequence.max : "");\r
-                    }\r
-                }\r
-            }\r
-        } else if (eq("empty", pseudoClass)) {\r
-            xpath = "count(child::*) = 0 and string-length(text()) = 0";\r
-        } else if (eq("contains", pseudoClass)) {\r
-            xpath = "contains(., '" + pseudoValue + "')";\r
-        } else if (eq("enabled", pseudoClass)) {\r
-            xpath = "not(@disabled)";\r
-        } else if (eq("disabled", pseudoClass)) {\r
-            xpath = "@disabled";\r
-        } else if (eq("checked", pseudoClass)) {\r
-            xpath = "@checked='checked'"; // Doesn't work in Opera 9.24\r
-        } else if (eq("not", pseudoClass)) {\r
-            if (new Regexp("^(:\\w+[\\w\\-]*)$").test(pseudoValue)) {\r
-                xpath = "not(" + pseudoToXPath(tag, pseudoValue.substring(1), "") + ")";\r
-            } else {\r
-\r
-                pseudoValue = pseudoValue\r
-                        .replaceFirst("^\\[#([\\w\\u00C0-\\uFFFF\\-\\_]+)\\]$", "[id=$1]");\r
-                String notSelector = pseudoValue\r
-                        .replaceFirst("^(\\w+)", "self::$1");\r
-                notSelector = notSelector.replaceAll("^\\.([\\w\\u00C0-\\uFFFF\\-_]+)",\r
-                        "contains(concat(' ', @class, ' '), ' $1 ')");\r
-                notSelector = replaceAttr2(notSelector);\r
-                xpath = "not(" + notSelector + ")";\r
-            }\r
-        } else {\r
-            xpath = "@" + pseudoClass + "='" + pseudoValue + "'";\r
-        }\r
-\r
-        return xpath;\r
-    }\r
-\r
-    private static String attrToXPath(String match, String p1, String p2,\r
-                                      String p3) {\r
-        if (eq("^", p2)) {\r
-            return "starts-with(@" + p1 + ", '" + p3 + "')";\r
-        }\r
-        if (eq("$", p2)) {\r
-            return "substring(@" + p1 + ", (string-length(@" + p1 + ") - "\r
-                    + (p3.length() - 1) + "), " + p3.length() + ") = '" + p3 + "'";\r
-        }\r
-        if (eq("*", p2)) {\r
-            return "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')";\r
-        }\r
-        if (eq("|", p2)) {\r
-            return "(@" + p1 + "='" + p3 + "' or starts-with(@" + p1 + ", '" + p3\r
-                    + "-'))";\r
-        }\r
-        if (eq("~", p2)) {\r
-            return "contains(concat(' ', @" + p1 + ", ' '), ' " + p3 + " ')";\r
-        }\r
-        return "@" + p1 + (truth(p3) ? "='" + p3 + "'" : "");\r
-    }\r
-\r
-    private native String replaceAttr(String allAttr) /*-{\r
-        if(!allAttr) return "";\r
-        return allAttr.replace(/(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?/g, \r
-            function(a,b,c,d) {\r
-              return @gwtquery.client.impl.SelectorEngineXPath::attrToXPath(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)(a,b || "",c || "",d || "");\r
-            });\r
-            \r
-    }-*/;\r
-\r
-    private native String replaceAttr2(String allAttr) /*-{\r
-        if(!allAttr) return "";\r
-        return allAttr.replace(/\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/g, @gwtquery.client.impl.SelectorEngineXPath::attrToXPath(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));\r
-    }-*/;\r
-}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorBase.java b/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorBase.java
deleted file mode 100644 (file)
index 3cf2c2e..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-package gwtquery.rebind;\r
-\r
-import com.google.gwt.core.ext.Generator;\r
-import com.google.gwt.core.ext.GeneratorContext;\r
-import com.google.gwt.core.ext.TreeLogger;\r
-import com.google.gwt.core.ext.UnableToCompleteException;\r
-import com.google.gwt.core.ext.typeinfo.JClassType;\r
-import com.google.gwt.core.ext.typeinfo.JMethod;\r
-import com.google.gwt.core.ext.typeinfo.JParameter;\r
-import com.google.gwt.core.ext.typeinfo.TypeOracle;\r
-import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;\r
-import com.google.gwt.user.rebind.SourceWriter;\r
-\r
-import java.io.PrintWriter;\r
-\r
-import gwtquery.client.Selector;\r
-\r
-/**\r
- *\r
- */\r
-public abstract class SelectorGeneratorBase extends Generator {\r
-\r
-  private TreeLogger treeLogger;\r
-\r
-  protected JClassType NODE_TYPE = null;\r
-\r
-  public String generate(TreeLogger treeLogger,\r
-      GeneratorContext generatorContext, String requestedClass)\r
-      throws UnableToCompleteException {\r
-    this.treeLogger = treeLogger;\r
-    TypeOracle oracle = generatorContext.getTypeOracle();\r
-    NODE_TYPE = oracle.findType("com.google.gwt.dom.client.Node");\r
-\r
-    JClassType selectorType = oracle.findType(requestedClass);\r
-    SourceWriter sw = getSourceWriter(treeLogger, generatorContext,\r
-        selectorType.getPackage().getName(),\r
-        selectorType.getSimpleSourceName() + getImplSuffix(), requestedClass);\r
-    if (sw != null) {\r
-      for (JMethod method : selectorType.getMethods()) {\r
-        generateMethod(sw, method, treeLogger);\r
-      }\r
-      genGetAllMethod(sw, selectorType.getMethods(), treeLogger);\r
-      sw.commit(treeLogger);\r
-    }\r
-\r
-    return selectorType.getPackage().getName() + "."\r
-        + selectorType.getSimpleSourceName() + getImplSuffix();\r
-  }\r
-\r
-  protected String getImplSuffix() {\r
-    return "Impl";\r
-  }\r
-\r
-  // used by benchmark harness\r
-  private void genGetAllMethod(SourceWriter sw, JMethod[] methods,\r
-      TreeLogger treeLogger) {\r
-    sw.println("public DeferredGQuery[] getAllSelectors() {");\r
-    sw.indent();\r
-    sw.println(\r
-        "DeferredGQuery[] dg = new DeferredGQuery[" + (methods.length) + "];");\r
-    int i = 0;\r
-    for (JMethod m : methods) {\r
-      Selector selectorAnnotation = m.getAnnotation(Selector.class);\r
-      if(selectorAnnotation == null) continue;\r
-      String selector = selectorAnnotation.value();\r
-\r
-      sw.println("dg[" + i + "]=new DeferredGQuery() {");\r
-      sw.indent();\r
-      sw.println(\r
-          "public String getSelector() { return \"" + selector + "\"; }");\r
-      sw.println("public GQuery eval(Node ctx) { return " + wrapJS(m, m.getName()\r
-          + (m.getParameters().length == 0 ? "()" : "(ctx)")+"") + " ;}");\r
-      sw.println("public NodeList<Element> array(Node ctx) { return "+("NodeList".equals(m.getReturnType().getSimpleSourceName()) ?\r
-        (m.getName()\r
-          + (m.getParameters().length == 0 ? "(); " : "(ctx); ")) : \r
-          "eval"+(m.getParameters().length == 0 ? "(null).get(); " : "(ctx).get(); "))+"}");\r
-      \r
-      i++;\r
-      sw.outdent();\r
-      sw.println("};");\r
-    }\r
-    sw.println("return dg;");\r
-    sw.outdent();\r
-    sw.println("}");\r
-  }\r
-\r
-  public void generateMethod(SourceWriter sw, JMethod method, TreeLogger logger)\r
-      throws UnableToCompleteException {\r
-      Selector selectorAnnotation = method.getAnnotation(Selector.class);\r
-    if(selectorAnnotation == null) return;\r
-\r
-    String selector = selectorAnnotation.value();\r
-    JParameter[] params = method.getParameters();\r
-\r
-    sw.indent();\r
-    String retType = method.getReturnType().getParameterizedQualifiedSourceName();\r
-    sw.print("public final "+retType+" "+method.getName());\r
-    boolean hasContext = false;\r
-    if (params.length == 0) {\r
-      sw.print("()");\r
-    } else if (params.length == 1) {\r
-      JClassType type = params[0].getType().isClassOrInterface();\r
-      if (type != null && type.isAssignableTo(NODE_TYPE)) {\r
-        sw.print("(Node root)");\r
-        hasContext = true;\r
-      }\r
-    }\r
-    sw.println(" {");\r
-    sw.indent();\r
-    Selector sel = method.getAnnotation(Selector.class);\r
-\r
-    // short circuit #foo\r
-    if (sel != null && sel.value().matches("^#\\w+$")) {\r
-      sw.println("return "+wrap(method, "JSArray.create(((Document)" + (hasContext ? "root" : "(Node)Document.get()")\r
-          + ").getElementById(\"" + sel.value().substring(1) + "\"))")+";");\r
-    }\r
-    // short circuit FOO\r
-    else if (sel != null && sel.value().matches("^\\w+$")) {\r
-      sw.println("return "+wrap(method, "JSArray.create(((Element)"+(hasContext ? "root" : "(Node)Document.get()")\r
-          + ").getElementsByTagName(\"" + sel.value() + "\"))")+";");\r
-    } // short circuit .foo for browsers with native getElementsByClassName \r
-    else if (sel != null && sel.value().matches("^\\.\\w+$")\r
-        && hasGetElementsByClassName()) {\r
-      sw.println("return "+wrap(method, "JSArray.create(getElementsByClassName(\""\r
-          + sel.value().substring(1) + "\", " + (hasContext ? "root" : "(Node)Document.get()")\r
-          + "))")+";");\r
-    } else {\r
-      generateMethodBody(sw, method, logger, hasContext);\r
-    }\r
-    sw.outdent();\r
-    sw.println("}");\r
-    sw.outdent();\r
-  }\r
-\r
-  protected boolean hasGetElementsByClassName() {\r
-    return false;\r
-  }\r
-\r
-  protected void debug(String s) {\r
-//    System.err.println(s);\r
-    treeLogger.log(TreeLogger.DEBUG, s, null);\r
-  }\r
-\r
-  protected boolean notNull(String s) {\r
-    return s != null && !"".equals(s);\r
-  }\r
-\r
-  protected SourceWriter getSourceWriter(TreeLogger logger,\r
-      GeneratorContext context, String packageName, String className,\r
-      String... interfaceNames) {\r
-    PrintWriter printWriter = context.tryCreate(logger, packageName, className);\r
-    if (printWriter == null) {\r
-      return null;\r
-    }\r
-    ClassSourceFileComposerFactory composerFactory\r
-        = new ClassSourceFileComposerFactory(packageName, className);\r
-    composerFactory.setSuperclass("gwtquery.client.SelectorEngine");\r
-    composerFactory.addImport("com.google.gwt.core.client.GWT");\r
-    composerFactory.addImport("gwtquery.client.*");\r
-//    composerFactory.addImport("gwtquery.client.JSArray");\r
-\r
-    composerFactory.addImport("com.google.gwt.dom.client.*");\r
-    for (String interfaceName : interfaceNames) {\r
-      composerFactory.addImplementedInterface(interfaceName);\r
-    }\r
-\r
-    return composerFactory.createSourceWriter(context, printWriter);\r
-  }\r
-\r
-  protected String wrap(JMethod method, String expr) {\r
-    if("NodeList".equals(method.getReturnType().getSimpleSourceName())) {\r
-      return expr;\r
-    }\r
-    else {\r
-      return "new GQuery("+expr+")";\r
-    }\r
-    \r
-  }\r
-  \r
-  protected String wrapJS(JMethod method, String expr) {\r
-    if("GQuery".equals(method.getReturnType().getSimpleSourceName())) {\r
-      return expr;\r
-    }\r
-    else {\r
-      return "new GQuery("+expr+")";\r
-    }\r
-    \r
-  }\r
-  \r
-  protected abstract void generateMethodBody(SourceWriter sw, JMethod method,\r
-      TreeLogger logger, boolean hasContext) throws UnableToCompleteException;\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorJS.java b/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorJS.java
deleted file mode 100644 (file)
index 8917f4c..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-package gwtquery.rebind;\r
-\r
-import com.google.gwt.core.ext.TreeLogger;\r
-import com.google.gwt.core.ext.UnableToCompleteException;\r
-import com.google.gwt.core.ext.typeinfo.JMethod;\r
-import com.google.gwt.user.rebind.SourceWriter;\r
-\r
-import java.util.regex.Pattern;\r
-\r
-import gwtquery.client.Selector;\r
-\r
-/**\r
- *\r
- */\r
-public class SelectorGeneratorJS extends SelectorGeneratorBase {\r
-\r
-  protected static Pattern nonSpace = Pattern.compile("\\S/");\r
-\r
-  private static final String trimReStr = "^\\s+|\\s+$";\r
-\r
-  protected static Pattern trimRe = Pattern.compile(trimReStr);\r
-\r
-  protected static Pattern tplRe = Pattern.compile("\\{(\\d+)\\}");\r
-\r
-  protected static Pattern modeRe = Pattern\r
-      .compile("^(\\s?[\\/>+~]\\s?|\\s|$)");\r
-\r
-  protected static Pattern tagTokenRe = Pattern\r
-      .compile("^(#)?([a-zA-Z_0-9-\\*]+)");\r
-\r
-  protected static Pattern nthRe = Pattern.compile("(\\d*)n\\+?(\\d*)");\r
-\r
-  protected static Pattern nthRe2 = Pattern.compile("\\D");\r
-\r
-  protected static RuleMatcher[] matchers = new RuleMatcher[]{new RuleMatcher(\r
-      "^\\.([a-zA-Z_0-9-]+)", "n = byClassName(n, null, \"{0}\");"),\r
-      new RuleMatcher("^\\:([a-zA-Z_0-9-]+)(?:\\(((?:[^ >]*|.*?))\\))?",\r
-          "n = byPseudo(n, \"{0}\", \"{1}\");"), new RuleMatcher(\r
-      "^(?:([\\[\\{])(?:@)?([a-zA-Z_0-9-]+)\\s?(?:(=|.=)\\s?['\"]?(.*?)[\"']?)?[\\]\\}])",\r
-      "n = byAttribute(n, \"{1}\", \"{3}\", \"{2}\", \"{0}\");"),\r
-      new RuleMatcher("^#([a-zA-Z_0-9-]+)", "n = byId(n, null, \"{0}\");")};\r
-\r
-  protected String getImplSuffix() {\r
-    return "JS"+super.getImplSuffix();\r
-  }\r
-\r
-  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
-      TreeLogger treeLogger, boolean hasContext) throws UnableToCompleteException {\r
-\r
-    String selector = method.getAnnotation(Selector.class).value();\r
-    if(!hasContext) sw.println("Node root = Document.get();");\r
-    \r
-    sw.println("return "+wrap(method, "new SelectorEngine().select(\""+selector+"\", root)")+";");\r
-//    sw.println("JSArray n = JSArray.create();");\r
-//    if(!hasContext) { \r
-//      sw.println("Node root = Document.get();");\r
-//    }\r
-//\r
-//    // add root node as context. \r
-//    // TODO: support any context\r
-//    sw.println("n.addNode(root);");\r
-//    String q = selector, lq = null;\r
-//    Matcher lmode = modeRe.matcher(q);\r
-//    Matcher mm = null;\r
-//    String mode = "";\r
-//    if (lmode.lookingAt() && notNull(lmode.group(1))) {\r
-//      mode = lmode.group(1).replaceAll(trimReStr, "").trim();\r
-//      q = q.replaceFirst("\\Q" + lmode.group(1) + "\\E", "");\r
-//    }\r
-//\r
-//    while (notNull(q) && !q.equals(lq)) {\r
-//      debug("Doing q=" + q);\r
-//\r
-//      lq = q;\r
-//      Matcher tm = tagTokenRe.matcher(q);\r
-//      if (tm.lookingAt()) {\r
-//        if ("#".equals(tm.group(1))) {\r
-//          sw.println("n = quickId(n, \"" + mode + "\", root, \"" + tm.group(2)\r
-//              + "\");");\r
-//        } else {\r
-//          String tagName = tm.group(2);\r
-//          tagName = "".equals(tagName) ? "*" : tagName;\r
-//     //     sw.println("if (n.size() == 0) { n=JSArray.create(); }");\r
-//          String func = "";\r
-//          if ("".equals(mode)) {\r
-//            func = "getDescendentNodes";\r
-//          } else if (">".equals(mode)) {\r
-//            func = "getChildNodes";\r
-//          } else if ("+".equals(mode)) {\r
-//            func = "getSiblingNodes";\r
-//          } else if ("~".equals(mode)) {\r
-//            func = "getGeneralSiblingNodes";\r
-//          } else {\r
-//            treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "\r
-//                + mode + " not recognized in " + selector, null);\r
-//            throw new UnableToCompleteException();\r
-//          }\r
-//          sw.println("n = " + func + "(n, \"" + tagName + "\");");\r
-//        }\r
-//        debug("replacing in q, the value " + tm.group(0));\r
-//        q = q.replaceFirst("\\Q" + tm.group(0) + "\\E", "");\r
-//      } else {\r
-//        String func = "";\r
-//        String tagName = "*";\r
-//        if ("".equals(mode)) {\r
-//          func = "getDescendentNodes";\r
-//        } else if (">".equals(mode)) {\r
-//          func = "getChildNodes";\r
-//        } else if ("+".equals(mode)) {\r
-//          func = "getSiblingNodes";\r
-//        } else if ("~".equals(mode)) {\r
-//          func = "getGeneralSiblingNodes";\r
-//        } else {\r
-//          treeLogger.log(TreeLogger.ERROR, "Error parsing selector, combiner "\r
-//              + mode + " not recognized in " + selector, null);\r
-//          throw new UnableToCompleteException();\r
-//        }\r
-//        sw.println("n = " + func + "(n, \"" + tagName + "\");");\r
-//      }\r
-//\r
-//      while (!(mm = modeRe.matcher(q)).lookingAt()) {\r
-//        debug("Looking at " + q);\r
-//        boolean matched = false;\r
-//        for (RuleMatcher rm : matchers) {\r
-//          Matcher rmm = rm.re.matcher(q);\r
-//          if (rmm.lookingAt()) {\r
-//            String res[] = new String[rmm.groupCount()];\r
-//            for (int i = 1; i <= rmm.groupCount(); i++) {\r
-//              res[i - 1] = rmm.group(i);\r
-//              debug("added param " + res[i - 1]);\r
-//            }\r
-//            Object[] r = res;\r
-//            // inline enum, perhaps type-tightening will allow inlined eval() \r
-//            // call\r
-//            if (rm.fnTemplate.indexOf("byPseudo") != -1) {\r
-//              sw.println("n = Pseudo."+res[0].toUpperCase().replace("-", "_") +\r
-//                  ".eval(n, \""+res[1]+"\");");\r
-//            } else {\r
-//              sw.println(MessageFormat.format(rm.fnTemplate, r));\r
-//            }\r
-//            q = q.replaceFirst("\\Q" + rmm.group(0) + "\\E", "");\r
-//            matched = true;\r
-//            break;\r
-//          }\r
-//        }\r
-//        if (!matched) {\r
-//          treeLogger\r
-//              .log(TreeLogger.ERROR, "Error parsing selector at " + q, null);\r
-//          throw new UnableToCompleteException();\r
-//        }\r
-//      }\r
-//\r
-//      if (notNull(mm.group(1))) {\r
-//        mode = mm.group(1).replaceAll(trimReStr, "");\r
-//        debug("replacing q=" + q + " this part:" + mm.group(1));\r
-//        q = q.replaceFirst("\\Q" + mm.group(1) + "\\E", "");\r
-//      }\r
-//    }\r
-//    sw.println("return "+wrap(method, "nodup(n)")+";");\r
-  }\r
-\r
\r
-  static class RuleMatcher {\r
-\r
-    public Pattern re;\r
-\r
-    public String fnTemplate;\r
-\r
-    RuleMatcher(String pat, String fnT) {\r
-      this.re = Pattern.compile(pat);\r
-      this.fnTemplate = fnT;\r
-    }\r
-  }\r
-}\r
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorNative.java b/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorNative.java
deleted file mode 100644 (file)
index e7db5da..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package gwtquery.rebind;\r
-\r
-import com.google.gwt.core.ext.TreeLogger;\r
-import com.google.gwt.core.ext.UnableToCompleteException;\r
-import com.google.gwt.core.ext.typeinfo.JMethod;\r
-import com.google.gwt.user.rebind.SourceWriter;\r
-\r
-import gwtquery.client.Selector;\r
-\r
-/**\r
- *\r
- */\r
-public class SelectorGeneratorNative extends SelectorGeneratorBase {\r
-\r
-  protected String getImplSuffix() {\r
-    return "Native" + super.getImplSuffix();\r
-  }\r
-\r
-  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
-      TreeLogger treeLogger, boolean hasContext)\r
-      throws UnableToCompleteException {\r
-    String selector = method.getAnnotation(Selector.class).value();\r
-    if (!hasContext) {\r
-      sw.println("return "\r
-          + wrap(method, "querySelectorAll(\"" + selector + "\"") + ");");\r
-    } else {\r
-      sw.println("return "\r
-          + wrap(method, "querySelectorAll(\"" + selector + "\", root)")\r
-          + ");");\r
-    }\r
-  }\r
-}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorXPath.java b/gwtquery-core/src/main/java/gwtquery/rebind/SelectorGeneratorXPath.java
deleted file mode 100644 (file)
index d43cfd3..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-package gwtquery.rebind;\r
-\r
-import com.google.gwt.core.ext.TreeLogger;\r
-import com.google.gwt.core.ext.UnableToCompleteException;\r
-import com.google.gwt.core.ext.typeinfo.JMethod;\r
-import com.google.gwt.user.rebind.SourceWriter;\r
-\r
-import java.util.ArrayList;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-import gwtquery.client.Selector;\r
-\r
-/**\r
- *\r
- */\r
-public class SelectorGeneratorXPath extends SelectorGeneratorBase {\r
-\r
-  private static Pattern cssSelectorRegExp = Pattern.compile(\r
-      "^(\\w+)?(#[a-zA-Z_0-9\u00C0-\uFFFF\\-\\_]+|(\\*))?((\\.[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)*)?((\\[\\w+(\\^|\\$|\\*|\\||~)?(=[a-zA-Z_0-9\u00C0-\uFFFF\\s\\-\\_\\.]+)?\\]+)*)?(((:\\w+[a-zA-Z_0-9\\-]*)(\\((odd|even|\\-?\\d*n?((\\+|\\-)\\d+)?|[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+|((\\w*\\.[a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)*)?|(\\[#?\\w+(\\^|\\$|\\*|\\||~)?=?[a-zA-Z_0-9\u00C0-\uFFFF\\s\\-\\_\\.]+\\]+)|(:\\w+[a-zA-Z_0-9\\-]*))\\))?)*)?(>|\\+|~)?");\r
-\r
-  private static Pattern selectorSplitRegExp = Pattern\r
-      .compile("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]");\r
-\r
-  private String prefix = "";\r
-\r
-  static class SplitRule {\r
-\r
-    public String tag;\r
-\r
-    public String id;\r
-\r
-    public String allClasses;\r
-\r
-    public String allAttr;\r
-\r
-    public String allPseudos;\r
-\r
-    public String tagRelation;\r
-  }\r
-\r
-  protected String getImplSuffix() {\r
-    return "XPath"+super.getImplSuffix();\r
-  }\r
-\r
-  protected void generateMethodBody(SourceWriter sw, JMethod method,\r
-      TreeLogger treeLogger, boolean hasContext)\r
-      throws UnableToCompleteException {\r
-\r
-    String selector = method.getAnnotation(Selector.class).value();\r
-    String[] cssRules = selector.replaceAll("\\s*(,)\\s*", "$1").split(",");\r
-    String currentRule;\r
-    boolean identical = false;\r
-    String xPathExpression = ".";\r
-\r
-    for (int i = 0; i < cssRules.length; i++) {\r
-      currentRule = cssRules[i];\r
-\r
-      if (i > 0) {\r
-        identical = false;\r
-        for (int x = 0, xl = i; x < xl; x++) {\r
-          if (cssRules[i].equals(cssRules[x])) {\r
-            identical = true;\r
-            break;\r
-          }\r
-        }\r
-        if (identical) {\r
-          continue;\r
-        }\r
-      }\r
-\r
-      ArrayList<String> cssSelectors = new ArrayList<String>();\r
-      Matcher selm = selectorSplitRegExp.matcher(currentRule);\r
-      while (selm.find()) {\r
-        cssSelectors.add(selm.group(0));\r
-      }\r
-\r
-      Matcher cssSelector;\r
-      for (int j = 0, jl = cssSelectors.size(); j < jl; j++) {\r
-        cssSelector = cssSelectorRegExp.matcher(cssSelectors.get(j));\r
-        if (cssSelector.matches()) {\r
-\r
-          SplitRule splitRule = new SplitRule();\r
-          splitRule.tag = prefix + ((!notNull(cssSelector.group(1)) || "*"\r
-              .equals(cssSelector.group(3))) ? "*" : cssSelector.group(1));\r
-          splitRule.id = (!"*".equals(cssSelector.group(3))) ? cssSelector\r
-              .group(2) : null;\r
-          splitRule.allClasses = cssSelector.group(4);\r
-          splitRule.allAttr = cssSelector.group(6);\r
-          splitRule.allPseudos = cssSelector.group(10);\r
-          splitRule.tagRelation = cssSelector.group(22);\r
-          if (notNull(splitRule.tagRelation)) {\r
-            if (">".equals(splitRule.tagRelation)) {\r
-              xPathExpression += "/child::";\r
-            } else if ("+".equals(splitRule.tagRelation)) {\r
-              xPathExpression += "/following-sibling::*[1]/self::";\r
-            } else if ("~".equals(splitRule.tagRelation)) {\r
-              xPathExpression += "/following-sibling::";\r
-            }\r
-          } else {\r
-            xPathExpression +=\r
-                (j > 0 && cssSelectors.get(j - 1).matches("(>|\\+|~)"))\r
-                    ? splitRule.tag : ("/descendant::" + splitRule.tag);\r
-          }\r
-\r
-          if (notNull(splitRule.id)) {\r
-            xPathExpression += "[@id = '" + splitRule.id.replaceAll("^#", "")\r
-                + "']";\r
-          }\r
-          if (notNull(splitRule.allClasses)) {\r
-            xPathExpression += splitRule.allClasses.replaceAll(\r
-                "\\.([a-zA-Z_0-9\u00C0 -\uFFFF\\-_]+)",\r
-                "[contains(concat(' ', @class, ' '), ' $1 ')]");\r
-          }\r
-          if (notNull(splitRule.allAttr)) {\r
-            xPathExpression += attrToXPath(splitRule.allAttr,\r
-                "(\\w+)(\\^|\\$|\\*|\\||~)?=?([a-zA-Z_0-9\u00C0-\uFFFF\\s\\-_\\.]+)?");\r
-          }\r
-          if (notNull(splitRule.allPseudos)) {\r
-            Pattern pseudoSplitRegExp = Pattern\r
-                .compile(":(\\w[a-zA-Z_0-9\\-]*)(\\(([^\\)]+)\\))?");\r
-            Matcher m = Pattern\r
-                .compile("(:\\w+[a-zA-Z_0-9\\-]*)(\\([^\\)]+\\))?")\r
-                .matcher(splitRule.allPseudos);\r
-            while (m.find()) {\r
-              String str = m.group(0);\r
-              Matcher pseudo = pseudoSplitRegExp\r
-                  .matcher(str == null ? "" : str);\r
-              if (pseudo.matches()) {\r
-                String pseudoClass = notNull(pseudo.group(1)) ? pseudo.group(1)\r
-                    .toLowerCase() : null;\r
-                String pseudoValue = notNull(pseudo.group(3)) ? pseudo.group(3)\r
-                    : null;\r
-                String xpath = pseudoToXPath(splitRule.tag, pseudoClass,\r
-                    pseudoValue);\r
-                if (notNull(xpath)) {\r
-                  xPathExpression += "[" + xpath + "]";\r
-                }\r
-              }\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    if (!hasContext) {\r
-      sw.println("Node root = Document.get();");\r
-    }\r
-    sw.println("return "+wrap(method, "SelectorEngine.xpathEvaluate(\""\r
-        + xPathExpression + "\", root)")+";");\r
-  }\r
-\r
-  static class Sequence {\r
-\r
-    public int start;\r
-\r
-    public int max;\r
-\r
-    public int add;\r
-\r
-    public int modVal;\r
-  }\r
-\r
-  private String pseudoToXPath(String tag, String pseudoClass,\r
-      String pseudoValue) {\r
-    tag = pseudoClass.matches(".*\\-child$") ? "*" : tag;\r
-    String xpath = "";\r
-    String pseudo[] = pseudoClass.split("-");\r
-    if ("first".equals(pseudo[0])) {\r
-      xpath = "not(preceding-sibling::" + tag + ")";\r
-    } else if ("last".equals(pseudo[0])) {\r
-      xpath = "not(following-sibling::" + tag + ")";\r
-    } else if ("only".equals(pseudo[0])) {\r
-      xpath = "not(preceding-sibling::" + tag + " or following-sibling::" + tag\r
-          + ")";\r
-    } else if ("nth".equals(pseudo[0])) {\r
-      if (!pseudoValue.matches("^n$")) {\r
-        String position = (("last".equals(pseudo[1]))\r
-            ? "(count(following-sibling::" : "(count(preceding-sibling::") + tag\r
-            + ") + 1)";\r
-        Sequence sequence = getSequence(pseudoValue);\r
-        if (sequence != null) {\r
-          if (sequence.start == sequence.max) {\r
-            xpath = position + " = " + sequence.start;\r
-          } else {\r
-            xpath = position + " mod " + sequence.add + " = " + sequence.modVal\r
-                + ((sequence.start > 1) ? " and " + position + " >= " + sequence\r
-                .start : "") + ((sequence.max > 0) ? " and " + position + " <= "\r
-                + sequence.max : "");\r
-          }\r
-        }\r
-      }\r
-    } else if ("empty".equals(pseudo[0])) {\r
-      xpath = "count(child::*) = 0 and string-length(text()) = 0";\r
-    } else if ("contains".equals(pseudo[0])) {\r
-      xpath = "contains(., '" + pseudoValue + "')";\r
-    } else if ("enabled".equals(pseudo[0])) {\r
-      xpath = "not(@disabled)";\r
-    } else if ("disabled".equals(pseudo[0])) {\r
-      xpath = "@disabled";\r
-    } else if ("checked".equals(pseudo[0])) {\r
-      xpath = "@checked='checked'"; // Doesn't work in Opera 9.24\r
-    } else if ("not".equals(pseudo[0])) {\r
-      if (pseudoValue.matches("^(:a-zA-Z_0-9+[a-zA-Z_0-9\\-]*)$")) {\r
-        xpath = "not(" + pseudoToXPath(tag, pseudoValue.substring(1), "") + ")";\r
-      } else {\r
-        pseudoValue = pseudoValue.replaceAll(\r
-            "^\\[#([a-zA-Z_0-9\u00C0-\uFFFF\\-\\_]+)\\]$", "[id=$1]");\r
-        String notSelector = pseudoValue\r
-            .replaceFirst("^(a-zA-Z_0-9+)", "self::$1");\r
-        notSelector = notSelector.replaceAll(\r
-            "^\\.([a-zA-Z_0-9\u00C0-\uFFFF\\-_]+)",\r
-            "contains(concat(' ', @class, ' '), ' $1 ')");\r
-        notSelector = attrToXPath(notSelector,\r
-            "\\[(a-zA-Z_0-9+)(\\^|\\$|\\*|\\||~)?=?([a-zA-Z_0-9\u00C0-\uFFFF\\s\\-_\\.]+)?\\]");\r
-        xpath = "not(" + notSelector + ")";\r
-      }\r
-    } else {\r
-      xpath = "@" + pseudoClass + "='" + pseudoValue + "'";\r
-    }\r
-    return xpath;\r
-  }\r
-\r
-  private String attrToXPath(String notSelector, String pattern) {\r
-    Pattern p = Pattern.compile(pattern);\r
-    Matcher m = p.matcher(notSelector);\r
-    m.reset();\r
-    boolean result = m.find();\r
-    if (result) {\r
-      StringBuffer sb = new StringBuffer();\r
-      do {\r
-        String replacement;\r
-        String p1 = m.group(1);\r
-        String p2 = m.group(2);\r
-        String p3 = m.group(3);\r
-        if ("^".equals(p2)) {\r
-          replacement = "starts-with(@" + p1 + ", '" + p3 + "')";\r
-        } else if ("$".equals(p2)) {\r
-          replacement = "substring(@" + p1 + ", (string-length(@" + p1 + ") - "\r
-              + (p3.length() - 1) + "), " + p3.length() + ") = '" + p3 + "'";\r
-        } else if ("*".equals(p2)) {\r
-          replacement = "contains(concat(' ', @" + p1 + ", ' '), '" + p3 + "')";\r
-        } else if ("|".equals(p2)) {\r
-          replacement = "(@" + p1 + "='" + p3 + "' or starts-with(@" + p1\r
-              + ", '" + p3 + "-'))";\r
-        } else if ("~".equals(p2)) {\r
-          replacement = "contains(concat(' ', @" + p1 + ", ' '), ' " + p3\r
-              + " ')";\r
-        } else {\r
-          replacement = "@" + p1 + (notNull(p3) ? "='" + p3 + "'" : "");\r
-        }\r
-        debug("p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " replacement is "\r
-            + replacement);\r
-        m.appendReplacement(sb, replacement.replace("$", "\\$"));\r
-        result = m.find();\r
-      } while (result);\r
-      m.appendTail(sb);\r
-      return sb.toString();\r
-    }\r
-    return notSelector;\r
-  }\r
-\r
-  private Sequence getSequence(String expression) {\r
-    int start = 0, add = 2, max = -1, modVal = -1;\r
-    Pattern expressionRegExp = Pattern.compile(\r
-        "^((odd|even)|([1-9]\\d*)|((([1-9]\\d*)?)n([\\+\\-]\\d+)?)|(\\-(([1-9]\\d*)?)n\\+(\\d+)))$");\r
-    Matcher pseudoValue = expressionRegExp.matcher(expression);\r
-    if (!pseudoValue.matches()) {\r
-      return null;\r
-    } else {\r
-      if (notNull(pseudoValue.group(2))) {   // odd or even\r
-        start = ("odd".equals(pseudoValue.group(2))) ? 1 : 2;\r
-        modVal = (start == 1) ? 1 : 0;\r
-      } else if (notNull(pseudoValue.group(3))) {      // single digit\r
-        start = Integer.parseInt(pseudoValue.group(3), 10);\r
-        add = 0;\r
-        max = start;\r
-      } else if (notNull(pseudoValue.group(4))) {      // an+b\r
-        add = notNull(pseudoValue.group(6)) ? getInt(pseudoValue.group(6), 1)\r
-            : 1;\r
-        start = notNull(pseudoValue.group(7)) ? getInt(pseudoValue.group(7), 0)\r
-            : 0;\r
-        while (start < 1) {\r
-          start += add;\r
-        }\r
-        modVal = (start > add) ? (start - add) % add\r
-            : ((start == add) ? 0 : start);\r
-      } else if (notNull(pseudoValue.group(8))) {      // -an+b\r
-        add = notNull(pseudoValue.group(10)) ? Integer\r
-            .parseInt(pseudoValue.group(10), 10) : 1;\r
-        start = max = Integer.parseInt(pseudoValue.group(10), 10);\r
-        while (start > add) {\r
-          start -= add;\r
-        }\r
-        modVal = (max > add) ? (max - add) % add : ((max == add) ? 0 : max);\r
-      }\r
-    }\r
-    Sequence s = new Sequence();\r
-    s.start = start;\r
-    s.add = add;\r
-    s.max = max;\r
-    s.modVal = modVal;\r
-    return s;\r
-  }\r
-\r
-  private int getInt(String s, int i) {\r
-    try {\r
-      if (s.startsWith("+")) {\r
-        s = s.substring(1);\r
-      }\r
-      return Integer.parseInt(s);\r
-    } catch (Exception e) {\r
-      debug("error parsing Integer " + s);\r
-      return i;\r
-    }\r
-  }\r
-}
\ No newline at end of file
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorJSGEBCN.java b/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorJSGEBCN.java
deleted file mode 100644 (file)
index a287303..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorJS;
-
-/**
- */
-public class SelectorGeneratorJSGEBCN extends SelectorGeneratorJS {
-
-  protected boolean hasGetElementsByClassName() {
-    return true;
-  }
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorNativeGEBCN.java b/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorNativeGEBCN.java
deleted file mode 100644 (file)
index 04226db..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorNative;
-
-/**
- * 
- */
-public class SelectorGeneratorNativeGEBCN extends SelectorGeneratorNative {
-
-  protected boolean hasGetElementsByClassName() {
-    return true;
-  }
-}
diff --git a/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorXPathGEBCN.java b/gwtquery-core/src/main/java/gwtquery/rebind/gebcn/SelectorGeneratorXPathGEBCN.java
deleted file mode 100644 (file)
index 9bcce9c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorXPath;
-
-/**
- */
-public class SelectorGeneratorXPathGEBCN extends SelectorGeneratorXPath {
-
-  protected boolean hasGetElementsByClassName() {
-    return true;
-  }
-}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GwtQueryCoreTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GwtQueryCoreTest.java
new file mode 100644 (file)
index 0000000..13509b7
--- /dev/null
@@ -0,0 +1,558 @@
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.Function;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootPanel;
+
+/**
+ * Test class for testing gwtquery-core api.
+ */
+public class GwtQueryCoreTest extends GWTTestCase {
+
+    public String getModuleName() {
+        return "com.google.gwt.query.Query";
+    }
+
+    static HTML testPanel = null;
+    static Element e = null;
+
+    public void gwtSetUp() {
+        if (e == null) {
+            testPanel = new HTML();
+            RootPanel.get().add(testPanel);
+            e = testPanel.getElement();
+            e.setId("tst");
+        } else {
+            e.setInnerHTML("");
+        }
+    }
+
+    public void testBrowserStartUp() {
+        // just a test for seeing in eclipse that GWTTestCase internal browser is starting
+        assertTrue(true);
+    }
+
+    public void testInnerMethods() {
+        String txt = "<p>I would like to say: </p>";
+
+        // Check that setHTML and getHTML works as GQuery html()
+        testPanel.setHTML(txt);
+        assertEquals(txt, testPanel.getHTML());
+        assertEquals(txt, $(e).html());
+        assertEquals(txt, $("#tst").html());
+        $(e).html("");
+        assertEquals("", $(e).html());
+        $(e).html(txt);
+        assertEquals(txt, $(e).html());
+
+        // toString()
+        assertEquals(txt, $("p", e).toString());
+
+        // remove()
+        $("p", e).remove();
+        assertEquals("", $(e).html());
+
+        // text()
+        String expected = "I would like to say: I would like to say: ";
+        $(e).html(txt + txt);
+        assertEquals(expected, $("p", e).text());
+
+        // empty()
+        expected = "<p></p><p></p>";
+        $("p", e).empty();
+        assertEquals(expected, $(e).html());
+    }
+
+    public void testAttributeMethods() {
+
+        $(e).html("<p class=\"a1\">Content</p>");
+        GQuery gq = $("p", e);
+        
+        // attr()
+        assertEquals("a1", gq.attr("class"));
+        gq.attr("class", "b1 b2");
+
+        // hasClass()
+        assertTrue(gq.hasClass("b1"));
+        assertTrue(gq.hasClass("b2"));
+
+        // addClass()
+        gq.addClass("c1", "c2");
+        assertTrue(gq.hasClass("b1"));
+        assertTrue(gq.hasClass("b2"));
+        assertTrue(gq.hasClass("c1"));
+        assertTrue(gq.hasClass("c2"));
+
+        // removeClass()
+        gq.removeClass("c2", "c1");
+        assertTrue(gq.hasClass("b1"));
+        assertTrue(gq.hasClass("b2"));
+        assertFalse(gq.hasClass("c1"));
+        assertFalse(gq.hasClass("c2"));
+
+        // css()
+        String content = "<p style='color:red;'>Test Paragraph.</p>";
+        $(e).html(content);
+        assertEquals("red", $("p", e).css("color"));
+        $("p", e).css("font-weight", "bold");
+        assertEquals("bold", $("p", e).css("font-weight"));
+
+        // css() properties
+        $(e).html("<p>Test Paragraph.</p>");
+        $("p", e).css(Properties.create("color: 'red', 'font-weight': 'bold', background: 'blue'"));
+        assertEquals("red", $("p", e).css("color"));
+        assertEquals("bold", $("p", e).css("font-weight"));
+        assertEquals("blue", $("p", e).css("background-color"));
+
+        // css() camelize and uppercase
+        $(e).html("<p>Test Paragraph.</p>");
+        $("p", e).css(Properties.create("COLOR: 'red', 'FONT-WEIGHT': 'bold'"));
+        assertEquals("red", $("p", e).css("color"));
+        assertEquals("", $("p", e).css("background"));
+
+    }
+
+    public void testSliceMethods() {
+        String content = "<p>This is just a test.</p><p>So is this</p>";
+        $(e).html(content);
+
+        String expected = "<p>So is this</p>";
+        assertEquals(1, $("p", e).eq(1).size());
+        assertEquals(expected, $("p", e).eq(1).toString());
+
+        expected = "<p>This is just a test.</p>";
+        assertEquals(1, $("p", e).lt(1).size());
+        assertEquals(expected, $("p", e).lt(1).toString());
+
+        expected = "<p>So is this</p>";
+        assertEquals(1, $("p", e).gt(0).size());
+        assertEquals(expected, $("p", e).gt(0).toString());
+
+        assertEquals(2, $("p", e).slice(0, 2).size());
+        assertEquals(2, $("p", e).slice(0, -1).size());
+        assertEquals(0, $("p", e).slice(3, 2).size());
+    }
+
+    public void testRelativeMethods() {
+        String content = "<p><span>Hello</span>, how are you?</p>";
+        String expected = "<span>Hello</span>";
+
+        // find()
+        $(e).html(content);
+        assertEquals(expected, $("p", e).find("span").toString());
+
+        // filter()
+        content = "<p>First</p><p class=\"selected\">Hello</p><p>How are you?</p>";
+        $(e).html(content);
+        expected = "<p class=\"selected\">Hello</p>";
+        assertEquals(expected, $("p", e).filter(".selected").toString());
+
+        // filter()
+        // Commented because GQuery doesn't support this syntax yet
+        // expected = "<p class=\"selected\">Hello</p>";
+        // assertEquals(expected, $("p", e).filter(".selected, :first").toString());
+
+        // not()
+        expected = "<p>First</p><p>How are you?</p>";
+        assertEquals(2, $("p", e).not(".selected").size());
+        assertEquals(expected, $("p", e).not(".selected").toString());
+        assertEquals(2, $("p", e).not($(".selected")).size());
+        assertEquals(expected, $("p", e).not($(".selected")).toString());
+        assertEquals(2, $("p", e).not($(".selected").get(0)).size());
+        assertEquals(expected, $("p", e).not($(".selected").get(0)).toString());
+
+        // add()
+        String added = "<p>Last</p>";
+        expected = content + added;
+        assertEquals(4, $("p", e).add(added).size());
+        assertEquals(expected, $("p", e).add(added).toString());
+
+        // parent()
+        expected = content = "<div><p>Hello</p><p>Hello</p></div>";
+        $(e).html(content);
+        assertEquals(expected, $("p", e).parent().toString());
+
+        // parent()
+        content = "<div><p>Hello</p></div><div class=\"selected\"><p>Hello Again</p></div>";
+        expected = "<div class=\"selected\"><p>Hello Again</p></div>";
+        $(e).html(content);
+        assertEquals(expected, $("p", e).parent(".selected").toString());
+
+        // parents()
+        content = "<div><p><span>Hello</span></p><span>Hello Again</span></div>";
+        $(e).html(content);
+        assertEquals(2, $("span", e).size());
+        assertTrue(3 < $("span", e).parents().size());
+        assertEquals(1, $("span", e).parents().filter("body").size());
+        $("span", e).parents().filter("body").toString().contains(content);
+
+        // is()
+        content = "<form><input type=\"checkbox\"></form>";
+        $(e).html(content);
+        assertEquals(true, $("input[type=\"checkbox\"]", e).parent().is("form"));
+
+        // is()
+        content = "<form><p><input type=\"checkbox\"></p></form>";
+        $(e).html(content);
+        assertEquals(false, $("input[type='checkbox']", e).parent().is("form"));
+
+        // next()
+        content = "<p>Hello</p><p>Hello Again</p><div><span>And Again</span></div>";
+        String next1 = "<p>Hello Again</p>";
+        String next2 = "<div><span>And Again</span></div>";
+        $(e).html(content);
+        assertEquals(2, $("p", e).next().size());
+        assertEquals(next1, $("p", e).next().get(0).getString());
+        assertEquals(next2, $("p", e).next().get(1).getString());
+
+        // next()
+        content = "<p>Hello</p><p class=\"selected\">Hello Again</p><div><span>And Again</span></div>";
+        expected = "<p class=\"selected\">Hello Again</p>";
+        $(e).html(content);
+        assertEquals(1, $("p", e).next(".selected").size());
+        assertEquals(expected, $("p", e).next(".selected").get(0).getString());
+
+        // prev()
+        content = "<p>Hello</p><div><span>Hello Again</span></div><p>And Again</p>";
+        expected = "<div><span>Hello Again</span></div>";
+        $(e).html(content);
+        assertEquals(1, $("p", e).prev().size());
+        assertEquals(expected, $("p", e).prev().get(0).getString());
+
+        // prev()
+        content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
+        expected = "<p class=\"selected\">Hello Again</p>";
+        $(e).html(content);
+        assertEquals(2, $("p", e).prev().size());
+        assertEquals(1, $("p", e).prev(".selected").size());
+        assertEquals(expected, $("p", e).prev(".selected").get(0).getString());
+
+        // siblings()
+        content = "<p>Hello</p><div><span>Hello Again</span></div><p>And Again</p>";
+        next1 = "<p>Hello</p>";
+        next2 = "<p>And Again</p>";
+        $(e).html(content);
+        assertEquals(2, $("div", e).siblings().size());
+        assertEquals(next1, $("div", e).siblings().get(0).getString());
+        assertEquals(next2, $("div", e).siblings().get(1).getString());
+
+        // siblings()
+        content = "<div><span>Hello</span></div><p class=\"selected\">Hello Again</p><p>And Again</p>";
+        expected = "<p class=\"selected\">Hello Again</p>";
+        $(e).html(content);
+        assertEquals(1, $("p", e).siblings(".selected").size());
+        assertEquals(expected, $("p", e).siblings(".selected").get(0).getString());
+
+        // children()
+        content = "<p>Hello</p><div><span>Hello Again</span></div><p>And Again</p>";
+        expected = "<span>Hello Again</span>";
+        $(e).html(content);
+        assertEquals(expected, $("div", e).children().toString());
+
+        // children()
+        content = "<div><span>Hello</span><p class=\"selected\">Hello Again</p><p>And Again</p></div>";
+        expected = "<p class=\"selected\">Hello Again</p>";
+        $(e).html(content);
+        assertEquals(expected, $("div", e).children(".selected").toString());
+
+        // contains()
+        content = "<p>This is just a test.</p><p>So is this</p>";
+        expected = "<p>This is just a test.</p>";
+        $(e).html(content);
+        assertEquals(expected, $("p", e).contains("test").toString());
+    }
+
+    public void testModifyMethods() {
+        String p_txt = "<p>I would like to say: </p>";
+        String b_txt = "<b>Hello</b>";
+
+        // append()
+        String expected = "<p>I would like to say: <b>Hello</b></p>";
+        $(e).html(p_txt);
+        $("p", e).append(b_txt);
+        assertEquals(expected, $(e).html());
+
+        // appendTo()
+        expected = "<p>I would like to say: <b>Hello</b></p>";
+        $(e).html(b_txt + p_txt);
+        $("b", e).appendTo($("p", e));
+        assertEquals(expected, $(e).html());
+
+        // prepend()
+        expected = "<p><b>Hello</b>I would like to say: </p>";
+        $(e).html(p_txt);
+        $("p", e).prepend(b_txt);
+        assertEquals(expected, $(e).html());
+
+        // prependTo()
+        expected = "<p><b>Hello</b>I would like to say: </p>";
+        $(e).html(b_txt + p_txt);
+        $("b", e).prependTo($("p", e));
+        assertEquals(expected, $(e).html());
+
+        // prependTo()
+        expected = "<b>Hello</b><p><b>Hello</b>I would like to say: </p>";
+        $(e).html(b_txt + p_txt);
+        $("b", e).clone().prependTo($("p", e));
+        assertEquals(expected, $(e).html());
+
+        // before()
+        expected = "<b>Hello</b><p>I would like to say: </p>";
+        $(e).html(p_txt);
+        $("p", e).before(b_txt);
+        assertEquals(expected, $(e).html());
+
+        // before()
+        expected = "<b>Hello</b><p>I would like to say: </p>";
+        $(e).html(p_txt + b_txt);
+        $("p", e).before($("b", e));
+        assertEquals(expected, $(e).html());
+
+        // before()
+        expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+        $(e).html(p_txt + b_txt);
+        $("p", e).before($("b", e).clone());
+        assertEquals(expected, $(e).html());
+
+        // insertBefore()
+        expected = "<b>Hello</b><p>I would like to say: </p>";
+        $(e).html(p_txt + b_txt);
+        $("b", e).insertBefore($("p", e));
+        assertEquals(expected, $(e).html());
+
+        // insertBefore()
+        expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+        $(e).html(p_txt + b_txt);
+        $("b", e).clone().insertBefore($("p", e));
+        assertEquals(expected, $(e).html());
+
+        // after()
+        expected = "<p>I would like to say: </p><b>Hello</b>";
+        $(e).html(p_txt);
+        $("p", e).after(b_txt);
+        assertEquals(expected, testPanel.getHTML());
+
+        // after()
+        expected = "<p>I would like to say: </p><b>Hello</b>";
+        $(e).html(b_txt + p_txt);
+        $("p", e).after($("b", e));
+        assertEquals(expected, $(e).html());
+
+        // after()
+        expected = "<b>Hello</b><p>I would like to say: </p><b>Hello</b>";
+        $(e).html(b_txt + p_txt);
+        $("p", e).after($("b", e).clone());
+        assertEquals(expected, $(e).html());
+    }
+
+    public void testWrapMethod() {
+        String content = "<p>Test Paragraph.</p><div id=\"content\">Content</div>";
+
+        String expected = "<div id=\"content\">Content<p>Test Paragraph.</p></div>";
+        $(e).html(content);
+
+        $("p", e).wrap($("div", e).get(0));
+        assertEquals(expected, $(e).html());
+
+        expected = "<b><p>Test Paragraph.</p></b><b><div id=\"content\">Content</div></b>";
+        $(e).html(content);
+        $("*", e).wrap("<b></b>");
+        assertEquals(expected, $(e).html());
+    }
+
+    public void testInputValueMethods() {
+        // imput text
+        $(e).html("<input type='text'/>");
+        GQuery gq = $("input", e);
+        assertEquals("", gq.val());
+        gq.val("some value");
+        assertEquals("some value", gq.val());
+        
+        // select
+        $(e).html("<select name='n'><option value='v1'>1</option><option value='v2' selected='selected'>2</option></select>");
+        gq = $("select", e);
+        assertEquals("v2", gq.val());
+        gq.val("v1");
+        assertEquals("v1", gq.val());
+        
+        // select multiple
+        $(e).html("<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2' selected='selected'>2</option><option value='v3'>3</option></select>");
+        gq = $("select", e);
+        gq.val("v1","v3","invalid");
+        assertEquals(2, gq.vals().length);
+        assertEquals("v1", gq.vals()[0]);
+        assertEquals("v3", gq.vals()[1]);
+        gq.val("v1");
+        assertEquals(1, gq.vals().length);
+        assertEquals("v1", gq.val());
+
+        // input radio
+        $(e).html("<input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input>");
+        gq = $("input", e);
+        assertEquals("v2", gq.val());
+        gq.val("v1");
+        assertEquals("v1", gq.val());
+        gq.val("v2");
+        assertEquals("v2", gq.val());
+        
+        // input checkbox
+        $(e).html("<input type='checkbox' name='n1' value='v1'>1</input><input type='checkbox' name='n2' value='v2' checked='checked'>2</input>");
+        gq = $("input", e);
+        assertEquals("", gq.val());
+        gq.val("v1");
+        assertEquals("v1", gq.val());
+    }
+
+    public void testEventsPlugin() {
+        $(e).html("<p>Content</p>");
+
+        // click
+        $("p", e).click(new Function() {
+            public void f(Element elem) {
+                $(elem).css("color", "red");
+            }
+        });
+        $("p", e).trigger(Event.ONCLICK);
+        assertEquals("red", $("p", e).css("color"));
+
+        // unbind
+        $("p", e).css("color", "");
+        $("p", e).unbind(Event.ONCLICK);
+        $("p", e).trigger(Event.ONCLICK);
+        assertEquals("rgb(0, 0, 0)", $("p", e).css("color"));
+
+        // one
+        $("p", e).one(Event.ONCLICK, null, new Function() {
+            public void f(Element elem) {
+                $(elem).css("color", "red");
+            }
+        });
+        $("p", e).trigger(Event.ONCLICK);
+        assertEquals("red", $("p", e).css("color"));
+        $("p", e).css("color", "");
+        $("p", e).trigger(Event.ONCLICK);
+        assertEquals("rgb(0, 0, 0)", $("p", e).css("color"));
+
+        // hover (mouseover, mouseout)
+        $("p", e).hover(new Function() {
+            public void f(Element elem) {
+                $(elem).css("background-color", "yellow");
+            }
+        }, new Function() {
+            public void f(Element elem) {
+                $(elem).css("background-color", "");
+            }
+        });
+        $("p", e).trigger(Event.ONMOUSEOVER);
+        assertEquals("yellow", $("p", e).css("background-color"));
+        $("p", e).trigger(Event.ONMOUSEOUT);
+        assertEquals("rgba(0, 0, 0, 0)", $("p", e).css("background-color"));
+
+        // focus
+        $("p", e).focus(new Function() {
+            public void f(Element elem) {
+                $(elem).css("border", "1px dotted black");
+            }
+        });
+        $("p", e).trigger(Event.ONFOCUS);
+        assertEquals("1px dotted black", $("p", e).css("border"));
+
+        // blur
+        $("p", e).blur(new Function() {
+            public void f(Element elem) {
+                $(elem).css("border", "");
+            }
+        });
+        $("p", e).trigger(Event.ONBLUR);
+        assertEquals("", $("p", e).css("border"));
+
+        // keypressed
+        $(e).html("<input type='text'/>");
+        $("input", e).keypressed(new Function() {
+            public boolean f(Event evnt) {
+                Element elem = evnt.getCurrentTarget();
+                InputElement input = InputElement.as(elem);
+                input.setValue(input.getValue() + Character.toString((char) evnt.getKeyCode()));
+                return false;
+            }
+        });
+        $("input", e).trigger(Event.ONFOCUS);
+        $("input", e).trigger(Event.ONKEYPRESS, 'a');
+        assertEquals("a", InputElement.as($("input", e).get(0)).getValue());
+
+    }
+
+    public void testEffectsPlugin() {
+        $(e).html("<p id='id1'>Content 1</p><p id='id2'>Content 2</p><p id='id3'>Content 3</p>");
+
+        final GQuery sect_a = $("#id1");
+        final GQuery sect_b = $("#id2");
+        final GQuery sect_c = $("#id3");
+        
+         // hide()
+        sect_a.hide();
+        assertEquals("none", sect_a.css("display"));
+
+        // show()
+        sect_b.show();
+        assertEquals("", sect_b.css("display"));
+
+        // toggle()
+        assertEquals("", sect_c.css("display"));
+        sect_c.toggle();
+        assertEquals("none", sect_c.css("display"));
+        sect_c.toggle();
+        assertEquals("", sect_c.css("display"));
+
+        // fadeIn() & fadeOut() are tested with delayed assertions
+        sect_a.fadeIn(2000);
+        sect_b.fadeOut(2000);
+        
+        // Configure the max duration for this test
+        // If the test exceeds the timeout without calling finishTest() it will fail
+        delayTestFinish(2500);
+        
+        // Delayed assertions at different intervals
+        Timer timer_shortTime = new Timer() {
+            public void run() {
+                double o = Double.valueOf(sect_a.css("opacity"));
+                assertTrue(o > 0 && o < 0.5);
+                o = Double.valueOf(sect_b.css("opacity"));
+                assertTrue(o > 0.5 && o < 1);
+            }
+        };
+        Timer timer_midTime = new Timer() {
+            public void run() {
+                assertEquals("", sect_a.css("display"));
+                assertEquals("", sect_b.css("display"));
+                double o = Double.valueOf(sect_a.css("opacity"));
+                assertTrue(o > 0.5 && o < 1);
+                o = Double.valueOf(sect_b.css("opacity"));
+                assertTrue(o > 0 && o < 0.5);
+            }
+        };
+        Timer timer_longTime = new Timer() {
+            public void run() {
+                assertEquals("", sect_a.css("display"));
+                assertEquals("none", sect_b.css("display"));
+                // Last delayed assertion has to stop the test to avoid a timeout failure
+                finishTest();
+            }
+        };
+        // schedule the delayed assertions
+        timer_shortTime.schedule(200);
+        timer_midTime.schedule(1200);
+        timer_longTime.schedule(2200);
+
+   }
+
+}
diff --git a/gwtquery-core/src/test/java/gwtquery/client/GwtQueryCoreTest.java b/gwtquery-core/src/test/java/gwtquery/client/GwtQueryCoreTest.java
deleted file mode 100644 (file)
index c65724b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package gwtquery.client;
-
-import com.google.gwt.junit.client.GWTTestCase;
-
-/**
- *
- */
-public class GwtQueryCoreTest extends GWTTestCase {
-
-  public String getModuleName() {
-    return "gwtquery.GwtQuery";
-  }
-}
diff --git a/pom.xml b/pom.xml
index 3ef7bbc1c937b65940b31519f05dadea336c9a5f..5b0483558bc465f2e87c4db89ef54b8911162de4 100644 (file)
--- a/pom.xml
+++ b/pom.xml
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>gwtquery</groupId>
-  <artifactId>gwtquery-project</artifactId>
-  <packaging>pom</packaging>
-  <version>1.0-SNAPSHOT</version>
-  <name>GwtQuery Project</name>
-  <url>http://gwtquery.com</url>
-  <description>GwtQuery is a jQuery clone written in GWT.</description>
-  <issueManagement>
-    <system>Google Code</system>
-    <url>http://code.google.com/p/gwtquery/issues/list</url>
-  </issueManagement>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.google.gwt</groupId>
+    <artifactId>gwtquery-project</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0-SNAPSHOT</version>
+    <name>Gwt Query Project</name>
+    <url>http://gwtquery.com</url>
+    <description>GwtQuery is a jQuery clone written in GWT.</description>
+    <issueManagement>
+        <system>Google Code</system>
+        <url>http://code.google.com/p/gwtquery/issues/list</url>
+    </issueManagement>
 
-  <developers>
-    <developer>
-      <id>ray</id>
-      <name>Ray Cromwell</name>
-      <email>ray@timefire.com</email>
-      <roles>
-        <role>Project Manager</role>
-        <role>Architect</role>
-      </roles>
-      <organization>Timepedia.org</organization>
-      <timezone>-8</timezone>
-    </developer>
-  </developers>
+    <developers>
+        <developer>
+            <id>ray</id>
+            <name>Ray Cromwell</name>
+            <email>ray@timefire.com</email>
+            <roles>
+                <role>Project Manager</role>
+                <role>Architect</role>
+            </roles>
+            <organization>Timefire.com</organization>
+            <timezone>-8</timezone>
+        </developer>
+    </developers>
 
-  <scm>
-    <connection>scm:svn:http://gwtquery.googlecode.com/svn/trunk</connection>
-    <developerConnection>scm:svn:https://gwtquery.googlecode.com/svn/trunk</developerConnection>
-    <url>http://code.google.com/p/gwtquery/source/browse/trunk</url>
-  </scm>
+    <scm>
+        <connection>scm:svn:http://gwtquery.googlecode.com/svn/trunk
+        </connection>
+        <developerConnection>scm:svn:https://gwtquery.googlecode.com/svn/trunk
+        </developerConnection>
+        <url>http://code.google.com/p/gwtquery/source/browse/trunk</url>
+    </scm>
 
-  <modules>
-    <module>gwtquery-core</module>
-    <module>samples</module> 
-  </modules>
+    <modules>
+        <module>gwtquery-core</module>
+        <module>samples</module>
+    </modules>
 
-   <distributionManagement>
-    <repository>
-      <uniqueVersion>false</uniqueVersion>
+    <distributionManagement>
+        <repository>
+            <uniqueVersion>false</uniqueVersion>
             <id>timepedia-deploy</id>
             <url>svn:https://gwt-chronoscope.googlecode.com/svn/mavenrepo/</url>
-    </repository>
-  </distributionManagement>
+        </repository>
+    </distributionManagement>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-release-plugin</artifactId>
-        <configuration>
-          <tagBase>
-            https://gwtquery.googlecode.com/svn/tags
-          </tagBase>
-           <preparationGoals>clean install</preparationGoals>        
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>1.5</source>
-          <target>1.5</target>
-        </configuration>
-      </plugin>
-    </plugins>
-    <extensions>
-      <extension>
-        <groupId>org.jvnet.wagon-svn</groupId>
-        <artifactId>wagon-svn</artifactId>
-        <version>1.8</version>
-      </extension>
-    </extensions>
-  </build>
-  <reporting>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>changelog-maven-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jxr-plugin</artifactId>
-        <configuration>
-          <aggregate>true</aggregate>
-        </configuration>
-      </plugin>
-    </plugins>
-  </reporting>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <configuration>
+                    <tagBase>
+                        https://gwtquery.googlecode.com/svn/tags
+                    </tagBase>
+                    <preparationGoals>clean install</preparationGoals>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+        </plugins>
+        <extensions>
+            <extension>
+                <groupId>org.jvnet.wagon-svn</groupId>
+                <artifactId>wagon-svn</artifactId>
+                <version>1.8</version>
+            </extension>
+        </extensions>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>changelog-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
 
-  <pluginRepositories>
-    <pluginRepository>
-      <id>gwt-maven</id>
-      <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
-    </pluginRepository>
-  </pluginRepositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>gwt-maven</id>
+            <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+        </pluginRepository>
+    </pluginRepositories>
 
-  <repositories>
-    <repository>
-      <id>gwt-maven</id>
-      <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
-    </repository>
-    <repository>
-      <id>timepedia</id>
-      <url>http://gwt-chronoscope.googlecode.com/svn/mavenrepo/</url>
-    </repository>
-    <repository>
-      <id>maven2-repository.dev.java.net</id>
-      <name>Java.net Repository for Maven</name>
-      <url>http://download.java.net/maven/2/</url>
-    </repository>
-  </repositories>
+    <repositories>
+        <repository>
+            <id>gwt-maven</id>
+            <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+        </repository>
+        <repository>
+            <id>timepedia</id>
+            <url>http://gwt-chronoscope.googlecode.com/svn/mavenrepo/</url>
+        </repository>
+        <repository>
+            <id>maven2-repository.dev.java.net</id>
+            <name>Java.net Repository for Maven</name>
+            <url>http://download.java.net/maven/2/</url>
+        </repository>
+    </repositories>
 
-  <profiles>
-    <profile>
-      <id>default</id>
-      <activation>
-        <jdk>1</jdk>
-      </activation>
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <jdk>1</jdk>
+            </activation>
 
-      <properties>
-        <gwtversion>1.6.4</gwtversion>
-        <!--           <maven.test.skip>true</maven.test.skip> -->
-      </properties>
-    </profile>
+            <properties>
+                <gwtversion>1.6.4</gwtversion>
+            </properties>
+        </profile>
 
 
-    <profile>
-      <id>linux</id>
-      <activation>
-        <os>
-          <name>linux</name>
-        </os>
-      </activation>
-      <properties>
-        <gwtplatform>linux</gwtplatform>
-      </properties>
-    </profile>
+        <profile>
+            <id>linux</id>
+            <activation>
+                <os>
+                    <name>linux</name>
+                </os>
+            </activation>
+            <properties>
+                <gwtplatform>linux</gwtplatform>
+            </properties>
+        </profile>
 
-      <profile>
-      <id>windows</id>
-      <activation>
-        <os>
-          <family>windows</family>
-        </os>
-      </activation>
-      <properties>
-        <gwtplatform>windows</gwtplatform>
-      </properties>
-    </profile>
+        <profile>
+            <id>windows</id>
+            <activation>
+                <os>
+                    <family>windows</family>
+                </os>
+            </activation>
+            <properties>
+                <gwtplatform>windows</gwtplatform>
+            </properties>
+        </profile>
 
-    <profile>
-      <id>macosx</id>
-      <activation>
-        <os>
-          <name>mac os x</name>
-        </os>
-      </activation>
-      <properties>
-        <gwtplatform>mac</gwtplatform>
-        <!--                <google.webtoolkit.extrajvmargs>-XstartOnFirstThread</google.webtoolkit.extrajvmargs> -->
-        <google.webtoolkit.extrajvmargs>-Xmx512m -XstartOnFirstThread</google.webtoolkit.extrajvmargs>
-      </properties>
-    </profile>
+        <profile>
+            <id>macosx</id>
+            <activation>
+                <os>
+                    <name>mac os x</name>
+                </os>
+            </activation>
+            <properties>
+                <gwtplatform>mac</gwtplatform>
+                <google.webtoolkit.extrajvmargs>-Xmx512m -XstartOnFirstThread
+                </google.webtoolkit.extrajvmargs>
+            </properties>
+        </profile>
 
-  </profiles>
+    </profiles>
 </project>
index a5420be10bd00a4125b50503fef2a8a45143178e..4813f3ae2eac2a878fea26dc5cf9fa513eefe093 100644 (file)
@@ -1,7 +1,7 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>gwtquery</groupId>
+    <groupId>com.google.gwt</groupId>
     <artifactId>gwtquery-project</artifactId>
     <version>1.0-SNAPSHOT</version>
   </parent>
index 29bddbeb4a50edeb5044c254fd264187e1c9e18e..6ddf66909ed3e7deb35382329ebb7386c812b046 100644 (file)
@@ -6,8 +6,9 @@ import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;\r
 import com.google.gwt.user.client.DeferredCommand;\r
 import com.google.gwt.user.client.IncrementalCommand;\r
-import gwtquery.client.*;\r
-import static gwtquery.client.GQuery.$;\r
+import com.google.gwt.query.client.DeferredGQuery;\r
+import com.google.gwt.query.client.SelectorEngine;\r
+import static com.google.gwt.query.client.GQuery.$;\r
    \r
 public class GwtQueryBenchModule implements EntryPoint {\r
 \r
index 2cc8fa273aad7a8dcbef99f9c78d85bce8ddca0f..3753c25c795c456eb5484512080a4a4381cf9540 100644 (file)
@@ -7,10 +7,13 @@ import com.google.gwt.dom.client.NodeList;
 import com.google.gwt.dom.client.Document;\r
 import com.google.gwt.dom.client.Node;\r
 import com.google.gwt.user.client.Event;\r
+import com.google.gwt.query.client.GQuery;\r
+import com.google.gwt.query.client.Selector;\r
+import com.google.gwt.query.client.Function;\r
+import com.google.gwt.query.client.Selectors;\r
 \r
-import static gwtquery.client.GQuery.$;\r
-import static gwtquery.client.Effects.Effects;\r
-import gwtquery.client.*;\r
+import static com.google.gwt.query.client.GQuery.$;\r
+import static com.google.gwt.query.client.Effects.Effects;\r
 \r
 /**\r
  * \r
index 23869aa52c4ca8901be4dfe5548ed5ad2d67f4e7..98ab6e4300fbaf355bdee241c182ed787b345b26 100644 (file)
@@ -2,6 +2,7 @@ package gwtquery.samples.client;
 \r
 import com.google.gwt.core.client.EntryPoint;\r
 import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.JavaScriptObject;\r
 import com.google.gwt.dom.client.Element;\r
 import com.google.gwt.user.client.Window;\r
 import gwtquery.client.*;\r
@@ -21,12 +22,32 @@ import gwtquery.client.*;
  * @author Ray Cromwell <ray@timepedia.log>\r
  */\r
 public class GwtQuerySampleModule implements EntryPoint {\r
-    public interface Sample extends Selectors {\r
-      @Selector(".note")\r
-      GQuery allNotes();\r
-    }\r
+//    public interface Sample extends Selectors {\r
+//      @Selector(".note")\r
+//      GQuery allNotes();\r
+//    }\r
     public void onModuleLoad() {\r
-       Sample s = GWT.create(Sample.class);\r
-       s.allNotes().html("This was a note");\r
+      Window.alert(Builder.newInstance().setFoo("Hello").setBar("World").setBaz("!").toString());\r
+    }\r
+  \r
+  static final class Builder extends JavaScriptObject {\r
+    protected Builder() {}\r
+    public static Builder newInstance() {\r
+      return createObject().cast();\r
     }\r
+    \r
+    public native Builder setFoo(String x) /*-{\r
+      return x=this.foo=x, this;\r
+    }-*/;\r
+    \r
+    public native Builder setBar(String x) /*-{\r
+      this.bar = x;\r
+      return this;\r
+    }-*/;\r
+    \r
+     public native Builder setBaz(String x) /*-{\r
+      this.baz = x;\r
+      return this;\r
+    }-*/;\r
+  }\r
 }\r
index 5cb634a4bc2991834c6ff8d739cdb00acdb18741..ff0424d2d6c94284b5273f6259b28f00f2790920 100644 (file)
@@ -2,7 +2,8 @@ package gwtquery.samples.client;
 
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NodeList;
-import gwtquery.client.*;
+import com.google.gwt.query.client.Selector;
+import com.google.gwt.query.client.Selectors;
 
 /**
 */