]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/dom/GarbageCollector.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / dom / GarbageCollector.js
CommitLineData
6527f429
DM
1/**\r
2 * @private\r
3 * Garbage collector for Ext.dom.Element instances. Automatically cleans up Elements\r
4 * that are no longer in the dom, but were not properly destroyed using\r
5 * {@link Ext.dom.Element#destroy destroy()}. Recommended practice is for Components to\r
6 * clean up their own elements, but the GarbageCollector runs on regularly scheduled\r
7 * intervals to attempt to clean up orphaned Elements that may have slipped through the cracks.\r
8 */\r
9Ext.define('Ext.dom.GarbageCollector', {\r
10 singleton: true,\r
11\r
12 /**\r
13 * @property {Number}\r
14 * The interval at which to run Element garbage collection. Set this property directly\r
15 * to tune the interval.\r
16 *\r
17 * Ext.dom.GarbageCollector.interval = 60000; // run garbage collection every one minute\r
18 */\r
19 interval: 30000,\r
20\r
21 constructor: function() {\r
22 var me = this;\r
23 me.collect = Ext.Function.bind(me.collect, me);\r
24 me.lastTime = Ext.now();\r
25 me.resume();\r
26 },\r
27\r
28 /**\r
29 * Collects orphaned Ext.dom.Elements by removing their listeners and evicting them\r
30 * from the cache. Runs on a regularly scheduled {@link #interval} but can be called\r
31 * directly to force garbage collection.\r
32 * @return {String[]} An array containing the IDs of the elements that were garbage\r
33 * collected, prefixed by their tag names. Only applies in dev mode. Returns nothing\r
34 * in a production build.\r
35 */\r
36 collect: function() {\r
37 var me = this,\r
38 cache = Ext.cache,\r
39 eid, dom, el, t, isGarbage, tagName;\r
40 \r
41 //<debug>\r
42 var collectedIds = [];\r
43 //</debug>\r
44 \r
45\r
46 for (eid in cache) {\r
47 if (!cache.hasOwnProperty(eid)) {\r
48 continue;\r
49 }\r
50\r
51 el = cache[eid];\r
52\r
53 if (el.skipGarbageCollection) {\r
54 continue;\r
55 }\r
56\r
57 dom = el.dom;\r
58\r
59 //<debug>\r
60 // Should always have a DOM node\r
61 if (!dom) {\r
62 Ext.raise('Missing DOM node in element garbage collection: ' + eid);\r
63 }\r
64 //</debug>\r
65 \r
66 try {\r
67 // In IE, accessing any properties of the window object of an orphaned iframe\r
68 // can result in a "Permission Denied" error. The same error also occurs\r
69 // when accessing any properties of orphaned documentElement or body inside\r
70 // of an iframe (documentElement and body become orphaned when the iframe\r
71 // contentWindow is unloaded)\r
72 isGarbage = Ext.isGarbage(dom);\r
73 } catch (e) {\r
74 // if an error was thrown in isGarbage it is most likely because we are\r
75 // dealing with an inaccessible window or documentElement inside an orphaned\r
76 // iframe in IE. In this case we can't do anything except remove the\r
77 // cache entry.\r
78 delete cache[eid];\r
79 //<debug>\r
80 collectedIds.push('#' + el.id);\r
81 //</debug>\r
82 continue;\r
83 }\r
84 \r
85 if (isGarbage) {\r
86 if (el && el.dom) {\r
87 //<debug>\r
88 tagName = el.dom.tagName;\r
89 //</debug>\r
90 el.collect();\r
91 //<debug>\r
92 collectedIds.push((tagName ? tagName : '') + '#' + el.id);\r
93 //</debug>\r
94 }\r
95 }\r
96 }\r
97 //<feature legacyBrowser>\r
98 // Cleanup IE Object leaks\r
99 if (Ext.isIE9m) {\r
100 t = {};\r
101 for (eid in cache) {\r
102 if (cache.hasOwnProperty(eid)) {\r
103 t[eid] = cache[eid];\r
104 }\r
105 }\r
106 Ext.cache = Ext.dom.Element.cache = t;\r
107 }\r
108 //</feature>\r
109\r
110 me.lastTime = Ext.now();\r
111\r
112 //<debug>\r
113 return collectedIds;\r
114 //</debug>\r
115 },\r
116\r
117 /**\r
118 * Pauses the timer and stops garbage collection\r
119 */\r
120 pause: function() {\r
121 clearTimeout(this.timerId);\r
122 },\r
123\r
124 /**\r
125 * Resumes garbage collection at the specified {@link #interval}\r
126 */\r
127 resume: function() {\r
128 var me = this,\r
129 lastTime = me.lastTime;\r
130\r
131 if (Ext.enableGarbageCollector && (Ext.now() - lastTime > me.interval)) {\r
132 me.collect();\r
133 }\r
134\r
135 me.timerId = Ext.interval(me.collect, me.interval);\r
136 }\r
137});