[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