[OpenLayers-Commits] r2993 - in trunk/openlayers: lib/OpenLayers tests

commits at openlayers.org commits at openlayers.org
Tue Apr 3 12:54:15 EDT 2007


Author: euzuro
Date: 2007-04-03 12:54:14 -0400 (Tue, 03 Apr 2007)
New Revision: 2993

Modified:
   trunk/openlayers/lib/OpenLayers/Events.js
   trunk/openlayers/tests/test_Events.html
Log:
patch for #621 - assign items in the elements hash table a unique cacheID instead of relying on the element's actual 'id' property. thx for thorough review sde

Modified: trunk/openlayers/lib/OpenLayers/Events.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Events.js	2007-04-03 16:42:19 UTC (rev 2992)
+++ trunk/openlayers/lib/OpenLayers/Events.js	2007-04-03 16:54:14 UTC (rev 2993)
@@ -10,7 +10,8 @@
  */
 OpenLayers.Event = {
 
-    /** A hashtable cache of the event observers, keyed by element.id
+    /** A hashtable cache of the event observers.
+     *   Keyed by element._eventCacheID
      * 
      * @type Object
      */
@@ -118,14 +119,25 @@
         if (!this.observers) {
             this.observers = new Object();
         }
-        
+
+        //if not already assigned, make a new unique cache ID
+        if (!element._eventCacheID) {
+            var idPrefix = "eventCacheID_";
+            if (element.id) {
+                idPrefix = element.id + "_" + idPrefix;
+            }
+            element._eventCacheID = OpenLayers.Util.createUniqueID(idPrefix);
+        }
+
+        var cacheID = element._eventCacheID;
+
         //if there is not yet a hash entry for this element, add one
-        if (!this.observers[element.id]) {
-            this.observers[element.id] = new Array();
+        if (!this.observers[cacheID]) {
+            this.observers[cacheID] = new Array();
         }
 
         //add a new observer to this element's list
-        this.observers[element.id].push({
+        this.observers[cacheID].push({
             'element': element,
             'name': name,
             'observer': observer,
@@ -147,23 +159,28 @@
      * @param {DOMElement || String} elementParam
      */
     stopObservingElement: function(elementParam) {
+        var element = OpenLayers.Util.getElement(elementParam);
+        var cacheID = element._eventCacheID;
 
-        var elementId = (typeof elementParam == "string") ? elementParam 
-                            : OpenLayers.Util.getElement(elementParam).id;
+        this._removeElementObservers(OpenLayers.Event.observers[cacheID]);
+    },
 
-        var elementObservers = OpenLayers.Event.observers[elementId];
+    /**
+     * @private
+     * 
+     * @param {Array(Object)} elementObservers Array of (element, name, 
+     *                                         observer, usecapture) objects, 
+     *                                         taken directly from hashtable
+     */
+    _removeElementObservers: function(elementObservers) {
         if (elementObservers) {
-            var i=0;
-            while(i < elementObservers.length) {
-                var entry = elementObservers[0];
+            for(var i = elementObservers.length-1; i >= 0; i--) {
+                var entry = elementObservers[i];
                 var args = new Array(entry.element,
                                      entry.name,
                                      entry.observer,
                                      entry.useCapture);
                 var removed = OpenLayers.Event.stopObserving.apply(this, args);
-                if (!removed) {
-                    i++;
-                }
             }
         }
     },
@@ -181,8 +198,7 @@
         useCapture = useCapture || false;
     
         var element = OpenLayers.Util.getElement(elementParam);
-        var elementId = (typeof elementParam == "string") ? elementParam
-                                                          : element.id;
+        var cacheID = element._eventCacheID;
 
         if (name == 'keypress') {
             if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) || 
@@ -193,7 +209,7 @@
 
         // find element's entry in this.observers cache and remove it
         var foundEntry = false;
-        var elementObservers = OpenLayers.Event.observers[elementId];
+        var elementObservers = OpenLayers.Event.observers[cacheID];
         if (elementObservers) {
     
             // find the specific event type in the element's list
@@ -207,7 +223,7 @@
     
                     elementObservers.splice(i, 1);
                     if (elementObservers.length == 0) {
-                        delete OpenLayers.Event.observers[element.id];
+                        delete OpenLayers.Event.observers[cacheID];
                     }
                     foundEntry = true;
                     break; 
@@ -230,8 +246,10 @@
      */
     unloadCache: function() {
         if (OpenLayers.Event.observers) {
-            for (var elementId in OpenLayers.Event.observers) {
-                OpenLayers.Event.stopObservingElement.apply(this, [elementId]);
+            for (var cacheID in OpenLayers.Event.observers) {
+                var elementObservers = OpenLayers.Event.observers[cacheID];
+                OpenLayers.Event._removeElementObservers.apply(this, 
+                                                           [elementObservers]);
             }
             OpenLayers.Event.observers = false;
         }

Modified: trunk/openlayers/tests/test_Events.html
===================================================================
--- trunk/openlayers/tests/test_Events.html	2007-04-03 16:42:19 UTC (rev 2992)
+++ trunk/openlayers/tests/test_Events.html	2007-04-03 16:54:14 UTC (rev 2993)
@@ -202,14 +202,15 @@
         t.eq(a, 5, "if Events has no object set and an event is registered also with no object, triggerEvent() calls it without trying to set the context to null");        
     }
 
-    function test_05_Event_destroy (t) {
+    function test_05_Events_destroy (t) {
         t.plan(2);
 
         var div   = OpenLayers.Util.getElement('test');
         var obj   = {};
         var events = new OpenLayers.Events(obj, div);
+
         // +1 because of blocking dragstart in attachToElement()
-        t.eq(OpenLayers.Event.observers["test"].length,
+        t.eq(OpenLayers.Event.observers[div._eventCacheID].length,
              OpenLayers.Events.prototype.BROWSER_EVENTS.length + 1,
              "construction creates new arrayin hash, registers appropriate events");
              
@@ -218,6 +219,92 @@
         t.eq(OpenLayers.Event.observers["test"], null,
              "destruction removes the event observer from hash");
     }
+    
+    function test_06_Event(t) {
+        t.plan(24);
+        
+        var div   = OpenLayers.Util.getElement('test');
+        var name = "mouseover";
+        var func = function() {};
+
+      //1st elem 1st listener        
+        OpenLayers.Event.observe(div, name, func);
+
+        var cacheID = div._eventCacheID;
+        t.ok(cacheID, "element given new cache id");
+        
+        var elementObservers = OpenLayers.Event.observers[cacheID];
+        
+        t.ok(elementObservers, "new cache bucket made for event");
+        t.eq(elementObservers.length, 1, "one listener registered");        
+        
+        var listener = elementObservers[0];
+        
+        t.ok(listener.element == div, "element registered");
+        t.eq(listener.name, name, "name registered");
+        t.ok(listener.observer == func, "function registered");
+        t.eq(listener.useCapture, false, "useCapture defaults to false");
+
+      //1st elem 2nd listener        
+        name = "mouseout";
+        var newFunc = function() {};
+      
+        OpenLayers.Event.observe(div, name, newFunc, true);
+        var newCacheID = div._eventCacheID;
+        t.eq(newCacheID, cacheID, "element's cache id not overridden");
+        
+        t.eq(elementObservers.length, 2, "listener added to existing bucket");        
+        
+        var listener = elementObservers[1];
+        
+        t.ok(listener.element == div, "element registered");
+        t.eq(listener.name, name, "name registered");
+        t.ok(listener.observer == newFunc, "function registered");
+        t.eq(listener.useCapture, true, "useCapture correctly registered");
+
+      //2st elem 1st listener        
+        div = OpenLayers.Util.getElement('test2'); 
+        OpenLayers.Event.observe(div, name, func);
+
+        var cacheID = div._eventCacheID;
+        t.ok(cacheID, "new element given new cache id");
+        t.ok(cacheID != newCacheID, "new cache id is unique");
+        
+        elementObservers = OpenLayers.Event.observers[cacheID];
+        
+        t.ok(elementObservers, "new cache bucket made for event");
+        t.eq(elementObservers.length, 1, "one listener registered");        
+        
+        var listener = elementObservers[0];
+        
+        t.ok(listener.element == div, "element registered");
+        t.eq(listener.name, name, "name registered");
+        t.ok(listener.observer == func, "function registered");
+        t.eq(listener.useCapture, false, "useCapture defaults to false");
+
+      //stopObservingElement by element
+        OpenLayers.Event.stopObservingElement(div);
+        elementObservers = OpenLayers.Event.observers[cacheID];
+        t.ok(elementObservers == null, "stopObservingElement by elem works");
+
+      //stopObservingElement by id
+        OpenLayers.Event.stopObservingElement("test");
+        elementObservers = OpenLayers.Event.observers[newCacheID];
+        t.ok(elementObservers == null, "stopObservingElement by id works");
+
+
+      //unloadCache by element
+        OpenLayers.Event.observe(div, name, func);
+        
+        OpenLayers.Event.unloadCache();
+
+        elementObservers = OpenLayers.Event.observers[cacheID];
+        t.ok(elementObservers == null, "stopObservingElement by elem works");
+
+        
+    }
+
+
    
   // -->
   </script>
@@ -225,5 +312,6 @@
 <body>
     <div id="map" style="width: 1024px; height: 512px;"/>
     <div id="test"></div>
+    <div id="test2"></div>
 </body>
 </html>



More information about the Commits mailing list