<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>
--- /dev/null
+<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
--- /dev/null
+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);
+ }
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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);
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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;
+ }-*/;
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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);
+ }
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+++ /dev/null
-<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
+++ /dev/null
-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);
- }
-}
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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;
- }
-}
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-package gwtquery.client;\r
-\r
-/**\r
- * A GQuery plugin\r
- */\r
-public interface Plugin<T extends GQuery> {\r
- T init(GQuery gq);\r
-}\r
+++ /dev/null
-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);
-}
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-package gwtquery.client;\r
-\r
-/**\r
- */\r
-public interface Selectors {\r
- DeferredGQuery[] getAllSelectors();\r
-}\r
+++ /dev/null
-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;
- }-*/;
-}
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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);
- }
-}
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorJS;
-
-/**
- */
-public class SelectorGeneratorJSGEBCN extends SelectorGeneratorJS {
-
- protected boolean hasGetElementsByClassName() {
- return true;
- }
-}
+++ /dev/null
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorNative;
-
-/**
- *
- */
-public class SelectorGeneratorNativeGEBCN extends SelectorGeneratorNative {
-
- protected boolean hasGetElementsByClassName() {
- return true;
- }
-}
+++ /dev/null
-package gwtquery.rebind.gebcn;
-
-import gwtquery.rebind.SelectorGeneratorXPath;
-
-/**
- */
-public class SelectorGeneratorXPathGEBCN extends SelectorGeneratorXPath {
-
- protected boolean hasGetElementsByClassName() {
- return true;
- }
-}
--- /dev/null
+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);
+
+ }
+
+}
+++ /dev/null
-package gwtquery.client;
-
-import com.google.gwt.junit.client.GWTTestCase;
-
-/**
- *
- */
-public class GwtQueryCoreTest extends GWTTestCase {
-
- public String getModuleName() {
- return "gwtquery.GwtQuery";
- }
-}
-<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>
<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>
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
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
\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
* @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
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;
/**
*/