From ba2b023d7c2786c9d3a78635fffc58f48e889e9b Mon Sep 17 00:00:00 2001 From: Ray Cromwell Date: Wed, 22 Apr 2009 23:27:30 +0000 Subject: interrim commit --- .../src/main/java/gwtquery/GwtQuery.gwt.xml | 19 +- gwtquery-core/src/main/java/gwtquery/client/$.java | 81 +++ .../src/main/java/gwtquery/client/Function.java | 4 + .../src/main/java/gwtquery/client/GQuery.java | 685 ++++++++++++++++++++- .../src/main/java/gwtquery/client/Predicate.java | 10 + .../main/java/gwtquery/client/SelectorEngine.java | 78 +-- .../gwtquery/client/impl/DocumentStyleImpl.java | 41 ++ .../gwtquery/client/impl/DocumentStyleImplIE.java | 57 ++ 8 files changed, 930 insertions(+), 45 deletions(-) create mode 100644 gwtquery-core/src/main/java/gwtquery/client/$.java create mode 100644 gwtquery-core/src/main/java/gwtquery/client/Predicate.java create mode 100644 gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java create mode 100644 gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java (limited to 'gwtquery-core/src/main/java') diff --git a/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml b/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml index aa236dfb..8cfabdb0 100644 --- a/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml +++ b/gwtquery-core/src/main/java/gwtquery/GwtQuery.gwt.xml @@ -19,7 +19,7 @@ - + @@ -40,8 +40,8 @@ - - + + @@ -61,6 +61,17 @@ + + + + + + + + + + + @@ -91,4 +102,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/gwtquery-core/src/main/java/gwtquery/client/$.java b/gwtquery-core/src/main/java/gwtquery/client/$.java new file mode 100644 index 00000000..273c951c --- /dev/null +++ b/gwtquery-core/src/main/java/gwtquery/client/$.java @@ -0,0 +1,81 @@ +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 $(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 $(String selector, Class 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 GQuery $(String selector, Node context, + Class plugin) { + return GQuery.$(selector, context, plugin); + } + + /** + * Wrap a GQuery around existing Elements. + */ + public static GQuery $(NodeList 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 plugin, + Plugin pluginFactory) { + GQuery.registerPlugin(plugin, pluginFactory); + } +} diff --git a/gwtquery-core/src/main/java/gwtquery/client/Function.java b/gwtquery-core/src/main/java/gwtquery/client/Function.java index a30bd8ea..f9d70a4f 100644 --- a/gwtquery-core/src/main/java/gwtquery/client/Function.java +++ b/gwtquery-core/src/main/java/gwtquery/client/Function.java @@ -8,6 +8,10 @@ import com.google.gwt.user.client.Event; */ public abstract class Function { + public String f(Element e, int i) { + return ""; + } + public void f(Element e) { } diff --git a/gwtquery-core/src/main/java/gwtquery/client/GQuery.java b/gwtquery-core/src/main/java/gwtquery/client/GQuery.java index 1fa9bba3..e5598598 100644 --- a/gwtquery-core/src/main/java/gwtquery/client/GQuery.java +++ b/gwtquery-core/src/main/java/gwtquery/client/GQuery.java @@ -1,14 +1,17 @@ package gwtquery.client; import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.ButtonElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.InputElement; +import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.OptionElement; import com.google.gwt.dom.client.SelectElement; +import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.TextAreaElement; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -17,6 +20,8 @@ import com.google.gwt.user.client.EventListener; import java.util.HashMap; import java.util.Map; +import gwtquery.client.impl.DocumentStyleImpl; + /** * */ @@ -34,8 +39,144 @@ public class GQuery { } } + private static class DataCache extends JavaScriptObject { + + protected DataCache() { + } + + public native void delete(String name) /*-{ + delete this[name]; + }-*/; + + public native void delete(int name) /*-{ + delete this[name]; + }-*/; + + public native boolean exists(int id) /*-{ + return !!this[id]; + }-*/; + + public native JavaScriptObject get(String id) /*-{ + return this[id]; + }-*/; + + public native JavaScriptObject get(int id) /*-{ + return this[id]; + }-*/; /*-{ + delete this[name]; + }-*/ + + public DataCache getCache(int id) { + return get(id).cast(); + } + + public native double getDouble(String id) /*-{ + return this[id]; + }-*/; + + public native double getDouble(int id) /*-{ + return this[id]; + }-*/; + + public native int getInt(String id) /*-{ + return this[id]; + }-*/; + + public native int getInt(int id) /*-{ + return this[id]; + }-*/; + + public native String getString(String id) /*-{ + return this[id]; + }-*/; + + public native String getString(int id) /*-{ + return this[id]; + }-*/; + + public native boolean isEmpty() /*-{ + var foo = ""; + for(foo in this) break; + return !foo; + }-*/; + + public native void put(String id, Object obj) /*-{ + return this[id]=obj; + }-*/; + + public native void put(int id, Object obj) /*-{ + return this[id]=obj; + }-*/; + } + + private static class FastSet extends JavaScriptObject { + + public static FastSet create() { + return JavaScriptObject.createObject().cast(); + } + + protected FastSet() { + } + + public void add(Object o) { + add0(o.hashCode()); + } + + public boolean contains(Object o) { + return contains0(o.hashCode()); + } + + public void remove(Object o) { + remove0(o.hashCode()); + } + + private native void add0(int hc) /*-{ + this[hc]=true; + }-*/; + + private native boolean contains0(int hc) /*-{ + return this[hc]; + }-*/; + + private native void remove0(int hc) /*-{ + delete this[hc]; + }-*/; + } + + private static class Queue extends JavaScriptObject { + + public static Queue newInstance() { + return createArray().cast(); + } + + protected Queue() { + } + + public native T dequeue() /*-{ + return this.shift(); + }-*/; + + public native void enqueue(T foo) /*-{ + this.push(foo); + }-*/; + + public native int length() /*-{ + return this.length; + }-*/; + + public native T peek(int i) /*-{ + return this[i]; + }-*/; + } + private static Map, Plugin> plugins; + private static Element windowData = null; + + private static DataCache dataCache = null; + + private static DocumentStyleImpl styleImpl; + /** * 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 @@ -49,6 +190,7 @@ public class GQuery { } public static T $(T gq) { + return gq; } @@ -216,6 +358,14 @@ public class GQuery { protected NodeList elements = null; + private String selector; + + private GQuery previousObject; + + public GQuery() { + elements = JavaScriptObject.createArray().cast(); + } + public GQuery(NodeList list) { elements = list; } @@ -250,10 +400,19 @@ public class GQuery { throw new RuntimeException("No plugin registered for class " + plugin); } + /** + * Access a property on the first matched element. This method makes it easy + * to retrieve a property value from the first matched element. If the element + * does not have an attribute with such a name, undefined is returned. + * Attributes include title, alt, src, href, width, style, etc. + */ public String attr(String name) { return elements.getItem(0).getAttribute(name); } + /** + * Set a single property to a value, on all matched elements. + */ public GQuery attr(String key, String value) { for (Element e : elements()) { e.setAttribute(key, value); @@ -261,6 +420,9 @@ public class GQuery { return this; } + /** + * Set a key/value object as properties to all matched elements. + */ public GQuery attr(Properties properties) { for (Element e : elements()) { for (String name : properties.keys()) { @@ -270,6 +432,21 @@ public class GQuery { return this; } + /** + * Set a single property to a computed value, on all matched elements. + */ + public GQuery attr(String key, Function closure) { + for (int i = 0; i < elements.getLength(); i++) { + Element e = elements.getItem(i); + e.setAttribute(key, closure.f(e, i)); + } + return this; + } + + /** + * Binds a handler to one or more events (like click) for each matched + * element. + */ public GQuery bind(int eventbits, final Object data, final Function f) { EventListener listener = new EventListener() { public void onBrowserEvent(Event event) { @@ -290,18 +467,62 @@ public class GQuery { return bind(Event.ONBLUR, null, f); } + public GQuery blur() { + return trigger(Document.get().createBlurEvent(), null); + } + public GQuery change(Function f) { return bind(Event.ONCHANGE, null, f); } + public GQuery change() { + return trigger(Document.get().createChangeEvent(), null); + } + + /** + * Get a set of elements containing all of the unique immediate children of + * each of the matched set of elements. Also note: while parents() will look + * at all ancestors, children() will only consider immediate child elements. + */ + public GQuery children() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + allNextSiblingElements(e.getFirstChildElement(), result); + } + return new GQuery(unique(result)); + } + + public GQuery click() { + return trigger( + Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false, + false), null); + } + + /** + * Triggers the click event of each matched element. Causes all of the + * functions that have been bound to that click event to be executed. + */ public GQuery click(final Function f) { return bind(Event.ONCLICK, null, f); } + /** + * Return a style property on the first matched element. + */ public String css(String name) { return elements.getItem(0).getStyle().getProperty(name); } + /** + * Set a key/value object as style properties to all matched elements. This is + * the best way to set several style properties on all matched elements. Be + * aware, however, that when the key contains a hyphen, such as + * "background-color," it must either be placed within quotation marks or be + * written in camel case like so: backgroundColor. As "float" and "class" are + * reserved words in JavaScript, it's recommended to always surround those + * terms with quotes. gQuery normalizes the "opacity" property in Internet + * Explorer. + */ public GQuery css(Properties properties) { for (String property : properties.keys()) { css(property, properties.get(property)); @@ -309,6 +530,10 @@ public class GQuery { return this; } + /** + * Set a single style property to a value on all matched elements. If a number + * is provided, it is automatically converted into a pixel value. + */ public GQuery css(String prop, String val) { for (Element e : elements()) { e.getStyle().setProperty(prop, val); @@ -316,10 +541,60 @@ public class GQuery { return this; } + /** + * Returns value at named data store for the element, as set by data(name, + * value). + */ + public Object data(String name) { + return data(elements.getItem(0), name, null); + } + + /** + * Returns value at named data store for the element, as set by data(name, + * value) with desired return type. + * + * @param clz return type class literal + */ + public T data(String name, Class clz) { + return (T) data(elements.getItem(0), name, null); + } + + /** + * Stores the value in the named spot with desired return type. + */ + public void data(String name, String value) { + for (Element e : elements()) { + data(e, name, value); + } + } + + public GQuery dblclick() { + return trigger( + Document.get().createDblClickEvent(0, 0, 0, 0, 0, false, false, false, + false), null); + } + public GQuery dblclick(Function f) { return bind(Event.ONDBLCLICK, null, f); } + /** + * Removes a queued function from the front of the queue and executes it. + */ + public GQuery dequeue(String type) { + for (Element e : elements()) { + dequeue(e, type); + } + return this; + } + + /** + * Removes a queued function from the front of the FX queue and executes it. + */ + public GQuery dequeue() { + return dequeue("__FX"); + } + /** * Run one or more Functions over each element of the GQuery. */ @@ -340,6 +615,14 @@ public class GQuery { return asArray(elements); } + /** + * Revert the most recent 'destructive' operation, changing the set of matched + * elements to its previous state (right before the destructive operation). + */ + public GQuery end() { + return previousObject != null ? previousObject : new GQuery(); + } + /** * Reduce GQuery to element in the specified position. */ @@ -347,10 +630,35 @@ public class GQuery { return $(elements.getItem(pos)); } + public GQuery error() { + return trigger(Document.get().createErrorEvent(), null); + } + public GQuery error(Function f) { return bind(Event.ONERROR, null, f); } + /** + * Removes all elements from the set of matched elements that do not match the + * specified function. The function is called with a context equal to the + * current element. If the function returns false, then the element is removed + * - anything else and the element is kept. + */ + public GQuery filter(Predicate filterFn) { + JSArray result = JSArray.create(); + for (int i = 0; i < elements.getLength(); i++) { + Element e = elements.getItem(i); + if (filterFn.f(e, i)) { + result.addNode(e); + } + } + return pushStack(result, "filter", selector); + } + + public GQuery focus() { + return trigger(Document.get().createFocusEvent(), null); + } + public GQuery focus(Function f) { return bind(Event.ONFOCUS, null, f); } @@ -370,6 +678,14 @@ public class GQuery { return elements.getItem(i); } + public GQuery getPreviousObject() { + return previousObject; + } + + public String getSelector() { + return selector; + } + /** * Returns true any of the specified classes are present on any of the matched * elements. @@ -424,14 +740,32 @@ public class GQuery { return -1; } + public GQuery keydown() { + return trigger( + Document.get().createKeyDownEvent(false, false, false, false, 0, 0), + null); + } + public GQuery keydown(Function f) { return bind(Event.ONKEYDOWN, null, f); } + public GQuery keypress() { + return trigger( + Document.get().createKeyPressEvent(false, false, false, false, 0, 0), + null); + } + public GQuery keypressed(Function f) { return bind(Event.ONKEYPRESS, null, f); } + public GQuery keyup() { + return trigger( + Document.get().createKeyUpEvent(false, false, false, false, 0, 0), + null); + } + public GQuery keyup(Function f) { return bind(Event.ONKEYUP, null, f); } @@ -460,10 +794,152 @@ public class GQuery { return bind(Event.ONMOUSEUP, null, f); } + /** + * Get a set of elements containing the unique next siblings of each of the + * given set of elements. next only returns the very next sibling for each + * element, not all next siblings see {#nextAll}. + */ + public GQuery next() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + Element next = e.getNextSiblingElement(); + if (next != null) { + result.addNode(next); + } + } + return new GQuery(unique(result)); + } + + /** + * Find all sibling elements after the current element. + */ + public GQuery nextAll() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + allNextSiblingElements(e.getNextSiblingElement(), result); + } + return new GQuery(unique(result)); + } + public Offset offset() { return new Offset(get(0).getOffsetLeft(), get(0).getOffsetTop()); } + /** + * Returns a jQuery collection with the positioned parent of the first matched + * element. This is the first parent of the element that has position (as in + * relative or absolute). This method only works with visible elements. + */ + public GQuery offsetParent() { + Element offParent = SelectorEngine + .or(elements.getItem(0).getOffsetParent(), Document.get().getBody()); + while (offParent != null && !"body".equalsIgnoreCase(offParent.getTagName()) + && !"html".equalsIgnoreCase(offParent.getTagName()) && "static" + .equals(curCSS(offParent, "position"))) { + offParent = offParent.getOffsetParent(); + } + return new GQuery(offParent); + } + + /** + * Get a set of elements containing the unique parents of the matched set of + * elements. + */ + public GQuery parent() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + result.addNode(e.getParentElement()); + } + return new GQuery(unique(result)); + } + + /** + * Get a set of elements containing the unique ancestors of the matched set of + * elements (except for the root element). + */ + public GQuery parents() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + Node par = e.getParentNode(); + while (par != null && par != Document.get()) { + result.addNode(par); + par = par.getParentNode(); + } + } + return new GQuery(unique(result)); + } + + /** + * Get a set of elements containing the unique previous siblings of each of + * the matched set of elements. Only the immediately previous sibling is + * returned, not all previous siblings. + */ + public GQuery prev() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + Element next = getPreviousSiblingElement(e); + if (next != null) { + result.addNode(next); + } + } + return new GQuery(unique(result)); + } + + /** + * Find all sibling elements in front of the current element. + */ + public GQuery prevAll() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + allPreviousSiblingElements(getPreviousSiblingElement(e), result); + } + return new GQuery(unique(result)); + } + + /** + * Returns a reference to the first element's queue (which is an array of + * functions). + */ + public Queue queue(String type) { + return queue(elements.getItem(0), type, null); + } + + /** + * Returns a reference to the FX queue. + */ + public Queue queue() { + return queue(elements.getItem(0), "__FX", null); + } + + /** + * Adds a new function, to be executed, onto the end of the queue of all + * matched elements. + */ + public GQuery queue(String type, Function data) { + for (Element e : elements()) { + queue(e, type, data); + } + return this; + } + + /** + * Replaces the current queue with the given queue on all matched elements. + */ + public GQuery queue(String type, Queue data) { + for (Element e : elements()) { + replacequeue(e, type, data); + } + return this; + } + + /** + * Adds a new function, to be executed, onto the end of the queue of all + * matched elements in the FX queue. + */ + public GQuery queue(Function data) { + return queue("__FX", data); + } + /** * Remove the named attribute from every element in the matched set. */ @@ -486,10 +962,46 @@ public class GQuery { return this; } + /** + * Removes named data store from an element. + */ + public GQuery removeData(String name) { + for (Element e : elements()) { + removeData(e, name); + } + return this; + } + public GQuery scroll(Function f) { return bind(Event.ONSCROLL, null, f); } + public GQuery select() { + return trigger(Document.get().createHtmlEvent("select", false, false), + null); + } + + public void setPreviousObject(GQuery previousObject) { + this.previousObject = previousObject; + } + + public void setSelector(String selector) { + this.selector = selector; + } + + /** + * Get a set of elements containing all of the unique siblings of each of the + * matched set of elements. + */ + public GQuery siblings() { + JSArray result = JSArray.create(); + for (Element e : elements()) { + allNextSiblingElements(e.getParentElement().getFirstChildElement(), + result); + } + return new GQuery(unique(result)); + } + /** * Return the number of elements in the matched set. */ @@ -497,6 +1009,9 @@ public class GQuery { return elements.getLength(); } + /** + * Selects a subset of the matched elements. + */ public GQuery slice(int start, int end) { JSArray slice = JSArray.create(); if (end == -1 || end > elements.getLength()) { @@ -508,6 +1023,11 @@ public class GQuery { return new GQuery(slice); } + public GQuery submit() { + return trigger(Document.get().createHtmlEvent("submit", false, false), + null); + } + /** * Return the text contained in the first matched element. */ @@ -541,6 +1061,33 @@ public class GQuery { return this; } + /** + * Adds or removes the specified classes to each matched element. + */ + public GQuery toggleClass(String clz, boolean sw) { + for (Element e : elements()) { + setStyleName(e, clz, sw); + } + return this; + } + + /** + * Remove all duplicate elements from an array of elements. Note that this + * only works on arrays of DOM elements, not strings or numbers. + */ + public JSArray unique(JSArray result) { + FastSet f = FastSet.create(); + JSArray ret = JSArray.create(); + for (int i = 0; i < result.getLength(); i++) { + Element e = result.getElement(i); + if (!f.contains(e)) { + f.add(e); + ret.addNode(e); + } + } + return ret; + } + /** * Get the content of the value attribute of the first matched element, * returns more than one value if it is a multiple select. @@ -621,9 +1168,143 @@ public class GQuery { return this; } + protected GQuery pushStack(JSArray elts, String name, String selector) { + GQuery g = new GQuery(elts); + g.setPreviousObject(this); + g.setSelector(selector); + return g; + } + + private void allNextSiblingElements(Element firstChildElement, + JSArray result) { + while (firstChildElement != null) { + result.addNode(firstChildElement); + firstChildElement = firstChildElement.getNextSiblingElement(); + } + } + + private void allPreviousSiblingElements(Element firstChildElement, + JSArray result) { + while (firstChildElement != null) { + result.addNode(firstChildElement); + firstChildElement = getPreviousSiblingElement(firstChildElement); + } + } + + private String curCSS(Element elem, String name) { + Style s = elem.getStyle(); + ensureStyleImpl(); + name = styleImpl.getPropertyName(name); + + if (SelectorEngine.truth(s.getProperty(name))) { + return s.getProperty(name); + } + return styleImpl.getCurrentStyle(elem, name); + } + + private Object data(Element item, String name, S value) { + if (dataCache == null) { + windowData = JavaScriptObject.createObject().cast(); + dataCache = JavaScriptObject.createObject().cast(); + } + item = item == window() ? windowData : item; + int id = item.hashCode(); + if (name != null && !dataCache.exists(id)) { + dataCache.put(id, DataCache.createObject().cast()); + } + + DataCache d = dataCache.get(id).cast(); + if (name != null && value != null) { + d.put(name, value); + } + return name != null ? value : id; + } + + private void dequeue(Element elem, String type) { + Queue q = queue(elem, type, null); + Function f = q.dequeue(); + + if (q != null) { + if (SelectorEngine.eq(type, "__FX")) { + f = q.peek(0); + } + if (f != null) { + f.f(elem); + } + } + } + + private void ensureStyleImpl() { + if (styleImpl != null) { + styleImpl = GWT.create(DocumentStyleImpl.class); + } + } + + private native Element getPreviousSiblingElement(Element elem) /*-{ + var sib = elem.previousSibling; + while (sib && sib.nodeType != 1) + sib = sib.previousSibling; + return sib; + }-*/; + private void init(GQuery gQuery) { this.elements = gQuery.elements; } - - + + private Queue queue(Element elem, String type, Function data) { + if (elem != null) { + type = type + "queue"; + Object q = (Queue) data(elem, type, null); + if (q == null) { + q = data(elem, type, Queue.newInstance()); + } + Queue qq = (Queue) q; + if (data != null) { + qq.enqueue(data); + } + if (SelectorEngine.eq(type, "__FX") && qq.length() == 1) { + data.f(elem); + } + return qq; + } + return null; + } + + private void removeData(Element item, String name) { + if (dataCache == null) { + windowData = JavaScriptObject.createObject().cast(); + dataCache = JavaScriptObject.createObject().cast(); + } + item = item == window() ? windowData : item; + int id = item.hashCode(); + if (name != null) { + if (!dataCache.exists(id)) { + dataCache.getCache(id).delete(name); + } + if (dataCache.getCache(id).isEmpty()) { + removeData(item, null); + } + } else { + dataCache.delete(id); + } + } + + private void replacequeue(Element elem, String type, Queue data) { + if (elem != null) { + type = type + "queue"; + Object q = (Queue) data(elem, type, null); + data(elem, type, data); + } + } + + private GQuery trigger(NativeEvent event, Object o) { + for (Element e : elements()) { + e.dispatchEvent(event); + } + return this; + } + + private native Element window() /*-{ + return $wnd; + }-*/; } diff --git a/gwtquery-core/src/main/java/gwtquery/client/Predicate.java b/gwtquery-core/src/main/java/gwtquery/client/Predicate.java new file mode 100644 index 00000000..feb7b644 --- /dev/null +++ b/gwtquery-core/src/main/java/gwtquery/client/Predicate.java @@ -0,0 +1,10 @@ +package gwtquery.client; + +import com.google.gwt.dom.client.Element; + +/** + * A predicate function used by some GQuery methods. + */ +public interface Predicate { + boolean f(Element e, int index); +} diff --git a/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java b/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java index 63c246ec..167a6758 100644 --- a/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java +++ b/gwtquery-core/src/main/java/gwtquery/client/SelectorEngine.java @@ -13,53 +13,53 @@ import gwtquery.client.impl.SelectorEngineImpl; * */ public class SelectorEngine { - private SelectorEngineImpl impl; + private SelectorEngineImpl impl; - public SelectorEngine() { - impl = (SelectorEngineImpl) GWT - .create(SelectorEngineImpl.class); - } + public SelectorEngine() { + impl = (SelectorEngineImpl) GWT.create(SelectorEngineImpl.class); + } - public static native boolean eq(String s1, String s2) /*-{ + public static native boolean eq(String s1, String s2) /*-{ return s1 == s2; }-*/; - public static native NodeList getElementsByClassName(String clazz, - Node ctx) /*-{ + public static native NodeList getElementsByClassName(String clazz, + Node ctx) /*-{ return ctx.getElementsByClassName(clazz); }-*/; - public static native String or(String s1, String s2) /*-{ + public static native T or(T s1, T s2) /*-{ return s1 || s2; }-*/; - public static native NodeList querySelectorAll(String selector) /*-{ + public static native NodeList querySelectorAll(String selector) /*-{ return $doc.querySelectorAll(selector); }-*/; - public static native NodeList querySelectorAll(String selector, - Node ctx) /*-{ + public static native NodeList querySelectorAll(String selector, + Node ctx) /*-{ return ctx.querySelectorAll(selector); }-*/; - public NodeList select(String selector, Node ctx) { - return impl.select(selector, ctx); - } - public static boolean truth(String a) { - return GWT.isScript() ? truth0(a) : a != null && !"".equals(a); - } + public NodeList select(String selector, Node ctx) { + return impl.select(selector, ctx); + } - public static boolean truth(JavaScriptObject a) { - return GWT.isScript() ? truth0(a) : a != null; - } + public static boolean truth(String a) { + return GWT.isScript() ? truth0(a) : a != null && !"".equals(a); + } - public static NodeList xpathEvaluate(String selector, Node ctx) { - return xpathEvaluate(selector, ctx, JSArray.create()); - } + public static boolean truth(JavaScriptObject a) { + return GWT.isScript() ? truth0(a) : a != null; + } + + public static NodeList xpathEvaluate(String selector, Node ctx) { + return xpathEvaluate(selector, ctx, JSArray.create()); + } - public static native NodeList xpathEvaluate(String selector, - Node ctx, JSArray r) /*-{ + public static native NodeList xpathEvaluate(String selector, + Node ctx, JSArray r) /*-{ var node; var result = $doc.evaluate(selector, ctx, null, 0, null); while ((node = result.iterateNext())) { @@ -68,30 +68,30 @@ public class SelectorEngine { return r; }-*/; - private static native boolean truth0(String a) /*-{ + private static native boolean truth0(String a) /*-{ return a; }-*/; - private static native boolean truth0(JavaScriptObject a) /*-{ + private static native boolean truth0(JavaScriptObject a) /*-{ return a; }-*/; - protected JSArray veryQuickId(Node context, String id) { - JSArray r = JSArray.create(); - if (context.getNodeType() == Node.DOCUMENT_NODE) { - r.addNode(((Document) context).getElementById(id)); - return r; - } else { - r.addNode(context.getOwnerDocument().getElementById(id)); - return r; - } + protected JSArray veryQuickId(Node context, String id) { + JSArray r = JSArray.create(); + if (context.getNodeType() == Node.DOCUMENT_NODE) { + r.addNode(((Document) context).getElementById(id)); + return r; + } else { + r.addNode(context.getOwnerDocument().getElementById(id)); + return r; } + } - public static native Node getNextSibling(Node n) /*-{ + public static native Node getNextSibling(Node n) /*-{ return n.nextSibling || null; }-*/; - public static native Node getPreviousSibling(Node n) /*-{ + public static native Node getPreviousSibling(Node n) /*-{ return n.previousSibling || null; }-*/; } diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java new file mode 100644 index 00000000..c61a88b9 --- /dev/null +++ b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImpl.java @@ -0,0 +1,41 @@ +package gwtquery.client.impl; + +import com.google.gwt.dom.client.Element; + +import gwtquery.client.SelectorEngine; + +/** + * + */ +public class DocumentStyleImpl { + + public String getPropertyName(String name) { + if ("float".equals(name)) { + return "cssFloat"; + } else if ("class".equals(name)) { + return "className"; + } else if ("for".equals(name)) { + return "htmlFor"; + } + return name; + } + + public String getCurrentStyle(Element elem, String name) { + name = hyphenize(name); + String propVal = getComputedStyle(elem, name, null); + if ("opacity".equals(name)) { + propVal = SelectorEngine.or(propVal, "1"); + } + return propVal; + } + + protected native String hyphenize(String name) /*-{ + return name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + }-*/; + + private native String getComputedStyle(Element elem, String name, + String pseudo) /*-{ + var cStyle = $doc.defaultView.getComputedStyle( elem, pseudo ); + return cStyle ? cStyle.getPropertyValue( name ) : null; + }-*/; +} diff --git a/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java new file mode 100644 index 00000000..b9d95bcb --- /dev/null +++ b/gwtquery-core/src/main/java/gwtquery/client/impl/DocumentStyleImplIE.java @@ -0,0 +1,57 @@ +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 -- cgit v1.2.3