From e7949180eba17c7b070bbcce4f75bd3db81d66b7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Manuel=20Carrasco=20Mo=C3=B1ino?= Date: Fri, 22 Feb 2013 15:41:11 +0100 Subject: [PATCH] First step towards supporting Deferred: implementing Callbacks collections --- .../google/gwt/query/client/Properties.java | 1 - .../google/gwt/query/client/js/JsCache.java | 13 +- .../gwt/query/client/js/JsObjectArray.java | 14 ++ .../client/plugins/callbacks/Callbacks.java | 166 ++++++++++++++++++ .../query/client/GQueryDeferredTestGwt.java | 134 ++++++++++++++ .../gwt/query/client/GQueryGwtSuiteTest.java | 1 + 6 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java create mode 100644 gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java 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 8e68b184..090089f5 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 @@ -61,7 +61,6 @@ public class Properties extends JavaScriptObject { .replaceAll("[;,]+([\\]\\}]|$)", "$1") // remove endings ; ret = ret.matches("(^[\\[\\{].*[\\]\\}]$)") ? ret : "{" + ret + "}"; - System.out.println(s + " -> " + ret); return ret; } 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 35fef9c1..f8dca659 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 @@ -70,8 +70,7 @@ public class JsCache extends JavaScriptObject { } public final native boolean getBoolean(T id) /*-{ - var r = this[id], t = typeof r; - return 'boolean' == r ? r : 'true' == String(r); + return /true|1/.test(this[id]); }-*/; public final float getFloat(T id) { @@ -110,8 +109,18 @@ public class JsCache extends JavaScriptObject { for (k in this) return false; return true; }-*/; + + public final native boolean contains(Object o)/*-{ + return this.indexOf(o) >= 0; + }-*/; + + public final native void remove(Object o) /*-{ + var i = this.indexOf(o); + if (i >= 0) this.splice(i, 1); + }-*/; public final native int indexOf(Object o) /*-{ + // HtmlUnit fails when this returns 0 return this.indexOf(o); }-*/; diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsObjectArray.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsObjectArray.java index 9eac0d79..d8d5e312 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsObjectArray.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsObjectArray.java @@ -71,5 +71,19 @@ public final class JsObjectArray extends JavaScriptObject { public void pushAll(JavaScriptObject prevElem) { c().pushAll(prevElem); } + + public boolean contains(Object o) { + return c().contains(o); + } + + public void remove(Object... objects) { + for (Object o : objects) { + c().remove(o); + } + } + + public Object[] elements() { + return c().elements(); + } } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java new file mode 100644 index 00000000..db5bed00 --- /dev/null +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java @@ -0,0 +1,166 @@ +/* + * 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.callbacks; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.query.client.Function; +import com.google.gwt.query.client.Properties; +import com.google.gwt.query.client.builders.JsonBuilder; +import com.google.gwt.query.client.js.JsObjectArray; + +/** + * Implementation of jQuery.Callbacks for gwtquery. + */ +public class Callbacks { + + /** + * Iterface used for callbacks which could cancel the execution + * when returning false; + * + */ + public static interface Callback { + /** + * Return false to avoid executing the rest of functions + */ + boolean f(Object ...objects); + } + + /** + * Interface representing the options of a Callbacks collection. + * + * To create an implementation of this interface just call: Callbacks.createOptions() + */ + public static interface CallbackOptions extends JsonBuilder { + boolean getMemory(); + boolean getOnce(); + boolean getStopOnFalse(); + boolean getUnique(); + CallbackOptions setMemory(); + CallbackOptions setOnce(); + CallbackOptions setStopOnFalse(); + CallbackOptions setUnique(); + } + + public static CallbackOptions createOptions() { + return GWT.create(CallbackOptions.class); + } + + private JsObjectArray callbacks = JsObjectArray.create(); + + private boolean done = false; + + private JsObjectArray memory = JsObjectArray.create(); + + public final CallbackOptions opts; + + /** + * Create a new Callbacks object with default options + */ + public Callbacks() { + opts = createOptions(); + } + + /** + * Create a new Callbacks object with given options + */ + public Callbacks(CallbackOptions options) { + opts = options; + } + + /** + * Create a new Callbacks object with options given as a space delimited string. + * + * Valid options are: + * + * once, memory, unique, stopOnFalse + */ + public Callbacks(String options) { + this(); + opts.load(Properties.create(options.replaceAll("[^\\S]+|$", ":1,"))); + } + + /** + * Add a Callback or a collection of callbacks to a callback list. + * + */ + public Callbacks add(Callback... c) { + addAll((Object[])c); + return this; + } + + /** + * Add a Callback or a collection of callbacks to a callback list. + */ + public Callbacks add(com.google.gwt.core.client.Callback... c) { + addAll((Object[])c); + return this; + } + + /** + * Add a Function or a collection of Function to a callback list. + */ + public Callbacks add(Function... f) { + addAll((Object[])f); + return this; + } + + /** + * Disable a callback list from doing anything more. + */ + public Callbacks disable() { + done = true; + return this; + } + + /** + * Call all of the callbacks with the given arguments. + */ + public Callbacks fire(Object... o) { + run(opts.getMemory() ? memory.add(o).elements() : o); + return this; + } + + /** + * Remove a callback or a collection of callbacks from a callback list. + */ + public Callbacks remove(Object... o) { + callbacks.remove(o); + return this; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private void run(Object... o) { + if (!done) { + done = opts.getOnce(); + for (Object c : callbacks.elements()) { + if (c instanceof Callback) { + boolean r = ((Callback)c).f(o); + if (opts.getStopOnFalse() && !r) break; + } else if (c instanceof Function) { + ((Function)c).f(o); + } else if (c instanceof com.google.gwt.core.client.Callback) { + ((com.google.gwt.core.client.Callback)c).onSuccess(o); + } + } + } + } + + private void addAll(Object...o) { + for (Object i : o) { + if (!opts.getUnique() || !callbacks.contains(i)) { + callbacks.add(i); + } + } + } +} diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java new file mode 100644 index 00000000..dfd3f28a --- /dev/null +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java @@ -0,0 +1,134 @@ +/* + * 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 + * 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.junit.client.GWTTestCase; +import com.google.gwt.query.client.plugins.callbacks.Callbacks; +import com.google.gwt.query.client.plugins.callbacks.Callbacks.Callback; + +/** + * Test class for testing deferred and callbacks stuff. + */ +public class GQueryDeferredTestGwt extends GWTTestCase { + + public String getModuleName() { + return "com.google.gwt.query.Query"; + } + + private String result = ""; + + public void testCallbacks() { + Function fn1 = new Function() { + public void f() { + String s = " f1:"; + for (Object o: getData()){ + s += " " + o; + } + result += s; + } + }; + + Callback fn2 = new Callback() { + public boolean f(Object... objects) { + String s = " f2:"; + for (Object o: objects){ + s += " " + o; + } + result += s; + return false; + } + }; + + com.google.gwt.core.client.Callback fn3 = new com.google.gwt.core.client.Callback() { + public void onFailure(Object reason) { + String s = " f3_fail: " + reason; + System.out.println(s); + } + public void onSuccess(Object objects) { + String s = " f3_success:"; + for (Object o: (Object[])objects){ + s += " " + o; + } + result += s; + } + }; + + + + result = ""; + Callbacks callbacks = new Callbacks(); + callbacks.add( fn1 ); + callbacks.fire( "foo" ); + assertEquals(" f1: foo", result); + + result = ""; + callbacks.add( fn2 ); + callbacks.fire( "bar" ); + assertEquals(" f1: bar f2: bar", result); + + result = ""; + callbacks.remove( fn2 ); + callbacks.fire( "foobar" ); + assertEquals(" f1: foobar", result); + + result = ""; + callbacks.add( fn1 ); + callbacks.fire( "foo" ); + assertEquals(" f1: foo f1: foo", result); + + result = ""; + callbacks = new Callbacks("unique"); + callbacks.add( fn1 ); + callbacks.add( fn1 ); + callbacks.fire( "foo" ); + assertEquals(" f1: foo", result); + + result = ""; + callbacks.add( fn3 ); + callbacks.fire( "bar" ); + assertEquals(" f1: bar f3_success: bar", result); + + result = ""; + callbacks = new Callbacks("memory"); + callbacks.add( fn1 ); + callbacks.fire( "foo" ); + callbacks.add( fn2 ); + callbacks.fire( "bar" ); + assertEquals(" f1: foo f1: foo bar f2: foo bar", result); + + result = ""; + callbacks = new Callbacks("stopOnFalse"); + callbacks.add( fn2 ); + callbacks.add( fn1 ); + callbacks.fire( "bar" ); + assertEquals(" f2: bar", result); + + result = ""; + callbacks.disable(); + callbacks.fire( "bar" ); + assertEquals("", result); + + result = ""; + callbacks = new Callbacks("once"); + callbacks.add( fn1 ); + callbacks.fire( "bar" ); + assertEquals(" f1: bar", result); + callbacks.fire( "foo" ); + assertEquals(" f1: bar", result); + } + +} diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java index 370b5cc7..4093efae 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryGwtSuiteTest.java @@ -15,6 +15,7 @@ public class GQueryGwtSuiteTest extends GWTTestSuite { GWTTestSuite suite = new GWTTestSuite( "GQuery Suite" ); suite.addTestSuite(GQueryAjaxTestGwt.class); + suite.addTestSuite(GQueryDeferredTestGwt.class); suite.addTestSuite(GQuerySelectorsTestGwt.class); suite.addTestSuite(GQueryCoreTestGwt.class); suite.addTestSuite(GQueryCssTestGwt.class); -- 2.39.5