]> source.dussan.org Git - gwtquery.git/commitdiff
First implementation of Deferred and Promises. Ajax tests work. then implementation...
authorManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Sun, 3 Mar 2013 21:00:29 +0000 (22:00 +0100)
committerManuel Carrasco Moñino <manuel.carrasco.m@gmail.com>
Sun, 3 Mar 2013 21:00:29 +0000 (22:00 +0100)
12 files changed:
devtest/pom.xml
devtest/src/main/java/com/google/gwt/query/DevTestRunner.gwt.xml
devtest/src/main/java/com/google/gwt/query/client/DevTestRunner.java
gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/ajax/Ajax.java
gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java

index 3f73740f4c5fd224973407f9c005761439c51d99..42e25b5609d8a0c4af4777b5c3c800b9b153a35e 100644 (file)
             <version>${gwtversion}</version>
             <scope>provided</scope>
         </dependency>        
+        <dependency>
+          <groupId>com.google.gwt</groupId>
+          <artifactId>gwt-codeserver</artifactId>
+          <version>${gwtversion}</version>
+        </dependency>
     </dependencies>
     <build>
         <resources>
                  </additionalProjectnatures>
               </configuration>
           </plugin>
+          <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                   <execution>
+                     <goals>
+                       <goal>java</goal>
+                     </goals>
+                   </execution>
+                </executions>
+               <configuration>
+                  <mainClass>com.google.gwt.dev.codeserver.CodeServer</mainClass>
+                  <arguments>
+                      <argument>-src</argument>
+                      <argument>src/main/java</argument>
+                      <argument>-bindAddress</argument>
+                      <argument>0.0.0.0</argument>
+                      <argument>com.google.gwt.query.DevTestRunner</argument>
+                  </arguments>
+                  <classpathScope>compile</classpathScope>
+               </configuration>
+          </plugin>
+
         </plugins>
         <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
     </build>
index 401fde05622858318b75409e0e7cfd1bb1827ef7..b3ce809fee994537dc0c9cd38e8493b54ae8d098 100644 (file)
@@ -1,5 +1,6 @@
 <module rename-to="test">
     <inherits name='com.google.gwt.query.Query'/>
     <entry-point class='com.google.gwt.query.client.DevTestRunner'/>
+    <set-property name="compiler.useSourceMaps" value="false"/>
 </module>
 
index 53ef8e188af90c103626dfd03a2bf10921992450..18de0c876ac22951602ed859993be04727a68178 100644 (file)
@@ -22,6 +22,9 @@ import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
 import com.google.gwt.query.client.js.JsUtils;
+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.Window;
 
 /**
  * This module is thought to emulate a test environment similar to
@@ -45,8 +48,92 @@ public class DevTestRunner extends MyTestCase implements EntryPoint {
       $(e).html("").after("<div>ERROR: " + ex.getMessage() + "</div>");
     }
   }
-
+  
   public void testSomething() {
+    System.out.println("com");
+    
+    delayTestFinish(5000);
+    String nonJsonpUrl = "http://127.0.0.1/nopage";
+
+    Settings s = Ajax.createSettings();
+    s.setTimeout(1000);
+    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);
+    
+//    GQuery.ajax(Ajax.createSettings()
+//        .setUrl("test.html")
+//        .setDataType("txt") // txt, json, jsonp, xml
+//        .setType("get")     // post, get
+//        .setData(GQuery.$$("param1: 1, param2: 2")) // parameters for the query-string
+//        .setTimeout(3000)
+//        .setSuccess(new Function(){ // callback to be run if the request success
+//          public void f() {
+//            // The response when dataType=xml, is a dom tree which we can traverse using gquery
+//            Window.alert("ok");
+//          }
+//        })
+////        .setError(new Function(){ // callback to be run if the request fails
+////          public void f() {
+////            Window.alert("There was an error" + getDataObject());
+////          }
+////        })
+//      ).done(new Function(){
+//        public void f() {
+//          System.out.println("Aqui");
+//        }
+//      }, new Function(){
+//        public void f() {
+//          System.out.println("Aqui2");
+//        }
+//      }
+//      );
+//    
+    
+    
+//    Settings set = Ajax.createSettings();
+//    
+//    $(window).delay(1000, new Function(){
+//      public void f() {
+//        System.out.println("Run 1");
+//      }
+//    });
+//    $(window).delay(3000, new Function(){
+//      public void f() {
+//        System.out.println("Run 3");
+//      }
+//    });
+  }
+
+  
+  private native void setWindowVars() /*-{
+    $wnd._boolean = true;
+    $wnd._number = 0.56;
+    $wnd._string = "string";
+    $wnd._element = $doc.body;
+    $wnd._object = $wnd.console;
+  }-*/;
+
+  public void testSomething2() {
+    setWindowVars();
+    System.out.println($(window).prop("_boolean"));
+    System.out.println($(window).propString("_string"));
+    System.out.println($(window).propDouble("_number"));
+    System.out.println($(window).propObject("_boolean"));
+    System.out.println($(window).propJSO("_element"));
+    Object o = window.getPropertyObject("_element");
+    System.out.println(o);
     // Copy and paste any test from the gquery suite
   }
 
