From: Manolo Carrasco Date: Mon, 19 Sep 2011 16:09:19 +0000 (+0000) Subject: Added GQ static class to house all static methods of the Api. It should be named... X-Git-Tag: release-1.3.2~200 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f30f1c4b15fd53a4d4b7e175bb11904698c46d58;p=gwtquery.git Added GQ static class to house all static methods of the Api. It should be named $, but gwt compiler fails when a class contains the dollar. Added a simple implementation of the jquery Ajax API, text, html, xml and json responses are handle well by gquery. --- diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml b/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml index a4124550..bf096c37 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml +++ b/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml @@ -115,6 +115,15 @@ + + + + + + + + + diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java index 1293071b..75a023ce 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java @@ -15,6 +15,8 @@ */ package com.google.gwt.query.client; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.query.client.js.JsUtils; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Widget; @@ -147,6 +149,25 @@ public abstract class Function { f(); } + /** + * Override this method for bound callbacks + */ + public void f(int i, Object... data) { + setIndex(i); + setData(data); + if (data.length == 1 && data[0] instanceof JavaScriptObject) { + if (JsUtils.isElement((JavaScriptObject)data[0])) { + setElement((com.google.gwt.dom.client.Element)data[0]); + f(getElement(), i); + } else if (JsUtils.isEvent((JavaScriptObject)data[0])) { + setEvent((Event)data[0]); + f(getEvent()); + } else { + f(); + } + } + } + /** * Override this method for bound event handlers if you wish to deal with * per-handler user data. diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQ.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQ.java new file mode 100644 index 00000000..1932df40 --- /dev/null +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQ.java @@ -0,0 +1,107 @@ +package com.google.gwt.query.client; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.JsArrayMixed; +import com.google.gwt.query.client.plugins.ajax.AjaxImpl; +import com.google.gwt.dom.client.Element; + +/** + * Class to implement the GQuery API static methods. + * + * NOTE: This class should be named $ but gwtc does not support the Dollar char + * in class names. If gwtc fixed this someday, this class would be renamed to $ + * but we would maintain a copy of this in order not to break apps. + * + * This class is abstract because is thought to contain only static methods and + * it extends GQuery so as static methods and attributes defined in GQuery are + * available here when statically importing this class. + * + * Code example: + *
+  GQ.$("div").css("background", "red");
+ * 
+ *
+  import static com.google.gwt.query.client.GQ.*;
+  ...
+  $("div").css("background", "red");
+ * 
+ * + */ +public abstract class GQ extends GQuery { + + /** + * Non instantiable class. + * + * TODO: move all public static GQuery methods here. + */ + private GQ(GQuery gq) { + super(gq); + } + + public static void ajax(Properties settings) { + ajax(null, null, null, settings); + } + + public static void ajax(final Function onSuccess, Properties settings) { + ajax(null, onSuccess, null, settings); + } + + public static void ajax(final Function onSuccess, final Function onError, + Properties settings) { + ajax(null, onSuccess, onError, settings); + } + + private static AjaxImpl ajaxImpl; + + public static void ajax(String url, Function onSuccess, Function onError, + Properties settings) { + if (ajaxImpl == null) { + ajaxImpl = GWT.create(AjaxImpl.class); + } + ajaxImpl.ajax(url, onSuccess, onError, settings); + } + + public static boolean contains(Element a, Element b) { + return engine.contains(a, b); + } + + public static Object data(Element e, String key) { + return GQuery.data(e, key, null); + } + + public static Object data(Element e, String key, String value) { + return GQuery.data(e, key, value); + } + + public static void each(List objects, Function f) { + for (int i = 0, l = objects.size(); i < l; i++) { + f.f(i, objects.get(i)); + } + } + + public static void each(T[] objects, Function f) { + for (int i = 0, l = objects.length; i < l; i++) { + f.f(i, objects[i]); + } + } + + public static void each(JsArrayMixed objects, Function f) { + for (int i = 0, l = objects.length(); i < l; i++) { + f.f(i, objects.getObject(i)); + } + } + + @SuppressWarnings("unchecked") + public static T[] grep(T[] objects, Predicate f) { + ArrayList ret = new ArrayList(); + for (int i = 0, l = objects.length; i < l; i++) { + if (f.f(objects[i], i)) { + ret.add(objects[i]); + } + } + return (T[]) ret.toArray(new Object[0]); + } +} diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index 37bcc4d7..bd7c218c 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -225,6 +225,16 @@ public class GQuery implements Lazy { public static GQuery $(Function f) { return $(f.getElement()); } + + /** + * Wrap a GQuery around an existing element, event, node or nodelist. + */ + public static GQuery $(JavaScriptObject e) { + return JsUtils.isElement(e) ? GQuery.$(e.cast()) : + JsUtils.isEvent(e) ? GQuery.$(e.cast()) : + JsUtils.isNodeList(e) ? GQuery.$(e.>cast()) : + $(); + } /** * Create a new GQuery given a list of nodes, elements or widgets @@ -247,7 +257,7 @@ public class GQuery implements Lazy { * Wrap a GQuery around an existing node. */ public static GQuery $(Node n) { - return n == null ? $() : new GQuery(JsNodeArray.create(n)); + return $((Element)n); } /** @@ -294,7 +304,7 @@ public class GQuery implements Lazy { return $(); } if (selector.startsWith("<")) { - return innerHtml(selectorOrHtml, getOwnerDocument(ctx)); + return innerHtml(selectorOrHtml, JsUtils.getOwnerDocument(ctx)); } return new GQuery().select(selectorOrHtml, ctx); } @@ -348,6 +358,9 @@ public class GQuery implements Lazy { return $(selector, context.getElement(), plugin); } + /** + * wraps a GQuery or a plugin object + */ public static T $(T gq) { return gq; } @@ -452,11 +465,6 @@ public class GQuery implements Lazy { return d; }-*/; - private static Document getOwnerDocument(Node n) { - return n== null || n.getNodeType() == Node.DOCUMENT_NODE ? - n. cast() : n.getOwnerDocument(); - } - private static boolean hasClass(Element e, String clz) { return e.getClassName().matches("(^|.*\\s)" + clz + "(\\s.*|$)"); } @@ -923,7 +931,7 @@ public class GQuery implements Lazy { */ public GQuery attr(Properties properties) { for (String name : properties.keys()) { - attr(JsUtils.hyphenize(name), properties.getStr(name)); + attr(name, properties.getStr(name)); } return this; } @@ -1442,7 +1450,9 @@ public class GQuery implements Lazy { * Stores the value in the named spot with desired return type. */ public GQuery data(String name, Object value) { - for (Element e : elements) { +// System.out.println("DDD " + size() + " " + elements().length + " " + name + " " + value); + for (Element e : elements()) { +// System.out.println("DATAT ....."); data(e, name, value); } return this; @@ -1812,7 +1822,7 @@ public class GQuery implements Lazy { private GQuery domManip(String htmlString, DomMan type) { JsMap cache = JsMap.createObject().cast(); for (Element e : elements) { - Document d = getOwnerDocument(e); + Document d = JsUtils.getOwnerDocument(e); GQuery g = cache.get(d); if (g == null) { g = cleanHtmlString(htmlString, d); @@ -3866,7 +3876,7 @@ public class GQuery implements Lazy { } String elStr; try { - elStr = e.getString(); + elStr = JsUtils.isXML(e) ? JsUtils.XML2String(e) : e.getString(); } catch (Exception e2) { elStr = "< " + (e == null ? "null" : e.getNodeName()) + "(gquery, error getting the element string representation: " + e2.getMessage() + ")/>"; } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java index e52b233b..268fa397 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Predicate.java @@ -20,7 +20,7 @@ import com.google.gwt.dom.client.Element; /** * A predicate function used by some GQuery methods. */ -public interface Predicate { +public class Predicate { /** * Used by GQuery methods which loop over matched widgets and @@ -31,5 +31,13 @@ public interface Predicate { * @param index * the element position in the gquery elements array. */ - boolean f(Element e, int index); + public boolean f(Element e, int index) { + return f((Object)e, index); + } + + public boolean f(T e, int index) { + return false; + } + + } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java index 04f6c370..b9c62e0f 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java @@ -25,14 +25,14 @@ import com.google.gwt.query.client.js.JsCache; public class Properties extends JavaScriptObject { public static Properties create() { - return (Properties) createImpl("({})"); + return createImpl("({})"); } public static Properties create(String properties) { if (properties != null && !properties.isEmpty()) { - String p = camelizePropertiesKeys(wrapPropertiesString(properties)); + String p = wrapPropertiesString(properties); try { - return (Properties) createImpl(p); + return createImpl(p); } catch (Exception e) { System.err.println("Error creating Properties: \n> " + properties + "\n< " + p + "\n" + e.getMessage()); } @@ -40,7 +40,7 @@ public class Properties extends JavaScriptObject { return create(); } - public static final native JavaScriptObject createImpl(String properties) /*-{ + public static final native Properties createImpl(String properties) /*-{ return eval(properties); }-*/; @@ -52,19 +52,15 @@ public class Properties extends JavaScriptObject { .replaceFirst("^[{\\(]+(|.*[^}\\)])[}\\)]+$", "$1") // Remove ({}) .replaceAll("\\('([^\\)]+)'\\)" , "($1)") // Remove quotes .replaceAll(",+([\\w-]+:+)" , ";$1") // put semicolon - .replaceAll(":\\s*[\"']?([^'\\]};]*)[\"']?\\s*(;+|$)", ":'$1',") // put quotes + .replaceAll(":\\s*[\"']?([^'\\]};]*)[\"']?\\s*(;+|$)", ":'$1',") // put quotes to values + .replaceAll(";([^:]+):", ",$1:") // change semicolon .replaceAll(":'(-?[\\d\\.]+|null|false|true)',", ":$1,") // numbers do not need quote + .replaceAll("(^|[^\\w-'])([\\w]+[-][\\w-]+):", "$1'$2':") // quote keys with illegal chars .replaceFirst("[;,]$", "") // remove endings + "})"; return ret; } - public static native String camelizePropertiesKeys(String s)/*-{ - return s.replace(/(\w+)\-(\w)(\w*:)/g, function(all, g1, letter, g2) { - return g1 + letter.toUpperCase() + g2; - }); - }-*/; - protected Properties() { } @@ -151,13 +147,16 @@ public class Properties extends JavaScriptObject { } else { Properties p = getJavaScriptObject(k); if (p != null) { - ret += k + ":" + p.toJsonString(); + ret += k + ":" + p.toJsonString() + ","; } else { ret += k + ":'" + getStr(k) + "',"; } } } - return "{" + ret.replaceAll(",\\s*([\\]}]|$)","").replaceAll("([:,\\[])'(-?[\\d\\.]+|null|false|true)'", "$1$2") + "}"; + return "{" + ret.replaceAll(",\\s*([\\]}]|$)","") + .replaceAll("([:,\\[])'(-?[\\d\\.]+|null|false|true)'", "$1$2") + .replaceAll("(^|[^\\w-'])([\\w]+[-][\\w-]+):", "$1'$2':") + + "}"; } public final String toQueryString() { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeImpl.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeImpl.java index 8add2758..b991c5e8 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeImpl.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeImpl.java @@ -1,5 +1,4 @@ -/* - * Copyright 2011, The gwtquery team. +/* Copyright 2011, The gwtquery team. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -11,8 +10,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. - */ + * the License. */ package com.google.gwt.query.client.impl; import com.google.gwt.dom.client.Element; @@ -23,10 +21,12 @@ import com.google.gwt.query.client.js.JsUtils; /** * Helper class for setting and getting attribute on an element. - * */ public class AttributeImpl { - + + /** + * Interface used for attribute setter implementations. + */ public interface AttributeSetter { public boolean isRemoval(Object value); @@ -34,13 +34,11 @@ public class AttributeImpl { } /** - * Default setter using e.setAttribute() method - * + * Default setter using e.setAttribute() method. */ protected static class DefaultSetter implements AttributeSetter { - private static AttributeSetter INSTANCE; - + public static AttributeSetter getInstance() { if (INSTANCE == null) { INSTANCE = new DefaultSetter(); @@ -48,8 +46,6 @@ public class AttributeImpl { return INSTANCE; } - protected DefaultSetter(){} - public boolean isRemoval(Object value) { return value == null; } @@ -57,15 +53,12 @@ public class AttributeImpl { public void setAttribute(Element e, String key, Object value) { e.setAttribute(key, String.valueOf(value)); } - } - + /** - * value must be set on element directly - * + * value must be set on element directly */ protected static class ValueAttrSetter extends DefaultSetter { - private static AttributeSetter INSTANCE; public static AttributeSetter getInstance() { @@ -75,25 +68,20 @@ public class AttributeImpl { return INSTANCE; } - protected ValueAttrSetter(){} - public void setAttribute(Element e, String key, Object value) { - e.setPropertyObject("value", String.valueOf(value)); - super.setAttribute(e, key, value); } - - } /** * Boolean attribute : - * - Ensure to set a boolean value to the element's property with the same name if this last exists - * - Ensure to set an attribute having the value equals to the name (i.e checked="checked") + * - Ensure to set a boolean value to the element's property with the same + * name if this last exists + * - Ensure to set an attribute having the value equals to the name (i.e + * checked="checked") */ private static class BooleanAttrSetter extends DefaultSetter { - private static AttributeSetter INSTANCE; public static AttributeSetter getInstance() { @@ -103,58 +91,71 @@ public class AttributeImpl { return INSTANCE; } - protected BooleanAttrSetter(){} - public boolean isRemoval(Object value) { return super.isRemoval(value) || Boolean.FALSE.equals(value); } public void setAttribute(Element e, String key, Object value) { - if (JsUtils.hasProperty(e, key)) { e.setPropertyBoolean(key, true); } - super.setAttribute(e, key, key.toLowerCase()); } + } + + /** + * Id attribute. + */ + private static class IdAttrSetter extends DefaultSetter { + private static AttributeSetter INSTANCE; + public static AttributeSetter getInstance() { + if (INSTANCE == null) { + INSTANCE = new IdAttrSetter(); + } + return INSTANCE; + } + + public void setAttribute(Element e, String key, Object value) { + e.setId(value == null ? null : value.toString()); + super.setAttribute(e, key, value); + } } /** - * For button and inputs, the type cannot be changed once the element is attached to the dom ! - * + * For button and inputs, the type cannot be changed once the element is + * attached to the dom ! */ private static class TypeAttrSetter extends DefaultSetter { - private static AttributeSetter INSTANCE; + private static JsRegexp NOT_AUTHORIZED_NODE = new JsRegexp( + "^(?:button|input)$", "i"); - private static JsRegexp NOT_AUTHORIZED_NODE = new JsRegexp("^(?:button|input)$","i"); public static AttributeSetter getInstance() { if (INSTANCE == null) { INSTANCE = new TypeAttrSetter(); } return INSTANCE; } - - protected TypeAttrSetter(){} - + + protected TypeAttrSetter() { + } + public void setAttribute(Element e, String name, Object value) { String tag = e.getNodeName(); - - if (NOT_AUTHORIZED_NODE.test(tag) && GQuery.$(e).parents("body").length() > 0){ + if (NOT_AUTHORIZED_NODE.test(tag) + && GQuery.$(e).parents("body").length() > 0) { //TODO maybe it's better to simply do nothing... - throw new RuntimeException("You cannot change type of button or input element if the element is already attached to the dom"); + throw new RuntimeException( + "You cannot change type of button or input element if the element is already attached to the dom"); } - if ("input".equals(tag.toLowerCase()) && "radio".equals(value)){ + if ("input".equals(tag.toLowerCase()) && "radio".equals(value)) { //some browser (IE6-9) resets value property of the input when you change the type to radio button InputElement ie = InputElement.as(e); - String keepValue = ie.getValue(); - + String keepValue = ie.getValue(); super.setAttribute(ie, "type", value); - ie.setValue(keepValue); - - }else{ + } else { super.setAttribute(e, name, value); } } @@ -164,60 +165,49 @@ public class AttributeImpl { "^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$", "i"); - public void removeAttribute(GQuery gQuery, String key){ - + public void removeAttribute(GQuery gQuery, String key) { for (Element e : gQuery.elements()) { if (e.getNodeType() != 1) { continue; } - e.removeAttribute( key ); - - if (BOOLEAN_ATTR_REGEX.test(key) && JsUtils.hasProperty(e, key)){ + e.removeAttribute(key); + if (BOOLEAN_ATTR_REGEX.test(key) && JsUtils.hasProperty(e, key)) { e.setPropertyBoolean(key, false); } } } - - public void setAttribute(GQuery gQuery, String key, Object value) { + public void setAttribute(GQuery gQuery, String key, Object value) { AttributeSetter setter = getAttributeSetter(key); - if (setter.isRemoval(value)) { gQuery.removeAttr(key); return; } - value = fixValue(key, value); - for (Element e : gQuery.elements()) { - int nodeType = e.getNodeType(); - + int nodeType = e.getNodeType(); //don't set attribute on text, comment and attributes nodes if (nodeType == 3 || nodeType == 8 || nodeType == 2) { continue; } - setter.setAttribute(e, key, value); } - } protected Object fixValue(String key, Object value) { - return value; + return value; } protected AttributeSetter getAttributeSetter(String key) { - if ("type".equalsIgnoreCase(key)) { - return TypeAttrSetter.getInstance(); - - } else if ("value".equals(key)){ + return TypeAttrSetter.getInstance(); + } else if ("id".equals(key)) { + return IdAttrSetter.getInstance(); + } else if ("value".equals(key)) { return ValueAttrSetter.getInstance(); - } else if (BOOLEAN_ATTR_REGEX.test(key)) { - return BooleanAttrSetter.getInstance(); + return BooleanAttrSetter.getInstance(); } return DefaultSetter.getInstance(); } - } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeTridentImpl.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeTridentImpl.java index ea650306..f746f54e 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeTridentImpl.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/AttributeTridentImpl.java @@ -19,16 +19,13 @@ import com.google.gwt.dom.client.Element; /** * Helper class for setting and getting attribute on an element. - * */ public class AttributeTridentImpl extends AttributeImpl { /** - * use {@link AttrNodeSetter} for button element - * + * Use {@link AttrNodeSetter} for button element. */ protected static class IEValueAttrSetter extends ValueAttrSetter { - private static AttributeSetter INSTANCE; public static AttributeSetter getInstance() { @@ -38,23 +35,15 @@ public class AttributeTridentImpl extends AttributeImpl { return INSTANCE; } - private IEValueAttrSetter() { - - } - public void setAttribute(Element e, String key, Object value) { - if ("button".equals(e.getTagName())) { AttrNodeSetter.getInstance().setAttribute(e, key, value); return; } - super.setAttribute(e, key, value); } - } private static class AttrNodeSetter extends DefaultSetter { - private static AttributeSetter INSTANCE; public static AttributeSetter getInstance() { @@ -64,17 +53,11 @@ public class AttributeTridentImpl extends AttributeImpl { return INSTANCE; } - private AttrNodeSetter() { - } - - @Override public void setAttribute(Element e, String key, Object value) { if (!setAttributeNode(e, key, value)) { super.setAttribute(e, key, value); } - } - } private static native String getAttributeNode(Element e, String name)/*-{ @@ -114,5 +97,4 @@ public class AttributeTridentImpl extends AttributeImpl { } return super.getAttributeSetter(key); } - } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java index bda3a655..d5bddaf4 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java @@ -16,13 +16,11 @@ package com.google.gwt.query.client.impl; import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JsArray; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.query.client.js.JsNodeArray; -import com.google.gwt.query.client.js.JsObjectArray; import com.google.gwt.query.client.js.JsRegexp; import com.google.gwt.query.client.js.JsUtils; diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java index 735478e8..f7af867c 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java @@ -15,20 +15,81 @@ */ package com.google.gwt.query.client.js; +import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; +import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.query.client.GQuery; +import com.google.gwt.query.client.Properties; import com.google.gwt.user.client.DOM; /** * A bunch of utility methods for GQuery. - * - * These methods could be moved to $ class, but the class - * doesn't work right now. */ public class JsUtils { + + private static JsUtilsImpl utilsImpl = GWT.create(JsUtilsImpl.class); + + public static class JsUtilsImpl { + public native Element parseXML(String xml) /*-{ + return new DOMParser().parseFromString(xml, "text/xml").documentElement; + }-*/; + + public native Properties parseJSON(String json) /*-{ + return $wnd.JSON.parse(json); + }-*/; + + public native String XML2String(JavaScriptObject o) /*-{ + return (new XMLSerializer()).serializeToString(o); + }-*/; + + public JsArray unique(JsArray a) { + JsArray ret = JavaScriptObject.createArray().cast(); + JsCache cache = JsCache.create(); + for (int i = 0; i < a.length(); i++) { + Element e = a.get(i); + int id = e.hashCode(); + if (!cache.exists(id)) { + cache.put(id, 1); + ret.push(e); + } + } + return ret; + } + } + + public static class JsUtilsImplIE6 extends JsUtilsImpl { + @Override + public native Element parseXML(String xml) /*-{ + var d = new ActiveXObject("Microsoft.XmlDom"); + d.loadXML(xml); + return d.documentElement; + }-*/; + + @Override + public Properties parseJSON(String json) { + // No checks to the passed string so json should be + // a well-formed json string. + return Properties.createImpl(json); + } + + @Override + public native String XML2String(JavaScriptObject o) /*-{ + return o.xml; + }-*/; + + @Override + public JsArray unique(JsArray a) { + // in IE6 XML elements does not support adding hashId to the object + if (a.length() > 0 && isXML(a.get(0))) { + return a; + } + return super.unique(a); + } + } /** * Camelize style property names. for instance: font-name -> fontName @@ -144,21 +205,81 @@ public class JsUtils { public static native boolean hasProperty(JavaScriptObject o, String name)/*-{ return name in o; }-*/; - + + /** + * Check is a javascript object can be cast to an Element + */ + public static boolean isElement(JavaScriptObject o) { + return hasProperty(o, "nodeName"); + } + + /** + * Check is a javascript object can be cast to an Event + */ + public static boolean isEvent(JavaScriptObject o) { + return hasProperty(o, "currentTarget"); + } + + /** + * Check is a javascript object can be used as an array + */ + public static native boolean isArray(JavaScriptObject o) /*-{ + return Object.prototype.toString.call(o) == '[object Array]' + || typeof o.length == 'number'; + }-*/; + + /** + * Check is a javascript can be cast to a node list + */ + public static native boolean isNodeList(JavaScriptObject o) /*-{ + var r = Object.prototype.toString.call(o); + return r == '[object HTMLCollection]' || r == '[object NodeList]' || + (typeof o == 'object' && o.length && o[0].tagName) + ? true : false; + }-*/; + + /** + * Check if an element is a DOM or a XML node + */ + public static boolean isXML(Node o) { + return o == null ? false : + !"HTML".equals(getOwnerDocument(o).getDocumentElement().getNodeName()); + } + + public static String XML2String(JavaScriptObject o) { + return utilsImpl.XML2String(o); + } + + /** + * Parses a xml string and return the xml document element which + * can then be passed to GQuery to create a typical GQuery object + * that can be traversed and manipulated. + */ + public static Element parseXML(String xml) { + return utilsImpl.parseXML(xml); + } + + /** + * Returns the owner document element of an element. + */ + public static Document getOwnerDocument(Node n) { + return n == null ? null : + n.getNodeType() == Node.DOCUMENT_NODE ? + n.cast() : n.getOwnerDocument(); + } + /** * Remove duplicates from an elements array */ public static JsArray unique(JsArray a) { - JsArray ret = JavaScriptObject.createArray().cast(); - JsCache cache = JsCache.create(); - for (int i = 0; i < a.length(); i++) { - Element e = a.get(i); - int id = e.hashCode(); - if (!cache.exists(id)) { - cache.put(id, 1); - ret.push(e); - } - } - return ret; + return utilsImpl.unique(a); + } + + /** + * Parses a json string returning a Object with useful method + * to get the content. + */ + public static Properties parseJSON(String json) { + return utilsImpl.parseJSON(json); } } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/AjaxImpl.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/AjaxImpl.java new file mode 100644 index 00000000..f10d712e --- /dev/null +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/AjaxImpl.java @@ -0,0 +1,174 @@ +package com.google.gwt.query.client.plugins.ajax; + +import static com.google.gwt.query.client.GQuery.$$; + +import com.google.gwt.dom.client.Element; +import com.google.gwt.http.client.Request; +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestCallback; +import com.google.gwt.http.client.RequestException; +import com.google.gwt.http.client.Response; +import com.google.gwt.http.client.RequestBuilder.Method; +import com.google.gwt.query.client.Function; +import com.google.gwt.query.client.GQ; +import com.google.gwt.query.client.Properties; +import com.google.gwt.query.client.js.JsUtils; + +/** + * Ajax class for GQuery. + * + * It is not actually a plugin but we prefer this name-space in order + * to centralize jquery core features in a common folder. + * + */ +public class AjaxImpl { + + /** + * The jQuery library has a full suite of AJAX capabilities, but GWT + * is plenty of classes to get data from server side: RPC, XHR, RF, etc. + * + * This class is not a substitute for the GWT utilities, but a complement + * to get server data in a jquery way, specially when querying non java + * backends. + * + * We do not pretend to clone all the jquery Ajax API inside gquery, just take + * its syntax and to implement the most popular usage of it. + * This implementation is almost thought to be used as an alternative to + * the GWT-XHR, GWT-XML and GWT-JSON modules. + * + * Example: + *
+    import static com.google.gwt.query.client.GQ.*
+    ...
+    Properties properties = $$("dataType: xml, type: post; data: {q: 'gwt'}, headers: {X-Powered-By: GQuery}");
+    ajax("test.php", new Function() {
+      public void f() {
+        Element xmlElem = getData()[0];
+        System.out.println($("message", xmlElem));
+      }
+    }, new Function(){
+      public void f() {
+        System.err.println("Ajax Error: " + getData()[1]);
+      }
+    }, properties);
+   * 
+ * + * @param url The url to connect + * @param onSuccess a function to execute in the case of success + * @param onError the function to execute on error + * @param settings a Properties object with the configuration of the Ajax request. + */ + public void ajax(String url, Function onSuccess, Function onError, + Properties settings) { + Method httpMethod = RequestBuilder.POST; + String method = settings.getStr("type"); + if ("get".equalsIgnoreCase(method)) { + httpMethod = RequestBuilder.GET; + } + + if (settings.getStr("url") != null) { + url = settings.getStr("url"); + } + + String data = null; + Properties props = settings.getJavaScriptObject("data"); + if (props != null) { + data = props.toQueryString(); + } else { + data = settings.getStr("data"); + } + + if (data != null && httpMethod == RequestBuilder.GET) { + url += (url.contains("?") ? "&" : "?") + data; + } + RequestBuilder r = new RequestBuilder(httpMethod, url); + if (data != null && httpMethod != RequestBuilder.GET) { + r.setRequestData(data); + } + + int timeout = settings.getInt("timeout"); + r.setTimeoutMillis(timeout); + + String user = settings.getStr("username"); + if (user != null) { + r.setUser(user); + } + + String password = settings.getStr("password"); + if (password != null) { + r.setPassword(password); + } + + String ctype = settings.getStr("contentType"); + r.setHeader("Content-type", ctype != null ? ctype + : "application/x-www-form-urlencoded"); + + final String dataType = settings.defined("dataType") + ? settings.getStr("dataType") : "text"; + + Properties p = settings.getJavaScriptObject("headers"); + if (p != null) { + for (String s : p.keys()) { + r.setHeader(s, p.getStr(s)); + } + } + + Element ctx = settings.getJavaScriptObject("context"); + if (ctx != null) { + if (onSuccess != null) { + onSuccess.setElement(ctx); + } + if (onError != null) { + onError.setElement(ctx); + } + } + + Object o = settings.getObject("success"); + final Function success = (o != null && (o instanceof Function)) + ? (Function) o : onSuccess; + + o = settings.getObject("error"); + final Function error = (o != null && (o instanceof Function)) + ? (Function) o : onError; + + r.setCallback(new RequestCallback() { + public void onResponseReceived(Request request, Response response) { + if (response.getStatusCode() > 202) { + if (error != null) { + error.f(response.getText(), "error", request, response); + } + } else if (success != null) { + Object retData = null; + try { + if ("xml".equalsIgnoreCase(dataType)) { + retData = JsUtils.parseXML(response.getText()); + } else if ("json".equalsIgnoreCase(dataType)) { + retData = JsUtils.parseJSON(response.getText()); + } else { + retData = response.getText(); + } + } catch (Exception e) { + System.err.println("Error parsing '" + dataType + + "' received data: " + e.getMessage()); + System.err.println("Server response was: \n" + response.getText()); + } + success.f(retData, "success", request, response); + } + } + + public void onError(Request request, Throwable exception) { + if (error != null) { + error.f(null, exception.getMessage(), request, null, exception); + } + } + }); + + try { + r.send(); + } catch (RequestException e) { + if (onError != null) { + onError.f(null, -1, null, null, e); + } + } + } +} diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/LazyGenerator.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/LazyGenerator.java index c9c3ab52..56a15f18 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/LazyGenerator.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/LazyGenerator.java @@ -112,7 +112,6 @@ public class LazyGenerator extends Generator { throws UnableToCompleteException { JParameter[] params = method.getParameters(); - String thisClass = method.getEnclosingType().getQualifiedSourceName(); JTypeParameter gType = method.getReturnType().isTypeParameter(); String retType = method.getReturnType() diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java index 01239aeb..2b3d7c00 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java @@ -58,6 +58,8 @@ public class JreQueryCoreTest extends GWTTestCase { .wrapPropertiesString("color: 'rgb(0, 0,139)', background: red")); assertEquals("({width:'',top:''})", Properties .wrapPropertiesString("width: '' ; top:'' ;")); + assertEquals("({'border-left':'solid'})", Properties + .wrapPropertiesString("border-left: solid")); } }