Ticket #9466: event_ie_leak_fix.diff
| File event_ie_leak_fix.diff, 5.1 kB (added by jdalton, 5 months ago) |
|---|
-
event.js
old new 130 130 })(); 131 131 132 132 Object.extend(Event, (function() { 133 var cache = Event.cache; 134 133 var cache = Event.cache, 134 Wrapper = Class.create({ 135 initialize: function(element, eventName, handler){ 136 this.id = getEventID(element); 137 this.handler = handler; 138 this.element = element; 139 this.eventName = eventName; 140 this.callback = function(event) { 141 if (!Event || !Event.extend || 142 (event.eventName && event.eventName != this.eventName)) 143 return false; 144 145 this.handler.call(this.element, Event.extend(event)); 146 }.bind(this); 147 } 148 }); 149 135 150 function getEventID(element) { 136 151 if (element._prototypeEventID) return element._prototypeEventID[0]; 137 arguments.callee.id = arguments.callee.id || 1; 138 return element._prototypeEventID = [++arguments.callee.id]; 152 return element._prototypeEventID = [arguments.callee.id++]; 139 153 } 154 getEventID.id = 1; 140 155 141 156 function getDOMEventName(eventName) { 142 157 if (eventName && eventName.include(':')) return "dataavailable"; … … 153 168 } 154 169 155 170 function createWrapper(element, eventName, handler) { 156 var id = getEventID(element); 157 var c = getWrappersForEventName(id, eventName); 171 var c = getWrappersForEventName(getEventID(element), eventName); 158 172 if (c.pluck("handler").include(handler)) return false; 159 173 160 var wrapper = function(event) { 161 if (!Event || !Event.extend || 162 (event.eventName && event.eventName != eventName)) 163 return false; 164 165 Event.extend(event); 166 handler.call(element, event); 167 }; 168 169 wrapper.handler = handler; 174 var wrapper = new Wrapper(element, eventName, handler); 170 175 c.push(wrapper); 171 176 return wrapper; 172 177 } … … 177 182 } 178 183 179 184 function destroyWrapper(id, eventName, handler) { 185 var wrapper = (id instanceof Wrapper)? id : null; 186 if(wrapper){ 187 id = wrapper.id; 188 eventName = wrapper.eventName; 189 } 180 190 var c = getCacheForID(id); 181 191 if (!c[eventName]) return false; 182 c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); 192 if(!wrapper) wrapper = findWrapper(id, eventName, handler); 193 c[eventName] = c[eventName].without(wrapper); 194 wrapper.element = null; 183 195 } 184 196 185 197 function destroyCache() { 186 198 for (var id in cache) 187 for (var eventName in cache[id]) 199 for (var eventName in cache[id]){ 200 var i = cache[id][eventName].length; 201 while(i) Event.stopObserving(cache[id][eventName][--i]); 188 202 cache[id][eventName] = null; 203 } 189 204 } 190 205 191 206 if (window.attachEvent) { … … 201 216 if (!wrapper) return element; 202 217 203 218 if (element.addEventListener) { 204 element.addEventListener(name, wrapper , false);219 element.addEventListener(name, wrapper.callback, false); 205 220 } else { 206 element.attachEvent("on" + name, wrapper );221 element.attachEvent("on" + name, wrapper.callback); 207 222 } 208 223 209 224 return element; 210 225 }, 211 226 212 227 stopObserving: function(element, eventName, handler) { 213 228 element = $(element); 214 var id = getEventID(element), name = getDOMEventName(eventName);215 229 216 if (!handler && eventName) { 217 getWrappersForEventName(id, eventName).each(function(wrapper) { 218 element.stopObserving(eventName, wrapper.handler); 219 }); 220 return element; 221 222 } else if (!eventName) { 223 Object.keys(getCacheForID(id)).each(function(eventName) { 224 element.stopObserving(eventName); 225 }); 226 return element; 230 var name, wrapper; 231 if((wrapper=arguments[0]) instanceof Wrapper){ 232 element = wrapper.element; 233 eventName = wrapper.eventName; 227 234 } 235 else{ 236 var id = getEventID(element); 237 if (!handler && eventName) { 238 getWrappersForEventName(id, eventName).each(function(wrapper) { 239 Element.stopObserving(wrapper); 240 }); 241 return element; 242 243 } else if (!eventName) { 244 Object.keys(getCacheForID(id)).each(function(eventName) { 245 element.stopObserving(eventName); 246 }); 247 return element; 248 } 249 if (!(wrapper = findWrapper(id, eventName, handler))) return element; 250 } 228 251 229 var wrapper = findWrapper(id, eventName, handler); 230 if (!wrapper) return element; 231 252 var name = getDOMEventName(eventName); 232 253 if (element.removeEventListener) { 233 element.removeEventListener(name, wrapper , false);254 element.removeEventListener(name, wrapper.callback, false); 234 255 } else { 235 element.detachEvent("on" + name, wrapper );256 element.detachEvent("on" + name, wrapper.callback); 236 257 } 237 238 destroyWrapper(id, eventName, handler); 239 258 259 destroyWrapper(wrapper); 240 260 return element; 241 261 }, 242 262 243 263 fire: function(element, eventName, memo) { 244 264 element = $(element); 245 265 if (element == document && document.createEvent && !element.dispatchEvent)