OpenLayers OpenLayers

Ticket #621: FINAL-eventCacheID.2.patch

File FINAL-eventCacheID.2.patch, 9.3 kB (added by euzuro, 2 years ago)

final patch.... take two. updated to work with the latest version of trunk, plus renamed row() function to _removeElementObservers() on smart request from sde. tests pass FF & ie6

  • tests/test_Events.html

    old new  
    202202        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");         
    203203    } 
    204204 
    205     function test_05_Event_destroy (t) { 
     205    function test_05_Events_destroy (t) { 
    206206        t.plan(2); 
    207207 
    208208        var div   = OpenLayers.Util.getElement('test'); 
    209209        var obj   = {}; 
    210210        var events = new OpenLayers.Events(obj, div); 
     211 
    211212        // +1 because of blocking dragstart in attachToElement() 
    212         t.eq(OpenLayers.Event.observers["test"].length, 
     213        t.eq(OpenLayers.Event.observers[div._eventCacheID].length, 
    213214             OpenLayers.Events.prototype.BROWSER_EVENTS.length + 1, 
    214215             "construction creates new arrayin hash, registers appropriate events"); 
    215216              
     
    218219        t.eq(OpenLayers.Event.observers["test"], null, 
    219220             "destruction removes the event observer from hash"); 
    220221    } 
     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 
    221308    
    222309  // --> 
    223310  </script> 
     
    225312<body> 
    226313    <div id="map" style="width: 1024px; height: 512px;"/> 
    227314    <div id="test"></div> 
     315    <div id="test2"></div> 
    228316</body> 
    229317</html> 
  • lib/OpenLayers/Events.js

    old new  
    1010 */ 
    1111OpenLayers.Event = { 
    1212 
    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 
    1415     *  
    1516     * @type Object 
    1617     */ 
     
    118119        if (!this.observers) { 
    119120            this.observers = new Object(); 
    120121        } 
    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 
    122134        //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(); 
    125137        } 
    126138 
    127139        //add a new observer to this element's list 
    128         this.observers[element.id].push({ 
     140        this.observers[cacheID].push({ 
    129141            'element': element, 
    130142            'name': name, 
    131143            'observer': observer, 
     
    147159     * @param {DOMElement || String} elementParam 
    148160     */ 
    149161    stopObservingElement: function(elementParam) { 
     162        var element = OpenLayers.Util.getElement(elementParam); 
     163        var cacheID = element._eventCacheID; 
    150164 
    151         var elementId = (typeof elementParam == "string") ? elementParam  
    152                             : OpenLayers.Util.getElement(elementParam).id; 
     165        this._removeElementObservers(OpenLayers.Event.observers[cacheID]); 
     166    }, 
    153167 
    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) { 
    155176        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]; 
    159179                var args = new Array(entry.element, 
    160180                                     entry.name, 
    161181                                     entry.observer, 
    162182                                     entry.useCapture); 
    163183                var removed = OpenLayers.Event.stopObserving.apply(this, args); 
    164                 if (!removed) { 
    165                     i++; 
    166                 } 
    167184            } 
    168185        } 
    169186    }, 
     
    181198        useCapture = useCapture || false; 
    182199     
    183200        var element = OpenLayers.Util.getElement(elementParam); 
    184         var elementId = (typeof elementParam == "string") ? elementParam 
    185                                                           : element.id; 
     201        var cacheID = element._eventCacheID; 
    186202 
    187203        if (name == 'keypress') { 
    188204            if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||  
     
    193209 
    194210        // find element's entry in this.observers cache and remove it 
    195211        var foundEntry = false; 
    196         var elementObservers = OpenLayers.Event.observers[elementId]; 
     212        var elementObservers = OpenLayers.Event.observers[cacheID]; 
    197213        if (elementObservers) { 
    198214     
    199215            // find the specific event type in the element's list 
     
    207223     
    208224                    elementObservers.splice(i, 1); 
    209225                    if (elementObservers.length == 0) { 
    210                         delete OpenLayers.Event.observers[element.id]; 
     226                        delete OpenLayers.Event.observers[cacheID]; 
    211227                    } 
    212228                    foundEntry = true; 
    213229                    break;  
     
    230246     */ 
    231247    unloadCache: function() { 
    232248        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]); 
    235253            } 
    236254            OpenLayers.Event.observers = false; 
    237255        }