]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * This class manages ready detection and handling. Direct use of this class is not\r | |
3 | * recommended. Instead use `Ext.onReady`:\r | |
4 | * \r | |
5 | * Ext.onReady(function () {\r | |
6 | * // DOM and Framework are ready...\r | |
7 | * });\r | |
8 | *\r | |
9 | * ## DOM Ready\r | |
10 | *\r | |
11 | * The lowest-level of readiness is DOM readiness. This level implies only that the document\r | |
12 | * body exists. Many things require the DOM to be ready for manipulation. If that is all\r | |
13 | * that is required, the `Ext.onDocumentReady` method can be called to register a callback\r | |
14 | * to be called as soon as the DOM is ready:\r | |
15 | *\r | |
16 | * Ext.onDocumentReady(function () {\r | |
17 | * // the document body is ready\r | |
18 | * });\r | |
19 | *\r | |
20 | * ## Framework Ready\r | |
21 | *\r | |
22 | * In production builds of applications it is common to have all of the code loaded before\r | |
23 | * DOM ready, so the need to wait for "onReady" is often confused with only that concern.\r | |
24 | * This is easy to understand, at least in part because historically `Ext.onReady` only\r | |
25 | * waited for DOM ready.\r | |
26 | *\r | |
27 | * With the introduction of `Ext.Loader`, however, it became common for DOM ready to occur\r | |
28 | * in the middle of dynamically loading code. If application code were executed at that\r | |
29 | * time, any use of the yet-to-be-loaded classes would throw errors. As a consequence of\r | |
30 | * this, the `Ext.onReady` mechanism was extended to wait for both DOM ready *and* all of\r | |
31 | * the required classes to be loaded.\r | |
32 | *\r | |
33 | * When the framework enters or leaves a state where it is not ready (for example, the\r | |
34 | * first dynamic load is requested or last load completes), `Ext.env.Ready` is informed.\r | |
35 | * For example:\r | |
36 | *\r | |
37 | * Ext.env.Ready.block();\r | |
38 | *\r | |
39 | * //...\r | |
40 | *\r | |
41 | * Ext.env.Ready.unblock();\r | |
42 | *\r | |
43 | * When there are no blocks and the DOM is ready, the Framework is ready and the "onReady"\r | |
44 | * callbacks are called.\r | |
45 | *\r | |
46 | * Priority can be used to control the ordering of onReady listeners, for example:\r | |
47 | *\r | |
48 | * Ext.onReady(function() {\r | |
49 | *\r | |
50 | * }, null, {\r | |
51 | * priority: 100\r | |
52 | * });\r | |
53 | *\r | |
54 | * Ready listeners with higher priorities will run sooner than those with lower priorities,\r | |
55 | * the default priority being `0`. Internally the framework reserves priorities of 1000\r | |
56 | * or greater, and -1000 or lesser for onReady handlers that must run before or after\r | |
57 | * any application code. Applications should stick to using priorities in the -999 - 999\r | |
58 | * range. The following priorities are currently in use by the framework:\r | |
59 | *\r | |
60 | * - Element_scroll rtl override: `1001`\r | |
61 | * - Event system initialization: `2000`\r | |
62 | * - Ext.dom.Element: `1500`\r | |
63 | *\r | |
64 | * @class Ext.env.Ready\r | |
65 | * @singleton\r | |
66 | * @private\r | |
67 | * @since 5.0.0\r | |
68 | */\r | |
69 | Ext.env.Ready = {\r | |
70 | // @define Ext.env.Ready\r | |
71 | // @require Ext.env.Browser\r | |
72 | // @require Ext.env.OS\r | |
73 | // @require Ext.env.Feature\r | |
74 | \r | |
75 | /**\r | |
76 | * @property {Number} blocks The number of Framework readiness blocks.\r | |
77 | * @private\r | |
78 | */\r | |
79 | blocks: (location.search || '').indexOf('ext-pauseReadyFire') > 0 ? 1 : 0,\r | |
80 | \r | |
81 | /**\r | |
82 | * @property {Number} bound This property stores the state of event listeners bound\r | |
83 | * to the document or window to detect ready state.\r | |
84 | * @private\r | |
85 | */\r | |
86 | bound: 0,\r | |
87 | \r | |
88 | /**\r | |
89 | * @property {Number} [delay=1]\r | |
90 | * This allows the DOM listener thread to complete (usually desirable with mobWebkit,\r | |
91 | * Gecko) before firing the entire onReady chain (high stack load on Loader). For mobile\r | |
92 | * devices when running from Home Screen, the splash screen will not disappear until\r | |
93 | * all external resource requests finish. This delay clears the splash screen.\r | |
94 | * @private\r | |
95 | */\r | |
96 | delay: 1,\r | |
97 | \r | |
98 | //<debug>\r | |
99 | /**\r | |
100 | * @property {Event[]} events An array of events that have triggered ready state. This\r | |
101 | * is for diagnostic purposes only and is only available in debug builds.\r | |
102 | * An array\r | |
103 | * @private\r | |
104 | */\r | |
105 | events: [],\r | |
106 | //</debug>\r | |
107 | \r | |
108 | /**\r | |
109 | * @property {Boolean} firing This property is `true` when we currently calling the\r | |
110 | * listeners.\r | |
111 | * @private\r | |
112 | */\r | |
113 | firing: false,\r | |
114 | \r | |
115 | /**\r | |
116 | * @property {Number} generation A counter of the number of mutations of `listeners`.\r | |
117 | * @private\r | |
118 | */\r | |
119 | generation: 0,\r | |
120 | \r | |
121 | /**\r | |
122 | * @property {Object[]} listeners The set of listeners waiting for ready.\r | |
123 | * @private\r | |
124 | */\r | |
125 | listeners: [],\r | |
126 | \r | |
127 | /**\r | |
128 | * @property {Number} nextId A counter so we can assign listeners an `id` to keep\r | |
129 | * them in FIFO order.\r | |
130 | * @private\r | |
131 | */\r | |
132 | nextId: 0,\r | |
133 | \r | |
134 | /**\r | |
135 | * @property {Number} sortGeneration A captured value of `generation` that indicates\r | |
136 | * when the `listeners` were last sorted.\r | |
137 | * @private\r | |
138 | */\r | |
139 | sortGeneration: 0,\r | |
140 | \r | |
141 | /**\r | |
142 | * @property {Number} state\r | |
143 | * Holds the current ready state as managed by this class. The values possible are:\r | |
144 | * \r | |
145 | * * 0 - Not ready.\r | |
146 | * * 1 - Ready detected but listeners are not yet notified.\r | |
147 | * * 2 - Ready detected and listeners are notified. See also `firing`.\r | |
148 | * \r | |
149 | * @private\r | |
150 | */\r | |
151 | state: 0,\r | |
152 | \r | |
153 | /**\r | |
154 | * @property {Object} timer The handle from `setTimeout` for the delayed notification\r | |
155 | * of ready.\r | |
156 | * @private\r | |
157 | */\r | |
158 | timer: null,\r | |
159 | \r | |
160 | /**\r | |
161 | * Binds the appropriate browser event for checking if the DOM has loaded.\r | |
162 | * @private\r | |
163 | */\r | |
164 | bind: function () {\r | |
165 | var me = Ext.env.Ready,\r | |
166 | doc = document;\r | |
167 | \r | |
168 | if (!me.bound) {\r | |
169 | // Test scenario where load is dynamic AFTER window.load\r | |
170 | if (doc.readyState === 'complete') {\r | |
171 | // Firefox4+ got support for this state, others already do.\r | |
172 | me.onReadyEvent({\r | |
173 | type: doc.readyState || 'body'\r | |
174 | });\r | |
175 | } else {\r | |
176 | me.bound = 1;\r | |
177 | if (Ext.browser.is.PhoneGap && !Ext.os.is.Desktop) {\r | |
178 | me.bound = 2;\r | |
179 | doc.addEventListener('deviceready', me.onReadyEvent, false);\r | |
180 | }\r | |
181 | doc.addEventListener('DOMContentLoaded', me.onReadyEvent, false);\r | |
182 | window.addEventListener('load', me.onReadyEvent, false);\r | |
183 | }\r | |
184 | }\r | |
185 | },\r | |
186 | \r | |
187 | block: function () {\r | |
188 | ++this.blocks;\r | |
189 | Ext.isReady = false;\r | |
190 | },\r | |
191 | \r | |
192 | /**\r | |
193 | * This method starts the process of firing the ready event. This may be delayed based\r | |
194 | * on the `delay` property.\r | |
195 | * @private\r | |
196 | */\r | |
197 | fireReady: function () {\r | |
198 | var me = Ext.env.Ready;\r | |
199 | \r | |
200 | if (!me.state) {\r | |
201 | Ext._readyTime = Ext.ticks();\r | |
202 | Ext.isDomReady = true;\r | |
203 | me.state = 1;\r | |
204 | \r | |
205 | // As soon as we transition to domready, complete the feature detection:\r | |
206 | Ext.feature.detect(true);\r | |
207 | \r | |
208 | if (!me.delay) {\r | |
209 | me.handleReady();\r | |
210 | } else if (navigator.standalone) {\r | |
211 | // When running from Home Screen, the splash screen will not disappear\r | |
212 | // until all external resource requests finish.\r | |
213 | // The first timeout clears the splash screen\r | |
214 | // The second timeout allows inital HTML content to be displayed\r | |
215 | me.timer = Ext.defer(function() {\r | |
216 | me.timer = null;\r | |
217 | me.handleReadySoon();\r | |
218 | }, 1);\r | |
219 | } else {\r | |
220 | me.handleReadySoon();\r | |
221 | }\r | |
222 | }\r | |
223 | },\r | |
224 | \r | |
225 | /**\r | |
226 | * This method iterates over the `listeners` and invokes them. This advances the\r | |
227 | * `state` from 1 to 2 and ensure the proper subset of `listeners` are invoked.\r | |
228 | * @private\r | |
229 | */\r | |
230 | handleReady: function () {\r | |
231 | var me = this;\r | |
232 | \r | |
233 | if (me.state === 1) {\r | |
234 | me.state = 2;\r | |
235 | \r | |
236 | Ext._beforeReadyTime = Ext.ticks();\r | |
237 | me.invokeAll();\r | |
238 | Ext._afterReadyTime = Ext.ticks();\r | |
239 | }\r | |
240 | },\r | |
241 | \r | |
242 | /**\r | |
243 | * This method is called to schedule a call to `handleReady` using a `setTimeout`. It\r | |
244 | * ensures that only one timer is pending.\r | |
245 | * @param {Number} [delay] If passed, this overrides the `delay` property.\r | |
246 | * @private\r | |
247 | */\r | |
248 | handleReadySoon: function (delay) {\r | |
249 | var me = this;\r | |
250 | \r | |
251 | if (!me.timer) {\r | |
252 | me.timer = Ext.defer(function () {\r | |
253 | me.timer = null;\r | |
254 | me.handleReady();\r | |
255 | }, delay || me.delay);\r | |
256 | }\r | |
257 | },\r | |
258 | \r | |
259 | /**\r | |
260 | * This method invokes the given `listener` instance based on its options.\r | |
261 | * @param {Object} listener\r | |
262 | */\r | |
263 | invoke: function (listener) {\r | |
264 | var delay = listener.delay;\r | |
265 | \r | |
266 | if (delay) {\r | |
267 | Ext.defer(listener.fn, delay, listener.scope);\r | |
268 | } else {\r | |
269 | if (Ext.elevateFunction) {\r | |
270 | Ext.elevateFunction(listener.fn, listener.scope);\r | |
271 | } else {\r | |
272 | listener.fn.call(listener.scope);\r | |
273 | }\r | |
274 | }\r | |
275 | },\r | |
276 | \r | |
277 | /**\r | |
278 | * Invokes as many listeners as are appropriate given the current state. This should\r | |
279 | * only be called when DOM ready is achieved. The remaining business of `blocks` is\r | |
280 | * handled here.\r | |
281 | */\r | |
282 | invokeAll: function() {\r | |
283 | if (Ext.elevateFunction) {\r | |
284 | Ext.elevateFunction(this.doInvokeAll, this);\r | |
285 | } else {\r | |
286 | this.doInvokeAll();\r | |
287 | }\r | |
288 | },\r | |
289 | \r | |
290 | doInvokeAll: function () {\r | |
291 | var me = this,\r | |
292 | listeners = me.listeners,\r | |
293 | listener;\r | |
294 | \r | |
295 | if (!me.blocks) {\r | |
296 | // Since DOM is ready and we have no blocks, we mark the framework as ready.\r | |
297 | Ext.isReady = true;\r | |
298 | }\r | |
299 | me.firing = true;\r | |
300 | \r | |
301 | // NOTE: We cannot cache this length because each time through the loop a callback\r | |
302 | // may have added new callbacks.\r | |
303 | while (listeners.length) {\r | |
304 | if (me.sortGeneration !== me.generation) {\r | |
305 | me.sortGeneration = me.generation;\r | |
306 | \r | |
307 | // This will happen just once on the first pass... if nothing is being\r | |
308 | // added as we call the callbacks. This sorts the listeners such that the\r | |
309 | // highest priority listener is at the *end* of the array ... so we can\r | |
310 | // use pop (as opposed to shift) to extract it.\r | |
311 | listeners.sort(me.sortFn);\r | |
312 | }\r | |
313 | \r | |
314 | listener = listeners.pop();\r | |
315 | if (me.blocks && !listener.dom) {\r | |
316 | // If we are blocked (i.e., only DOM ready) and this listener is not a\r | |
317 | // DOM-ready listener we have reached the end of the line. The remaining\r | |
318 | // listeners are Framework ready listeners.\r | |
319 | listeners.push(listener);\r | |
320 | break;\r | |
321 | }\r | |
322 | \r | |
323 | me.invoke(listener);\r | |
324 | }\r | |
325 | \r | |
326 | me.firing = false;\r | |
327 | },\r | |
328 | \r | |
329 | /**\r | |
330 | * This method wraps the given listener pieces in a proper object for the `listeners`\r | |
331 | * array and `invoke` methods.\r | |
332 | * @param {Function} fn The method to call.\r | |
333 | * @param {Object} [scope] The scope (`this` reference) in which the `fn` executes.\r | |
334 | * Defaults to the browser window.\r | |
335 | * @param {Object} [options] An object with extra options.\r | |
336 | * @param {Number} [options.delay=0] A number of milliseconds to delay.\r | |
337 | * @param {Number} [options.priority=0] Relative priority of this callback. A larger\r | |
338 | * number will result in the callback being sorted before the others. Priorities\r | |
339 | * 1000 or greater and -1000 or lesser are reserved for internal framework use only.\r | |
340 | * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`\r | |
341 | * means full Framework and DOM readiness.\r | |
342 | * @return {Object} The listener instance.\r | |
343 | * @private\r | |
344 | */\r | |
345 | makeListener: function (fn, scope, options) {\r | |
346 | var ret = {\r | |
347 | fn: fn,\r | |
348 | id: ++this.nextId, // so sortFn can respect FIFO\r | |
349 | scope: scope,\r | |
350 | dom: false,\r | |
351 | priority: 0\r | |
352 | };\r | |
353 | if (options) {\r | |
354 | Ext.apply(ret, options);\r | |
355 | }\r | |
356 | ret.phase = ret.dom ? 0 : 1; // to simplify the sortFn\r | |
357 | return ret;\r | |
358 | },\r | |
359 | \r | |
360 | /**\r | |
361 | * Adds a listener to be notified when the document is ready (before onload and before\r | |
362 | * images are loaded).\r | |
363 | *\r | |
364 | * @param {Function} fn The method to call.\r | |
365 | * @param {Object} [scope] The scope (`this` reference) in which the `fn` executes.\r | |
366 | * Defaults to the browser window.\r | |
367 | * @param {Object} [options] An object with extra options.\r | |
368 | * @param {Number} [options.delay=0] A number of milliseconds to delay.\r | |
369 | * @param {Number} [options.priority=0] Relative priority of this callback. A larger\r | |
370 | * number will result in the callback being sorted before the others. Priorities\r | |
371 | * 1000 or greater and -1000 or lesser are reserved for internal framework use only.\r | |
372 | * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`\r | |
373 | * means full Framework and DOM readiness.\r | |
374 | * @private\r | |
375 | */\r | |
376 | on: function (fn, scope, options) {\r | |
377 | var me = Ext.env.Ready,\r | |
378 | listener = me.makeListener(fn, scope, options);\r | |
379 | \r | |
380 | if (me.state === 2 && !me.firing && (listener.dom || !me.blocks)) {\r | |
381 | // If we are DOM ready (state === 2) and not currently in invokeAll (!firing)\r | |
382 | // and this listener is ready to call (either a DOM ready listener or there\r | |
383 | // are no blocks), then we need to invoke the listener now.\r | |
384 | //\r | |
385 | // Otherwise we can fall to the else block and push the listener. The eventual\r | |
386 | // (or currently executing) call to handleReady or unblock will trigger its\r | |
387 | // delivery in proper priority order.\r | |
388 | me.invoke(listener);\r | |
389 | } else {\r | |
390 | me.listeners.push(listener);\r | |
391 | ++me.generation;\r | |
392 | \r | |
393 | if (!me.bound) {\r | |
394 | // If we have never bound then bind the ready event now. If we have unbound\r | |
395 | // the event then me.bound == -1 and we don't want to rebind it as the DOM\r | |
396 | // is ready.\r | |
397 | me.bind();\r | |
398 | }\r | |
399 | }\r | |
400 | },\r | |
401 | \r | |
402 | /**\r | |
403 | * This is a generic event handler method attached to all of the various events that\r | |
404 | * may indicate ready state. The first call to this method indicates ready state has\r | |
405 | * been achieved.\r | |
406 | * @param {Event} [ev] The event instance.\r | |
407 | * @private\r | |
408 | */\r | |
409 | onReadyEvent: function (ev) {\r | |
410 | var me = Ext.env.Ready;\r | |
411 | \r | |
412 | if (Ext.elevateFunction) {\r | |
413 | Ext.elevateFunction(me.doReadyEvent, me, arguments);\r | |
414 | } else {\r | |
415 | me.doReadyEvent(ev);\r | |
416 | }\r | |
417 | },\r | |
418 | \r | |
419 | doReadyEvent: function (ev) {\r | |
420 | var me = this;\r | |
421 | \r | |
422 | //<debug>\r | |
423 | if (ev && ev.type) {\r | |
424 | me.events.push(ev);\r | |
425 | }\r | |
426 | //</debug>\r | |
427 | \r | |
428 | if (me.bound > 0) {\r | |
429 | me.unbind();\r | |
430 | me.bound = -1; // NOTE: *not* 0 or false - we never want to rebind!\r | |
431 | }\r | |
432 | \r | |
433 | if (!me.state) {\r | |
434 | me.fireReady();\r | |
435 | }\r | |
436 | },\r | |
437 | \r | |
438 | /**\r | |
439 | * Sorts the `listeners` array by `phase` and `priority` such that the first listener\r | |
440 | * to fire can be determined using `pop` on the `listeners` array.\r | |
441 | * @private\r | |
442 | */\r | |
443 | sortFn: function (a, b) {\r | |
444 | return -((a.phase - b.phase) || (b.priority - a.priority) || (a.id - b.id));\r | |
445 | },\r | |
446 | \r | |
447 | unblock: function () {\r | |
448 | var me = this;\r | |
449 | \r | |
450 | if (me.blocks) {\r | |
451 | if (! --me.blocks) {\r | |
452 | if (me.state === 2 && !me.firing) {\r | |
453 | // We have already finished handleReady (the DOM ready handler) so\r | |
454 | // this trigger just needs to dispatch all the remaining listeners.\r | |
455 | me.invokeAll();\r | |
456 | }\r | |
457 | // if we are currently firing then invokeAll will pick up the Framework\r | |
458 | // ready listeners automatically.\r | |
459 | //\r | |
460 | // If me.state < 2 then we are waiting for DOM ready so it will eventually\r | |
461 | // call handleReady and invokeAll when everything is ready.\r | |
462 | }\r | |
463 | }\r | |
464 | },\r | |
465 | \r | |
466 | /**\r | |
467 | * This method is called to remove all event listeners that may have been set up to\r | |
468 | * detect ready state.\r | |
469 | * @private\r | |
470 | */\r | |
471 | unbind: function () {\r | |
472 | var me = this,\r | |
473 | doc = document;\r | |
474 | \r | |
475 | if (me.bound > 1) {\r | |
476 | doc.removeEventListener('deviceready', me.onReadyEvent, false);\r | |
477 | }\r | |
478 | \r | |
479 | doc.removeEventListener('DOMContentLoaded', me.onReadyEvent, false);\r | |
480 | window.removeEventListener('load', me.onReadyEvent, false);\r | |
481 | }\r | |
482 | };\r | |
483 | \r | |
484 | (function () {\r | |
485 | var Ready = Ext.env.Ready;\r | |
486 | \r | |
487 | //<feature legacyBrowser>\r | |
488 | \r | |
489 | /*\r | |
490 | * EXTJS-13522\r | |
491 | * Although IE 9 has the DOMContentLoaded event available, usage of that causes\r | |
492 | * timing issues when attempting to access document.namespaces (VmlCanvas.js).\r | |
493 | * Consequently, even in IE 9 we need to use the legacy bind override for ready\r | |
494 | * detection. This defers ready firing enough to allow access to the\r | |
495 | * document.namespaces property.\r | |
496 | *\r | |
497 | * NOTE: this issue is very timing sensitive, and typically only displays itself\r | |
498 | * when there is a large amount of latency between the browser and the server, and\r | |
499 | * when testing against a built page (ext-all.js) and not a dev mode page.\r | |
500 | */\r | |
501 | if (Ext.isIE9m) {\r | |
502 | /* Customized implementation for Legacy IE. The default implementation is \r | |
503 | * configured for use with all other 'standards compliant' agents.\r | |
504 | * References: http://javascript.nwbox.com/IEContentLoaded/\r | |
505 | * licensed courtesy of http://developer.yahoo.com/yui/license.html\r | |
506 | */\r | |
507 | Ext.apply(Ready, {\r | |
508 | /**\r | |
509 | * Timer for doScroll polling\r | |
510 | * @private\r | |
511 | */\r | |
512 | scrollTimer: null,\r | |
513 | \r | |
514 | /**\r | |
515 | * @private\r | |
516 | */\r | |
517 | readyStatesRe : /complete/i,\r | |
518 | \r | |
519 | /**\r | |
520 | * This strategy has minimal benefits for Sencha solutions that build\r | |
521 | * themselves (ie. minimal initial page markup). However, progressively-enhanced\r | |
522 | * pages (with image content and/or embedded frames) will benefit the most\r | |
523 | * from it. Browser timer resolution is too poor to ensure a doScroll check\r | |
524 | * more than once on a page loaded with minimal assets (the readystatechange\r | |
525 | * event 'complete' usually beats the doScroll timer on a 'lightly-loaded'\r | |
526 | * initial document).\r | |
527 | * @private\r | |
528 | */\r | |
529 | pollScroll : function() {\r | |
530 | var scrollable = true;\r | |
531 | \r | |
532 | try {\r | |
533 | document.documentElement.doScroll('left');\r | |
534 | } catch(e) {\r | |
535 | scrollable = false;\r | |
536 | }\r | |
537 | \r | |
538 | // on IE8, when running within an iFrame, document.body is not immediately\r | |
539 | // available\r | |
540 | if (scrollable && document.body) {\r | |
541 | Ready.onReadyEvent({\r | |
542 | type: 'doScroll'\r | |
543 | });\r | |
544 | } else {\r | |
545 | // Minimize thrashing --\r | |
546 | // adjusted for setTimeout's close-to-minimums (not too low),\r | |
547 | // as this method SHOULD always be called once initially\r | |
548 | Ready.scrollTimer = Ext.defer(Ready.pollScroll, 20);\r | |
549 | }\r | |
550 | \r | |
551 | return scrollable;\r | |
552 | },\r | |
553 | \r | |
554 | bind: function () {\r | |
555 | if (Ready.bound) {\r | |
556 | return;\r | |
557 | }\r | |
558 | \r | |
559 | var doc = document,\r | |
560 | topContext;\r | |
561 | \r | |
562 | // See if we are in an IFRAME? (doScroll ineffective here)\r | |
563 | try {\r | |
564 | topContext = window.frameElement === undefined;\r | |
565 | } catch(e) {\r | |
566 | // If we throw an exception, it means we're probably getting access\r | |
567 | // denied, which means we're in an iframe cross domain.\r | |
568 | }\r | |
569 | \r | |
570 | if (!topContext || !doc.documentElement.doScroll) {\r | |
571 | Ready.pollScroll = Ext.emptyFn; //then noop this test altogether\r | |
572 | }\r | |
573 | else if (Ready.pollScroll()) { // starts scroll polling if necessary\r | |
574 | return;\r | |
575 | }\r | |
576 | \r | |
577 | if (doc.readyState === 'complete') {\r | |
578 | // Loaded AFTER initial document write/load...\r | |
579 | Ready.onReadyEvent({\r | |
580 | type: 'already ' + (doc.readyState || 'body')\r | |
581 | });\r | |
582 | } else {\r | |
583 | doc.attachEvent('onreadystatechange', Ready.onReadyStateChange);\r | |
584 | window.attachEvent('onload', Ready.onReadyEvent);\r | |
585 | Ready.bound = 1;\r | |
586 | }\r | |
587 | },\r | |
588 | \r | |
589 | unbind : function () {\r | |
590 | document.detachEvent('onreadystatechange', Ready.onReadyStateChange);\r | |
591 | window.detachEvent('onload', Ready.onReadyEvent);\r | |
592 | \r | |
593 | if (Ext.isNumber(Ready.scrollTimer)) {\r | |
594 | clearTimeout(Ready.scrollTimer);\r | |
595 | Ready.scrollTimer = null;\r | |
596 | }\r | |
597 | },\r | |
598 | \r | |
599 | /**\r | |
600 | * This event handler is called when the readyState changes.\r | |
601 | * @private\r | |
602 | */\r | |
603 | onReadyStateChange: function() {\r | |
604 | var state = document.readyState;\r | |
605 | \r | |
606 | if (Ready.readyStatesRe.test(state)) {\r | |
607 | Ready.onReadyEvent({\r | |
608 | type: state\r | |
609 | });\r | |
610 | }\r | |
611 | }\r | |
612 | });\r | |
613 | }\r | |
614 | //</feature>\r | |
615 | \r | |
616 | /**\r | |
617 | * @property {Boolean} isDomReady\r | |
618 | * `true` when the document body is ready for use.\r | |
619 | * @member Ext\r | |
620 | * @readonly\r | |
621 | */\r | |
622 | \r | |
623 | /**\r | |
624 | * @property {Boolean} isReady\r | |
625 | * `true` when `isDomReady` is true and the Framework is ready for use.\r | |
626 | * @member Ext\r | |
627 | * @readonly\r | |
628 | */\r | |
629 | \r | |
630 | /**\r | |
631 | * @method onDocumentReady\r | |
632 | * @member Ext\r | |
633 | * Adds a listener to be notified when the document is ready (before onload and before\r | |
634 | * images are loaded).\r | |
635 | *\r | |
636 | * @param {Function} fn The method to call.\r | |
637 | * @param {Object} [scope] The scope (`this` reference) in which the handler function\r | |
638 | * executes. Defaults to the browser window.\r | |
639 | * @param {Object} [options] An object with extra options.\r | |
640 | * @param {Number} [options.delay=0] A number of milliseconds to delay.\r | |
641 | * @param {Number} [options.priority=0] Relative priority of this callback. A larger\r | |
642 | * number will result in the callback being sorted before the others. Priorities\r | |
643 | * 1000 or greater and -1000 or lesser are reserved for internal framework use only.\r | |
644 | * @private\r | |
645 | */\r | |
646 | Ext.onDocumentReady = function (fn, scope, options) {\r | |
647 | var opt = {\r | |
648 | dom: true\r | |
649 | };\r | |
650 | \r | |
651 | if (options) {\r | |
652 | Ext.apply(opt, options);\r | |
653 | }\r | |
654 | \r | |
655 | Ready.on(fn, scope, opt);\r | |
656 | };\r | |
657 | \r | |
658 | /**\r | |
659 | * @method onReady\r | |
660 | * @member Ext\r | |
661 | * Adds a listener to be notified when the document is ready (before onload and before\r | |
662 | * images are loaded).\r | |
663 | *\r | |
664 | * @param {Function} fn The method to call.\r | |
665 | * @param {Object} [scope] The scope (`this` reference) in which the handler function\r | |
666 | * executes. Defaults to the browser window.\r | |
667 | * @param {Object} [options] An object with extra options.\r | |
668 | * @param {Number} [options.delay=0] A number of milliseconds to delay.\r | |
669 | * @param {Number} [options.priority=0] Relative priority of this callback. A larger\r | |
670 | * number will result in the callback being sorted before the others. Priorities\r | |
671 | * 1000 or greater and -1000 or lesser are reserved for internal framework use only.\r | |
672 | * @param {Boolean} [options.dom=false] Pass `true` to only wait for DOM ready, `false`\r | |
673 | * means full Framework and DOM readiness.\r | |
674 | * numbers are reserved.\r | |
675 | */\r | |
676 | Ext.onReady = function (fn, scope, options) {\r | |
677 | Ready.on(fn, scope, options);\r | |
678 | };\r | |
679 | \r | |
680 | // A shortcut method for onReady with a high priority\r | |
681 | Ext.onInternalReady = function(fn, scope, options) {\r | |
682 | Ready.on(fn, scope, Ext.apply({\r | |
683 | priority: 1000\r | |
684 | }, options));\r | |
685 | }\r | |
686 | \r | |
687 | Ready.bind();\r | |
688 | }());\r |