WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Proposed fix (rebased)
bug-135830-20140828102450.patch (text/plain), 63.49 KB, created by
Brian Burg
on 2014-08-28 10:25:19 PDT
(
hide
)
Description:
Proposed fix (rebased)
Filename:
MIME Type:
Creator:
Brian Burg
Created:
2014-08-28 10:25:19 PDT
Size:
63.49 KB
patch
obsolete
>Subversion Revision: 173064 >diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 1e02cf29d00923458ff47e55f3a96feb512d70b3..180c450b9e5a75556a3b3d3038dfa2044e9a541b 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,35 @@ >+2014-08-28 Brian J. Burg <burg@cs.washington.edu> >+ >+ Promise reactions in the Inspector page do not run when the debugger is paused on the inspected page >+ https://bugs.webkit.org/show_bug.cgi?id=135830 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This will hopefully be fixed by multi-process Web Inspector in the future, but until that lands, we >+ can use a pure-JavaScript promises implementation that doesn't use callOnMainThread under the hood. >+ >+ Refactor all callsites to use WebInspector.Promise as the constructor, which is assigned >+ to the RSVP.Promise constructor now (but can revert to the native Promise constructor later). >+ >+ * UserInterface/Base/DOMUtilities.js: >+ * UserInterface/Base/Test.js: >+ (InspectorTest.reloadPage): >+ * UserInterface/Controllers/DebuggerManager.js: >+ * UserInterface/Controllers/ReplayManager.js: >+ (WebInspector.ReplayManager.prototype.getSession.get var): >+ (WebInspector.ReplayManager.prototype.getSegment.get var): >+ (WebInspector.ReplayManager.prototype.createSession.return): >+ (WebInspector.ReplayManager.prototype.createSession): >+ (WebInspector.ReplayManager.prototype._suppressBreakpointsAndResumeIfNeeded): >+ (WebInspector.ReplayManager.prototype.startCapturing.result): Deleted. >+ (WebInspector.ReplayManager.prototype.segmentUnloaded): Deleted. >+ * UserInterface/External/RSVP/LICENSE: Added. >+ * UserInterface/External/RSVP/rsvp.js: Added. >+ * UserInterface/Main.html: >+ * UserInterface/Models/ReplaySession.js: >+ * UserInterface/Protocol/InspectorBackend.js: >+ (InspectorBackend.Command.prototype.promise): >+ > 2014-08-27 Saam Barati <sbarati@apple.com> > > Web Inspector: Layout issues for popover on not legacy OS >diff --git a/Source/WebInspectorUI/UserInterface/Base/DOMUtilities.js b/Source/WebInspectorUI/UserInterface/Base/DOMUtilities.js >index 2dba61347154541071312a118474729a1bfde2d4..b0c15e46371e202691af4bf60a7a978513a736ec 100644 >--- a/Source/WebInspectorUI/UserInterface/Base/DOMUtilities.js >+++ b/Source/WebInspectorUI/UserInterface/Base/DOMUtilities.js >@@ -29,6 +29,9 @@ > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > >+// This is a workaround for problems with the debugger and native Promises. <https://webkit.org/b/135830> >+WebInspector.Promise = RSVP.Promise; >+ > WebInspector.displayNameForNode = function(node) > { > var title = node.nodeNameInCorrectCase(); >diff --git a/Source/WebInspectorUI/UserInterface/Base/Test.js b/Source/WebInspectorUI/UserInterface/Base/Test.js >index ab5af104a44c92aeca81be8b0c1b2e3a8b79eefa..e3b537aa840f7fdaa4d30f6655872358094d205a 100644 >--- a/Source/WebInspectorUI/UserInterface/Base/Test.js >+++ b/Source/WebInspectorUI/UserInterface/Base/Test.js >@@ -213,7 +213,7 @@ InspectorTest.reloadPage = function(shouldIgnoreCache) > this._shouldResendResults = true; > this._testPageIsReloading = true; > >- return Promise.resolve(null); >+ return WebInspector.Promise.resolve(null); > }); > } > >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js b/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js >index 1732d337c15208dba8b8ec9685b9ad65df2f8ded..021042b87a9a009ddeb85bb6a9fbab5d12137891 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js >@@ -143,11 +143,11 @@ WebInspector.DebuggerManager.prototype = { > pause: function() > { > if (this._paused) >- return Promise.resolve(); >+ return WebInspector.Promise.resolve(); > > var listener = new WebInspector.EventListener(this, true); > >- var managerResult = new Promise(function(resolve, reject) { >+ var managerResult = new WebInspector.Promise(function(resolve, reject) { > listener.connect(WebInspector.debuggerManager, WebInspector.DebuggerManager.Event.Paused, resolve); > }); > >@@ -158,17 +158,17 @@ WebInspector.DebuggerManager.prototype = { > throw error; > }); > >- return Promise.all([managerResult, protocolResult]); >+ return WebInspector.Promise.all([managerResult, protocolResult]); > }, > > resume: function() > { > if (!this._paused) >- return Promise.resolve(); >+ return WebInspector.Promise.resolve(); > > var listener = new WebInspector.EventListener(this, true); > >- var managerResult = new Promise(function(resolve, reject) { >+ var managerResult = new WebInspector.Promise(function(resolve, reject) { > listener.connect(WebInspector.debuggerManager, WebInspector.DebuggerManager.Event.Resumed, resolve); > }); > >@@ -179,17 +179,17 @@ WebInspector.DebuggerManager.prototype = { > throw error; > }); > >- return Promise.all([managerResult, protocolResult]); >+ return WebInspector.Promise.all([managerResult, protocolResult]); > }, > > stepOver: function() > { > if (!this._paused) >- return Promise.reject(new Error("Cannot step over because debugger is not paused.")); >+ return WebInspector.Promise.reject(new Error("Cannot step over because debugger is not paused.")); > > var listener = new WebInspector.EventListener(this, true); > >- var managerResult = new Promise(function(resolve, reject) { >+ var managerResult = new WebInspector.Promise(function(resolve, reject) { > listener.connect(WebInspector.debuggerManager, WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, resolve); > }); > >@@ -200,17 +200,17 @@ WebInspector.DebuggerManager.prototype = { > throw error; > }); > >- return Promise.all([managerResult, protocolResult]); >+ return WebInspector.Promise.all([managerResult, protocolResult]); > }, > > stepInto: function() > { > if (!this._paused) >- return Promise.reject(new Error("Cannot step into because debugger is not paused.")); >+ return WebInspector.Promise.reject(new Error("Cannot step into because debugger is not paused.")); > > var listener = new WebInspector.EventListener(this, true); > >- var managerResult = new Promise(function(resolve, reject) { >+ var managerResult = new WebInspector.Promise(function(resolve, reject) { > listener.connect(WebInspector.debuggerManager, WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, resolve); > }); > >@@ -221,17 +221,17 @@ WebInspector.DebuggerManager.prototype = { > throw error; > }); > >- return Promise.all([managerResult, protocolResult]); >+ return WebInspector.Promise.all([managerResult, protocolResult]); > }, > > stepOut: function() > { > if (!this._paused) >- return Promise.reject(new Error("Cannot step out because debugger is not paused.")); >+ return WebInspector.Promise.reject(new Error("Cannot step out because debugger is not paused.")); > > var listener = new WebInspector.EventListener(this, true); > >- var managerResult = new Promise(function(resolve, reject) { >+ var managerResult = new WebInspector.Promise(function(resolve, reject) { > listener.connect(WebInspector.debuggerManager, WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, resolve); > }); > >@@ -242,7 +242,7 @@ WebInspector.DebuggerManager.prototype = { > throw error; > }); > >- return Promise.all([managerResult, protocolResult]); >+ return WebInspector.Promise.all([managerResult, protocolResult]); > }, > > get allExceptionsBreakpoint() >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js b/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js >index 46c0505135dee41f35f5816f8466ee45cb36ec36..f1d9a8785cebb969fe6141ae7a66cbc3586e07fb 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js >@@ -176,7 +176,7 @@ WebInspector.ReplayManager.prototype = { > > var newPromise = ReplayAgent.getSessionData.promise(sessionId) > .then(function(payload) { >- return Promise.resolve(WebInspector.ReplaySession.fromPayload(sessionId, payload)); >+ return WebInspector.Promise.resolve(WebInspector.ReplaySession.fromPayload(sessionId, payload)); > }); > > this._sessionPromises.set(sessionId, newPromise); >@@ -191,7 +191,7 @@ WebInspector.ReplayManager.prototype = { > > var newPromise = ReplayAgent.getSegmentData.promise(segmentId) > .then(function(payload) { >- return Promise.resolve(new WebInspector.ReplaySessionSegment(segmentId, payload)); >+ return WebInspector.Promise.resolve(new WebInspector.ReplaySessionSegment(segmentId, payload)); > }); > > this._segmentPromises.set(segmentId, newPromise); >@@ -545,7 +545,7 @@ WebInspector.ReplayManager.prototype = { > // be removed once the segment is complete, and then its data will be fetched. > var incompleteSegment = new WebInspector.IncompleteSessionSegment(segmentId); > this._segments.set(segmentId, incompleteSegment); >- this._segmentPromises.set(segmentId, Promise.resolve(incompleteSegment)); >+ this._segmentPromises.set(segmentId, WebInspector.Promise.resolve(incompleteSegment)); > > this.dispatchEventToListeners(WebInspector.ReplayManager.Event.SessionSegmentAdded, {segmentIdentifier: segmentId}); > }, >@@ -584,7 +584,7 @@ WebInspector.ReplayManager.prototype = { > // Wait for any outstanding promise to settle so it doesn't get re-added. > this.getSegment(segmentId) > .catch(function(error) { >- return Promise.resolve(); >+ return WebInspector.Promise.resolve(); > }).then(function() { > manager._segmentPromises.delete(segmentId); > var removedSegment = manager._segments.take(segmentId); >@@ -672,7 +672,7 @@ WebInspector.ReplayManager.prototype = { > { > var manager = this; > >- return new Promise(function(resolve, reject) { >+ return new WebInspector.Promise(function(resolve, reject) { > manager._breakpointsWereSuppressed = WebInspector.debuggerManager.breakpointsEnabled; > WebInspector.debuggerManager.breakpointsEnabled = false; > >diff --git a/Source/WebInspectorUI/UserInterface/External/RSVP/LICENSE b/Source/WebInspectorUI/UserInterface/External/RSVP/LICENSE >new file mode 100644 >index 0000000000000000000000000000000000000000..954ec5992df7508499c41d0e9d7ed74ef5d5032c >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/External/RSVP/LICENSE >@@ -0,0 +1,19 @@ >+Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors >+ >+Permission is hereby granted, free of charge, to any person obtaining a copy of >+this software and associated documentation files (the "Software"), to deal in >+the Software without restriction, including without limitation the rights to >+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies >+of the Software, and to permit persons to whom the Software is furnished to do >+so, subject to the following conditions: >+ >+The above copyright notice and this permission notice shall be included in all >+copies or substantial portions of the Software. >+ >+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE >+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, >+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE >+SOFTWARE. >diff --git a/Source/WebInspectorUI/UserInterface/External/RSVP/rsvp.js b/Source/WebInspectorUI/UserInterface/External/RSVP/rsvp.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0d1e4569ac58df0e057ba0cd4b1de1c9789242c5 >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/External/RSVP/rsvp.js >@@ -0,0 +1,1610 @@ >+/*! >+ * @overview RSVP - a tiny implementation of Promises/A+. >+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors >+ * @license Licensed under MIT license >+ * See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE >+ * @version 3.0.13 >+ */ >+ >+(function() { >+ "use strict"; >+ >+ function $$rsvp$events$$indexOf(callbacks, callback) { >+ for (var i=0, l=callbacks.length; i<l; i++) { >+ if (callbacks[i] === callback) { return i; } >+ } >+ >+ return -1; >+ } >+ >+ function $$rsvp$events$$callbacksFor(object) { >+ var callbacks = object._promiseCallbacks; >+ >+ if (!callbacks) { >+ callbacks = object._promiseCallbacks = {}; >+ } >+ >+ return callbacks; >+ } >+ >+ var $$rsvp$events$$default = { >+ >+ /** >+ `RSVP.EventTarget.mixin` extends an object with EventTarget methods. For >+ Example: >+ >+ ```javascript >+ var object = {}; >+ >+ RSVP.EventTarget.mixin(object); >+ >+ object.on('finished', function(event) { >+ // handle event >+ }); >+ >+ object.trigger('finished', { detail: value }); >+ ``` >+ >+ `EventTarget.mixin` also works with prototypes: >+ >+ ```javascript >+ var Person = function() {}; >+ RSVP.EventTarget.mixin(Person.prototype); >+ >+ var yehuda = new Person(); >+ var tom = new Person(); >+ >+ yehuda.on('poke', function(event) { >+ console.log('Yehuda says OW'); >+ }); >+ >+ tom.on('poke', function(event) { >+ console.log('Tom says OW'); >+ }); >+ >+ yehuda.trigger('poke'); >+ tom.trigger('poke'); >+ ``` >+ >+ @method mixin >+ @for RSVP.EventTarget >+ @private >+ @param {Object} object object to extend with EventTarget methods >+ */ >+ mixin: function(object) { >+ object.on = this.on; >+ object.off = this.off; >+ object.trigger = this.trigger; >+ object._promiseCallbacks = undefined; >+ return object; >+ }, >+ >+ /** >+ Registers a callback to be executed when `eventName` is triggered >+ >+ ```javascript >+ object.on('event', function(eventInfo){ >+ // handle the event >+ }); >+ >+ object.trigger('event'); >+ ``` >+ >+ @method on >+ @for RSVP.EventTarget >+ @private >+ @param {String} eventName name of the event to listen for >+ @param {Function} callback function to be called when the event is triggered. >+ */ >+ on: function(eventName, callback) { >+ var allCallbacks = $$rsvp$events$$callbacksFor(this), callbacks; >+ >+ callbacks = allCallbacks[eventName]; >+ >+ if (!callbacks) { >+ callbacks = allCallbacks[eventName] = []; >+ } >+ >+ if ($$rsvp$events$$indexOf(callbacks, callback) === -1) { >+ callbacks.push(callback); >+ } >+ }, >+ >+ /** >+ You can use `off` to stop firing a particular callback for an event: >+ >+ ```javascript >+ function doStuff() { // do stuff! } >+ object.on('stuff', doStuff); >+ >+ object.trigger('stuff'); // doStuff will be called >+ >+ // Unregister ONLY the doStuff callback >+ object.off('stuff', doStuff); >+ object.trigger('stuff'); // doStuff will NOT be called >+ ``` >+ >+ If you don't pass a `callback` argument to `off`, ALL callbacks for the >+ event will not be executed when the event fires. For example: >+ >+ ```javascript >+ var callback1 = function(){}; >+ var callback2 = function(){}; >+ >+ object.on('stuff', callback1); >+ object.on('stuff', callback2); >+ >+ object.trigger('stuff'); // callback1 and callback2 will be executed. >+ >+ object.off('stuff'); >+ object.trigger('stuff'); // callback1 and callback2 will not be executed! >+ ``` >+ >+ @method off >+ @for RSVP.EventTarget >+ @private >+ @param {String} eventName event to stop listening to >+ @param {Function} callback optional argument. If given, only the function >+ given will be removed from the event's callback queue. If no `callback` >+ argument is given, all callbacks will be removed from the event's callback >+ queue. >+ */ >+ off: function(eventName, callback) { >+ var allCallbacks = $$rsvp$events$$callbacksFor(this), callbacks, index; >+ >+ if (!callback) { >+ allCallbacks[eventName] = []; >+ return; >+ } >+ >+ callbacks = allCallbacks[eventName]; >+ >+ index = $$rsvp$events$$indexOf(callbacks, callback); >+ >+ if (index !== -1) { callbacks.splice(index, 1); } >+ }, >+ >+ /** >+ Use `trigger` to fire custom events. For example: >+ >+ ```javascript >+ object.on('foo', function(){ >+ console.log('foo event happened!'); >+ }); >+ object.trigger('foo'); >+ // 'foo event happened!' logged to the console >+ ``` >+ >+ You can also pass a value as a second argument to `trigger` that will be >+ passed as an argument to all event listeners for the event: >+ >+ ```javascript >+ object.on('foo', function(value){ >+ console.log(value.name); >+ }); >+ >+ object.trigger('foo', { name: 'bar' }); >+ // 'bar' logged to the console >+ ``` >+ >+ @method trigger >+ @for RSVP.EventTarget >+ @private >+ @param {String} eventName name of the event to be triggered >+ @param {Any} options optional value to be passed to any event handlers for >+ the given `eventName` >+ */ >+ trigger: function(eventName, options) { >+ var allCallbacks = $$rsvp$events$$callbacksFor(this), callbacks, callback; >+ >+ if (callbacks = allCallbacks[eventName]) { >+ // Don't cache the callbacks.length since it may grow >+ for (var i=0; i<callbacks.length; i++) { >+ callback = callbacks[i]; >+ >+ callback(options); >+ } >+ } >+ } >+ }; >+ >+ var $$rsvp$config$$config = { >+ instrument: false >+ }; >+ >+ $$rsvp$events$$default.mixin($$rsvp$config$$config); >+ >+ function $$rsvp$config$$configure(name, value) { >+ if (name === 'onerror') { >+ // handle for legacy users that expect the actual >+ // error to be passed to their function added via >+ // `RSVP.configure('onerror', someFunctionHere);` >+ $$rsvp$config$$config.on('error', value); >+ return; >+ } >+ >+ if (arguments.length === 2) { >+ $$rsvp$config$$config[name] = value; >+ } else { >+ return $$rsvp$config$$config[name]; >+ } >+ } >+ >+ function $$utils$$objectOrFunction(x) { >+ return typeof x === 'function' || (typeof x === 'object' && x !== null); >+ } >+ >+ function $$utils$$isFunction(x) { >+ return typeof x === 'function'; >+ } >+ >+ function $$utils$$isMaybeThenable(x) { >+ return typeof x === 'object' && x !== null; >+ } >+ >+ var $$utils$$_isArray; >+ >+ if (!Array.isArray) { >+ $$utils$$_isArray = function (x) { >+ return Object.prototype.toString.call(x) === '[object Array]'; >+ }; >+ } else { >+ $$utils$$_isArray = Array.isArray; >+ } >+ >+ var $$utils$$isArray = $$utils$$_isArray; >+ var $$utils$$now = Date.now || function() { return new Date().getTime(); }; >+ function $$utils$$F() { } >+ >+ var $$utils$$o_create = (Object.create || function (o) { >+ if (arguments.length > 1) { >+ throw new Error('Second argument not supported'); >+ } >+ if (typeof o !== 'object') { >+ throw new TypeError('Argument must be an object'); >+ } >+ $$utils$$F.prototype = o; >+ return new $$utils$$F(); >+ }); >+ >+ var $$instrument$$queue = []; >+ >+ var $$instrument$$default = function instrument(eventName, promise, child) { >+ if (1 === $$instrument$$queue.push({ >+ name: eventName, >+ payload: { >+ guid: promise._guidKey + promise._id, >+ eventName: eventName, >+ detail: promise._result, >+ childGuid: child && promise._guidKey + child._id, >+ label: promise._label, >+ timeStamp: $$utils$$now(), >+ stack: new Error(promise._label).stack >+ }})) { >+ >+ setTimeout(function() { >+ var entry; >+ for (var i = 0; i < $$instrument$$queue.length; i++) { >+ entry = $$instrument$$queue[i]; >+ $$rsvp$config$$config.trigger(entry.name, entry.payload); >+ } >+ $$instrument$$queue.length = 0; >+ }, 50); >+ } >+ }; >+ >+ function $$$internal$$noop() {} >+ var $$$internal$$PENDING = void 0; >+ var $$$internal$$FULFILLED = 1; >+ var $$$internal$$REJECTED = 2; >+ var $$$internal$$GET_THEN_ERROR = new $$$internal$$ErrorObject(); >+ >+ function $$$internal$$getThen(promise) { >+ try { >+ return promise.then; >+ } catch(error) { >+ $$$internal$$GET_THEN_ERROR.error = error; >+ return $$$internal$$GET_THEN_ERROR; >+ } >+ } >+ >+ function $$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) { >+ try { >+ then.call(value, fulfillmentHandler, rejectionHandler); >+ } catch(e) { >+ return e; >+ } >+ } >+ >+ function $$$internal$$handleForeignThenable(promise, thenable, then) { >+ $$rsvp$config$$config.async(function(promise) { >+ var sealed = false; >+ var error = $$$internal$$tryThen(then, thenable, function(value) { >+ if (sealed) { return; } >+ sealed = true; >+ if (thenable !== value) { >+ $$$internal$$resolve(promise, value); >+ } else { >+ $$$internal$$fulfill(promise, value); >+ } >+ }, function(reason) { >+ if (sealed) { return; } >+ sealed = true; >+ >+ $$$internal$$reject(promise, reason); >+ }, 'Settle: ' + (promise._label || ' unknown promise')); >+ >+ if (!sealed && error) { >+ sealed = true; >+ $$$internal$$reject(promise, error); >+ } >+ }, promise); >+ } >+ >+ function $$$internal$$handleOwnThenable(promise, thenable) { >+ if (thenable._state === $$$internal$$FULFILLED) { >+ $$$internal$$fulfill(promise, thenable._result); >+ } else if (promise._state === $$$internal$$REJECTED) { >+ $$$internal$$reject(promise, thenable._result); >+ } else { >+ $$$internal$$subscribe(thenable, undefined, function(value) { >+ if (thenable !== value) { >+ $$$internal$$resolve(promise, value); >+ } else { >+ $$$internal$$fulfill(promise, value); >+ } >+ }, function(reason) { >+ $$$internal$$reject(promise, reason); >+ }); >+ } >+ } >+ >+ function $$$internal$$handleMaybeThenable(promise, maybeThenable) { >+ if (maybeThenable.constructor === promise.constructor) { >+ $$$internal$$handleOwnThenable(promise, maybeThenable); >+ } else { >+ var then = $$$internal$$getThen(maybeThenable); >+ >+ if (then === $$$internal$$GET_THEN_ERROR) { >+ $$$internal$$reject(promise, $$$internal$$GET_THEN_ERROR.error); >+ } else if (then === undefined) { >+ $$$internal$$fulfill(promise, maybeThenable); >+ } else if ($$utils$$isFunction(then)) { >+ $$$internal$$handleForeignThenable(promise, maybeThenable, then); >+ } else { >+ $$$internal$$fulfill(promise, maybeThenable); >+ } >+ } >+ } >+ >+ function $$$internal$$resolve(promise, value) { >+ if (promise === value) { >+ $$$internal$$fulfill(promise, value); >+ } else if ($$utils$$objectOrFunction(value)) { >+ $$$internal$$handleMaybeThenable(promise, value); >+ } else { >+ $$$internal$$fulfill(promise, value); >+ } >+ } >+ >+ function $$$internal$$publishRejection(promise) { >+ if (promise._onerror) { >+ promise._onerror(promise._result); >+ } >+ >+ $$$internal$$publish(promise); >+ } >+ >+ function $$$internal$$fulfill(promise, value) { >+ if (promise._state !== $$$internal$$PENDING) { return; } >+ >+ promise._result = value; >+ promise._state = $$$internal$$FULFILLED; >+ >+ if (promise._subscribers.length === 0) { >+ if ($$rsvp$config$$config.instrument) { >+ $$instrument$$default('fulfilled', promise); >+ } >+ } else { >+ $$rsvp$config$$config.async($$$internal$$publish, promise); >+ } >+ } >+ >+ function $$$internal$$reject(promise, reason) { >+ if (promise._state !== $$$internal$$PENDING) { return; } >+ promise._state = $$$internal$$REJECTED; >+ promise._result = reason; >+ >+ $$rsvp$config$$config.async($$$internal$$publishRejection, promise); >+ } >+ >+ function $$$internal$$subscribe(parent, child, onFulfillment, onRejection) { >+ var subscribers = parent._subscribers; >+ var length = subscribers.length; >+ >+ parent._onerror = null; >+ >+ subscribers[length] = child; >+ subscribers[length + $$$internal$$FULFILLED] = onFulfillment; >+ subscribers[length + $$$internal$$REJECTED] = onRejection; >+ >+ if (length === 0 && parent._state) { >+ $$rsvp$config$$config.async($$$internal$$publish, parent); >+ } >+ } >+ >+ function $$$internal$$publish(promise) { >+ var subscribers = promise._subscribers; >+ var settled = promise._state; >+ >+ if ($$rsvp$config$$config.instrument) { >+ $$instrument$$default(settled === $$$internal$$FULFILLED ? 'fulfilled' : 'rejected', promise); >+ } >+ >+ if (subscribers.length === 0) { return; } >+ >+ var child, callback, detail = promise._result; >+ >+ for (var i = 0; i < subscribers.length; i += 3) { >+ child = subscribers[i]; >+ callback = subscribers[i + settled]; >+ >+ if (child) { >+ $$$internal$$invokeCallback(settled, child, callback, detail); >+ } else { >+ callback(detail); >+ } >+ } >+ >+ promise._subscribers.length = 0; >+ } >+ >+ function $$$internal$$ErrorObject() { >+ this.error = null; >+ } >+ >+ var $$$internal$$TRY_CATCH_ERROR = new $$$internal$$ErrorObject(); >+ >+ function $$$internal$$tryCatch(callback, detail) { >+ try { >+ return callback(detail); >+ } catch(e) { >+ $$$internal$$TRY_CATCH_ERROR.error = e; >+ return $$$internal$$TRY_CATCH_ERROR; >+ } >+ } >+ >+ function $$$internal$$invokeCallback(settled, promise, callback, detail) { >+ var hasCallback = $$utils$$isFunction(callback), >+ value, error, succeeded, failed; >+ >+ if (hasCallback) { >+ value = $$$internal$$tryCatch(callback, detail); >+ >+ if (value === $$$internal$$TRY_CATCH_ERROR) { >+ failed = true; >+ error = value.error; >+ value = null; >+ } else { >+ succeeded = true; >+ } >+ >+ if (promise === value) { >+ $$$internal$$reject(promise, new TypeError('A promises callback cannot return that same promise.')); >+ return; >+ } >+ >+ } else { >+ value = detail; >+ succeeded = true; >+ } >+ >+ if (promise._state !== $$$internal$$PENDING) { >+ // noop >+ } else if (hasCallback && succeeded) { >+ $$$internal$$resolve(promise, value); >+ } else if (failed) { >+ $$$internal$$reject(promise, error); >+ } else if (settled === $$$internal$$FULFILLED) { >+ $$$internal$$fulfill(promise, value); >+ } else if (settled === $$$internal$$REJECTED) { >+ $$$internal$$reject(promise, value); >+ } >+ } >+ >+ function $$$internal$$initializePromise(promise, resolver) { >+ try { >+ resolver(function resolvePromise(value){ >+ $$$internal$$resolve(promise, value); >+ }, function rejectPromise(reason) { >+ $$$internal$$reject(promise, reason); >+ }); >+ } catch(e) { >+ $$$internal$$reject(promise, e); >+ } >+ } >+ >+ function $$enumerator$$makeSettledResult(state, position, value) { >+ if (state === $$$internal$$FULFILLED) { >+ return { >+ state: 'fulfilled', >+ value: value >+ }; >+ } else { >+ return { >+ state: 'rejected', >+ reason: value >+ }; >+ } >+ } >+ >+ function $$enumerator$$Enumerator(Constructor, input, abortOnReject, label) { >+ this._instanceConstructor = Constructor; >+ this.promise = new Constructor($$$internal$$noop, label); >+ this._abortOnReject = abortOnReject; >+ >+ if (this._validateInput(input)) { >+ this._input = input; >+ this.length = input.length; >+ this._remaining = input.length; >+ >+ this._init(); >+ >+ if (this.length === 0) { >+ $$$internal$$fulfill(this.promise, this._result); >+ } else { >+ this.length = this.length || 0; >+ this._enumerate(); >+ if (this._remaining === 0) { >+ $$$internal$$fulfill(this.promise, this._result); >+ } >+ } >+ } else { >+ $$$internal$$reject(this.promise, this._validationError()); >+ } >+ } >+ >+ $$enumerator$$Enumerator.prototype._validateInput = function(input) { >+ return $$utils$$isArray(input); >+ }; >+ >+ $$enumerator$$Enumerator.prototype._validationError = function() { >+ return new Error('Array Methods must be provided an Array'); >+ }; >+ >+ $$enumerator$$Enumerator.prototype._init = function() { >+ this._result = new Array(this.length); >+ }; >+ >+ var $$enumerator$$default = $$enumerator$$Enumerator; >+ >+ $$enumerator$$Enumerator.prototype._enumerate = function() { >+ var length = this.length; >+ var promise = this.promise; >+ var input = this._input; >+ >+ for (var i = 0; promise._state === $$$internal$$PENDING && i < length; i++) { >+ this._eachEntry(input[i], i); >+ } >+ }; >+ >+ $$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) { >+ var c = this._instanceConstructor; >+ if ($$utils$$isMaybeThenable(entry)) { >+ if (entry.constructor === c && entry._state !== $$$internal$$PENDING) { >+ entry._onerror = null; >+ this._settledAt(entry._state, i, entry._result); >+ } else { >+ this._willSettleAt(c.resolve(entry), i); >+ } >+ } else { >+ this._remaining--; >+ this._result[i] = this._makeResult($$$internal$$FULFILLED, i, entry); >+ } >+ }; >+ >+ $$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) { >+ var promise = this.promise; >+ >+ if (promise._state === $$$internal$$PENDING) { >+ this._remaining--; >+ >+ if (this._abortOnReject && state === $$$internal$$REJECTED) { >+ $$$internal$$reject(promise, value); >+ } else { >+ this._result[i] = this._makeResult(state, i, value); >+ } >+ } >+ >+ if (this._remaining === 0) { >+ $$$internal$$fulfill(promise, this._result); >+ } >+ }; >+ >+ $$enumerator$$Enumerator.prototype._makeResult = function(state, i, value) { >+ return value; >+ }; >+ >+ $$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) { >+ var enumerator = this; >+ >+ $$$internal$$subscribe(promise, undefined, function(value) { >+ enumerator._settledAt($$$internal$$FULFILLED, i, value); >+ }, function(reason) { >+ enumerator._settledAt($$$internal$$REJECTED, i, reason); >+ }); >+ }; >+ >+ var $$promise$all$$default = function all(entries, label) { >+ return new $$enumerator$$default(this, entries, true /* abort on reject */, label).promise; >+ }; >+ >+ var $$promise$race$$default = function race(entries, label) { >+ /*jshint validthis:true */ >+ var Constructor = this; >+ >+ var promise = new Constructor($$$internal$$noop, label); >+ >+ if (!$$utils$$isArray(entries)) { >+ $$$internal$$reject(promise, new TypeError('You must pass an array to race.')); >+ return promise; >+ } >+ >+ var length = entries.length; >+ >+ function onFulfillment(value) { >+ $$$internal$$resolve(promise, value); >+ } >+ >+ function onRejection(reason) { >+ $$$internal$$reject(promise, reason); >+ } >+ >+ for (var i = 0; promise._state === $$$internal$$PENDING && i < length; i++) { >+ $$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection); >+ } >+ >+ return promise; >+ }; >+ >+ var $$promise$resolve$$default = function resolve(object, label) { >+ /*jshint validthis:true */ >+ var Constructor = this; >+ >+ if (object && typeof object === 'object' && object.constructor === Constructor) { >+ return object; >+ } >+ >+ var promise = new Constructor($$$internal$$noop, label); >+ $$$internal$$resolve(promise, object); >+ return promise; >+ }; >+ >+ var $$promise$reject$$default = function reject(reason, label) { >+ /*jshint validthis:true */ >+ var Constructor = this; >+ var promise = new Constructor($$$internal$$noop, label); >+ $$$internal$$reject(promise, reason); >+ return promise; >+ }; >+ >+ var $$rsvp$promise$$guidKey = 'rsvp_' + $$utils$$now() + '-'; >+ var $$rsvp$promise$$counter = 0; >+ >+ function $$rsvp$promise$$needsResolver() { >+ throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); >+ } >+ >+ function $$rsvp$promise$$needsNew() { >+ throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); >+ } >+ >+ var $$rsvp$promise$$default = $$rsvp$promise$$Promise; >+ >+ /** >+ Promise objects represent the eventual result of an asynchronous operation. The >+ primary way of interacting with a promise is through its `then` method, which >+ registers callbacks to receive either a promiseââ¬â¢s eventual value or the reason >+ why the promise cannot be fulfilled. >+ >+ Terminology >+ ----------- >+ >+ - `promise` is an object or function with a `then` method whose behavior conforms to this specification. >+ - `thenable` is an object or function that defines a `then` method. >+ - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). >+ - `exception` is a value that is thrown using the throw statement. >+ - `reason` is a value that indicates why a promise was rejected. >+ - `settled` the final resting state of a promise, fulfilled or rejected. >+ >+ A promise can be in one of three states: pending, fulfilled, or rejected. >+ >+ Promises that are fulfilled have a fulfillment value and are in the fulfilled >+ state. Promises that are rejected have a rejection reason and are in the >+ rejected state. A fulfillment value is never a thenable. >+ >+ Promises can also be said to *resolve* a value. If this value is also a >+ promise, then the original promise's settled state will match the value's >+ settled state. So a promise that *resolves* a promise that rejects will >+ itself reject, and a promise that *resolves* a promise that fulfills will >+ itself fulfill. >+ >+ >+ Basic Usage: >+ ------------ >+ >+ ```js >+ var promise = new Promise(function(resolve, reject) { >+ // on success >+ resolve(value); >+ >+ // on failure >+ reject(reason); >+ }); >+ >+ promise.then(function(value) { >+ // on fulfillment >+ }, function(reason) { >+ // on rejection >+ }); >+ ``` >+ >+ Advanced Usage: >+ --------------- >+ >+ Promises shine when abstracting away asynchronous interactions such as >+ `XMLHttpRequest`s. >+ >+ ```js >+ function getJSON(url) { >+ return new Promise(function(resolve, reject){ >+ var xhr = new XMLHttpRequest(); >+ >+ xhr.open('GET', url); >+ xhr.onreadystatechange = handler; >+ xhr.responseType = 'json'; >+ xhr.setRequestHeader('Accept', 'application/json'); >+ xhr.send(); >+ >+ function handler() { >+ if (this.readyState === this.DONE) { >+ if (this.status === 200) { >+ resolve(this.response); >+ } else { >+ reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); >+ } >+ } >+ }; >+ }); >+ } >+ >+ getJSON('/posts.json').then(function(json) { >+ // on fulfillment >+ }, function(reason) { >+ // on rejection >+ }); >+ ``` >+ >+ Unlike callbacks, promises are great composable primitives. >+ >+ ```js >+ Promise.all([ >+ getJSON('/posts'), >+ getJSON('/comments') >+ ]).then(function(values){ >+ values[0] // => postsJSON >+ values[1] // => commentsJSON >+ >+ return values; >+ }); >+ ``` >+ >+ @class RSVP.Promise >+ @param {function} resolver >+ @param {String} label optional string for labeling the promise. >+ Useful for tooling. >+ @constructor >+ */ >+ function $$rsvp$promise$$Promise(resolver, label) { >+ this._id = $$rsvp$promise$$counter++; >+ this._label = label; >+ this._state = undefined; >+ this._result = undefined; >+ this._subscribers = []; >+ >+ if ($$rsvp$config$$config.instrument) { >+ $$instrument$$default('created', this); >+ } >+ >+ if ($$$internal$$noop !== resolver) { >+ if (!$$utils$$isFunction(resolver)) { >+ $$rsvp$promise$$needsResolver(); >+ } >+ >+ if (!(this instanceof $$rsvp$promise$$Promise)) { >+ $$rsvp$promise$$needsNew(); >+ } >+ >+ $$$internal$$initializePromise(this, resolver); >+ } >+ } >+ >+ // deprecated >+ $$rsvp$promise$$Promise.cast = $$promise$resolve$$default; >+ >+ $$rsvp$promise$$Promise.all = $$promise$all$$default; >+ $$rsvp$promise$$Promise.race = $$promise$race$$default; >+ $$rsvp$promise$$Promise.resolve = $$promise$resolve$$default; >+ $$rsvp$promise$$Promise.reject = $$promise$reject$$default; >+ >+ $$rsvp$promise$$Promise.prototype = { >+ constructor: $$rsvp$promise$$Promise, >+ >+ _guidKey: $$rsvp$promise$$guidKey, >+ >+ _onerror: function (reason) { >+ $$rsvp$config$$config.trigger('error', reason); >+ }, >+ >+ /** >+ The primary way of interacting with a promise is through its `then` method, >+ which registers callbacks to receive either a promise's eventual value or the >+ reason why the promise cannot be fulfilled. >+ >+ ```js >+ findUser().then(function(user){ >+ // user is available >+ }, function(reason){ >+ // user is unavailable, and you are given the reason why >+ }); >+ ``` >+ >+ Chaining >+ -------- >+ >+ The return value of `then` is itself a promise. This second, 'downstream' >+ promise is resolved with the return value of the first promise's fulfillment >+ or rejection handler, or rejected if the handler throws an exception. >+ >+ ```js >+ findUser().then(function (user) { >+ return user.name; >+ }, function (reason) { >+ return 'default name'; >+ }).then(function (userName) { >+ // If `findUser` fulfilled, `userName` will be the user's name, otherwise it >+ // will be `'default name'` >+ }); >+ >+ findUser().then(function (user) { >+ throw new Error('Found user, but still unhappy'); >+ }, function (reason) { >+ throw new Error('`findUser` rejected and we're unhappy'); >+ }).then(function (value) { >+ // never reached >+ }, function (reason) { >+ // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. >+ // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. >+ }); >+ ``` >+ If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. >+ >+ ```js >+ findUser().then(function (user) { >+ throw new PedagogicalException('Upstream error'); >+ }).then(function (value) { >+ // never reached >+ }).then(function (value) { >+ // never reached >+ }, function (reason) { >+ // The `PedgagocialException` is propagated all the way down to here >+ }); >+ ``` >+ >+ Assimilation >+ ------------ >+ >+ Sometimes the value you want to propagate to a downstream promise can only be >+ retrieved asynchronously. This can be achieved by returning a promise in the >+ fulfillment or rejection handler. The downstream promise will then be pending >+ until the returned promise is settled. This is called *assimilation*. >+ >+ ```js >+ findUser().then(function (user) { >+ return findCommentsByAuthor(user); >+ }).then(function (comments) { >+ // The user's comments are now available >+ }); >+ ``` >+ >+ If the assimliated promise rejects, then the downstream promise will also reject. >+ >+ ```js >+ findUser().then(function (user) { >+ return findCommentsByAuthor(user); >+ }).then(function (comments) { >+ // If `findCommentsByAuthor` fulfills, we'll have the value here >+ }, function (reason) { >+ // If `findCommentsByAuthor` rejects, we'll have the reason here >+ }); >+ ``` >+ >+ Simple Example >+ -------------- >+ >+ Synchronous Example >+ >+ ```javascript >+ var result; >+ >+ try { >+ result = findResult(); >+ // success >+ } catch(reason) { >+ // failure >+ } >+ ``` >+ >+ Errback Example >+ >+ ```js >+ findResult(function(result, err){ >+ if (err) { >+ // failure >+ } else { >+ // success >+ } >+ }); >+ ``` >+ >+ Promise Example; >+ >+ ```javascript >+ findResult().then(function(result){ >+ // success >+ }, function(reason){ >+ // failure >+ }); >+ ``` >+ >+ Advanced Example >+ -------------- >+ >+ Synchronous Example >+ >+ ```javascript >+ var author, books; >+ >+ try { >+ author = findAuthor(); >+ books = findBooksByAuthor(author); >+ // success >+ } catch(reason) { >+ // failure >+ } >+ ``` >+ >+ Errback Example >+ >+ ```js >+ >+ function foundBooks(books) { >+ >+ } >+ >+ function failure(reason) { >+ >+ } >+ >+ findAuthor(function(author, err){ >+ if (err) { >+ failure(err); >+ // failure >+ } else { >+ try { >+ findBoooksByAuthor(author, function(books, err) { >+ if (err) { >+ failure(err); >+ } else { >+ try { >+ foundBooks(books); >+ } catch(reason) { >+ failure(reason); >+ } >+ } >+ }); >+ } catch(error) { >+ failure(err); >+ } >+ // success >+ } >+ }); >+ ``` >+ >+ Promise Example; >+ >+ ```javascript >+ findAuthor(). >+ then(findBooksByAuthor). >+ then(function(books){ >+ // found books >+ }).catch(function(reason){ >+ // something went wrong >+ }); >+ ``` >+ >+ @method then >+ @param {Function} onFulfilled >+ @param {Function} onRejected >+ @param {String} label optional string for labeling the promise. >+ Useful for tooling. >+ @return {Promise} >+ */ >+ then: function(onFulfillment, onRejection, label) { >+ var parent = this; >+ var state = parent._state; >+ >+ if (state === $$$internal$$FULFILLED && !onFulfillment || state === $$$internal$$REJECTED && !onRejection) { >+ if ($$rsvp$config$$config.instrument) { >+ $$instrument$$default('chained', this, this); >+ } >+ return this; >+ } >+ >+ parent._onerror = null; >+ >+ var child = new this.constructor($$$internal$$noop, label); >+ var result = parent._result; >+ >+ if ($$rsvp$config$$config.instrument) { >+ $$instrument$$default('chained', parent, child); >+ } >+ >+ if (state) { >+ var callback = arguments[state - 1]; >+ $$rsvp$config$$config.async(function(){ >+ $$$internal$$invokeCallback(state, child, callback, result); >+ }); >+ } else { >+ $$$internal$$subscribe(parent, child, onFulfillment, onRejection); >+ } >+ >+ return child; >+ }, >+ >+ /** >+ `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same >+ as the catch block of a try/catch statement. >+ >+ ```js >+ function findAuthor(){ >+ throw new Error('couldn't find that author'); >+ } >+ >+ // synchronous >+ try { >+ findAuthor(); >+ } catch(reason) { >+ // something went wrong >+ } >+ >+ // async with promises >+ findAuthor().catch(function(reason){ >+ // something went wrong >+ }); >+ ``` >+ >+ @method catch >+ @param {Function} onRejection >+ @param {String} label optional string for labeling the promise. >+ Useful for tooling. >+ @return {Promise} >+ */ >+ 'catch': function(onRejection, label) { >+ return this.then(null, onRejection, label); >+ }, >+ >+ /** >+ `finally` will be invoked regardless of the promise's fate just as native >+ try/catch/finally behaves >+ >+ Synchronous example: >+ >+ ```js >+ findAuthor() { >+ if (Math.random() > 0.5) { >+ throw new Error(); >+ } >+ return new Author(); >+ } >+ >+ try { >+ return findAuthor(); // succeed or fail >+ } catch(error) { >+ return findOtherAuther(); >+ } finally { >+ // always runs >+ // doesn't affect the return value >+ } >+ ``` >+ >+ Asynchronous example: >+ >+ ```js >+ findAuthor().catch(function(reason){ >+ return findOtherAuther(); >+ }).finally(function(){ >+ // author was either found, or not >+ }); >+ ``` >+ >+ @method finally >+ @param {Function} callback >+ @param {String} label optional string for labeling the promise. >+ Useful for tooling. >+ @return {Promise} >+ */ >+ 'finally': function(callback, label) { >+ var constructor = this.constructor; >+ >+ return this.then(function(value) { >+ return constructor.resolve(callback()).then(function(){ >+ return value; >+ }); >+ }, function(reason) { >+ return constructor.resolve(callback()).then(function(){ >+ throw reason; >+ }); >+ }, label); >+ } >+ }; >+ >+ function $$rsvp$node$$Result() { >+ this.value = undefined; >+ } >+ >+ var $$rsvp$node$$ERROR = new $$rsvp$node$$Result(); >+ var $$rsvp$node$$GET_THEN_ERROR = new $$rsvp$node$$Result(); >+ >+ function $$rsvp$node$$getThen(obj) { >+ try { >+ return obj.then; >+ } catch(error) { >+ $$rsvp$node$$ERROR.value= error; >+ return $$rsvp$node$$ERROR; >+ } >+ } >+ >+ function $$rsvp$node$$tryApply(f, s, a) { >+ try { >+ f.apply(s, a); >+ } catch(error) { >+ $$rsvp$node$$ERROR.value = error; >+ return $$rsvp$node$$ERROR; >+ } >+ } >+ >+ function $$rsvp$node$$makeObject(_, argumentNames) { >+ var obj = {}; >+ var name; >+ var i; >+ var length = _.length; >+ var args = new Array(length); >+ >+ for (var x = 0; x < length; x++) { >+ args[x] = _[x]; >+ } >+ >+ for (i = 0; i < argumentNames.length; i++) { >+ name = argumentNames[i]; >+ obj[name] = args[i + 1]; >+ } >+ >+ return obj; >+ } >+ >+ function $$rsvp$node$$arrayResult(_) { >+ var length = _.length; >+ var args = new Array(length - 1); >+ >+ for (var i = 1; i < length; i++) { >+ args[i - 1] = _[i]; >+ } >+ >+ return args; >+ } >+ >+ function $$rsvp$node$$wrapThenable(then, promise) { >+ return { >+ then: function(onFulFillment, onRejection) { >+ return then.call(promise, onFulFillment, onRejection); >+ } >+ }; >+ } >+ >+ var $$rsvp$node$$default = function denodeify(nodeFunc, options) { >+ var fn = function() { >+ var self = this; >+ var l = arguments.length; >+ var args = new Array(l + 1); >+ var arg; >+ var promiseInput = false; >+ >+ for (var i = 0; i < l; ++i) { >+ arg = arguments[i]; >+ >+ if (!promiseInput) { >+ // TODO: clean this up >+ promiseInput = $$rsvp$node$$needsPromiseInput(arg); >+ if (promiseInput === $$rsvp$node$$GET_THEN_ERROR) { >+ var p = new $$rsvp$promise$$default($$$internal$$noop); >+ $$$internal$$reject(p, $$rsvp$node$$GET_THEN_ERROR.value); >+ return p; >+ } else if (promiseInput && promiseInput !== true) { >+ arg = $$rsvp$node$$wrapThenable(promiseInput, arg); >+ } >+ } >+ args[i] = arg; >+ } >+ >+ var promise = new $$rsvp$promise$$default($$$internal$$noop); >+ >+ args[l] = function(err, val) { >+ if (err) >+ $$$internal$$reject(promise, err); >+ else if (options === undefined) >+ $$$internal$$resolve(promise, val); >+ else if (options === true) >+ $$$internal$$resolve(promise, $$rsvp$node$$arrayResult(arguments)); >+ else if ($$utils$$isArray(options)) >+ $$$internal$$resolve(promise, $$rsvp$node$$makeObject(arguments, options)); >+ else >+ $$$internal$$resolve(promise, val); >+ }; >+ >+ if (promiseInput) { >+ return $$rsvp$node$$handlePromiseInput(promise, args, nodeFunc, self); >+ } else { >+ return $$rsvp$node$$handleValueInput(promise, args, nodeFunc, self); >+ } >+ }; >+ >+ fn.__proto__ = nodeFunc; >+ >+ return fn; >+ }; >+ >+ function $$rsvp$node$$handleValueInput(promise, args, nodeFunc, self) { >+ var result = $$rsvp$node$$tryApply(nodeFunc, self, args); >+ if (result === $$rsvp$node$$ERROR) { >+ $$$internal$$reject(promise, result.value); >+ } >+ return promise; >+ } >+ >+ function $$rsvp$node$$handlePromiseInput(promise, args, nodeFunc, self){ >+ return $$rsvp$promise$$default.all(args).then(function(args){ >+ var result = $$rsvp$node$$tryApply(nodeFunc, self, args); >+ if (result === $$rsvp$node$$ERROR) { >+ $$$internal$$reject(promise, result.value); >+ } >+ return promise; >+ }); >+ } >+ >+ function $$rsvp$node$$needsPromiseInput(arg) { >+ if (arg && typeof arg === 'object') { >+ if (arg.constructor === $$rsvp$promise$$default) { >+ return true; >+ } else { >+ return $$rsvp$node$$getThen(arg); >+ } >+ } else { >+ return false; >+ } >+ } >+ >+ var $$rsvp$all$$default = function all(array, label) { >+ return $$rsvp$promise$$default.all(array, label); >+ }; >+ >+ function $$rsvp$all$settled$$AllSettled(Constructor, entries, label) { >+ this._superConstructor(Constructor, entries, false /* don't abort on reject */, label); >+ } >+ >+ $$rsvp$all$settled$$AllSettled.prototype = $$utils$$o_create($$enumerator$$default.prototype); >+ $$rsvp$all$settled$$AllSettled.prototype._superConstructor = $$enumerator$$default; >+ $$rsvp$all$settled$$AllSettled.prototype._makeResult = $$enumerator$$makeSettledResult; >+ >+ $$rsvp$all$settled$$AllSettled.prototype._validationError = function() { >+ return new Error('allSettled must be called with an array'); >+ }; >+ >+ var $$rsvp$all$settled$$default = function allSettled(entries, label) { >+ return new $$rsvp$all$settled$$AllSettled($$rsvp$promise$$default, entries, label).promise; >+ }; >+ >+ var $$rsvp$race$$default = function race(array, label) { >+ return $$rsvp$promise$$default.race(array, label); >+ }; >+ >+ function $$promise$hash$$PromiseHash(Constructor, object, label) { >+ this._superConstructor(Constructor, object, true, label); >+ } >+ >+ var $$promise$hash$$default = $$promise$hash$$PromiseHash; >+ $$promise$hash$$PromiseHash.prototype = $$utils$$o_create($$enumerator$$default.prototype); >+ $$promise$hash$$PromiseHash.prototype._superConstructor = $$enumerator$$default; >+ >+ $$promise$hash$$PromiseHash.prototype._init = function() { >+ this._result = {}; >+ }; >+ >+ $$promise$hash$$PromiseHash.prototype._validateInput = function(input) { >+ return input && typeof input === 'object'; >+ }; >+ >+ $$promise$hash$$PromiseHash.prototype._validationError = function() { >+ return new Error('Promise.hash must be called with an object'); >+ }; >+ >+ $$promise$hash$$PromiseHash.prototype._enumerate = function() { >+ var promise = this.promise; >+ var input = this._input; >+ var results = []; >+ >+ for (var key in input) { >+ if (promise._state === $$$internal$$PENDING && input.hasOwnProperty(key)) { >+ results.push({ >+ position: key, >+ entry: input[key] >+ }); >+ } >+ } >+ >+ var length = results.length; >+ this._remaining = length; >+ var result; >+ >+ for (var i = 0; promise._state === $$$internal$$PENDING && i < length; i++) { >+ result = results[i]; >+ this._eachEntry(result.entry, result.position); >+ } >+ }; >+ >+ var $$rsvp$hash$$default = function hash(object, label) { >+ return new $$promise$hash$$default($$rsvp$promise$$default, object, label).promise; >+ }; >+ >+ function $$rsvp$hash$settled$$HashSettled(Constructor, object, label) { >+ this._superConstructor(Constructor, object, false, label); >+ } >+ >+ $$rsvp$hash$settled$$HashSettled.prototype = $$utils$$o_create($$promise$hash$$default.prototype); >+ $$rsvp$hash$settled$$HashSettled.prototype._superConstructor = $$enumerator$$default; >+ $$rsvp$hash$settled$$HashSettled.prototype._makeResult = $$enumerator$$makeSettledResult; >+ >+ $$rsvp$hash$settled$$HashSettled.prototype._validationError = function() { >+ return new Error('hashSettled must be called with an object'); >+ }; >+ >+ var $$rsvp$hash$settled$$default = function hashSettled(object, label) { >+ return new $$rsvp$hash$settled$$HashSettled($$rsvp$promise$$default, object, label).promise; >+ }; >+ >+ var $$rsvp$rethrow$$default = function rethrow(reason) { >+ setTimeout(function() { >+ throw reason; >+ }); >+ throw reason; >+ }; >+ >+ var $$rsvp$defer$$default = function defer(label) { >+ var deferred = { }; >+ >+ deferred.promise = new $$rsvp$promise$$default(function(resolve, reject) { >+ deferred.resolve = resolve; >+ deferred.reject = reject; >+ }, label); >+ >+ return deferred; >+ }; >+ >+ var $$rsvp$map$$default = function map(promises, mapFn, label) { >+ return $$rsvp$promise$$default.all(promises, label).then(function(values) { >+ if (!$$utils$$isFunction(mapFn)) { >+ throw new TypeError("You must pass a function as map's second argument."); >+ } >+ >+ var length = values.length; >+ var results = new Array(length); >+ >+ for (var i = 0; i < length; i++) { >+ results[i] = mapFn(values[i]); >+ } >+ >+ return $$rsvp$promise$$default.all(results, label); >+ }); >+ }; >+ >+ var $$rsvp$resolve$$default = function resolve(value, label) { >+ return $$rsvp$promise$$default.resolve(value, label); >+ }; >+ >+ var $$rsvp$reject$$default = function reject(reason, label) { >+ return $$rsvp$promise$$default.reject(reason, label); >+ }; >+ >+ var $$rsvp$filter$$default = function filter(promises, filterFn, label) { >+ return $$rsvp$promise$$default.all(promises, label).then(function(values) { >+ if (!$$utils$$isFunction(filterFn)) { >+ throw new TypeError("You must pass a function as filter's second argument."); >+ } >+ >+ var length = values.length; >+ var filtered = new Array(length); >+ >+ for (var i = 0; i < length; i++) { >+ filtered[i] = filterFn(values[i]); >+ } >+ >+ return $$rsvp$promise$$default.all(filtered, label).then(function(filtered) { >+ var results = new Array(length); >+ var newLength = 0; >+ >+ for (var i = 0; i < length; i++) { >+ if (filtered[i]) { >+ results[newLength] = values[i]; >+ newLength++; >+ } >+ } >+ >+ results.length = newLength; >+ >+ return results; >+ }); >+ }); >+ }; >+ >+ var $$rsvp$asap$$len = 0; >+ >+ var $$rsvp$asap$$default = function asap(callback, arg) { >+ $$rsvp$asap$$queue[$$rsvp$asap$$len] = callback; >+ $$rsvp$asap$$queue[$$rsvp$asap$$len + 1] = arg; >+ $$rsvp$asap$$len += 2; >+ if ($$rsvp$asap$$len === 2) { >+ // If len is 1, that means that we need to schedule an async flush. >+ // If additional callbacks are queued before the queue is flushed, they >+ // will be processed by this flush that we are scheduling. >+ $$rsvp$asap$$scheduleFlush(); >+ } >+ }; >+ >+ var $$rsvp$asap$$browserGlobal = (typeof window !== 'undefined') ? window : {}; >+ var $$rsvp$asap$$BrowserMutationObserver = $$rsvp$asap$$browserGlobal.MutationObserver || $$rsvp$asap$$browserGlobal.WebKitMutationObserver; >+ >+ // test for web worker but not in IE10 >+ var $$rsvp$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' && >+ typeof importScripts !== 'undefined' && >+ typeof MessageChannel !== 'undefined'; >+ >+ // node >+ function $$rsvp$asap$$useNextTick() { >+ return function() { >+ process.nextTick($$rsvp$asap$$flush); >+ }; >+ } >+ >+ function $$rsvp$asap$$useMutationObserver() { >+ var iterations = 0; >+ var observer = new $$rsvp$asap$$BrowserMutationObserver($$rsvp$asap$$flush); >+ var node = document.createTextNode(''); >+ observer.observe(node, { characterData: true }); >+ >+ return function() { >+ node.data = (iterations = ++iterations % 2); >+ }; >+ } >+ >+ // web worker >+ function $$rsvp$asap$$useMessageChannel() { >+ var channel = new MessageChannel(); >+ channel.port1.onmessage = $$rsvp$asap$$flush; >+ return function () { >+ channel.port2.postMessage(0); >+ }; >+ } >+ >+ function $$rsvp$asap$$useSetTimeout() { >+ return function() { >+ setTimeout($$rsvp$asap$$flush, 1); >+ }; >+ } >+ >+ var $$rsvp$asap$$queue = new Array(1000); >+ >+ function $$rsvp$asap$$flush() { >+ for (var i = 0; i < $$rsvp$asap$$len; i+=2) { >+ var callback = $$rsvp$asap$$queue[i]; >+ var arg = $$rsvp$asap$$queue[i+1]; >+ >+ callback(arg); >+ >+ $$rsvp$asap$$queue[i] = undefined; >+ $$rsvp$asap$$queue[i+1] = undefined; >+ } >+ >+ $$rsvp$asap$$len = 0; >+ } >+ >+ var $$rsvp$asap$$scheduleFlush; >+ >+ // Decide what async method to use to triggering processing of queued callbacks: >+ if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') { >+ $$rsvp$asap$$scheduleFlush = $$rsvp$asap$$useNextTick(); >+ } else if ($$rsvp$asap$$BrowserMutationObserver) { >+ $$rsvp$asap$$scheduleFlush = $$rsvp$asap$$useMutationObserver(); >+ } else if ($$rsvp$asap$$isWorker) { >+ $$rsvp$asap$$scheduleFlush = $$rsvp$asap$$useMessageChannel(); >+ } else { >+ $$rsvp$asap$$scheduleFlush = $$rsvp$asap$$useSetTimeout(); >+ } >+ >+ // default async is asap; >+ $$rsvp$config$$config.async = $$rsvp$asap$$default; >+ >+ var $$rsvp$$cast = $$rsvp$resolve$$default; >+ >+ function $$rsvp$$async(callback, arg) { >+ $$rsvp$config$$config.async(callback, arg); >+ } >+ >+ function $$rsvp$$on() { >+ $$rsvp$config$$config.on.apply($$rsvp$config$$config, arguments); >+ } >+ >+ function $$rsvp$$off() { >+ $$rsvp$config$$config.off.apply($$rsvp$config$$config, arguments); >+ } >+ >+ // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__` >+ if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') { >+ var $$rsvp$$callbacks = window['__PROMISE_INSTRUMENTATION__']; >+ $$rsvp$config$$configure('instrument', true); >+ for (var $$rsvp$$eventName in $$rsvp$$callbacks) { >+ if ($$rsvp$$callbacks.hasOwnProperty($$rsvp$$eventName)) { >+ $$rsvp$$on($$rsvp$$eventName, $$rsvp$$callbacks[$$rsvp$$eventName]); >+ } >+ } >+ } >+ >+ var rsvp$umd$$RSVP = { >+ 'race': $$rsvp$race$$default, >+ 'Promise': $$rsvp$promise$$default, >+ 'allSettled': $$rsvp$all$settled$$default, >+ 'hash': $$rsvp$hash$$default, >+ 'hashSettled': $$rsvp$hash$settled$$default, >+ 'denodeify': $$rsvp$node$$default, >+ 'on': $$rsvp$$on, >+ 'off': $$rsvp$$off, >+ 'map': $$rsvp$map$$default, >+ 'filter': $$rsvp$filter$$default, >+ 'resolve': $$rsvp$resolve$$default, >+ 'reject': $$rsvp$reject$$default, >+ 'all': $$rsvp$all$$default, >+ 'rethrow': $$rsvp$rethrow$$default, >+ 'defer': $$rsvp$defer$$default, >+ 'EventTarget': $$rsvp$events$$default, >+ 'configure': $$rsvp$config$$configure, >+ 'async': $$rsvp$$async >+ }; >+ >+ /* global define:true module:true window: true */ >+ if (typeof define === 'function' && define.amd) { >+ define(function() { return rsvp$umd$$RSVP; }); >+ } else if (typeof module !== 'undefined' && module.exports) { >+ module.exports = rsvp$umd$$RSVP; >+ } else if (typeof this !== 'undefined') { >+ this['RSVP'] = rsvp$umd$$RSVP; >+ } >+}).call(this); >diff --git a/Source/WebInspectorUI/UserInterface/Main.html b/Source/WebInspectorUI/UserInterface/Main.html >index 28ba47f283fe59b1ee7d927a4145299857e5ee8f..c38109b9df3900767bea709cc4273d87eac1e200 100644 >--- a/Source/WebInspectorUI/UserInterface/Main.html >+++ b/Source/WebInspectorUI/UserInterface/Main.html >@@ -142,6 +142,8 @@ > <link rel="stylesheet" href="Controllers/CodeMirrorGradientEditingController.css"> > <link rel="stylesheet" href="Controllers/CodeMirrorTokenTrackingController.css"> > >+ <script src="External/RSVP/rsvp.js"></script> >+ > <script src="External/CodeMirror/codemirror.js"></script> > > <script src="External/CodeMirror/clojure.js"></script> >diff --git a/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js b/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js >index c11a3eda41941e0dc7c1a14fa87a701f49749fa0..256360311c2803b40076ed84f66fdee03d84e8b5 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js >+++ b/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js >@@ -73,7 +73,7 @@ WebInspector.ReplaySession.prototype = { > pendingSegments.push(WebInspector.replayManager.getSegment(segmentId)); > > var session = this; >- Promise.all(pendingSegments).then( >+ WebInspector.Promise.all(pendingSegments).then( > function(segmentsArray) { > session._segments = segmentsArray; > session.dispatchEventToListeners(WebInspector.ReplaySession.Event.SegmentsChanged, {oldSegments: oldSegments}); >diff --git a/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js b/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js >index fe4e93e3e4d04c7ee6c821cbb5130427e6f8b813..347201a7e1b0eae2569eea2083ffaa742a399a8c 100644 >--- a/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js >+++ b/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js >@@ -388,7 +388,7 @@ InspectorBackend.Command.prototype = { > { > var instance = this._instance; > var promiseArguments = Array.prototype.slice.call(arguments); >- return new Promise(function(resolve, reject) { >+ return new WebInspector.Promise(function(resolve, reject) { > function convertToPromiseCallback(error, payload) { > return error ? reject(error) : resolve(payload); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 135830
:
237316
|
237317
|
237321