The original behavior of DOM event sinks was that any element on which you
called sinkEvents() would have its events dispatched to the 'nearest listener',
as defined by DOM.setEventListener(). In practice this is always the Widget
that 'owns' that element. As Sandy points out, this is actually quite useful
behavior, because it allows you to sink specific events on sub-elements, but
not on the Widget's root element -- which means that onBrowserEvent() will be
called much less often in some instances.
I originally pulled this dispatch code out because I thought it was a leftover
that wasn't intended to be there in the first place. That was an overzealous
mistake on my part, and it turns out this behavior was actually specified in
the DOM.sinkEvents() method:
> Sets the current set of events sunk by a given element. These events will be
> fired to the nearest {@link EventListener} specified on any of the element's
> parents.
I also went ahead and added DOM.eventGetCurrentTarget(), which can useful when
the listener and the current target can be different.
Issue: 1159
Patch by: jgw
Review by: knorton
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1265 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java
index c4afea4..b2a77cd 100644
--- a/user/src/com/google/gwt/user/client/DOM.java
+++ b/user/src/com/google/gwt/user/client/DOM.java
@@ -408,6 +408,19 @@
}
/**
+ * Gets the current target element of the given event. This is the element
+ * whose listener fired last, not the element which fired the event
+ * initially.
+ *
+ * @param evt the event
+ * @return the event's current target element
+ * @see DOM#eventGetTarget(Event)
+ */
+ public static Element eventGetCurrentTarget(Event evt) {
+ return impl.eventGetCurrentTarget(evt);
+ }
+
+ /**
* Gets the element from which the mouse pointer was moved (only valid for
* {@link Event#ONMOUSEOVER}).
*
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImpl.java b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
index c6400f2..9cd8197 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImpl.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
@@ -75,6 +75,10 @@
return !!evt.ctrlKey;
}-*/;
+ public native Element eventGetCurrentTarget(Event evt) /*-{
+ return evt.currentTarget;
+ }-*/;
+
public abstract Element eventGetFromElement(Event evt);
public native int eventGetKeyCode(Event evt) /*-{
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
index 1acd724..1c22000 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
@@ -177,8 +177,12 @@
return;
}
- if (this.__listener)
- @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)($wnd.event, this, this.__listener);
+ var listener, curElem = this;
+ while (curElem && !(listener = curElem.__listener))
+ curElem = curElem.parentElement;
+
+ if (listener)
+ @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)($wnd.event, curElem, listener);
};
$wnd.__dispatchDblClickEvent = function() {
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
index af2c684..fa41753 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -158,8 +158,14 @@
// Set up normal event dispatcher.
$wnd.__dispatchEvent = function(evt) {
- if (this.__listener)
- @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, this, this.__listener);
+ var listener, curElem = this;
+ while (curElem && !(listener = curElem.__listener))
+ curElem = curElem.parentNode;
+ if (curElem && curElem.nodeType != 1)
+ curElem = null;
+
+ if (listener)
+ @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, curElem, listener);
};
$wnd.__captureElem = null;