Revision: 8209
Author: gwt.mirror...@gmail.com
Date: Tue May 25 11:50:14 2010
Log: Have IE's DOMImpl invoke its event dispatching function via a
round-trip through the window object. That way, the only reference
from DOM objects into GWT's code is on the window object, a
place IE is careful to clean up when the browser navigates to
a new page. This fixes a problem where the cross-site linker on
IE could lead to memory leaking across page refreshes.

Review at http://gwt-code-reviews.appspot.com/543801

Review by: j...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=8209

Modified:
 /branches/2.1/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java

=======================================
--- /branches/2.1/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java Thu Feb 25 06:49:47 2010 +++ /branches/2.1/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java Tue May 25 11:50:14 2010
@@ -24,15 +24,14 @@
  * {...@link com.google.gwt.user.client.impl.DOMImpl}.
  */
 public abstract class DOMImplTrident extends DOMImpl {
-
   @SuppressWarnings("unused")
-  private static JavaScriptObject dispatchEvent;
+  private static JavaScriptObject callDispatchEvent;

   @SuppressWarnings("unused")
-  private static JavaScriptObject dispatchDblClickEvent;
+  private static JavaScriptObject callDispatchDblClickEvent;

   @SuppressWarnings("unused")
-  private static JavaScriptObject dispatchUnhandledEvent;
+  private static JavaScriptObject callDispatchUnhandledEvent;

   /**
* Let every GWT app on the page preview the current event. If any app cancels
@@ -106,7 +105,7 @@
return @com.google.gwt.user.client.DOM::previewEvent(Lcom/google/gwt/user/client/Event;)($wnd.event);
     });

- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent = $entry(function() {
+    var dispatchEvent = $entry(function() {
// IE doesn't define event.currentTarget, so we squirrel it away here. It // also seems that IE won't allow you to add expandos to the event object, // so we have to store it in a global. This is ok because only one event
@@ -139,7 +138,7 @@
@com.google.gwt.dom.client.DOMImplTrident::currentEventTarget = oldEventTarget;
     });

- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchDblClickEvent = $entry(function() {
+    var dispatchDblClickEvent = $entry(function() {
       var newEvent = $doc.createEventObject();
       // Synthesize a click event if one hasn't already been synthesized.
       // Issue 4027: fireEvent is undefined on disabled input elements.
@@ -147,7 +146,7 @@
         $wnd.event.srcElement.fireEvent('onclick', newEvent);
       }
       if (this.__eventBits & 2) {
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent.call(this);
+        dispatchEvent.call(this);
       } else if ($wnd.event.returnValue == null) {
         // Ensure that we preview the event even if we aren't handling it.
         $wnd.event.returnValue = true;
@@ -155,16 +154,34 @@
       }
     });

- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchUnhandledEvent = $entry(function() {
+    var dispatchUnhandledEvent = $entry(function() {
       this.__gwtLastUnhandledEvent = $wnd.event.type;
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent.call(this);
+      dispatchEvent.call(this);
     });

+    // Hook the above functions on the current window object, and
+    // create a caller function for each one that indirects via
+    // the global object. Make sure that the caller function has
+    // no direct reference to the GWT program.
+ var moduleName = @com.google.gwt.core.client.GWT::getModuleName()().replace(/\./g,'_');
+
+    $wnd['__gwt_dispatchEvent_' + moduleName] = dispatchEvent;
+ @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent = new Function('w', + 'return function() { w.__gwt_dispatchEvent_' + moduleName + '.call(this) }')($wnd);
+
+ $wnd['__gwt_dispatchDblClickEvent_' + moduleName] = dispatchDblClickEvent; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchDblClickEvent = new Function('w', + 'return function() { w.__gwt_dispatchDblClickEvent_' + moduleName + '.call(this)}')($wnd);
+
+ $wnd['__gwt_dispatchUnhandledEvent_' + moduleName] = dispatchUnhandledEvent; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent = new Function('w', + 'return function() { w.__gwt_dispatchUnhandledEvent_' + moduleName + '.call(this)}')($wnd);
+
// We need to create these delegate functions to fix up the 'this' context.
     // Normally, 'this' is the firing element, but this is only true for
// 'onclick = ...' event handlers, not for handlers setup via attachEvent(). - var bodyDispatcher = $entry(function() { @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent.call($doc.body); }); - var bodyDblClickDispatcher = $entry(function() { @com.google.gwt.user.client.impl.DOMImplTrident::dispatchDblClickEvent.call($doc.body); }); + var bodyDispatcher = $entry(function() { dispatchEvent.call($doc.body); }); + var bodyDblClickDispatcher = $entry(function() { dispatchDblClickEvent.call($doc.body); });

     $doc.body.attachEvent('onclick', bodyDispatcher);
     $doc.body.attachEvent('onmousedown', bodyDispatcher);
@@ -218,48 +235,48 @@
     var chMask = (elem.__eventBits || 0) ^ bits;
     elem.__eventBits = bits;
     if (!chMask) return;
-
+
     if (chMask & 0x00001) elem.onclick       = (bits & 0x00001) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     // Add a ondblclick handler if onclick is desired to ensure that
     // a user's double click will result in two onclick events.
     if (chMask & (0x00003)) elem.ondblclick  = (bits & (0x00003)) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchDblClickEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchDblClickEvent : null;
     if (chMask & 0x00004) elem.onmousedown   = (bits & 0x00004) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00008) elem.onmouseup     = (bits & 0x00008) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00010) elem.onmouseover   = (bits & 0x00010) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00020) elem.onmouseout    = (bits & 0x00020) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00040) elem.onmousemove   = (bits & 0x00040) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00080) elem.onkeydown     = (bits & 0x00080) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00100) elem.onkeypress    = (bits & 0x00100) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00200) elem.onkeyup       = (bits & 0x00200) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00400) elem.onchange      = (bits & 0x00400) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x00800) elem.onfocus       = (bits & 0x00800) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x01000) elem.onblur        = (bits & 0x01000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x04000) elem.onscroll      = (bits & 0x04000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x08000) elem.onload        = (bits & 0x08000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchUnhandledEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent : null;
     if (chMask & 0x10000) elem.onerror       = (bits & 0x10000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x20000) elem.onmousewheel  = (bits & 0x20000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x40000) elem.oncontextmenu = (bits & 0x40000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
     if (chMask & 0x80000) elem.onpaste       = (bits & 0x80000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::dispatchEvent : null; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
   }-*/;
 }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to