Skip to content

Commit e9c18bc

Browse files
committed
Memory leak fix in Prototype.
1 parent e3d5200 commit e9c18bc

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

src/prototype/dom/event.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,10 @@
593593
// Remove the entry from the collection;
594594
var index = entries.indexOf(entry);
595595
entries.splice(index, 1);
596-
596+
597+
if (entries.length == 0) {
598+
stopObservingEventName(element, eventName);
599+
}
597600
return entry;
598601
}
599602

@@ -928,6 +931,14 @@
928931
var i = entries.length;
929932
while (i--)
930933
removeEvent(element, eventName, entries[i].responder);
934+
935+
for (var name in registry) {
936+
if (name === 'element') continue;
937+
return; // There is another registered event
938+
}
939+
940+
// No other events for the element, destroy the registry:
941+
destroyRegistryForElement(element);
931942
}
932943

933944

test/unit/event_test.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ new Test.Unit.Runner({
159159
var span = $("span"), observer = Prototype.emptyFunction, eventID;
160160

161161
span.observe("test:somethingHappened", observer);
162-
162+
span.observe("test:somethingHappened", function() {});
163+
163164
function uidForElement(elem) {
164165
return elem.uniqueID ? elem.uniqueID : elem._prototypeUID;
165166
}
@@ -168,17 +169,35 @@ new Test.Unit.Runner({
168169

169170
this.assert(registry, 'registry should exist');
170171
this.assert(Object.isArray(registry['test:somethingHappened']));
171-
this.assertEqual(1, registry['test:somethingHappened'].length);
172+
this.assertEqual(2, registry['test:somethingHappened'].length);
172173

173174
span.stopObserving("test:somethingHappened", observer);
174175

175176
registry = Event.cache[uidForElement(span)];
176177

177178
this.assert(registry);
178179
this.assert(Object.isArray(registry['test:somethingHappened']));
179-
this.assertEqual(0, registry['test:somethingHappened'].length);
180+
this.assertEqual(1, registry['test:somethingHappened'].length);
180181
},
181182

183+
testLastStopObservingClearesCache: function() {
184+
var span = $("span"), observer = Prototype.emptyFunction, eventID;
185+
delete Event.cache[uidForElement(span)];
186+
187+
span.observe("test:somethingHappened", observer);
188+
189+
function uidForElement(elem) {
190+
return elem.uniqueID ? elem.uniqueID : elem._prototypeUID;
191+
}
192+
193+
span.stopObserving("test:somethingHappened", observer);
194+
195+
var registry = Event.cache[uidForElement(span)];
196+
197+
this.assert(!registry);
198+
// console.info(registry)
199+
},
200+
182201
testObserveAndStopObservingAreChainable: function() {
183202
var span = $("span"), observer = Prototype.emptyFunction;
184203

0 commit comments

Comments
 (0)