Ticket #621: FINAL-eventCacheID.2.patch
| File FINAL-eventCacheID.2.patch, 9.3 kB (added by euzuro, 2 years ago) |
|---|
-
tests/test_Events.html
old new 202 202 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"); 203 203 } 204 204 205 function test_05_Event _destroy (t) {205 function test_05_Events_destroy (t) { 206 206 t.plan(2); 207 207 208 208 var div = OpenLayers.Util.getElement('test'); 209 209 var obj = {}; 210 210 var events = new OpenLayers.Events(obj, div); 211 211 212 // +1 because of blocking dragstart in attachToElement() 212 t.eq(OpenLayers.Event.observers[ "test"].length,213 t.eq(OpenLayers.Event.observers[div._eventCacheID].length, 213 214 OpenLayers.Events.prototype.BROWSER_EVENTS.length + 1, 214 215 "construction creates new arrayin hash, registers appropriate events"); 215 216 … … 218 219 t.eq(OpenLayers.Event.observers["test"], null, 219 220 "destruction removes the event observer from hash"); 220 221 } 222 223 function test_06_Event(t) { 224 t.plan(24); 225 226 var div = OpenLayers.Util.getElement('test'); 227 var name = "mouseover"; 228 var func = function() {}; 229 230 //1st elem 1st listener 231 OpenLayers.Event.observe(div, name, func); 232 233 var cacheID = div._eventCacheID; 234 t.ok(cacheID, "element given new cache id"); 235 236 var elementObservers = OpenLayers.Event.observers[cacheID]; 237 238 t.ok(elementObservers, "new cache bucket made for event"); 239 t.eq(elementObservers.length, 1, "one listener registered"); 240 241 var listener = elementObservers[0]; 242 243 t.ok(listener.element == div, "element registered"); 244 t.eq(listener.name, name, "name registered"); 245 t.ok(listener.observer == func, "function registered"); 246 t.eq(listener.useCapture, false, "useCapture defaults to false"); 247 248 //1st elem 2nd listener 249 name = "mouseout"; 250 var newFunc = function() {}; 251 252 OpenLayers.Event.observe(div, name, newFunc, true); 253 var newCacheID = div._eventCacheID; 254 t.eq(newCacheID, cacheID, "element's cache id not overridden"); 255 256 t.eq(elementObservers.length, 2, "listener added to existing bucket"); 257 258 var listener = elementObservers[1]; 259 260 t.ok(listener.element == div, "element registered"); 261 t.eq(listener.name, name, "name registered"); 262 t.ok(listener.observer == newFunc, "function registered"); 263 t.eq(listener.useCapture, true, "useCapture correctly registered"); 264 265 //2st elem 1st listener 266 div = OpenLayers.Util.getElement('test2'); 267 OpenLayers.Event.observe(div, name, func); 268 269 var cacheID = div._eventCacheID; 270 t.ok(cacheID, "new element given new cache id"); 271 t.ok(cacheID != newCacheID, "new cache id is unique"); 272 273 elementObservers = OpenLayers.Event.observers[cacheID]; 274 275 t.ok(elementObservers, "new cache bucket made for event"); 276 t.eq(elementObservers.length, 1, "one listener registered"); 277 278 var listener = elementObservers[0]; 279 280 t.ok(listener.element == div, "element registered"); 281 t.eq(listener.name, name, "name registered"); 282 t.ok(listener.observer == func, "function registered"); 283 t.eq(listener.useCapture, false, "useCapture defaults to false"); 284 285 //stopObservingElement by element 286 OpenLayers.Event.stopObservingElement(div); 287 elementObservers = OpenLayers.Event.observers[cacheID]; 288 t.ok(elementObservers == null, "stopObservingElement by elem works"); 289 290 //stopObservingElement by id 291 OpenLayers.Event.stopObservingElement("test"); 292 elementObservers = OpenLayers.Event.observers[newCacheID]; 293 t.ok(elementObservers == null, "stopObservingElement by id works"); 294 295 296 //unloadCache by element 297 OpenLayers.Event.observe(div, name, func); 298 299 OpenLayers.Event.unloadCache(); 300 301 elementObservers = OpenLayers.Event.observers[cacheID]; 302 t.ok(elementObservers == null, "stopObservingElement by elem works"); 303 304 305 } 306 307 221 308 222 309 // --> 223 310 </script> … … 225 312 <body> 226 313 <div id="map" style="width: 1024px; height: 512px;"/> 227 314 <div id="test"></div> 315 <div id="test2"></div> 228 316 </body> 229 317 </html> -
lib/OpenLayers/Events.js
old new 10 10 */ 11 11 OpenLayers.Event = { 12 12 13 /** A hashtable cache of the event observers, keyed by element.id 13 /** A hashtable cache of the event observers. 14 * Keyed by element._eventCacheID 14 15 * 15 16 * @type Object 16 17 */ … … 118 119 if (!this.observers) { 119 120 this.observers = new Object(); 120 121 } 121 122 123 //if not already assigned, make a new unique cache ID 124 if (!element._eventCacheID) { 125 var idPrefix = "eventCacheID_"; 126 if (element.id) { 127 idPrefix = element.id + "_" + idPrefix; 128 } 129 element._eventCacheID = OpenLayers.Util.createUniqueID(idPrefix); 130 } 131 132 var cacheID = element._eventCacheID; 133 122 134 //if there is not yet a hash entry for this element, add one 123 if (!this.observers[ element.id]) {124 this.observers[ element.id] = new Array();135 if (!this.observers[cacheID]) { 136 this.observers[cacheID] = new Array(); 125 137 } 126 138 127 139 //add a new observer to this element's list 128 this.observers[ element.id].push({140 this.observers[cacheID].push({ 129 141 'element': element, 130 142 'name': name, 131 143 'observer': observer, … … 147 159 * @param {DOMElement || String} elementParam 148 160 */ 149 161 stopObservingElement: function(elementParam) { 162 var element = OpenLayers.Util.getElement(elementParam); 163 var cacheID = element._eventCacheID; 150 164 151 var elementId = (typeof elementParam == "string") ? elementParam152 : OpenLayers.Util.getElement(elementParam).id;165 this._removeElementObservers(OpenLayers.Event.observers[cacheID]); 166 }, 153 167 154 var elementObservers = OpenLayers.Event.observers[elementId]; 168 /** 169 * @private 170 * 171 * @param {Array(Object)} elementObservers Array of (element, name, 172 * observer, usecapture) objects, 173 * taken directly from hashtable 174 */ 175 _removeElementObservers: function(elementObservers) { 155 176 if (elementObservers) { 156 var i=0; 157 while(i < elementObservers.length) { 158 var entry = elementObservers[0]; 177 for(var i = elementObservers.length-1; i >= 0; i--) { 178 var entry = elementObservers[i]; 159 179 var args = new Array(entry.element, 160 180 entry.name, 161 181 entry.observer, 162 182 entry.useCapture); 163 183 var removed = OpenLayers.Event.stopObserving.apply(this, args); 164 if (!removed) {165 i++;166 }167 184 } 168 185 } 169 186 }, … … 181 198 useCapture = useCapture || false; 182 199 183 200 var element = OpenLayers.Util.getElement(elementParam); 184 var elementId = (typeof elementParam == "string") ? elementParam 185 : element.id; 201 var cacheID = element._eventCacheID; 186 202 187 203 if (name == 'keypress') { 188 204 if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) || … … 193 209 194 210 // find element's entry in this.observers cache and remove it 195 211 var foundEntry = false; 196 var elementObservers = OpenLayers.Event.observers[ elementId];212 var elementObservers = OpenLayers.Event.observers[cacheID]; 197 213 if (elementObservers) { 198 214 199 215 // find the specific event type in the element's list … … 207 223 208 224 elementObservers.splice(i, 1); 209 225 if (elementObservers.length == 0) { 210 delete OpenLayers.Event.observers[ element.id];226 delete OpenLayers.Event.observers[cacheID]; 211 227 } 212 228 foundEntry = true; 213 229 break; … … 230 246 */ 231 247 unloadCache: function() { 232 248 if (OpenLayers.Event.observers) { 233 for (var elementId in OpenLayers.Event.observers) { 234 OpenLayers.Event.stopObservingElement.apply(this, [elementId]); 249 for (var cacheID in OpenLayers.Event.observers) { 250 var elementObservers = OpenLayers.Event.observers[cacheID]; 251 OpenLayers.Event._removeElementObservers.apply(this, 252 [elementObservers]); 235 253 } 236 254 OpenLayers.Event.observers = false; 237 255 }
