/** * @private * Handle batch read / write of DOMs, currently used in SizeMonitor + PaintMonitor */Ext.define('Ext.TaskQueue', { requires: 'Ext.AnimationQueue', singleton: true, pending: false, mode: true, constructor: function() { this.readQueue = []; this.writeQueue = []; this.run = Ext.Function.bind(this.run, this); // iOS has a nasty bug which causes pending requestAnimationFrame to not release // the callback when the WebView is switched back and forth from / to being background process // We use a watchdog timer to workaround this, and restore the pending state correctly if this happens // This timer has to be set as an interval from the very beginning and we have to keep it running for // as long as the app lives, setting it later doesn't seem to work if (Ext.os.is.iOS) { Ext.interval(this.watch, 500, this); } }, requestRead: function(fn, scope, args) { this.request(true); this.readQueue.push(arguments); }, requestWrite: function(fn, scope, args) { this.request(false); this.writeQueue.push(arguments); }, request: function(mode) { if (!this.pending) { this.pendingTime = Date.now(); this.pending = true; this.mode = mode; if (mode) { Ext.defer(this.run, 1, this); } else { Ext.Function.requestAnimationFrame(this.run); } } }, watch: function() { if (this.pending && Date.now() - this.pendingTime >= 500) { this.run(); } }, run: function() { this.pending = false; var readQueue = this.readQueue, writeQueue = this.writeQueue, request = null, queue; if (this.mode) { queue = readQueue; if (writeQueue.length > 0) { request = false; } } else { queue = writeQueue; if (readQueue.length > 0) { request = true; } } var tasks = queue.slice(), i, ln, task, fn, scope; queue.length = 0; for (i = 0, ln = tasks.length; i < ln; i++) { task = tasks[i]; fn = task[0]; scope = task[1]; if (scope && (scope.destroying || scope.destroyed)) { continue; } if (typeof fn === 'string') { fn = scope[fn]; } if (task.length > 2) { fn.apply(scope, task[2]); } else { fn.call(scope); } } tasks.length = 0; if (request !== null) { this.request(request); } } //<debug> ,privates: { flush: function() { while (this.readQueue.length || this.writeQueue.length) { this.run(); } } } //</debug> });