aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManolo Carrasco <manolo@apache.org>2012-02-08 11:55:08 +0000
committerManolo Carrasco <manolo@apache.org>2012-02-08 11:55:08 +0000
commit1b2bc50acd572a992e5178a205501c2a5b96d0b2 (patch)
treec21e69e6a2c8c88324f08f44f446997f35e9cc2e
parent6b56b6422bf2ded23ec857f39ddfd102b69ba962 (diff)
downloadgwtquery-1b2bc50acd572a992e5178a205501c2a5b96d0b2.tar.gz
gwtquery-1b2bc50acd572a992e5178a205501c2a5b96d0b2.zip
Implementation of Ajax JSONP using script tags
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java38
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java2
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java267
-rw-r--r--gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java54
4 files changed, 194 insertions, 167 deletions
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 75a023ce..08f6415d 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
@@ -40,7 +40,7 @@ public abstract class Function {
public void setEvent(Event e) {
event = e;
- element = e.getCurrentEventTarget().<com.google.gwt.dom.client.Element>cast();
+ element = e != null ? e.getCurrentEventTarget().<com.google.gwt.dom.client.Element>cast() : null;
}
public Event getEvent() {
@@ -59,6 +59,38 @@ public abstract class Function {
this.data = data;
}
+ public Object getDataObject() {
+ return getDataObject(0);
+ }
+
+ public Object getDataObject(int idx) {
+ return data.length > idx ? data[idx] : null;
+ }
+
+ public Properties getDataProperties() {
+ return getDataProperties(0);
+ }
+
+ public Properties getDataProperties(int idx) {
+ Object o = getDataObject(idx);
+ if (o != null && o instanceof JavaScriptObject) {
+ return (Properties)o;
+ }
+ return null;
+ }
+
+ public void setData(boolean b) {
+ setData(Boolean.valueOf(b));
+ }
+
+ public void setData(double b) {
+ setData(Double.valueOf(b));
+ }
+
+ public void setDataObject(Object data) {
+ setData(data);
+ }
+
public int getIndex() {
return index;
}
@@ -183,7 +215,7 @@ public abstract class Function {
*/
public boolean f(Event e) {
setEvent(e);
- f(e.getCurrentEventTarget().<com.google.gwt.dom.client.Element>cast());
+ f(element);
return true;
}
@@ -208,7 +240,7 @@ public abstract class Function {
private boolean loop = false;
public void f(com.google.gwt.user.client.Element e) {
setElement(e);
- Widget w = GQuery.getAssociatedWidget(e);
+ Widget w = e != null ? GQuery.getAssociatedWidget(e) : null;
if (w != null){
loop = true;
f(w);
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
index 2bc9aa45..bf64308d 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
@@ -77,6 +77,8 @@ public class JsCache extends JavaScriptObject {
}
public final native <T> double getDouble(T id) /*-{
+ // HtmlUnit prints an 'Unknown property name in get valueOf'
+ // error here, but it is ok.
var r = this[id] ? Number(this[id]) : 0;
return r ? r : 0;
}-*/;
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java
index d2881c28..d30020c5 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java
@@ -11,6 +11,7 @@ import com.google.gwt.http.client.Response;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.builders.JsonBuilder;
import com.google.gwt.query.client.js.JsUtils;
import com.google.gwt.query.client.plugins.Plugin;
@@ -33,159 +34,33 @@ public class Ajax extends GQuery {
/**
* Ajax Settings object
*/
- public static class Settings {
-
- private static final String CONTENT_TYPE_KEY = "contentType";
- private static final String CONTEXT_KEY = "context";
- private static final String DATA_KEY = "data";
- private static final String DATA_STRING_KEY = "dataString";
- private static final String DATA_TYPE_KEY = "dataType";
- private static final String HEADERS_KEY = "headers";
- private static final String PASSWORD_KEY = "password";
- private static final String TIMEOUT_KEY = "timeout";
- private static final String TYPE_KEY = "type";
- private static final String URL_KEY = "url";
- private static final String USERNAME_KEY = "username";
-
- public Properties settings;
- public Function onSuccess;
- public Function onError;
-
- public Settings() {
- settings = Properties.create();
- initDefaults();
- }
-
- /**
- * Init some settings with default value
- */
- private void initDefaults() {
- setDataType("text");
- setType("POST");
- setContentType("application/x-www-form-urlencoded");
- }
-
- public String getContentType() {
- return settings.getStr(CONTENT_TYPE_KEY);
- }
-
- public Element getContext() {
- return settings.get(CONTEXT_KEY);
- }
-
- public Properties getData() {
- return settings.get(DATA_KEY);
- }
-
- public String getDataString() {
- return settings.get(DATA_STRING_KEY);
- }
-
- public String getDataType() {
- return settings.get(DATA_TYPE_KEY);
- }
-
- public Function getError() {
- return onError;
- }
-
- public Properties getHeaders() {
- return settings.get(HEADERS_KEY);
- }
-
- public String getPassword() {
- return settings.get(PASSWORD_KEY);
- }
-
- public Function getSuccess() {
- return onSuccess;
- }
-
- public int getTimeout() {
- Integer timeout = settings.get(TIMEOUT_KEY);
- return timeout != null ? timeout.intValue() : 0;
- }
-
- public String getType() {
- return settings.get(TYPE_KEY);
- }
-
- public String getUrl() {
- return settings.get(URL_KEY);
- }
-
- public String getUsername() {
- return settings.get(USERNAME_KEY);
- }
-
- public Settings setContentType(String t) {
- settings.set(CONTENT_TYPE_KEY, t);
- return this;
- }
-
- public Settings setContext(Element e) {
- settings.set(CONTEXT_KEY, e);
- return this;
- }
-
- public Settings setData(Properties p) {
- settings.set(DATA_KEY, p);
- return this;
- }
-
- public Settings setDataString(String d) {
- settings.set(DATA_STRING_KEY, d);
- return this;
- }
-
- public Settings setDataType(String t) {
- settings.set(DATA_TYPE_KEY, t);
- return this;
- }
-
- public Settings setError(Function f) {
- onError = f;
- return this;
- }
-
- public Settings setHeaders(Properties p) {
- settings.set(HEADERS_KEY, p);
- return this;
- }
-
- public Settings setPassword(String p) {
- settings.set(PASSWORD_KEY, p);
- return this;
- }
-
- public Settings setSuccess(Function f) {
- onSuccess = f;
- return this;
- }
-
- public Settings setTimeout(int t) {
- settings.set(TIMEOUT_KEY, t);
- return this;
- }
-
- public Settings setType(String t) {
- settings.set(TYPE_KEY, t);
- return this;
- }
-
- public Settings setUrl(String u) {
- settings.set(URL_KEY, u);
- return this;
- }
-
- public Settings setUsername(String u) {
- settings.set(USERNAME_KEY, u);
- return this;
- }
-
- public void load(Properties p) {
- settings = p;
- }
+ public interface Settings extends JsonBuilder {
+ String getContentType();
+ Element getContext();
+ Properties getData();
+ String getDataString();
+ String getDataType();
+ Function getError();
+ Properties getHeaders();
+ String getPassword();
+ Function getSuccess();
+ int getTimeout();
+ String getType();
+ String getUrl();
+ String getUsername();
+ Settings setContentType(String t);
+ Settings setContext(Element e);
+ Settings setData(Properties p);
+ Settings setDataString(String d);
+ Settings setDataType(String t);
+ Settings setError(Function f);
+ Settings setHeaders(Properties p);
+ Settings setPassword(String p);
+ Settings setSuccess(Function f);
+ Settings setTimeout(int t);
+ Settings setType(String t);
+ Settings setUrl(String u);
+ Settings setUsername(String u);
}
public static final Class<Ajax> Ajax = registerPlugin(Ajax.class, new Plugin<Ajax>() {
@@ -229,10 +104,6 @@ public class Ajax extends GQuery {
*/
public static void ajax(Settings settings) {
- final RequestBuilder requestBuilder = createRequestBuilder(settings);
-
- final String dataType = settings.getDataType();
-
final Function onSuccess = settings.getSuccess();
if (onSuccess != null) {
@@ -244,6 +115,19 @@ public class Ajax extends GQuery {
if (onError != null) {
onError.setElement(settings.getContext());
}
+
+
+ final String dataType = settings.getDataType();
+ if ("jsonp".equalsIgnoreCase(dataType)) {
+ Method httpMethod = resolveHttpMethod(settings);
+ String data = resolveData(settings);
+ String url = resolveUrl(settings, httpMethod, data);
+ int timeout = settings.getTimeout();
+ getJSONP(url, onSuccess, onError, timeout);
+ return;
+ }
+
+ final RequestBuilder requestBuilder = createRequestBuilder(settings);
requestBuilder.setCallback(new RequestCallback() {
@@ -323,7 +207,6 @@ public class Ajax extends GQuery {
}
private static String resolveUrl(Settings settings, Method httpMethod, String data) {
-
String url = settings.getUrl();
assert url != null : "no url found in settings";
@@ -331,7 +214,6 @@ public class Ajax extends GQuery {
if (data != null && httpMethod == RequestBuilder.GET) {
url += (url.contains("?") ? "&" : "?") + data;
}
-
return url;
}
@@ -341,18 +223,15 @@ public class Ajax extends GQuery {
if (data == null && settings.getData() != null) {
data = settings.getData().toQueryString();
}
-
return data;
}
private static Method resolveHttpMethod(Settings settings) {
-
String method = settings.getType();
if ("get".equalsIgnoreCase(method)) {
return RequestBuilder.GET;
}
-
return RequestBuilder.POST;
}
@@ -380,7 +259,7 @@ public class Ajax extends GQuery {
}
public static Settings createSettings() {
- return new Settings();
+ return createSettings($$(""));
}
public static Settings createSettings(String prop) {
@@ -412,6 +291,30 @@ public class Ajax extends GQuery {
s.setSuccess(onSuccess);
ajax(s);
}
+
+ public static void getJSONP(String url, Properties data, Function onSuccess) {
+ Settings s = createSettings();
+ s.setUrl(url);
+ s.setDataType("jsonp");
+ s.setType("get");
+ s.setData(data);
+ s.setSuccess(onSuccess);
+ ajax(s);
+ }
+
+ public static void getJSONP(String url, Function success, Function error, int timeout) {
+ System.err.println("EEE");
+
+ if (!url.contains("=?")) {
+ url += (url.contains("?") ? "&" : "?") + "callback=?";
+ }
+ url += "&_=" + System.currentTimeMillis();
+ Element e = $("head").get(0);
+ if (e == null) {
+ e = document.getDocumentElement();
+ }
+ getJsonpImpl(e, url, null, success, error == null ? success : error, timeout);
+ }
public static void post(String url, Properties data, final Function onSuccess) {
Settings s = createSettings();
@@ -447,4 +350,42 @@ public class Ajax extends GQuery {
ajax(s);
return this;
}
+
+ private static int callBackCounter = 0;
+
+ public static native void getJsonpImpl(Element elem, String url, String charset, Function success, Function error, int timeout) /*-{
+ var fName = "__GQ_cb_" + @com.google.gwt.query.client.plugins.ajax.Ajax::callBackCounter ++;
+ var done = false;
+ $wnd[fName] = function(data) {
+ if (!done) {
+ done = true;
+ $wnd[fName] = null;
+ success.@com.google.gwt.query.client.Function::setDataObject(Ljava/lang/Object;)(data);
+ success.@com.google.gwt.query.client.Function::f()();
+ }
+ }
+ function err() {
+ if (!done) {
+ done = true;
+ $wnd[fName] = null;
+ if (error) error.@com.google.gwt.query.client.Function::f()();
+ else success.@com.google.gwt.query.client.Function::f()();
+ }
+ }
+ if (timeout) {
+ setTimeout(err, timeout);
+ }
+
+ url = url.replace(/=\?/g,'=' + fName);
+ var script = document.createElement("script" );
+ script.async = "async";
+ if (charset) script.charset = charset;
+ script.src = url;
+ script.onload = script.onreadystatechange = function(evt) {
+ script.onload = script.onreadystatechange = null;
+ elem.removeChild(script);
+ err();
+ };
+ elem.insertBefore(script, elem.firstChild);
+ }-*/;
}
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java
index 5d3e8d68..98a85094 100644
--- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java
+++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java
@@ -24,10 +24,14 @@ import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.query.client.builders.JsonBuilder;
import com.google.gwt.query.client.builders.Name;
import com.google.gwt.query.client.builders.XmlBuilder;
+import com.google.gwt.query.client.plugins.ajax.Ajax;
+import com.google.gwt.query.client.plugins.ajax.Ajax.Settings;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
@@ -81,7 +85,7 @@ public class GQueryAjaxTestGwt extends GWTTestCase {
}
public void testJsonBuilder() {
- String json = "[{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}]";
+ String json = "{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}";
JsonExample c = GWT.create(JsonExample.class);
assertEquals(0, c.getA());
c.parse(json, true);
@@ -140,4 +144,52 @@ public class GQueryAjaxTestGwt extends GWTTestCase {
assertEquals("X", x.getA());
assertEquals(1234, x.getNumber());
}
+
+ public void testJsonValidService() {
+ delayTestFinish(5000);
+ String testJsonpUrl = "http://services.digg.com/stories/top?appkey=http://mashup.com&type=javascript&callback=?";
+ Ajax.getJSONP(testJsonpUrl, new Function(){
+ public void f() {
+ Properties p = getDataProperties();
+ assertTrue(0 < p.getInt("count"));
+ finishTest();
+ }
+ }, null, 0);
+ }
+
+ @DoNotRunWith({Platform.HtmlUnitLayout})
+ public void testJsonNonCallbackResponse() {
+ delayTestFinish(5000);
+ String testJsonpUrl = "http://www.google.com";
+ Ajax.getJSONP(testJsonpUrl, null, new Function(){
+ public void f() {
+ Properties p = getDataProperties();
+ assertNull(p);
+ finishTest();
+ }
+ }, 500);
+ }
+
+ public void testJsonTimeout() {
+ delayTestFinish(5000);
+ String nonJsonpUrl = "http://www.google.com/nopage";
+
+ Settings s = Ajax.createSettings();
+ s.setTimeout(400);
+ s.setSuccess(new Function(){
+ public void f() {
+ fail();
+ }
+ });
+ s.setError(new Function(){
+ public void f() {
+ finishTest();
+ }
+ });
+ s.setDataType("jsonp");
+ s.setUrl(nonJsonpUrl);
+
+ Ajax.ajax(s);
+ }
+
}