1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/contentprefs/tests/unit_cps2/AsyncRunner.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,72 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +let EXPORTED_SYMBOLS = [ 1.9 + "AsyncRunner", 1.10 +]; 1.11 + 1.12 +const { interfaces: Ci, classes: Cc } = Components; 1.13 + 1.14 +function AsyncRunner(callbacks) { 1.15 + this._callbacks = callbacks; 1.16 + this._iteratorQueue = []; 1.17 + 1.18 + // This catches errors reported to the console, e.g., via Cu.reportError. 1.19 + Cc["@mozilla.org/consoleservice;1"]. 1.20 + getService(Ci.nsIConsoleService). 1.21 + registerListener(this); 1.22 +} 1.23 + 1.24 +AsyncRunner.prototype = { 1.25 + 1.26 + appendIterator: function AR_appendIterator(iter) { 1.27 + this._iteratorQueue.push(iter); 1.28 + }, 1.29 + 1.30 + next: function AR_next(/* ... */) { 1.31 + if (!this._iteratorQueue.length) { 1.32 + this.destroy(); 1.33 + this._callbacks.done(); 1.34 + return; 1.35 + } 1.36 + 1.37 + // send() discards all arguments after the first, so there's no choice here 1.38 + // but to send only one argument to the yielder. 1.39 + let args = [arguments.length <= 1 ? arguments[0] : Array.slice(arguments)]; 1.40 + try { 1.41 + var val = this._iteratorQueue[0].send.apply(this._iteratorQueue[0], args); 1.42 + } 1.43 + catch (err if err instanceof StopIteration) { 1.44 + this._iteratorQueue.shift(); 1.45 + this.next(); 1.46 + return; 1.47 + } 1.48 + catch (err) { 1.49 + this._callbacks.error(err); 1.50 + } 1.51 + 1.52 + // val is truthy => call next 1.53 + // val is an iterator => prepend it to the queue and start on it 1.54 + if (val) { 1.55 + if (typeof(val) != "boolean") 1.56 + this._iteratorQueue.unshift(val); 1.57 + this.next(); 1.58 + } 1.59 + }, 1.60 + 1.61 + destroy: function AR_destroy() { 1.62 + Cc["@mozilla.org/consoleservice;1"]. 1.63 + getService(Ci.nsIConsoleService). 1.64 + unregisterListener(this); 1.65 + this.destroy = function AR_alreadyDestroyed() {}; 1.66 + }, 1.67 + 1.68 + observe: function AR_consoleServiceListener(msg) { 1.69 + if (msg instanceof Ci.nsIScriptError && 1.70 + !(msg.flags & Ci.nsIScriptError.warningFlag)) 1.71 + { 1.72 + this._callbacks.consoleError(msg); 1.73 + } 1.74 + }, 1.75 +};