diff options
3 files changed, 114 insertions, 12 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsMap.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsMap.java index 2c87171d..6bc43077 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsMap.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsMap.java @@ -49,6 +49,12 @@ final public class JsMap<S, T> extends JavaScriptObject { return old; } + public T remove(int hashCode){ + T old = get(hashCode); + c().delete(hashCode()); + return old; + } + public final String[] keys() { return c().keys(); } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java index dad7099a..039ce0d1 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java @@ -13,8 +13,6 @@ */ package com.google.gwt.query.client.plugins.events; -import static com.google.gwt.query.client.GQuery.$; - import com.google.gwt.core.client.Duration; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; @@ -33,6 +31,8 @@ import com.google.gwt.user.client.EventListener; import java.util.ArrayList; import java.util.List; +import static com.google.gwt.query.client.GQuery.$; + /** * This class implements an event queue instance for one Element. The queue instance is configured * as the default event listener in GWT. @@ -154,7 +154,7 @@ public class EventsListener implements EventListener { } public boolean hasEventType(int etype) { - return type != BITLESS && (type & etype) != 0; + return type != BITLESS && etype != BITLESS && (type & etype) != 0; } public boolean isTypeOf(String eName) { @@ -179,7 +179,7 @@ public class EventsListener implements EventListener { @Override public String toString() { - return "bind function for event type " + type; + return "bind function for event type " + (eventName != null ? eventName : "" + type); } public boolean isEquals(Function f) { @@ -435,7 +435,6 @@ public class EventsListener implements EventListener { if (elem.__gwtlistener == gqevent) elem.__gwtlistener = null; }-*/; - // Gwt does't handle submit nor resize events in DOM.sinkEvents private static native void sinkBitlessEvent(Element elem, String name) /*-{ if (!elem.__gquery) elem.__gquery = []; @@ -561,17 +560,27 @@ public class EventsListener implements EventListener { public void die(int eventbits, String nameSpace, String eventName, String originalEventName, String cssSelector) { if (eventbits <= 0) { - if (eventName != null) { + if (eventName != null && eventName.length() > 0) { LiveBindFunction liveBindFunction = liveBindFunctionByEventName.get(eventName); maybeRemoveLiveBindFunction(liveBindFunction, cssSelector, BITLESS, eventName, nameSpace, originalEventName); - } + } else { + // if eventbits == -1 and eventName is null, remove all event handlers for this selector + for (String k : liveBindFunctionByEventType.keys()) { + int bits = Integer.parseInt(k); + LiveBindFunction liveBindFunction = liveBindFunctionByEventType.get(bits); + maybeRemoveLiveBindFunction(liveBindFunction, cssSelector, bits, null, nameSpace, null); + } - // if eventbits == -1 and eventName is null, remove all event handlers for this selector - for (String k : liveBindFunctionByEventType.keys()) { - int bits = Integer.parseInt(k); - LiveBindFunction liveBindFunction = liveBindFunctionByEventType.get(bits); - maybeRemoveLiveBindFunction(liveBindFunction, cssSelector, bits, null, nameSpace, null); + for (String k : liveBindFunctionByEventName.keys()) { + int realKey = Integer.parseInt(k); + LiveBindFunction liveBindFunction = liveBindFunctionByEventName.get(realKey); + if (liveBindFunction != null) { + String eName = liveBindFunction.eventName; + maybeRemoveLiveBindFunction(liveBindFunction, cssSelector, BITLESS, eName, + nameSpace, originalEventName); + } + } } } else { LiveBindFunction liveBindFunction = liveBindFunctionByEventType.get(eventbits); diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java index e3ada526..b781d1d9 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEventsTestGwt.java @@ -1603,4 +1603,91 @@ public class GQueryEventsTestGwt extends GWTTestCase { // this should not throw a NPE target.undelegate("li", "click"); } + + // issue 25 : https://github.com/gwtquery/gwtquery/issues/25 + public void testDelegateAfterUndelegateWithoutParameter() { + $(e).html( + "<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>"); + + CounterFunction clickFunction = new CounterFunction(); + CounterFunction mouseOverFunction = new CounterFunction(); + + $(".mainDiv", e).delegate(".subDiv", "click", clickFunction); + + $(".mainDiv", e).delegate(".subDiv", Event.ONMOUSEOVER, mouseOverFunction); + + for (Element mainDiv : $(".mainDiv", e).elements()) { + for (int i = 0; i < 3; i++) { + String html = "<div class='subDiv'>Content " + i + "<span>blop</span></div>"; + $(mainDiv).append(html); + } + } + + assertEquals(8, $(".subDiv", e).length()); + + $("span", e).click().trigger(Event.ONMOUSEOVER); + + assertEquals(8, clickFunction.invokationCounter); + assertEquals(8, mouseOverFunction.invokationCounter); + + clickFunction.invokationCounter = 0; + mouseOverFunction.invokationCounter = 0; + + $(".mainDiv", e).undelegate(); + + $("span", e).click().trigger(Event.ONMOUSEOVER); + assertEquals(0, clickFunction.invokationCounter); + assertEquals(0, mouseOverFunction.invokationCounter); + + //reattach the event + + $(".mainDiv", e).delegate(".subDiv", "click", clickFunction); + $(".mainDiv", e).delegate(".subDiv", Event.ONMOUSEOVER, mouseOverFunction); + + $("span", e).click().trigger(Event.ONMOUSEOVER); + + assertEquals(8, clickFunction.invokationCounter); + assertEquals(8, mouseOverFunction.invokationCounter); + + } + + public void testDelegateAfterUndelegateWithSelectorWithDifferentEvent() { + $(e).html( + "<div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div><div class='mainDiv'><div class='subDiv'>Content 0<span>blop</span></div></div>"); + + CounterFunction clickFunction = new CounterFunction(); + CounterFunction mouseOverFunction = new CounterFunction(); + CounterFunction customEventFunction = new CounterFunction(); + + $(".mainDiv", e).delegate(".subDiv", "click", clickFunction) + .delegate(".subDiv", Event.ONMOUSEOVER, mouseOverFunction) + .delegate(".subDiv", "custom", customEventFunction); + + for (Element mainDiv : $(".mainDiv", e).elements()) { + for (int i = 0; i < 3; i++) { + String html = "<div class='subDiv'>Content " + i + "<span>blop</span></div>"; + $(mainDiv).append(html); + } + } + + assertEquals(8, $(".subDiv", e).length()); + + $("span", e).click().trigger(Event.ONMOUSEOVER).trigger("custom"); + + assertEquals(8, clickFunction.invokationCounter); + assertEquals(8, mouseOverFunction.invokationCounter); + assertEquals(8, customEventFunction.invokationCounter); + + $(".mainDiv", e).undelegate(".subDiv"); + + clickFunction.invokationCounter = 0; + mouseOverFunction.invokationCounter = 0; + customEventFunction.invokationCounter = 0; + + $("span", e).click().trigger(Event.ONMOUSEOVER).trigger("custom"); + + assertEquals(0, clickFunction.invokationCounter); + assertEquals(0, mouseOverFunction.invokationCounter); + assertEquals(0, customEventFunction.invokationCounter); + } } |