<when-type-is class="com.google.gwt.query.client.impl.AttributeImpl" />\r
<when-property-is name="user.agent" value="ie6" />\r
</replace-with>\r
+ \r
+ <!-- JsUtils implementations -->\r
+ <replace-with class="com.google.gwt.query.client.js.JsUtils.JsUtilsImpl">\r
+ <when-type-is class="com.google.gwt.query.client.js.JsUtils.JsUtilsImpl" />\r
+ </replace-with>\r
+ <replace-with class="com.google.gwt.query.client.js.JsUtils.JsUtilsImplIE6">\r
+ <when-type-is class="com.google.gwt.query.client.js.JsUtils.JsUtilsImpl" />\r
+ <when-property-is name="user.agent" value="ie6" />\r
+ </replace-with>\r
\r
<!-- IE8 needs the iframe where the js of app is loaded set to standard in order \r
to use the queryAll native selector --> \r
*/
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;
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.
--- /dev/null
+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:
+ * <pre>
+ GQ.$("div").css("background", "red");
+ * </pre>
+ * <pre>
+ import static com.google.gwt.query.client.GQ.*;
+ ...
+ $("div").css("background", "red");
+ * </pre>
+ *
+ */
+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 <T> void each(List<T> objects, Function f) {
+ for (int i = 0, l = objects.size(); i < l; i++) {
+ f.f(i, objects.get(i));
+ }
+ }
+
+ public static <T> 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> T[] grep(T[] objects, Predicate f) {
+ ArrayList<Object> ret = new ArrayList<Object>();
+ 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]);
+ }
+}
public static GQuery $(Function f) {\r
return $(f.getElement());\r
}\r
+ \r
+ /**\r
+ * Wrap a GQuery around an existing element, event, node or nodelist.\r
+ */\r
+ public static GQuery $(JavaScriptObject e) {\r
+ return JsUtils.isElement(e) ? GQuery.$(e.<Element>cast()) :\r
+ JsUtils.isEvent(e) ? GQuery.$(e.<Event>cast()) :\r
+ JsUtils.isNodeList(e) ? GQuery.$(e.<NodeList<Element>>cast()) :\r
+ $(); \r
+ }\r
\r
/**\r
* Create a new GQuery given a list of nodes, elements or widgets\r
* Wrap a GQuery around an existing node.\r
*/\r
public static GQuery $(Node n) {\r
- return n == null ? $() : new GQuery(JsNodeArray.create(n));\r
+ return $((Element)n);\r
}\r
\r
/**\r
return $();\r
}\r
if (selector.startsWith("<")) {\r
- return innerHtml(selectorOrHtml, getOwnerDocument(ctx));\r
+ return innerHtml(selectorOrHtml, JsUtils.getOwnerDocument(ctx));\r
}\r
return new GQuery().select(selectorOrHtml, ctx);\r
}\r
return $(selector, context.getElement(), plugin);\r
}\r
\r
+ /**\r
+ * wraps a GQuery or a plugin object\r
+ */\r
public static <T extends GQuery> T $(T gq) {\r
return gq;\r
}\r
return d;\r
}-*/;\r
\r
- private static Document getOwnerDocument(Node n) {\r
- return n== null || n.getNodeType() == Node.DOCUMENT_NODE ? \r
- n.<Document> cast() : n.getOwnerDocument();\r
- }\r
-\r
private static boolean hasClass(Element e, String clz) {\r
return e.getClassName().matches("(^|.*\\s)" + clz + "(\\s.*|$)");\r
}\r
*/\r
public GQuery attr(Properties properties) {\r
for (String name : properties.keys()) {\r
- attr(JsUtils.hyphenize(name), properties.getStr(name));\r
+ attr(name, properties.getStr(name));\r
}\r
return this;\r
}\r
* Stores the value in the named spot with desired return type.\r
*/\r
public GQuery data(String name, Object value) {\r
- for (Element e : elements) {\r
+// System.out.println("DDD " + size() + " " + elements().length + " " + name + " " + value);\r
+ for (Element e : elements()) {\r
+// System.out.println("DATAT .....");\r
data(e, name, value);\r
}\r
return this;\r
private GQuery domManip(String htmlString, DomMan type) {\r
JsMap<Document, GQuery> cache = JsMap.createObject().cast();\r
for (Element e : elements) {\r
- Document d = getOwnerDocument(e);\r
+ Document d = JsUtils.getOwnerDocument(e);\r
GQuery g = cache.get(d);\r
if (g == null) {\r
g = cleanHtmlString(htmlString, d);\r
}\r
String elStr;\r
try {\r
- elStr = e.getString();\r
+ elStr = JsUtils.isXML(e) ? JsUtils.XML2String(e) : e.getString();\r
} catch (Exception e2) {\r
elStr = "< " + (e == null ? "null" : e.getNodeName()) + "(gquery, error getting the element string representation: " + e2.getMessage() + ")/>";\r
}\r
/**
* A predicate function used by some GQuery methods.
*/
-public interface Predicate {
+public class Predicate {
/**
* Used by GQuery methods which loop over matched widgets and
* @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 <T> boolean f(T e, int index) {
+ return false;
+ }
+
+
}
public class Properties extends JavaScriptObject {\r
\r
public static Properties create() {\r
- return (Properties) createImpl("({})");\r
+ return createImpl("({})");\r
}\r
\r
public static Properties create(String properties) {\r
if (properties != null && !properties.isEmpty()) {\r
- String p = camelizePropertiesKeys(wrapPropertiesString(properties));\r
+ String p = wrapPropertiesString(properties);\r
try {\r
- return (Properties) createImpl(p);\r
+ return createImpl(p);\r
} catch (Exception e) {\r
System.err.println("Error creating Properties: \n> " + properties + "\n< " + p + "\n" + e.getMessage());\r
}\r
return create();\r
}\r
\r
- public static final native JavaScriptObject createImpl(String properties) /*-{\r
+ public static final native Properties createImpl(String properties) /*-{\r
return eval(properties);\r
}-*/;\r
\r
.replaceFirst("^[{\\(]+(|.*[^}\\)])[}\\)]+$", "$1") // Remove ({})\r
.replaceAll("\\('([^\\)]+)'\\)" , "($1)") // Remove quotes\r
.replaceAll(",+([\\w-]+:+)" , ";$1") // put semicolon\r
- .replaceAll(":\\s*[\"']?([^'\\]};]*)[\"']?\\s*(;+|$)", ":'$1',") // put quotes\r
+ .replaceAll(":\\s*[\"']?([^'\\]};]*)[\"']?\\s*(;+|$)", ":'$1',") // put quotes to values\r
+ .replaceAll(";([^:]+):", ",$1:") // change semicolon\r
.replaceAll(":'(-?[\\d\\.]+|null|false|true)',", ":$1,") // numbers do not need quote\r
+ .replaceAll("(^|[^\\w-'])([\\w]+[-][\\w-]+):", "$1'$2':") // quote keys with illegal chars\r
.replaceFirst("[;,]$", "") // remove endings \r
+ "})";\r
return ret;\r
}\r
\r
- public static native String camelizePropertiesKeys(String s)/*-{\r
- return s.replace(/(\w+)\-(\w)(\w*:)/g, function(all, g1, letter, g2) {\r
- return g1 + letter.toUpperCase() + g2;\r
- });\r
- }-*/;\r
-\r
protected Properties() {\r
}\r
\r
} else {\r
Properties p = getJavaScriptObject(k);\r
if (p != null) {\r
- ret += k + ":" + p.toJsonString();\r
+ ret += k + ":" + p.toJsonString() + ",";\r
} else {\r
ret += k + ":'" + getStr(k) + "',";\r
}\r
}\r
}\r
- return "{" + ret.replaceAll(",\\s*([\\]}]|$)","").replaceAll("([:,\\[])'(-?[\\d\\.]+|null|false|true)'", "$1$2") + "}";\r
+ return "{" + ret.replaceAll(",\\s*([\\]}]|$)","")\r
+ .replaceAll("([:,\\[])'(-?[\\d\\.]+|null|false|true)'", "$1$2")\r
+ .replaceAll("(^|[^\\w-'])([\\w]+[-][\\w-]+):", "$1'$2':")\r
+ + "}";\r
}\r
\r
public final String toQueryString() {\r
-/*
- * 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
* 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;
/**
* 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);
}
/**
- * Default setter using <code>e.setAttribute()</code> method
- *
+ * Default setter using <code>e.setAttribute()</code> method.
*/
protected static class DefaultSetter implements AttributeSetter {
-
private static AttributeSetter INSTANCE;
-
+
public static AttributeSetter getInstance() {
if (INSTANCE == null) {
INSTANCE = new DefaultSetter();
return INSTANCE;
}
- protected DefaultSetter(){}
-
public boolean isRemoval(Object value) {
return value == null;
}
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() {
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() {
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);
}
}
"^(?: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();
}
-
}
/**
* 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() {
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() {
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)/*-{
}
return super.getAttributeSetter(key);
}
-
}
package com.google.gwt.query.client.impl;\r
\r
import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.core.client.JsArray;\r
import com.google.gwt.dom.client.Document;\r
import com.google.gwt.dom.client.Element;\r
import com.google.gwt.dom.client.Node;\r
import com.google.gwt.dom.client.NodeList;\r
import com.google.gwt.query.client.js.JsNodeArray;\r
-import com.google.gwt.query.client.js.JsObjectArray;\r
import com.google.gwt.query.client.js.JsRegexp;\r
import com.google.gwt.query.client.js.JsUtils;\r
\r
*/
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<Element> unique(JsArray<Element> a) {
+ JsArray<Element> 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<Element> unique(JsArray<Element> 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
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.<Document>cast() : n.getOwnerDocument();
+ }
+
/**
* Remove duplicates from an elements array
*/
public static JsArray<Element> unique(JsArray<Element> a) {
- JsArray<Element> 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);
}
}
--- /dev/null
+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:
+ * <pre>
+ 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);
+ * </pre>
+ *
+ * @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);
+ }
+ }
+ }
+}
throws UnableToCompleteException {
JParameter[] params = method.getParameters();
- String thisClass = method.getEnclosingType().getQualifiedSourceName();
JTypeParameter gType = method.getReturnType().isTypeParameter();
String retType = method.getReturnType()
.wrapPropertiesString("color: 'rgb(0, 0,139)', background: red"));
assertEquals("({width:'',top:''})", Properties
.wrapPropertiesString("width: '' ; top:'' ;"));
+ assertEquals("({'border-left':'solid'})", Properties
+ .wrapPropertiesString("border-left: solid"));
}
}