Fixed issue 908
Description: Adds guards to prevent unneeded element event assignments on DOMImpl.sinkEvents.
Review by:knorton
Patch by: ecc, 22dsse


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1779 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 ff8ca3a..efe794f 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
@@ -289,7 +289,7 @@
   public void setImgSrc(Element img, String src) {
     ImageSrcIE6.setImgSrc(img, src);
   }
-  
+
   @Override
   public native void setInnerText(Element elem, String text) /*-{
     elem.innerText = text || '';
@@ -306,13 +306,13 @@
     // IE standard mode || IE quirks mode.
     return $doc.documentElement.clientHeight || $doc.body.clientHeight; 
   }-*/;
- 
+
   @Override
   public native int windowGetClientWidth() /*-{
     // IE standard mode || IE quirks mode.
     return $doc.documentElement.clientWidth || $doc.body.clientWidth;
   }-*/;
-  
+
   private native void releaseCaptureImpl(Element elem) /*-{
     elem.releaseCapture();
   }-*/;
@@ -322,28 +322,48 @@
   }-*/;
 
   private native void sinkEventsImpl(Element elem, int bits) /*-{
+    var chMask = (elem.__eventBits || 0) ^ bits;
     elem.__eventBits = bits;
-
-    elem.onclick       = (bits & 0x00001) ? $wnd.__dispatchEvent : null;
-    // Add an ondblclick handler if onclick is desired to ensure that
-    // a user's double-click will result in two onclick events
-    elem.ondblclick    = (bits & (0x00001 | 0x00002)) ? $wnd.__dispatchDblClickEvent : null;
-    elem.onmousedown   = (bits & 0x00004) ? $wnd.__dispatchEvent : null;
-    elem.onmouseup     = (bits & 0x00008) ? $wnd.__dispatchEvent : null;
-    elem.onmouseover   = (bits & 0x00010) ? $wnd.__dispatchEvent : null;
-    elem.onmouseout    = (bits & 0x00020) ? $wnd.__dispatchEvent : null;
-    elem.onmousemove   = (bits & 0x00040) ? $wnd.__dispatchEvent : null;
-    elem.onkeydown     = (bits & 0x00080) ? $wnd.__dispatchEvent : null;
-    elem.onkeypress    = (bits & 0x00100) ? $wnd.__dispatchEvent : null;
-    elem.onkeyup       = (bits & 0x00200) ? $wnd.__dispatchEvent : null;
-    elem.onchange      = (bits & 0x00400) ? $wnd.__dispatchEvent : null;
-    elem.onfocus       = (bits & 0x00800) ? $wnd.__dispatchEvent : null;
-    elem.onblur        = (bits & 0x01000) ? $wnd.__dispatchEvent : null;
-    elem.onlosecapture = (bits & 0x02000) ? $wnd.__dispatchEvent : null;
-    elem.onscroll      = (bits & 0x04000) ? $wnd.__dispatchEvent : null;
-    elem.onload        = (bits & 0x08000) ? $wnd.__dispatchEvent : null;
-    elem.onerror       = (bits & 0x10000) ? $wnd.__dispatchEvent : null;
-    elem.onmousewheel  = (bits & 0x20000) ? $wnd.__dispatchEvent : null;
+    if (!chMask) return;
+     
+    if (chMask & 0x00001) elem.onclick       = (bits & 0x00001) ?
+        $wnd.__dispatchEvent : null;
+    // Add a ondblclick handler if onclick is desired to ensure that 
+    // a user's double click will result in two onlclick events.
+    if (chMask & (0x00003)) elem.ondblclick  = (bits & (0x00003)) ?
+        $wnd.__dispatchDblClickEvent : null;
+    if (chMask & 0x00004) elem.onmousedown   = (bits & 0x00004) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00008) elem.onmouseup     = (bits & 0x00008) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00010) elem.onmouseover   = (bits & 0x00010) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00020) elem.onmouseout    = (bits & 0x00020) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00040) elem.onmousemove   = (bits & 0x00040) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00080) elem.onkeydown     = (bits & 0x00080) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00100) elem.onkeypress    = (bits & 0x00100) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00200) elem.onkeyup       = (bits & 0x00200) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00400) elem.onchange      = (bits & 0x00400) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00800) elem.onfocus       = (bits & 0x00800) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x01000) elem.onblur        = (bits & 0x01000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x04000) elem.onscroll      = (bits & 0x04000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x08000) elem.onload        = (bits & 0x08000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x10000) elem.onerror       = (bits & 0x10000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x20000) elem.onmousewheel  = (bits & 0x20000) ? 
+        $wnd.__dispatchEvent : null;
   }-*/;
 
 }
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
index e34b4f3..ac38d80 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
@@ -71,8 +71,6 @@
     }
     return top;
   }-*/;
-  
-  
 
   @Override
   public native int windowGetClientHeight() /*-{
@@ -83,4 +81,30 @@
   public native int windowGetClientWidth() /*-{
     return $doc.body.clientWidth;
   }-*/;
