diff --git a/CHANGELOG b/CHANGELOG index ac6289a..4c903da 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Make sure event handlers and their wrappers are removed from the cache by Event.stopObserving. [sam, Severin Heiniger] + * Add line numbers to failures when unit testing in Firefox. Closes #9231. [John Resig] * Fix Function#argumentNames for Opera and IE. [Thomas Fuchs] diff --git a/src/event.js b/src/event.js index cb13b3d..850772d 100644 --- a/src/event.js +++ b/src/event.js @@ -24,6 +24,8 @@ Object.extend(Event, { 'DOMSubtreeModified', 'DOMNodeInserted', 'NodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified'], + + cache: { }, relatedTarget: function(event) { var element; @@ -106,7 +108,7 @@ Event.extend = (function() { })(); Object.extend(Event, (function() { - var cache = { }; + var cache = Event.cache; function getEventID(element) { if (element._eventID) return element._eventID; @@ -151,9 +153,9 @@ Object.extend(Event, (function() { } function destroyWrapper(id, eventName, handler) { - var c = getCacheForID(id), name = getDOMEventName(eventName); - if (!c[name]) return false; - c[name] = c[name].without(findWrapper(id, eventName, handler)); + var c = getCacheForID(id); + if (!c[eventName]) return false; + c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); } function destroyCache() { @@ -204,6 +206,8 @@ Object.extend(Event, (function() { } else { element.detachEvent("on" + name, wrapper); } + + destroyWrapper(id, eventName, handler); }, fire: function(element, eventName, memo) { diff --git a/test/unit/event.html b/test/unit/event.html index 3e08aca..049495c 100644 --- a/test/unit/event.html +++ b/test/unit/event.html @@ -166,6 +166,22 @@ assertEqual(1, count); }}, + testStopObservingRemovesHandlerFromCache: function() { with(this) { + var span = $("span"), observer = function() { }, eventID; + + span.observe("somethingHappened", observer); + eventID = span._eventID; + + assert(Event.cache[eventID]); + assert(Object.isArray(Event.cache[eventID].somethingHappened)); + assertEqual(1, Event.cache[eventID].somethingHappened.length); + + span.stopObserving("somethingHappened", observer); + assert(Event.cache[eventID]); + assert(Object.isArray(Event.cache[eventID].somethingHappened)); + assertEqual(0, Event.cache[eventID].somethingHappened.length); + }}, + testDocumentContentLoadedEventFiresBeforeWindowLoad: function() { with(this) { assert(eventResults.contentLoaded, "contentLoaded"); assert(eventResults.contentLoaded.endOfDocument, "contentLoaded.endOfDocument");