index 361eea1f15a5e254472a159acb05f8b1da141e97..5bb4f5f63b3c95bdb64c5030fba9fefca3b761af 100644 (file)
@@ -29,7 +29,7 @@ public abstract class Function {
   private com.google.gwt.dom.client.Element element = null;
   private Event event = null;
   private int index = -1;
-  private Object[] data = new Object[0];
+  protected Object[] arguments = new Object[0];
 
   public <T extends com.google.gwt.dom.client.Element> T getElement() {
     return element.<T>cast();
@@ -51,21 +51,48 @@ public abstract class Function {
   public void setIndex(int i) {
     index = i;
   }
-
+  
+  @Deprecated
   public Object[] getData() {
-    return data;
+    return getArguments();
   }
 
-  public void setData(Object...data) {
-    this.data = data;
+  public Object[] getArguments() {
+    return arguments;
+  }
+  
+  @Deprecated
+  public void setData(Object...arguments) {
+    setArguments(arguments);
+  }
+
+  /**
+   * Set the list of arguments to be passed to the function
+   */
+  public void setArguments(Object...arguments) {
+    this.arguments = arguments;
   }
 
+  /**
+   * Return the first element of the arguments list
+   */
   public Object getDataObject() {
-    return getDataObject(0);
+    return getArgument(0);
   }
 
+  /**
+   * @deprecated use getArgument instead 
+   */
+  @Deprecated
   public Object getDataObject(int idx) {
-    return data != null && data.length > idx ? data[idx] : null;
+    return getArgument(0);
+  }
+
+  /**
+   * return the argument in position idx; 
+   */
+  public Object getArgument(int idx) {
+    return arguments != null && arguments.length > idx ? arguments[idx] : null;
   }
 
   public Properties getDataProperties() {
@@ -73,7 +100,7 @@ public abstract class Function {
   }
 
   public Properties getDataProperties(int idx) {
-    Object o = getDataObject(idx);
+    Object o = getArgument(idx);
     if (o != null && o instanceof JavaScriptObject) {
       return (Properties)o;
     }
@@ -89,7 +116,7 @@ public abstract class Function {
   }
 
   public void setDataObject(Object data) {
-    setData(data);
+    setArguments(data);
   }
 
   public int getIndex() {
@@ -177,8 +204,10 @@ public abstract class Function {
   /**
    * Override this method for bound callbacks
    */
-  public void f(Object... data) {
-    fe(data);
+  public Object f(Object... data) {
+    setArguments(data);
+    f();
+    return true;
   }
 
   /**
@@ -193,7 +222,7 @@ public abstract class Function {
    */
   public void f(int i, Object... data) {
     setIndex(i);
-    setData(data);
+    setArguments(data);
     if (data.length == 1 && data[0] instanceof JavaScriptObject) {
       if (JsUtils.isElement((JavaScriptObject)data[0])) {
         setElement((com.google.gwt.dom.client.Element)data[0]);
@@ -212,7 +241,7 @@ public abstract class Function {
    * per-handler user data.
    */
   public boolean f(Event e, Object data) {
-    setData(data);
+    setArguments(data);
     setEvent(e);
     return f(e);
   }
@@ -282,7 +311,7 @@ public abstract class Function {
    * They are intentionally final to avoid override them
    */
   public final void fe() {
-    fe(data);
+    fe(arguments);
   }
 
   /**
@@ -299,17 +328,16 @@ public abstract class Function {
    * catch the exception and send it to the GWT UncaughtExceptionHandler
    * They are intentionally final to avoid override them
    */
-  public final void fe(Object... data) {
-    setData(data);
+  public final Object fe(Object... data) {
     if (GWT.getUncaughtExceptionHandler() != null) {
       try {
-        f();
+        return f(data);
       } catch (Exception e) {
         GWT.getUncaughtExceptionHandler().onUncaughtException(e);
       }
-      return;
+      return true;
     }
-    f();
+    return f(data);
   }
 
   /**
index 47370ef49599b6ecb753b1c0ddb0a70032f7be44..1a2afc78dfe80f4c9b743d78686a30f03f99cfe3 100644 (file)
@@ -25,9 +25,18 @@ import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.core.client.JsArray;
 import com.google.gwt.core.client.JsArrayMixed;
 import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.dom.client.*;
+import com.google.gwt.dom.client.BodyElement;
+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.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.Display;
 import com.google.gwt.dom.client.Style.HasCssName;
+import com.google.gwt.dom.client.TextAreaElement;
 import com.google.gwt.query.client.css.CSS;
 import com.google.gwt.query.client.css.HasCssValue;
 import com.google.gwt.query.client.css.TakesCssValue;
@@ -232,7 +241,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return JsUtils.isWindow(jso) ? $(jso.<Element> cast()) :
       JsUtils.isElement(jso) ? $(jso.<Element> cast()) :
       JsUtils.isEvent(jso) ? $(jso.<Event> cast()) :
-      JsUtils.isNodeList(jso) ? $(jso.<NodeList<Element>> cast()) : $();
+      JsUtils.isNodeList(jso) ? $(jso.<NodeList<Element>> cast()) : 
+        $(jso.<Element> cast());
   }
 
   /**
@@ -402,22 +412,22 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   /**
    * Perform an ajax request to the server.
    */
-  public static void ajax(Properties p) {
-    Ajax.ajax(p);
+  public static Promise ajax(Properties p) {
+    return Ajax.ajax(p);
   }
 
   /**
    * Perform an ajax request to the server.
    */
-  public static void ajax(Settings settings) {
-    Ajax.ajax(settings);
+  public static Promise ajax(Settings settings) {
+    return Ajax.ajax(settings);
   }
 
   /**
    * Perform an ajax request to the server.
    */
-  public static void ajax(String url, Settings settings) {
-    Ajax.ajax(url, settings);
+  public static Promise ajax(String url, Settings settings) {
+    return Ajax.ajax(url, settings);
   }
 
   @SuppressWarnings("unchecked")
@@ -3454,11 +3464,9 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    *
    */
   public boolean prop(String key) {
-    assert key != null : "Key is null";
-
-    return !isEmpty() && get(0).getPropertyBoolean(key);
+    return !isEmpty() && elements[0].getPropertyBoolean(key);
   }
-
+  
   /**
    * Sets a boolean property to a value on all matched elements.
    *
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java
new file mode 100644 (file)
index 0000000..c31e0c9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013, 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 the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 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.
+ */
+package com.google.gwt.query.client;
+
+import com.google.gwt.query.client.Function;
+
+/**
+ * Definition of jquery Promise interface used in gquery. 
+ */
+public interface Promise {
+
+  public static final String PENDING = "pending";
+  public static final String REJECTED = "rejected";
+  public static final String RESOLVED = "resolved";
+
+  Promise always(Function... o);
+
+  Promise done(Function... o);
+
+  Promise fail(Function... o);
+
+  Promise pipe(Function... f);
+
+  Promise progress(Function... o);
+
+  String state();
+
+  Promise then(Function... f);
+
+}
\ No newline at end of file
index f8dca6596344f7bb8c8700ae80d8d1ed9c166622..259ed204d27420e4e4a3b8b0e0b8215330e7764c 100644 (file)
@@ -94,7 +94,7 @@ public class JsCache extends JavaScriptObject {
 
   public final native <T> JsArrayMixed getArray(T id) /*-{
     var r = this[id];
-    if (r && @com.google.gwt.query.client.js.JsUtils::isArray(*)(r)) {
+    if (r && Object.prototype.toString.call(r) == '[object Array]') {
       return r;
     }
     return null;
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java
new file mode 100644 (file)
index 0000000..6b89b88
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2013, 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 the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 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.
+ */
+package com.google.gwt.query.client.plugins;
+
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.Promise;
+import com.google.gwt.query.client.plugins.callbacks.Callbacks;
+
+/**
+ * Implementation of jQuery.Deffered for gwtquery.
+ */
+public class Deferred extends GQuery {
+  
+  private class DeferredPromise extends GQuery implements Promise {
+    private Deferred dfd;
+
+    protected DeferredPromise(GQuery gq) {
+      super(gq);
+      if (gq instanceof Deferred) {
+        dfd = (Deferred) gq;
+      } else  if (gq instanceof DeferredPromise) {
+        dfd = ((DeferredPromise)gq).dfd;;
+      } else {
+        dfd = gq.as(Deferred);
+      }
+    }
+    
+    public Promise always(Function... o) {
+      return done(o).fail(o);
+    }
+
+    public Promise done(Function... o) {
+      dfd.resolve.add(o);
+      return this;
+    }
+    
+    public Promise fail(Function... o) {
+      dfd.reject.add(o);
+      return this;
+    }
+
+    public Promise pipe(Function... f) {
+      return then(f);
+    }
+    
+    public Promise progress(Function... o) {
+      dfd.notify.add(o);
+      return this;
+    }
+    
+    public String state() {
+      return dfd.state;
+    }
+    
+    public Promise then(Function... f) {
+      switch (f.length) {
+        case 3: progress(f[0]);
+        case 2: fail(f[0]);
+        case 1: done(f[0]);
+      }
+      return this;
+    }
+  }
+  public static final Class<Deferred> Deferred = GQuery.registerPlugin(
+      Deferred.class, new Plugin<Deferred>() {
+        public Deferred init(GQuery gq) {
+          return new Deferred(gq);
+        }
+      });
+  public static Promise when(Deferred d) {
+    return d.promise();
+  }
+  private Callbacks notify = new Callbacks("memory");
+  
+  private Promise promise = null;
+  
+  private Callbacks reject = new Callbacks("once memory");
+  
+  private Callbacks resolve = new Callbacks("once memory");
+  
+  private String state = Promise.PENDING;
+  
+  protected Deferred(GQuery gq) {
+    super(gq);
+    resolve.add(new Function() {
+      public void f() {
+        state = Promise.RESOLVED;
+        resolve.disable();
+        notify.lock();
+      }
+    });
+
+    reject.add(new Function() {
+      public void f() {
+        state = Promise.REJECTED;
+        reject.disable();
+        notify.lock();
+      }
+    });
+  }
+  // private, used from jsni
+  @SuppressWarnings("unused")
+  private void err(Object o) {
+    reject(o);
+  }
+  public Deferred notify(Object... o) {
+    notify.fire(o);
+    return this;
+  }
+  
+  // private, used from jsni
+  @SuppressWarnings("unused")
+  private void ok(Object o) {
+    resolve(o);
+  }
+  
+  public Promise promise() {
+    if (promise == null) {
+      promise = new DeferredPromise(this);
+    }
+    return promise;
+  }
+
+  
+  public Deferred reject(Object... o) {
+    reject.fire(o);
+    return this;
+  }
+  
+  public Deferred resolve(Object... o) {
+    resolve.fire(o);
+    return this;
+  }
+}
index 96a3d35b0cc2df15c3cf6ba471cf2dd116ff7a43..0c60de9c59a39420e1410e099caf03fad0148428 100644 (file)
@@ -1,6 +1,7 @@
 package com.google.gwt.query.client.plugins.ajax;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptException;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.http.client.Request;
 import com.google.gwt.http.client.RequestBuilder;
@@ -10,11 +11,15 @@ import com.google.gwt.http.client.RequestException;
 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.Promise;
 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.Deferred;
 import com.google.gwt.query.client.plugins.Plugin;
 import com.google.gwt.user.client.ui.FormPanel;
+import com.google.gwt.xhr.client.ReadyStateChangeHandler;
+import com.google.gwt.xhr.client.XMLHttpRequest;
 
 /**
  * Ajax class for GQuery.
@@ -70,10 +75,10 @@ public class Ajax extends GQuery {
     }
   });
 
-  public static void ajax(Properties p) {
+  public static Promise ajax(Properties p) {
     Settings s = createSettings();
     s.load(p);
-    ajax(s);
+    return ajax(s);
   }
 
   /**
@@ -103,7 +108,7 @@ public class Ajax extends GQuery {
    * @param onError the function to execute on error
    * @param settings a Properties object with the configuration of the Ajax request.
    */
-  public static void ajax(Settings settings) {
+  public static void ajaxOld(Settings settings) {
 
     final Function onSuccess = settings.getSuccess();
     if (onSuccess != null) {
@@ -133,6 +138,8 @@ public class Ajax extends GQuery {
           onError.f(null, exception.getMessage(), request, null, exception);
         }
       }
+      
+      
 
       public void onResponseReceived(Request request, Response response) {
         int statusCode = response.getStatusCode();
@@ -172,6 +179,120 @@ public class Ajax extends GQuery {
       }
     }
   }
+  
+  
+  public static Promise ajax(Settings settings) {
+
+    final Deferred dfd = $().as(Deferred.Deferred);
+
+    final Function onSuccess = settings.getSuccess();
+    if (onSuccess != null) {
+      onSuccess.setElement(settings.getContext());
+      dfd.promise().done(onSuccess);
+    }
+
+    final Function onError = settings.getError();
+    if (onError != null) {
+      onError.setElement(settings.getContext());
+      dfd.promise().fail(onError);
+    }
+
+    Method httpMethod = resolveHttpMethod(settings);
+    String data = resolveData(settings, httpMethod);
+    final String url = resolveUrl(settings, httpMethod, data);
+    final String dataType = settings.getDataType();
+
+    if ("jsonp".equalsIgnoreCase(dataType)) {
+      int timeout = settings.getTimeout();
+      return getJSONP(url, onSuccess, onError, timeout);
+    }
+
+    RequestCallback mdb = new RequestCallback() {
+      public void onError(Request request, Throwable exception) {
+        if (onError != null) {
+          onError.f(null, exception.getMessage(), request, null, exception);
+        }
+      }
+
+      public void onResponseReceived(Request request, Response response) {
+        int statusCode = response.getStatusCode();
+        if (statusCode <= 0 || statusCode >= 400) {
+          if (statusCode == 0) {
+            // Just warn the developer about the status code
+            GWT.log("GQuery.ajax error, the response.statusCode is 0, this usually happens when you try to access an external server without CORS enabled. url=" + url);
+          }
+          dfd.reject(response.getText(), "error", request, response);
+        } else if (onSuccess != 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) {
+            if (GWT.getUncaughtExceptionHandler() != null) {
+              GWT.getUncaughtExceptionHandler().onUncaughtException(e);
+            }
+          }
+          dfd.resolve(retData, "success", request, response);
+        }
+      }
+    };
+    
+    XMLHttpRequest xmlHttpRequest = createXHR(settings, httpMethod.toString(), url, dataType, mdb);
+    
+    try {
+      xmlHttpRequest.send(data);
+    } catch (JavaScriptException e) {
+      dfd.reject(e.getMessage(), "error", null, null, e);
+    }
+    
+    return dfd.promise();
+  }
+  
+  
+  private static native Request createRequest(XMLHttpRequest r, int t, RequestCallback c) /*-{
+   return @com.google.gwt.http.client.Request::new(Lcom/google/gwt/xhr/client/XMLHttpRequest;ILcom/google/gwt/http/client/RequestCallback;)(r, t, c);
+  }-*/;
+  
+  private static native void fireOnResponseReceived(Request q, RequestCallback c) /*-{
+    q.@com.google.gwt.http.client.Request::fireOnResponseReceived(*)(c);
+  }-*/;
+  
+  
+  private static XMLHttpRequest createXHR (Settings settings, String httpMethod, String url, String data, final RequestCallback cb) {
+    XMLHttpRequest xmlHttpRequest = XMLHttpRequest.create();
+
+    if (settings.getUsername() != null && settings.getPassword() != null) {
+      xmlHttpRequest.open(httpMethod.toString(), url, settings.getUsername(), settings.getPassword());
+    } else if (settings.getUsername() != null) {
+      xmlHttpRequest.open(httpMethod, url, settings.getUsername());
+    } else {
+      xmlHttpRequest.open(httpMethod, url);
+    }
+    
+    Properties headers = settings.getHeaders();
+    if (headers != null) {
+      for (String headerKey : headers.keys()) {
+        xmlHttpRequest.setRequestHeader(headerKey, headers.getStr(headerKey));
+      }
+    }
+
+    final Request request = createRequest(xmlHttpRequest, settings.getTimeout(), cb);
+    xmlHttpRequest.setOnReadyStateChange(new ReadyStateChangeHandler() {
+      public void onReadyStateChange(XMLHttpRequest xhr) {
+        if (xhr.getReadyState() == XMLHttpRequest.DONE) {
+          xhr.clearOnReadyStateChange();
+          fireOnResponseReceived(request, cb);
+        }
+      }
+    });
+    
+    return xmlHttpRequest;
+  }
 
   private static RequestBuilder createRequestBuilder(Settings settings, Method httpMethod, String url, String data) {
 
@@ -255,27 +376,27 @@ public class Ajax extends GQuery {
     return RequestBuilder.POST;
   }
 
-  public static void ajax(String url, Function onSuccess, Function onError) {
-    ajax(url, onSuccess, onError, (Settings) null);
+  public static Promise ajax(String url, Function onSuccess, Function onError) {
+    return ajax(url, onSuccess, onError, (Settings) null);
   }
 
-  public static void ajax(String url, Function onSuccess, Function onError, Settings s) {
+  public static Promise ajax(String url, Function onSuccess, Function onError, Settings s) {
     if (s == null) {
       s = createSettings();
     }
     s.setUrl(url).setSuccess(onSuccess).setError(onError);
-    ajax(s);
+    return ajax(s);
   }
 
-  public static void ajax(String url, Properties p) {
+  public static Promise ajax(String url, Properties p) {
     Settings s = createSettings();
     s.load(p);
     s.setUrl(url);
-    ajax(s);
+    return ajax(s);
   }
 
-  public static void ajax(String url, Settings settings) {
-    ajax(settings.setUrl(url));
+  public static Promise ajax(String url, Settings settings) {
+    return ajax(settings.setUrl(url));
   }
 
   public static Settings createSettings() {
@@ -322,7 +443,7 @@ public class Ajax extends GQuery {
     ajax(s);
   }
 
-  public static void getJSONP(String url, Function success, Function error, int timeout) {
+  public static Promise getJSONP(String url, Function success, Function error, int timeout) {
     if (!url.contains("=?") && !url.contains("callback=")) {
       url += (url.contains("?") ? "&" : "?") + "callback=?";
     }
@@ -331,7 +452,10 @@ public class Ajax extends GQuery {
     if (e == null) {
       e = document.getDocumentElement();
     }
-    getJsonpImpl(e, url, null, success, error == null ? success : error, timeout);
+    Deferred dfd = $().as(Deferred.Deferred);
+    dfd.promise().done(success).fail(error == null ? success : error);
+    getJsonpImpl(e, url, null, dfd, timeout);
+    return dfd.promise();
   }
 
   public static void post(String url, Properties data, final Function onSuccess) {
@@ -362,7 +486,7 @@ public class Ajax extends GQuery {
           // Note: using '\s\S' instead of '.' because gwt String emulation does
           // not support java embedded flag expressions (?s) and javascript does
           // not have multidot flag.
-          String s = getData()[0].toString().replaceAll("<![^>]+>\\s*", "")
+          String s = getArguments()[0].toString().replaceAll("<![^>]+>\\s*", "")
             .replaceAll("</?html[\\s\\S]*?>\\s*", "")
             .replaceAll("<head[\\s\\S]*?</head>\\s*", "")
             .replaceAll("<script[\\s\\S]*?</script>\\s*", "")
@@ -388,22 +512,21 @@ public class Ajax extends GQuery {
 
   private static int callBackCounter = 0;
 
-  public static native void getJsonpImpl(Element elem, String url, String charset, Function success, Function error, int timeout) /*-{
+  public static native void getJsonpImpl(Element elem, String url, String charset, Deferred dfd, 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::fe(Ljava/lang/Object;)(data);
+        dfd.@com.google.gwt.query.client.plugins.Deferred::ok(*)(data)
       }
     }
     function err() {
       if (!done) {
         done = true;
         $wnd[fName] = null;
-        var func = error ? error : success;
-        func.@com.google.gwt.query.client.Function::fe(Ljava/lang/Object;)();
+        dfd.@com.google.gwt.query.client.plugins.Deferred::err(*)(null)
       }
     }
     if (timeout) {
@@ -411,7 +534,7 @@ public class Ajax extends GQuery {
     }
 
     url = url.replace(/=\?/g,'=' + fName);
-    var script = document.createElement("script" );
+    var script = document.createElement("script");
     script.async = "async";
     if (charset) script.charset = charset;
     script.src = url;
index 0a34b5d593ab0bb8858115ba3284c5034496a023..7ffd510aa738a6b5e14fc57a47313844b78a54ba 100644 (file)
@@ -56,7 +56,7 @@ public class Callbacks {
     return GWT.create(CallbackOptions.class);
   }
   
-  private JsObjectArray<Object> callbacks = JsObjectArray.create();
+  private JsObjectArray<Object> stack = JsObjectArray.create();
   
   private boolean done = false;
     
@@ -119,10 +119,21 @@ public class Callbacks {
    * Disable a callback list from doing anything more.
    */
   public Callbacks disable() {
-    callbacks = memory = null;
+    stack = memory = null;
     done = true;
     return this;
   }
+  
+  /**
+   * lock
+   */
+  public Callbacks lock() {
+    if (!opts.getMemory()) {
+      disable();
+    }
+    stack = null;
+    return this;
+  }
 
   /**
    * Call all of the callbacks with the given arguments.
@@ -130,7 +141,7 @@ public class Callbacks {
   public Callbacks fire(Object... o) {
     if (!done) {
       done = opts.getOnce();
-      for (Object c : callbacks.elements()) {
+      for (Object c : stack.elements()) {
         if (!run(c, o) && opts.getStopOnFalse()) {
           break;
         }
@@ -146,15 +157,15 @@ public class Callbacks {
    * Remove a callback or a collection of callbacks from a callback list.
    */
   public Callbacks remove(Object... o) {
-    callbacks.remove(o);
+    stack.remove(o);
     return this;
   }
   
   private void addAll(Object...o) {
-    if (callbacks != null) {
+    if (stack != null) {
       for (Object c : o) {
-        if (!opts.getUnique() || !callbacks.contains(c)) {
-          callbacks.add(c);
+        if (!opts.getUnique() || !stack.contains(c)) {
+          stack.add(c);
         }
         // In jQuery add always is run when memory is true even when unique is set
         if (opts.getMemory() && memory != null) {
@@ -169,7 +180,8 @@ public class Callbacks {
     if (c instanceof Callback) {
       return ((Callback)c).f(o);
     } else if (c instanceof Function) {
-      ((Function)c).f(o);
+      Object r = ((Function)c).f(o);
+      return (r instanceof Boolean) ? (Boolean)r : true;
     } else if (c instanceof com.google.gwt.core.client.Callback) {
       ((com.google.gwt.core.client.Callback)c).onSuccess(o);
     }
index 9bcc48841210fecfb563c59b611d8acfa7a2780c..c7ceb12885e5b64cd9a51da62be1d2fce6409ef8 100644 (file)
@@ -33,12 +33,13 @@ public class GQueryDeferredTestGwt extends GWTTestCase {
 
   public void testCallbacks() {
     Function fn1 = new Function() {
-      public void f() {
+      public Object f(Object...arguments) {
         String s = " f1:";
-        for (Object o: getData()){
+        for (Object o: arguments){
           s += " " + o;
         }
         result += s;
+        return false;
       }
     };
     
@@ -55,8 +56,7 @@ public class GQueryDeferredTestGwt extends GWTTestCase {
     
     com.google.gwt.core.client.Callback<Object, Object> fn3 = new com.google.gwt.core.client.Callback<Object, Object>() {
       public void onFailure(Object reason) {
-        String s = " f3_fail: " + reason;
-        System.out.println(s);
+        result += " f3_fail: " + reason;
       }
       public void onSuccess(Object objects) {
         String s = " f3_success:";
@@ -112,10 +112,10 @@ public class GQueryDeferredTestGwt extends GWTTestCase {
 
     result = "";
     callbacks = new Callbacks("stopOnFalse");
-    callbacks.add( fn2 );
     callbacks.add( fn1 );
+    callbacks.add( fn2 );
     callbacks.fire( "bar" );
-    assertEquals(" f2: bar", result);
+    assertEquals(" f1: bar", result);
     
     result = "";
     callbacks.disable();
index c833c130e27928b76b0eb7a524e78de3dc2186d9..6951f7519a5f567a5e346c413d9b9e94f8fb809e 100644 (file)
@@ -953,7 +953,7 @@ public class GQueryEventsTestGwt extends GWTTestCase {
       public void f(Element elem) {
         $(elem).css(CSS.FONT_SIZE.with(Length.px(24)));
 
-        assertEquals("red", getData()[0]);
+        assertEquals("red", getArguments()[0]);
       }
     });
     $("p", e, Events.Events).trigger(Event.ONCLICK);