+
+  /**
+   * As Opera sinks events very quickly, adding guards to prevent the sinking of
+   * events actually slows Opera down.
+   */
+  private native void sinkEventsImpl(Element elem, int bits) /*-{
+    elem.__eventBits = bits;
+    elem.onclick       = (bits & 0x00001) ? $wnd.__dispatchEvent : null;
+    elem.ondblclick    = (bits & 0x00002) ? $wnd.__dispatchEvent : null;
+    elem.onmousedown   = (bits & 0x00004) ? $wnd.__dispatchEvent : null;
+    elem.onmouseup     = (bits & 0x00008) ? $wnd.__dispatchEvent : null;
+    elem.onmouseover   = (bits & 0x00010) ? $wnd.__dispatchEvent : null;
+    elem.onmouseout    = (bits & 0x00020) ? $wnd.__dispatchEvent : null;
+    elem.onmousemove   = (bits & 0x00040) ? $wnd.__dispatchEvent : null;
+    elem.onkeydown     = (bits & 0x00080) ? $wnd.__dispatchEvent : null;
+    elem.onkeypress    = (bits & 0x00100) ? $wnd.__dispatchEvent : null;
+    elem.onkeyup       = (bits & 0x00200) ? $wnd.__dispatchEvent : null;
+    elem.onchange      = (bits & 0x00400) ? $wnd.__dispatchEvent : null;
+    elem.onfocus       = (bits & 0x00800) ? $wnd.__dispatchEvent : null;
+    elem.onblur        = (bits & 0x01000) ? $wnd.__dispatchEvent : null;
+    elem.onlosecapture = (bits & 0x02000) ? $wnd.__dispatchEvent : null;
+    elem.onscroll      = (bits & 0x04000) ? $wnd.__dispatchEvent : null;
+    elem.onload        = (bits & 0x08000) ? $wnd.__dispatchEvent : null;
+    elem.onerror       = (bits & 0x10000) ? $wnd.__dispatchEvent : null;
+    elem.onmousewheel  = (bits & 0x20000) ? $wnd.__dispatchEvent : null;
+}-*/;
 }
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 0c642f1..14367e7 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2007 Google Inc.
- *
+ * 
  * 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
@@ -192,13 +192,13 @@
     maybeInitializeEventSystem();
     setCaptureImpl(elem);
   }
- 
+
   @Override
   public void sinkEvents(Element elem, int bits) {
     maybeInitializeEventSystem();
     sinkEventsImpl(elem, bits);
   }
-  
+
   @Override
   protected native void initEventSystem() /*-{
     // Set up capture event dispatchers.
@@ -246,7 +246,7 @@
 
     $wnd.__captureElem = null;
   }-*/;
-  
+
   private native void releaseCaptureImpl(Element elem) /*-{
     if (elem == $wnd.__captureElem)
       $wnd.__captureElem = null;
@@ -257,25 +257,46 @@
   }-*/;
 
   private native void sinkEventsImpl(Element elem, int bits) /*-{
+    var chMask = (elem.__eventBits || 0) ^ bits;
     elem.__eventBits = bits;
-
-    elem.onclick       = (bits & 0x00001) ? $wnd.__dispatchEvent : null;
-    elem.ondblclick    = (bits & 0x00002) ? $wnd.__dispatchEvent : null;
-    elem.onmousedown   = (bits & 0x00004) ? $wnd.__dispatchEvent : null;
-    elem.onmouseup     = (bits & 0x00008) ? $wnd.__dispatchEvent : null;
-    elem.onmouseover   = (bits & 0x00010) ? $wnd.__dispatchEvent : null;
-    elem.onmouseout    = (bits & 0x00020) ? $wnd.__dispatchEvent : null;
-    elem.onmousemove   = (bits & 0x00040) ? $wnd.__dispatchEvent : null;
-    elem.onkeydown     = (bits & 0x00080) ? $wnd.__dispatchEvent : null;
-    elem.onkeypress    = (bits & 0x00100) ? $wnd.__dispatchEvent : null;
-    elem.onkeyup       = (bits & 0x00200) ? $wnd.__dispatchEvent : null;
-    elem.onchange      = (bits & 0x00400) ? $wnd.__dispatchEvent : null;
-    elem.onfocus       = (bits & 0x00800) ? $wnd.__dispatchEvent : null;
-    elem.onblur        = (bits & 0x01000) ? $wnd.__dispatchEvent : null;
-    elem.onlosecapture = (bits & 0x02000) ? $wnd.__dispatchEvent : null;
-    elem.onscroll      = (bits & 0x04000) ? $wnd.__dispatchEvent : null;
-    elem.onload        = (bits & 0x08000) ? $wnd.__dispatchEvent : null;
-    elem.onerror       = (bits & 0x10000) ? $wnd.__dispatchEvent : null;
-    elem.onmousewheel  = (bits & 0x20000) ? $wnd.__dispatchEvent : null;
+    if (!chMask) return;
+   
+    if (chMask & 0x00001) elem.onclick       = (bits & 0x00001) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00002) elem.ondblclick    = (bits & 0x00002) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00004) elem.onmousedown   = (bits & 0x00004) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00008) elem.onmouseup     = (bits & 0x00008) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00010) elem.onmouseover   = (bits & 0x00010) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00020) elem.onmouseout    = (bits & 0x00020) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00040) elem.onmousemove   = (bits & 0x00040) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00080) elem.onkeydown     = (bits & 0x00080) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00100) elem.onkeypress    = (bits & 0x00100) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00200) elem.onkeyup       = (bits & 0x00200) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00400) elem.onchange      = (bits & 0x00400) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x00800) elem.onfocus       = (bits & 0x00800) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x01000) elem.onblur        = (bits & 0x01000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x04000) elem.onscroll      = (bits & 0x04000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x08000) elem.onload        = (bits & 0x08000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x10000) elem.onerror       = (bits & 0x10000) ?
+        $wnd.__dispatchEvent : null;
+    if (chMask & 0x20000) elem.onmousewheel  = (bits & 0x20000) ? 
+        $wnd.__dispatchEvent : null;
+   
   }-*/;
 }