From 66883167776b74b64d0dbc3329c3720aa8574747 Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Sat, 31 Jul 2010 11:20:14 +0000 Subject: [PATCH] added namespaces to bind/unbind methods in the Events plugins, fixes issue43 --- .../gwt/query/client/plugins/Events.java | 68 +++++++++++- .../query/client/plugins/EventsListener.java | 65 +++++++++-- .../gwt/query/client/GQueryEventsTest.java | 105 +++++++++++++----- 3 files changed, 197 insertions(+), 41 deletions(-) diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java index ec1c1d41..8566a759 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java @@ -50,7 +50,7 @@ public class Events extends GQuery { public Events(NodeList list) { super(list); } - + /** * Binds a set of handlers to a particular Event for each matched element. * @@ -68,6 +68,46 @@ public class Events extends GQuery { } return this; } + + /** + * Binds a set of handlers to a particular Event for each matched element. + * + * The namespace is a way to group events of the same type, making easier unbind + * specific handlers. + * + * The event handlers are passed as Functions that you can use to prevent + * default behavior. To stop both default action and event bubbling, the + * function event handler has to return false. + * + * You can pass an additional Object data to your Function + * + */ + public Events bind(int eventbits, String namespace, Object data, Function...funcs) { + for (Element e : elements()) { + EventsListener.getInstance(e).bind(eventbits, namespace, data, funcs); + } + return this; + } + + /** + * Binds a set of handlers to a particular Event for each matched element. + * + * The name could contain a namespace which is a way to group events of the same type, + * making easier unbind specific handlers. + * + * The event handlers are passed as Functions that you can use to prevent + * default behavior. To stop both default action and event bubbling, the + * function event handler has to return false. + * + * You can pass an additional Object data to your Function + * + */ + public Events bind(String event, Object data, Function...funcs) { + for (Element e : elements()) { + EventsListener.getInstance(e).bind(event, data, funcs); + } + return this; + } /** * Binds a handler to a particular Event (like Event.ONCLICK) for each matched @@ -163,6 +203,32 @@ public class Events extends GQuery { return this; } + /** + * Removes all handlers, that matches the events bits and the namespace + * passed, from each element. + * + * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER, "my.namespace") + */ + public Events unbind(int eventbits, String name) { + for (Element e : elements()) { + EventsListener.getInstance(e).unbind(eventbits, name); + } + return this; + } + + /** + * Removes all handlers, that matches event name passed. This name + * could contain a namespace. + * + * Example: unbind("click.my.namespace") + */ + public Events unbind(String name) { + for (Element e : elements()) { + EventsListener.getInstance(e).unbind(name); + } + return this; + } + private void dispatchEvent(NativeEvent evt) { for (Element e : elements()) { e.dispatchEvent(evt); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java index 9155b41a..93fb6881 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/EventsListener.java @@ -39,17 +39,21 @@ public class EventsListener implements EventListener { Object data; Function function; + String nameSpace = ""; int times = -1; int type; - BindFunction(int t, Function f, Object d) { + BindFunction(int t, String n, Function f, Object d) { type = t; function = f; data = d; + if (n!=null) { + nameSpace = n; + } } - BindFunction(int t, Function f, Object d, int times) { - this(t, f, d); + BindFunction(int t, String n, Function f, Object d, int times) { + this(t, n, f, d); this.times = times; } @@ -65,7 +69,6 @@ public class EventsListener implements EventListener { return (type | etype) == type; } } - // Gwt Events class has not this event defined public static int ONSUBMIT = 0x08000; @@ -119,17 +122,26 @@ public class EventsListener implements EventListener { setGQueryEventListener(element, this); DOM.setEventListener((com.google.gwt.user.client.Element) element, this); } - + public void bind(int eventbits, final Object data, Function...funcs) { + bind(eventbits, null, data, funcs); + } + + public void bind(int eventbits, final Object data, final Function function, + int times) { + bind(eventbits, null, data, function, times); + } + + public void bind(int eventbits, String name, final Object data, Function...funcs) { for (Function function: funcs) { - bind(eventbits, data, function, -1); + bind(eventbits, name, data, function, -1); } } - - public void bind(int eventbits, final Object data, final Function function, + + public void bind(int eventbits, String namespace, final Object data, final Function function, int times) { if (function == null) { - unbind(eventbits); + unbind(eventbits, namespace); return; } @@ -143,7 +155,21 @@ public class EventsListener implements EventListener { | DOM.getEventsSunk((com.google.gwt.user.client.Element) element)); } - elementEvents.add(new BindFunction(eventbits, function, data, times)); + elementEvents.add(new BindFunction(eventbits, namespace, function, data, times)); + } + + public void bind(String event, final Object data, Function...funcs) { + String nameSpace = event.replaceFirst("^[^\\.]+\\.*(.*)$", "$1"); + String eventName = event.replaceFirst("^([^\\.]+).*$", "$1"); + int b = 0; + if ("submit".equals(eventName)) { + b = ONSUBMIT; + } else { + b = Event.getTypeInt(eventName); + } + for (Function function: funcs) { + bind(b, nameSpace, data, function, -1); + } } public void dispatchEvent(Event event) { @@ -179,14 +205,31 @@ public class EventsListener implements EventListener { } public void unbind(int eventbits) { + unbind(eventbits, null); + } + + public void unbind(int eventbits, String namespace) { JsObjectArray newList = JsObjectArray .createArray().cast(); for (int i = 0; i < elementEvents.length(); i++) { BindFunction listener = elementEvents.get(i); - if (!listener.hasEventType(eventbits)) { + + if (!listener.hasEventType(eventbits) || (namespace != null && namespace.length() != 0 && !listener.nameSpace.equals(namespace))) { newList.add(listener); } } elementEvents = newList; } + + public void unbind(String event) { + String nameSpace = event.replaceFirst("^[^\\.]+\\.*(.*)$", "$1"); + String eventName = event.replaceFirst("^([^\\.]+).*$", "$1"); + int b = 0; + if ("submit".equals(eventName)) { + b = ONSUBMIT; + } else { + b = Event.getTypeInt(eventName); + } + unbind(b, nameSpace); + } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java index 6fa9e477..cf9da10c 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTest.java @@ -42,6 +42,8 @@ public class GQueryEventsTest extends GWTTestCase { static HTML testPanel = null; + int testSubmitEventCont = 0; + public String getModuleName() { return "com.google.gwt.query.Query"; } @@ -57,6 +59,22 @@ public class GQueryEventsTest extends GWTTestCase { } else { e.setInnerHTML(""); } + } + + /** + * TODO: DblClick doesn't work with HtmlUnit, investigate and report. + */ + @DoNotRunWith(Platform.HtmlUnit) + public void testEventsDblClick() { + $(e).html("

Content

"); + $("p", e).css("color", "white"); + $("p", e).dblclick(new Function() { + public void f(Element elem) { + $(elem).css("color", "yellow"); + } + }); + $("p", e).dblclick(); + assertEquals("yellow", $("p", e).css("color")); } public void testEventsPlugin() { @@ -165,22 +183,6 @@ public class GQueryEventsTest extends GWTTestCase { assertEquals("abc", $("input", e).val()); } - /** - * TODO: DblClick doesn't work with HtmlUnit, investigate and report. - */ - @DoNotRunWith(Platform.HtmlUnit) - public void testEventsDblClick() { - $(e).html("

Content

"); - $("p", e).css("color", "white"); - $("p", e).dblclick(new Function() { - public void f(Element elem) { - $(elem).css("color", "yellow"); - } - }); - $("p", e).dblclick(); - assertEquals("yellow", $("p", e).css("color")); - } - public void testLazyMethods() { $(e).css("color", "white"); assertEquals("white", $(e).css("color")); @@ -194,23 +196,52 @@ public class GQueryEventsTest extends GWTTestCase { assertEquals("black", $(e).css("color")); } - public void testWidgetEvents() { - final Button b = new Button("click-me"); - b.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - b.getElement().getStyle().setBackgroundColor("black"); + public void testNamedBinding() { + $(e).html("

Content

"); + + $("p", e, Events.Events).bind("click.first.namespace", null, new Function() {; + public void f(Element elem) { + $(elem).css("color", "red"); } }); - RootPanel.get().add(b); - $("button").click(lazy().css("color", "red").done()); + $("p", e, Events.Events).bind("click.second.namespace", null, new Function() {; + public void f(Element elem) { + $(elem).css("background", "green"); + } + }); + $("p", e, Events.Events).bind("click", null, new Function() {; + public void f(Element elem) { + $(elem).css("fontSize", "24px"); + } + }); + $("p", e, Events.Events).trigger(Event.ONCLICK); + assertEquals("red", $("p", e).css("color")); + assertEquals("green", $("p", e).css("background-color")); + assertEquals(24.0d, GQUtils.cur($("p", e).get(0), "fontSize", true)); + + $("p", e).css("color","").css("background-color","").css("fontSize", "12px"); + assertFalse("red".equalsIgnoreCase($("p", e).css("color"))); + assertFalse("green".equalsIgnoreCase($("p", e).css("background-color"))); + assertEquals(12.0d, GQUtils.cur($("p", e).get(0), "fontSize", true)); - $("button").click(); - assertEquals("red", $("button").css("color")); - assertEquals("black", $("button").css("background-color")); - RootPanel.get().remove(b); - } + $("p", e, Events.Events).unbind("click.first.namespace"); + $("p", e, Events.Events).trigger(Event.ONCLICK); + assertFalse("red".equalsIgnoreCase($("p", e).css("color"))); + assertEquals("green", $("p", e).css("background-color")); + assertEquals(24.0d, GQUtils.cur($("p", e).get(0), "fontSize", true)); + + + $("p", e).css("color","").css("background-color","").css("fontSize", "12px"); + assertFalse("red".equalsIgnoreCase($("p", e).css("color"))); + assertFalse("green".equalsIgnoreCase($("p", e).css("background-color"))); + assertEquals(12.0d, GQUtils.cur($("p", e).get(0), "fontSize", true)); - int testSubmitEventCont = 0; + $("p", e, Events.Events).unbind("click"); + $("p", e, Events.Events).trigger(Event.ONCLICK); + assertFalse("red".equalsIgnoreCase($("p", e).css("color"))); + assertFalse("green".equalsIgnoreCase($("p", e).css("background-color"))); + assertEquals(12.0d, GQUtils.cur($("p", e).get(0), "fontSize", true)); + } public void testSubmitEvent() { // Add a form and an iframe to the dom. The form target is the iframe @@ -245,4 +276,20 @@ public class GQueryEventsTest extends GWTTestCase { } }.schedule(500); } + + public void testWidgetEvents() { + final Button b = new Button("click-me"); + b.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + b.getElement().getStyle().setBackgroundColor("black"); + } + }); + RootPanel.get().add(b); + $("button").click(lazy().css("color", "red").done()); + + $("button").click(); + assertEquals("red", $("button").css("color")); + assertEquals("black", $("button").css("background-color")); + RootPanel.get().remove(b); + } } -- 2.39.5