public
Fork of sstephenson/prototype
Description: Prototype JavaScript framework
Homepage: http://prototypejs.org/
Clone URL: git://github.com/jdalton/prototype.git
Search Repo:
Switch to a different strategy for event handler garbage collection. Store 
references to elements instead of searching the entire document. [#10 
state:resolved]
Fri Apr 18 11:06:39 -0700 2008
commit  6ff8485e40b8633928bcfda0adc08469b7ea3c16
tree    308fac74015ad68e5e14a371133d3a1bf5ac57aa
parent  3d27a63da0e72807c6bb83e73ffa4359ee9e6465
...
 
 
1
2
3
...
1
2
3
4
5
0
@@ -1,3 +1,5 @@
0
+* Switch to a different strategy for event handler garbage collection. Store references to elements instead of searching the entire document. (jddalton, kangax, Andrew Dupont)
0
+
0
 * Add event cleanup on Element#update and Element#replace so that replaced content does not leak memory. (jddalton, Andrew Dupont)
0
 
0
 * Loop through all elements and remove all handlers on page unload. IE needs this in order to prevent memory leaks. (kangax, jddalton, Andrew Dupont)
...
878
879
880
881
 
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
 
898
899
900
...
878
879
880
 
881
882
 
 
 
 
 
883
884
 
 
 
 
 
 
 
 
885
886
887
888
0
@@ -878,23 +878,11 @@
0
     });
0
   })(Element._attributeTranslations.read.values);
0
 
0
- // Wrap Element#update and Element#replace to clean up event handlers on
0
+ // Wrap Element#update e to clean up event handlers on
0
   // newly-removed elements. Prevents memory leaks in IE.
0
- Element._purgeObservers = function(element, includeRoot) {
0
- Element.select(element, '*').each(Event.stopObserving);
0
- if (includeRoot === true) Event.stopObserving(element);
0
- };
0
-
0
   Element.Methods.update = Element.Methods.update.wrap(
0
     function(proceed, element, contents) {
0
- Element._purgeObservers(element, false);
0
- return proceed(element, contents);
0
- }
0
- );
0
-
0
- Element.Methods.replace = Element.Methods.replace.wrap(
0
- function(proceed, element, contents) {
0
- Element._purgeObservers(element, true);
0
+ Element.select(element, '*').each(Event.stopObserving);
0
       return proceed(element, contents);
0
     }
0
   );
...
148
149
150
 
 
151
152
 
153
154
155
...
168
169
170
171
 
 
 
 
 
 
172
173
174
175
...
200
201
202
203
204
205
206
 
 
 
 
 
207
208
209
210
211
212
 
213
214
215
...
148
149
150
151
152
153
154
155
156
157
158
...
171
172
173
 
174
175
176
177
178
179
180
181
182
183
...
208
209
210
 
 
 
 
211
212
213
214
215
216
217
218
219
220
 
221
222
223
224
0
@@ -148,8 +148,11 @@
0
   var cache = Event.cache;
0
 
0
   function getEventID(element) {
0
+ // Event ID is stored as the 0th index in a one-item array so that it
0
+ // won't get copied to a new node when cloneNode is called.
0
     if (element._prototypeEventID) return element._prototypeEventID[0];
0
     arguments.callee.id = arguments.callee.id || 1;
0
+
0
     return element._prototypeEventID = [++arguments.callee.id];
0
   }
0
   
0
@@ -168,7 +171,12 @@
0
   }
0
   
0
   function createWrapper(element, eventName, handler) {
0
- var id = getEventID(element);
0
+ var id = getEventID(element), _c = getCacheForID(id);
0
+
0
+ // Attach the element itself onto its cache entry so we can retrieve it for
0
+ // cleanup on page unload.
0
+ if (!_c.element) _c.element = element;
0
+
0
     var c = getWrappersForEventName(id, eventName);
0
     if (c.pluck("handler").include(handler)) return false;
0
     
0
0
@@ -200,16 +208,17 @@
0
   // Loop through all elements and remove all handlers on page unload. IE
0
   // needs this in order to prevent memory leaks.
0
   function purgeListeners() {
0
- var all = document.getElementsByTagName('*');
0
- for (var i, node; node = all[i]; i++) {
0
- if (node.nodeType !== Node.ELEMENT_NODE) continue;
0
- Element.stopObserving(node);
0
+ var element, entry;
0
+ for (var i in Event.cache) {
0
+ entry = Event.cache[i];
0
+ Event.stopObserving(entry.element);
0
+ entry.element = null;
0
     }
0
   }
0
   
0
   function onStop() {
0
     document.detachEvent('onstop', onStop);
0
- destroyCache();
0
+ purgeListeners();
0
   }
0
   
0
   function onBeforeUnload() {

Comments

    No one has commented yet.