ember-source 2.6.1 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f27e8a7aeeeb539e54c59e0c0310cf921ffbff2e
4
- data.tar.gz: b2b92945ff3d01a5fc31115f2a9704ca7744c406
3
+ metadata.gz: c0d8c3b9406ea1d1140cb439c440e7eeb7fbed0c
4
+ data.tar.gz: 4e4338c27890753f8b4000aee6c213a4c10e4fcd
5
5
  SHA512:
6
- metadata.gz: ba4e4a07a891624b1c2f8837f3dfacf5156dee31c3cb69baba00a10d41fd175dc11892727636f40c3c26f195a97d4cd8f97daca99e27497cf38b1e0cf7a30014
7
- data.tar.gz: 5aeb89bedaae8c73cb683583f88905991f297cc9472a0b86e51fb75ccdc45edae297d89a0b0d4eaa9dcfe2ee265534797bc42b8aa3bc9eb6d75ab5ce2ed1ce6e
6
+ metadata.gz: 259b517f55081bc9c308ca2efd425eeb8b78fcc468b253698000d13eb12324483d7ed833d2013833c27f8156ef8b30e0715658ee93620704733f388c15a0788c
7
+ data.tar.gz: ccccd446ec3bdf295fef208cf4d27049e07705183ffcdef644e8d864ee3fe8a1f5e467b414c6216d6c2c46bdb47021cf484a7db3fa3bdb1766ad33bbfe7814b9
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.6.1
1
+ 2.6.2
@@ -6,7 +6,7 @@
6
6
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
7
7
  * @license Licensed under MIT license
8
8
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
9
- * @version 2.6.1
9
+ * @version 2.6.2
10
10
  */
11
11
 
12
12
  var enifed, requireModule, require, Ember;
@@ -113,1053 +113,1053 @@ var mainContext = this;
113
113
  }
114
114
  })();
115
115
 
116
- enifed("backburner/binary-search", ["exports"], function (exports) {
117
- "use strict";
116
+ enifed('backburner', ['exports', 'backburner/utils', 'backburner/platform', 'backburner/binary-search', 'backburner/deferred-action-queues'], function (exports, _backburnerUtils, _backburnerPlatform, _backburnerBinarySearch, _backburnerDeferredActionQueues) {
117
+ 'use strict';
118
118
 
119
- exports.default = binarySearch;
119
+ exports.default = Backburner;
120
120
 
121
- function binarySearch(time, timers) {
122
- var start = 0;
123
- var end = timers.length - 2;
124
- var middle, l;
121
+ function Backburner(queueNames, options) {
122
+ this.queueNames = queueNames;
123
+ this.options = options || {};
124
+ if (!this.options.defaultQueue) {
125
+ this.options.defaultQueue = queueNames[0];
126
+ }
127
+ this.instanceStack = [];
128
+ this._debouncees = [];
129
+ this._throttlers = [];
130
+ this._eventCallbacks = {
131
+ end: [],
132
+ begin: []
133
+ };
125
134
 
126
- while (start < end) {
127
- // since timers is an array of pairs 'l' will always
128
- // be an integer
129
- l = (end - start) / 2;
135
+ var _this = this;
136
+ this._boundClearItems = function () {
137
+ clearItems();
138
+ };
130
139
 
131
- // compensate for the index in case even number
132
- // of pairs inside timers
133
- middle = start + l - l % 2;
140
+ this._timerTimeoutId = undefined;
141
+ this._timers = [];
134
142
 
135
- if (time >= timers[middle]) {
136
- start = middle + 2;
137
- } else {
138
- end = middle;
139
- }
140
- }
143
+ this._platform = this.options._platform || _backburnerPlatform.default;
141
144
 
142
- return time >= timers[start] ? start + 2 : start;
145
+ this._boundRunExpiredTimers = function () {
146
+ _this._runExpiredTimers();
147
+ };
143
148
  }
144
- });
145
- enifed('backburner/deferred-action-queues', ['exports', 'backburner/utils', 'backburner/queue'], function (exports, _backburnerUtils, _backburnerQueue) {
146
- 'use strict';
147
149
 
148
- exports.default = DeferredActionQueues;
150
+ Backburner.prototype = {
151
+ begin: function () {
152
+ var options = this.options;
153
+ var onBegin = options && options.onBegin;
154
+ var previousInstance = this.currentInstance;
149
155
 
150
- function DeferredActionQueues(queueNames, options) {
151
- var queues = this.queues = {};
152
- this.queueNames = queueNames = queueNames || [];
156
+ if (previousInstance) {
157
+ this.instanceStack.push(previousInstance);
158
+ }
153
159
 
154
- this.options = options;
160
+ this.currentInstance = new _backburnerDeferredActionQueues.default(this.queueNames, options);
161
+ this._trigger('begin', this.currentInstance, previousInstance);
162
+ if (onBegin) {
163
+ onBegin(this.currentInstance, previousInstance);
164
+ }
165
+ },
155
166
 
156
- _backburnerUtils.each(queueNames, function (queueName) {
157
- queues[queueName] = new _backburnerQueue.default(queueName, options[queueName], options);
158
- });
159
- }
167
+ end: function () {
168
+ var options = this.options;
169
+ var onEnd = options && options.onEnd;
170
+ var currentInstance = this.currentInstance;
171
+ var nextInstance = null;
160
172
 
161
- function noSuchQueue(name) {
162
- throw new Error('You attempted to schedule an action in a queue (' + name + ') that doesn\'t exist');
163
- }
173
+ // Prevent double-finally bug in Safari 6.0.2 and iOS 6
174
+ // This bug appears to be resolved in Safari 6.0.5 and iOS 7
175
+ var finallyAlreadyCalled = false;
176
+ try {
177
+ currentInstance.flush();
178
+ } finally {
179
+ if (!finallyAlreadyCalled) {
180
+ finallyAlreadyCalled = true;
164
181
 
165
- function noSuchMethod(name) {
166
- throw new Error('You attempted to schedule an action in a queue (' + name + ') for a method that doesn\'t exist');
167
- }
182
+ this.currentInstance = null;
168
183
 
169
- DeferredActionQueues.prototype = {
170
- schedule: function (name, target, method, args, onceFlag, stack) {
171
- var queues = this.queues;
172
- var queue = queues[name];
184
+ if (this.instanceStack.length) {
185
+ nextInstance = this.instanceStack.pop();
186
+ this.currentInstance = nextInstance;
187
+ }
188
+ this._trigger('end', currentInstance, nextInstance);
189
+ if (onEnd) {
190
+ onEnd(currentInstance, nextInstance);
191
+ }
192
+ }
193
+ }
194
+ },
173
195
 
174
- if (!queue) {
175
- noSuchQueue(name);
196
+ /**
197
+ Trigger an event. Supports up to two arguments. Designed around
198
+ triggering transition events from one run loop instance to the
199
+ next, which requires an argument for the first instance and then
200
+ an argument for the next instance.
201
+ @private
202
+ @method _trigger
203
+ @param {String} eventName
204
+ @param {any} arg1
205
+ @param {any} arg2
206
+ */
207
+ _trigger: function (eventName, arg1, arg2) {
208
+ var callbacks = this._eventCallbacks[eventName];
209
+ if (callbacks) {
210
+ for (var i = 0; i < callbacks.length; i++) {
211
+ callbacks[i](arg1, arg2);
212
+ }
176
213
  }
214
+ },
177
215
 
178
- if (!method) {
179
- noSuchMethod(name);
216
+ on: function (eventName, callback) {
217
+ if (typeof callback !== 'function') {
218
+ throw new TypeError('Callback must be a function');
219
+ }
220
+ var callbacks = this._eventCallbacks[eventName];
221
+ if (callbacks) {
222
+ callbacks.push(callback);
223
+ } else {
224
+ throw new TypeError('Cannot on() event "' + eventName + '" because it does not exist');
180
225
  }
226
+ },
181
227
 
182
- if (onceFlag) {
183
- return queue.pushUnique(target, method, args, stack);
228
+ off: function (eventName, callback) {
229
+ if (eventName) {
230
+ var callbacks = this._eventCallbacks[eventName];
231
+ var callbackFound = false;
232
+ if (!callbacks) return;
233
+ if (callback) {
234
+ for (var i = 0; i < callbacks.length; i++) {
235
+ if (callbacks[i] === callback) {
236
+ callbackFound = true;
237
+ callbacks.splice(i, 1);
238
+ i--;
239
+ }
240
+ }
241
+ }
242
+ if (!callbackFound) {
243
+ throw new TypeError('Cannot off() callback that does not exist');
244
+ }
184
245
  } else {
185
- return queue.push(target, method, args, stack);
246
+ throw new TypeError('Cannot off() event "' + eventName + '" because it does not exist');
186
247
  }
187
248
  },
188
249
 
189
- flush: function () {
190
- var queues = this.queues;
191
- var queueNames = this.queueNames;
192
- var queueName, queue;
193
- var queueNameIndex = 0;
194
- var numberOfQueues = queueNames.length;
250
+ run: function () /* target, method, args */{
251
+ var length = arguments.length;
252
+ var method, target, args;
195
253
 
196
- while (queueNameIndex < numberOfQueues) {
197
- queueName = queueNames[queueNameIndex];
198
- queue = queues[queueName];
254
+ if (length === 1) {
255
+ method = arguments[0];
256
+ target = null;
257
+ } else {
258
+ target = arguments[0];
259
+ method = arguments[1];
260
+ }
199
261
 
200
- var numberOfQueueItems = queue._queue.length;
262
+ if (_backburnerUtils.isString(method)) {
263
+ method = target[method];
264
+ }
201
265
 
202
- if (numberOfQueueItems === 0) {
203
- queueNameIndex++;
204
- } else {
205
- queue.flush(false /* async */);
206
- queueNameIndex = 0;
266
+ if (length > 2) {
267
+ args = new Array(length - 2);
268
+ for (var i = 0, l = length - 2; i < l; i++) {
269
+ args[i] = arguments[i + 2];
207
270
  }
271
+ } else {
272
+ args = [];
208
273
  }
209
- }
210
- };
211
- });
212
- enifed('backburner/platform', ['exports'], function (exports) {
213
- 'use strict';
214
274
 
215
- var GlobalContext;
275
+ var onError = getOnError(this.options);
216
276
 
217
- /* global self */
218
- if (typeof self === 'object') {
219
- GlobalContext = self;
277
+ this.begin();
220
278
 
221
- /* global global */
222
- } else if (typeof global === 'object') {
223
- GlobalContext = global;
279
+ // guard against Safari 6's double-finally bug
280
+ var didFinally = false;
224
281
 
225
- /* global window */
226
- } else if (typeof window === 'object') {
227
- GlobalContext = window;
282
+ if (onError) {
283
+ try {
284
+ return method.apply(target, args);
285
+ } catch (error) {
286
+ onError(error);
287
+ } finally {
288
+ if (!didFinally) {
289
+ didFinally = true;
290
+ this.end();
291
+ }
292
+ }
228
293
  } else {
229
- throw new Error('no global: `self`, `global` nor `window` was found');
294
+ try {
295
+ return method.apply(target, args);
296
+ } finally {
297
+ if (!didFinally) {
298
+ didFinally = true;
299
+ this.end();
300
+ }
301
+ }
230
302
  }
303
+ },
231
304
 
232
- exports.default = GlobalContext;
233
- });
234
- enifed('backburner/queue', ['exports', 'backburner/utils'], function (exports, _backburnerUtils) {
235
- 'use strict';
305
+ /*
306
+ Join the passed method with an existing queue and execute immediately,
307
+ if there isn't one use `Backburner#run`.
308
+ The join method is like the run method except that it will schedule into
309
+ an existing queue if one already exists. In either case, the join method will
310
+ immediately execute the passed in function and return its result.
311
+ @method join
312
+ @param {Object} target
313
+ @param {Function} method The method to be executed
314
+ @param {any} args The method arguments
315
+ @return method result
316
+ */
317
+ join: function () /* target, method, args */{
318
+ if (!this.currentInstance) {
319
+ return this.run.apply(this, arguments);
320
+ }
236
321
 
237
- exports.default = Queue;
238
-
239
- function Queue(name, options, globalOptions) {
240
- this.name = name;
241
- this.globalOptions = globalOptions || {};
242
- this.options = options;
243
- this._queue = [];
244
- this.targetQueues = {};
245
- this._queueBeingFlushed = undefined;
246
- }
247
-
248
- Queue.prototype = {
249
- push: function (target, method, args, stack) {
250
- var queue = this._queue;
251
- queue.push(target, method, args, stack);
252
-
253
- return {
254
- queue: this,
255
- target: target,
256
- method: method
257
- };
258
- },
322
+ var length = arguments.length;
323
+ var method, target;
259
324
 
260
- pushUniqueWithoutGuid: function (target, method, args, stack) {
261
- var queue = this._queue;
325
+ if (length === 1) {
326
+ method = arguments[0];
327
+ target = null;
328
+ } else {
329
+ target = arguments[0];
330
+ method = arguments[1];
331
+ }
262
332
 
263
- for (var i = 0, l = queue.length; i < l; i += 4) {
264
- var currentTarget = queue[i];
265
- var currentMethod = queue[i + 1];
333
+ if (_backburnerUtils.isString(method)) {
334
+ method = target[method];
335
+ }
266
336
 
267
- if (currentTarget === target && currentMethod === method) {
268
- queue[i + 2] = args; // replace args
269
- queue[i + 3] = stack; // replace stack
270
- return;
337
+ if (length === 1) {
338
+ return method();
339
+ } else if (length === 2) {
340
+ return method.call(target);
341
+ } else {
342
+ var args = new Array(length - 2);
343
+ for (var i = 0, l = length - 2; i < l; i++) {
344
+ args[i] = arguments[i + 2];
271
345
  }
346
+ return method.apply(target, args);
272
347
  }
273
-
274
- queue.push(target, method, args, stack);
275
348
  },
276
349
 
277
- targetQueue: function (targetQueue, target, method, args, stack) {
278
- var queue = this._queue;
279
-
280
- for (var i = 0, l = targetQueue.length; i < l; i += 2) {
281
- var currentMethod = targetQueue[i];
282
- var currentIndex = targetQueue[i + 1];
350
+ /*
351
+ Defer the passed function to run inside the specified queue.
352
+ @method defer
353
+ @param {String} queueName
354
+ @param {Object} target
355
+ @param {Function|String} method The method or method name to be executed
356
+ @param {any} args The method arguments
357
+ @return method result
358
+ */
359
+ defer: function (queueName /* , target, method, args */) {
360
+ var length = arguments.length;
361
+ var method, target, args;
283
362
 
284
- if (currentMethod === method) {
285
- queue[currentIndex + 2] = args; // replace args
286
- queue[currentIndex + 3] = stack; // replace stack
287
- return;
288
- }
363
+ if (length === 2) {
364
+ method = arguments[1];
365
+ target = null;
366
+ } else {
367
+ target = arguments[1];
368
+ method = arguments[2];
289
369
  }
290
370
 
291
- targetQueue.push(method, queue.push(target, method, args, stack) - 4);
292
- },
371
+ if (_backburnerUtils.isString(method)) {
372
+ method = target[method];
373
+ }
293
374
 
294
- pushUniqueWithGuid: function (guid, target, method, args, stack) {
295
- var hasLocalQueue = this.targetQueues[guid];
375
+ var stack = this.DEBUG ? new Error() : undefined;
296
376
 
297
- if (hasLocalQueue) {
298
- this.targetQueue(hasLocalQueue, target, method, args, stack);
377
+ if (length > 3) {
378
+ args = new Array(length - 3);
379
+ for (var i = 3; i < length; i++) {
380
+ args[i - 3] = arguments[i];
381
+ }
299
382
  } else {
300
- this.targetQueues[guid] = [method, this._queue.push(target, method, args, stack) - 4];
383
+ args = undefined;
301
384
  }
302
385
 
303
- return {
304
- queue: this,
305
- target: target,
306
- method: method
307
- };
386
+ if (!this.currentInstance) {
387
+ createAutorun(this);
388
+ }
389
+ return this.currentInstance.schedule(queueName, target, method, args, false, stack);
308
390
  },
309
391
 
310
- pushUnique: function (target, method, args, stack) {
311
- var KEY = this.globalOptions.GUID_KEY;
392
+ deferOnce: function (queueName /* , target, method, args */) {
393
+ var length = arguments.length;
394
+ var method, target, args;
312
395
 
313
- if (target && KEY) {
314
- var guid = target[KEY];
315
- if (guid) {
316
- return this.pushUniqueWithGuid(guid, target, method, args, stack);
317
- }
396
+ if (length === 2) {
397
+ method = arguments[1];
398
+ target = null;
399
+ } else {
400
+ target = arguments[1];
401
+ method = arguments[2];
318
402
  }
319
403
 
320
- this.pushUniqueWithoutGuid(target, method, args, stack);
404
+ if (_backburnerUtils.isString(method)) {
405
+ method = target[method];
406
+ }
321
407
 
322
- return {
323
- queue: this,
324
- target: target,
325
- method: method
326
- };
327
- },
408
+ var stack = this.DEBUG ? new Error() : undefined;
328
409
 
329
- invoke: function (target, method, args, _, _errorRecordedForStack) {
330
- if (args && args.length > 0) {
331
- method.apply(target, args);
410
+ if (length > 3) {
411
+ args = new Array(length - 3);
412
+ for (var i = 3; i < length; i++) {
413
+ args[i - 3] = arguments[i];
414
+ }
332
415
  } else {
333
- method.call(target);
416
+ args = undefined;
334
417
  }
335
- },
336
418
 
337
- invokeWithOnError: function (target, method, args, onError, errorRecordedForStack) {
338
- try {
339
- if (args && args.length > 0) {
340
- method.apply(target, args);
341
- } else {
342
- method.call(target);
343
- }
344
- } catch (error) {
345
- onError(error, errorRecordedForStack);
419
+ if (!this.currentInstance) {
420
+ createAutorun(this);
346
421
  }
422
+ return this.currentInstance.schedule(queueName, target, method, args, true, stack);
347
423
  },
348
424
 
349
- flush: function (sync) {
350
- var queue = this._queue;
351
- var length = queue.length;
425
+ setTimeout: function () {
426
+ var l = arguments.length;
427
+ var args = new Array(l);
352
428
 
353
- if (length === 0) {
354
- return;
429
+ for (var x = 0; x < l; x++) {
430
+ args[x] = arguments[x];
355
431
  }
356
432
 
357
- var globalOptions = this.globalOptions;
358
- var options = this.options;
359
- var before = options && options.before;
360
- var after = options && options.after;
361
- var onError = globalOptions.onError || globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod];
362
- var target, method, args, errorRecordedForStack;
363
- var invoke = onError ? this.invokeWithOnError : this.invoke;
364
-
365
- this.targetQueues = Object.create(null);
366
- var queueItems = this._queueBeingFlushed = this._queue.slice();
367
- this._queue = [];
368
-
369
- if (before) {
370
- before();
371
- }
433
+ var length = args.length,
434
+ method,
435
+ wait,
436
+ target,
437
+ methodOrTarget,
438
+ methodOrWait,
439
+ methodOrArgs;
372
440
 
373
- for (var i = 0; i < length; i += 4) {
374
- target = queueItems[i];
375
- method = queueItems[i + 1];
376
- args = queueItems[i + 2];
377
- errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
441
+ if (length === 0) {
442
+ return;
443
+ } else if (length === 1) {
444
+ method = args.shift();
445
+ wait = 0;
446
+ } else if (length === 2) {
447
+ methodOrTarget = args[0];
448
+ methodOrWait = args[1];
378
449
 
379
- if (_backburnerUtils.isString(method)) {
380
- method = target[method];
450
+ if (_backburnerUtils.isFunction(methodOrWait) || _backburnerUtils.isFunction(methodOrTarget[methodOrWait])) {
451
+ target = args.shift();
452
+ method = args.shift();
453
+ wait = 0;
454
+ } else if (_backburnerUtils.isCoercableNumber(methodOrWait)) {
455
+ method = args.shift();
456
+ wait = args.shift();
457
+ } else {
458
+ method = args.shift();
459
+ wait = 0;
381
460
  }
461
+ } else {
462
+ var last = args[args.length - 1];
382
463
 
383
- // method could have been nullified / canceled during flush
384
- if (method) {
385
- //
386
- // ** Attention intrepid developer **
387
- //
388
- // To find out the stack of this task when it was scheduled onto
389
- // the run loop, add the following to your app.js:
390
- //
391
- // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
392
- //
393
- // Once that is in place, when you are at a breakpoint and navigate
394
- // here in the stack explorer, you can look at `errorRecordedForStack.stack`,
395
- // which will be the captured stack when this job was scheduled.
396
- //
397
- invoke(target, method, args, onError, errorRecordedForStack);
464
+ if (_backburnerUtils.isCoercableNumber(last)) {
465
+ wait = args.pop();
466
+ } else {
467
+ wait = 0;
398
468
  }
399
- }
400
469
 
401
- if (after) {
402
- after();
470
+ methodOrTarget = args[0];
471
+ methodOrArgs = args[1];
472
+
473
+ if (_backburnerUtils.isFunction(methodOrArgs) || _backburnerUtils.isString(methodOrArgs) && methodOrTarget !== null && methodOrArgs in methodOrTarget) {
474
+ target = args.shift();
475
+ method = args.shift();
476
+ } else {
477
+ method = args.shift();
478
+ }
403
479
  }
404
480
 
405
- this._queueBeingFlushed = undefined;
481
+ var executeAt = Date.now() + parseInt(wait !== wait ? 0 : wait, 10);
406
482
 
407
- if (sync !== false && this._queue.length > 0) {
408
- // check if new items have been added
409
- this.flush(true);
483
+ if (_backburnerUtils.isString(method)) {
484
+ method = target[method];
410
485
  }
411
- },
412
486
 
413
- cancel: function (actionToCancel) {
414
- var queue = this._queue,
415
- currentTarget,
416
- currentMethod,
417
- i,
418
- l;
419
- var target = actionToCancel.target;
420
- var method = actionToCancel.method;
421
- var GUID_KEY = this.globalOptions.GUID_KEY;
422
-
423
- if (GUID_KEY && this.targetQueues && target) {
424
- var targetQueue = this.targetQueues[target[GUID_KEY]];
487
+ var onError = getOnError(this.options);
425
488
 
426
- if (targetQueue) {
427
- for (i = 0, l = targetQueue.length; i < l; i++) {
428
- if (targetQueue[i] === method) {
429
- targetQueue.splice(i, 1);
430
- }
489
+ function fn() {
490
+ if (onError) {
491
+ try {
492
+ method.apply(target, args);
493
+ } catch (e) {
494
+ onError(e);
431
495
  }
496
+ } else {
497
+ method.apply(target, args);
432
498
  }
433
499
  }
434
500
 
435
- for (i = 0, l = queue.length; i < l; i += 4) {
436
- currentTarget = queue[i];
437
- currentMethod = queue[i + 1];
501
+ return this._setTimeout(fn, executeAt);
502
+ },
438
503
 
439
- if (currentTarget === target && currentMethod === method) {
440
- queue.splice(i, 4);
441
- return true;
442
- }
504
+ _setTimeout: function (fn, executeAt) {
505
+ if (this._timers.length === 0) {
506
+ this._timers.push(executeAt, fn);
507
+ this._installTimerTimeout();
508
+ return fn;
443
509
  }
444
510
 
445
- // if not found in current queue
446
- // could be in the queue that is being flushed
447
- queue = this._queueBeingFlushed;
511
+ // find position to insert
512
+ var i = _backburnerBinarySearch.default(executeAt, this._timers);
448
513
 
449
- if (!queue) {
450
- return;
514
+ this._timers.splice(i, 0, executeAt, fn);
515
+
516
+ // we should be the new earliest timer if i == 0
517
+ if (i === 0) {
518
+ this._reinstallTimerTimeout();
451
519
  }
452
520
 
453
- for (i = 0, l = queue.length; i < l; i += 4) {
454
- currentTarget = queue[i];
455
- currentMethod = queue[i + 1];
521
+ return fn;
522
+ },
456
523
 
457
- if (currentTarget === target && currentMethod === method) {
458
- // don't mess with array during flush
459
- // just nullify the method
460
- queue[i + 1] = null;
461
- return true;
462
- }
524
+ throttle: function (target, method /* , args, wait, [immediate] */) {
525
+ var backburner = this;
526
+ var args = new Array(arguments.length);
527
+ for (var i = 0; i < arguments.length; i++) {
528
+ args[i] = arguments[i];
463
529
  }
464
- }
465
- };
466
- });
467
- enifed('backburner/utils', ['exports'], function (exports) {
468
- 'use strict';
469
-
470
- exports.each = each;
471
- exports.isString = isString;
472
- exports.isFunction = isFunction;
473
- exports.isNumber = isNumber;
474
- exports.isCoercableNumber = isCoercableNumber;
475
- var NUMBER = /\d+/;
530
+ var immediate = args.pop();
531
+ var wait, throttler, index, timer;
476
532
 
477
- function each(collection, callback) {
478
- for (var i = 0; i < collection.length; i++) {
479
- callback(collection[i]);
480
- }
481
- }
533
+ if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
534
+ wait = immediate;
535
+ immediate = true;
536
+ } else {
537
+ wait = args.pop();
538
+ }
482
539
 
483
- function isString(suspect) {
484
- return typeof suspect === 'string';
485
- }
540
+ wait = parseInt(wait, 10);
486
541
 
487
- function isFunction(suspect) {
488
- return typeof suspect === 'function';
489
- }
542
+ index = findThrottler(target, method, this._throttlers);
543
+ if (index > -1) {
544
+ return this._throttlers[index];
545
+ } // throttled
490
546
 
491
- function isNumber(suspect) {
492
- return typeof suspect === 'number';
493
- }
547
+ timer = this._platform.setTimeout(function () {
548
+ if (!immediate) {
549
+ backburner.run.apply(backburner, args);
550
+ }
551
+ var index = findThrottler(target, method, backburner._throttlers);
552
+ if (index > -1) {
553
+ backburner._throttlers.splice(index, 1);
554
+ }
555
+ }, wait);
494
556
 
495
- function isCoercableNumber(number) {
496
- return isNumber(number) || NUMBER.test(number);
497
- }
498
- });
499
- enifed('backburner', ['exports', 'backburner/utils', 'backburner/platform', 'backburner/binary-search', 'backburner/deferred-action-queues'], function (exports, _backburnerUtils, _backburnerPlatform, _backburnerBinarySearch, _backburnerDeferredActionQueues) {
500
- 'use strict';
557
+ if (immediate) {
558
+ this.run.apply(this, args);
559
+ }
501
560
 
502
- exports.default = Backburner;
561
+ throttler = [target, method, timer];
503
562
 
504
- function Backburner(queueNames, options) {
505
- this.queueNames = queueNames;
506
- this.options = options || {};
507
- if (!this.options.defaultQueue) {
508
- this.options.defaultQueue = queueNames[0];
509
- }
510
- this.instanceStack = [];
511
- this._debouncees = [];
512
- this._throttlers = [];
513
- this._eventCallbacks = {
514
- end: [],
515
- begin: []
516
- };
563
+ this._throttlers.push(throttler);
517
564
 
518
- var _this = this;
519
- this._boundClearItems = function () {
520
- clearItems();
521
- };
565
+ return throttler;
566
+ },
522
567
 
523
- this._timerTimeoutId = undefined;
524
- this._timers = [];
568
+ debounce: function (target, method /* , args, wait, [immediate] */) {
569
+ var backburner = this;
570
+ var args = new Array(arguments.length);
571
+ for (var i = 0; i < arguments.length; i++) {
572
+ args[i] = arguments[i];
573
+ }
525
574
 
526
- this._platform = this.options._platform || _backburnerPlatform.default;
575
+ var immediate = args.pop();
576
+ var wait, index, debouncee, timer;
527
577
 
528
- this._boundRunExpiredTimers = function () {
529
- _this._runExpiredTimers();
530
- };
531
- }
578
+ if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
579
+ wait = immediate;
580
+ immediate = false;
581
+ } else {
582
+ wait = args.pop();
583
+ }
532
584
 
533
- Backburner.prototype = {
534
- begin: function () {
535
- var options = this.options;
536
- var onBegin = options && options.onBegin;
537
- var previousInstance = this.currentInstance;
585
+ wait = parseInt(wait, 10);
586
+ // Remove debouncee
587
+ index = findDebouncee(target, method, this._debouncees);
538
588
 
539
- if (previousInstance) {
540
- this.instanceStack.push(previousInstance);
589
+ if (index > -1) {
590
+ debouncee = this._debouncees[index];
591
+ this._debouncees.splice(index, 1);
592
+ this._platform.clearTimeout(debouncee[2]);
541
593
  }
542
594
 
543
- this.currentInstance = new _backburnerDeferredActionQueues.default(this.queueNames, options);
544
- this._trigger('begin', this.currentInstance, previousInstance);
545
- if (onBegin) {
546
- onBegin(this.currentInstance, previousInstance);
595
+ timer = this._platform.setTimeout(function () {
596
+ if (!immediate) {
597
+ backburner.run.apply(backburner, args);
598
+ }
599
+ var index = findDebouncee(target, method, backburner._debouncees);
600
+ if (index > -1) {
601
+ backburner._debouncees.splice(index, 1);
602
+ }
603
+ }, wait);
604
+
605
+ if (immediate && index === -1) {
606
+ backburner.run.apply(backburner, args);
547
607
  }
608
+
609
+ debouncee = [target, method, timer];
610
+
611
+ backburner._debouncees.push(debouncee);
612
+
613
+ return debouncee;
548
614
  },
549
615
 
550
- end: function () {
551
- var options = this.options;
552
- var onEnd = options && options.onEnd;
553
- var currentInstance = this.currentInstance;
554
- var nextInstance = null;
616
+ cancelTimers: function () {
617
+ _backburnerUtils.each(this._throttlers, this._boundClearItems);
618
+ this._throttlers = [];
555
619
 
556
- // Prevent double-finally bug in Safari 6.0.2 and iOS 6
557
- // This bug appears to be resolved in Safari 6.0.5 and iOS 7
558
- var finallyAlreadyCalled = false;
559
- try {
560
- currentInstance.flush();
561
- } finally {
562
- if (!finallyAlreadyCalled) {
563
- finallyAlreadyCalled = true;
620
+ _backburnerUtils.each(this._debouncees, this._boundClearItems);
621
+ this._debouncees = [];
564
622
 
565
- this.currentInstance = null;
623
+ this._clearTimerTimeout();
624
+ this._timers = [];
566
625
 
567
- if (this.instanceStack.length) {
568
- nextInstance = this.instanceStack.pop();
569
- this.currentInstance = nextInstance;
570
- }
571
- this._trigger('end', currentInstance, nextInstance);
572
- if (onEnd) {
573
- onEnd(currentInstance, nextInstance);
574
- }
575
- }
626
+ if (this._autorun) {
627
+ this._platform.clearTimeout(this._autorun);
628
+ this._autorun = null;
576
629
  }
577
630
  },
578
631
 
579
- /**
580
- Trigger an event. Supports up to two arguments. Designed around
581
- triggering transition events from one run loop instance to the
582
- next, which requires an argument for the first instance and then
583
- an argument for the next instance.
584
- @private
585
- @method _trigger
586
- @param {String} eventName
587
- @param {any} arg1
588
- @param {any} arg2
589
- */
590
- _trigger: function (eventName, arg1, arg2) {
591
- var callbacks = this._eventCallbacks[eventName];
592
- if (callbacks) {
593
- for (var i = 0; i < callbacks.length; i++) {
594
- callbacks[i](arg1, arg2);
595
- }
596
- }
597
- },
598
-
599
- on: function (eventName, callback) {
600
- if (typeof callback !== 'function') {
601
- throw new TypeError('Callback must be a function');
602
- }
603
- var callbacks = this._eventCallbacks[eventName];
604
- if (callbacks) {
605
- callbacks.push(callback);
606
- } else {
607
- throw new TypeError('Cannot on() event "' + eventName + '" because it does not exist');
608
- }
632
+ hasTimers: function () {
633
+ return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
609
634
  },
610
635
 
611
- off: function (eventName, callback) {
612
- if (eventName) {
613
- var callbacks = this._eventCallbacks[eventName];
614
- var callbackFound = false;
615
- if (!callbacks) return;
616
- if (callback) {
617
- for (var i = 0; i < callbacks.length; i++) {
618
- if (callbacks[i] === callback) {
619
- callbackFound = true;
620
- callbacks.splice(i, 1);
621
- i--;
636
+ cancel: function (timer) {
637
+ var timerType = typeof timer;
638
+
639
+ if (timer && timerType === 'object' && timer.queue && timer.method) {
640
+ // we're cancelling a deferOnce
641
+ return timer.queue.cancel(timer);
642
+ } else if (timerType === 'function') {
643
+ // we're cancelling a setTimeout
644
+ for (var i = 0, l = this._timers.length; i < l; i += 2) {
645
+ if (this._timers[i + 1] === timer) {
646
+ this._timers.splice(i, 2); // remove the two elements
647
+ if (i === 0) {
648
+ this._reinstallTimerTimeout();
622
649
  }
650
+ return true;
623
651
  }
624
652
  }
625
- if (!callbackFound) {
626
- throw new TypeError('Cannot off() callback that does not exist');
627
- }
653
+ } else if (Object.prototype.toString.call(timer) === '[object Array]') {
654
+ // we're cancelling a throttle or debounce
655
+ return this._cancelItem(findThrottler, this._throttlers, timer) || this._cancelItem(findDebouncee, this._debouncees, timer);
628
656
  } else {
629
- throw new TypeError('Cannot off() event "' + eventName + '" because it does not exist');
657
+ return; // timer was null or not a timer
630
658
  }
631
659
  },
632
660
 
633
- run: function () /* target, method, args */{
634
- var length = arguments.length;
635
- var method, target, args;
636
-
637
- if (length === 1) {
638
- method = arguments[0];
639
- target = null;
640
- } else {
641
- target = arguments[0];
642
- method = arguments[1];
643
- }
644
-
645
- if (_backburnerUtils.isString(method)) {
646
- method = target[method];
647
- }
661
+ _cancelItem: function (findMethod, array, timer) {
662
+ var item, index;
648
663
 
649
- if (length > 2) {
650
- args = new Array(length - 2);
651
- for (var i = 0, l = length - 2; i < l; i++) {
652
- args[i] = arguments[i + 2];
653
- }
654
- } else {
655
- args = [];
664
+ if (timer.length < 3) {
665
+ return false;
656
666
  }
657
667
 
658
- var onError = getOnError(this.options);
668
+ index = findMethod(timer[0], timer[1], array);
659
669
 
660
- this.begin();
670
+ if (index > -1) {
661
671
 
662
- // guard against Safari 6's double-finally bug
663
- var didFinally = false;
672
+ item = array[index];
664
673
 
665
- if (onError) {
666
- try {
667
- return method.apply(target, args);
668
- } catch (error) {
669
- onError(error);
670
- } finally {
671
- if (!didFinally) {
672
- didFinally = true;
673
- this.end();
674
- }
675
- }
676
- } else {
677
- try {
678
- return method.apply(target, args);
679
- } finally {
680
- if (!didFinally) {
681
- didFinally = true;
682
- this.end();
683
- }
674
+ if (item[2] === timer[2]) {
675
+ array.splice(index, 1);
676
+ this._platform.clearTimeout(timer[2]);
677
+ return true;
684
678
  }
685
679
  }
686
- },
687
-
688
- /*
689
- Join the passed method with an existing queue and execute immediately,
690
- if there isn't one use `Backburner#run`.
691
- The join method is like the run method except that it will schedule into
692
- an existing queue if one already exists. In either case, the join method will
693
- immediately execute the passed in function and return its result.
694
- @method join
695
- @param {Object} target
696
- @param {Function} method The method to be executed
697
- @param {any} args The method arguments
698
- @return method result
699
- */
700
- join: function () /* target, method, args */{
701
- if (!this.currentInstance) {
702
- return this.run.apply(this, arguments);
703
- }
704
680
 
705
- var length = arguments.length;
706
- var method, target;
707
-
708
- if (length === 1) {
709
- method = arguments[0];
710
- target = null;
711
- } else {
712
- target = arguments[0];
713
- method = arguments[1];
714
- }
681
+ return false;
682
+ },
715
683
 
716
- if (_backburnerUtils.isString(method)) {
717
- method = target[method];
718
- }
684
+ _runExpiredTimers: function () {
685
+ this._timerTimeoutId = undefined;
686
+ this.run(this, this._scheduleExpiredTimers);
687
+ },
719
688
 
720
- if (length === 1) {
721
- return method();
722
- } else if (length === 2) {
723
- return method.call(target);
724
- } else {
725
- var args = new Array(length - 2);
726
- for (var i = 0, l = length - 2; i < l; i++) {
727
- args[i] = arguments[i + 2];
689
+ _scheduleExpiredTimers: function () {
690
+ var n = Date.now();
691
+ var timers = this._timers;
692
+ var i = 0;
693
+ var l = timers.length;
694
+ for (; i < l; i += 2) {
695
+ var executeAt = timers[i];
696
+ var fn = timers[i + 1];
697
+ if (executeAt <= n) {
698
+ this.schedule(this.options.defaultQueue, null, fn);
699
+ } else {
700
+ break;
728
701
  }
729
- return method.apply(target, args);
730
702
  }
703
+ timers.splice(0, i);
704
+ this._installTimerTimeout();
731
705
  },
732
706
 
733
- /*
734
- Defer the passed function to run inside the specified queue.
735
- @method defer
736
- @param {String} queueName
737
- @param {Object} target
738
- @param {Function|String} method The method or method name to be executed
739
- @param {any} args The method arguments
740
- @return method result
741
- */
742
- defer: function (queueName /* , target, method, args */) {
743
- var length = arguments.length;
744
- var method, target, args;
707
+ _reinstallTimerTimeout: function () {
708
+ this._clearTimerTimeout();
709
+ this._installTimerTimeout();
710
+ },
745
711
 
746
- if (length === 2) {
747
- method = arguments[1];
748
- target = null;
749
- } else {
750
- target = arguments[1];
751
- method = arguments[2];
712
+ _clearTimerTimeout: function () {
713
+ if (!this._timerTimeoutId) {
714
+ return;
752
715
  }
716
+ this._platform.clearTimeout(this._timerTimeoutId);
717
+ this._timerTimeoutId = undefined;
718
+ },
753
719
 
754
- if (_backburnerUtils.isString(method)) {
755
- method = target[method];
720
+ _installTimerTimeout: function () {
721
+ if (!this._timers.length) {
722
+ return;
756
723
  }
724
+ var minExpiresAt = this._timers[0];
725
+ var n = Date.now();
726
+ var wait = Math.max(0, minExpiresAt - n);
727
+ this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
728
+ }
729
+ };
757
730
 
758
- var stack = this.DEBUG ? new Error() : undefined;
731
+ Backburner.prototype.schedule = Backburner.prototype.defer;
732
+ Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
733
+ Backburner.prototype.later = Backburner.prototype.setTimeout;
759
734
 
760
- if (length > 3) {
761
- args = new Array(length - 3);
762
- for (var i = 3; i < length; i++) {
763
- args[i - 3] = arguments[i];
764
- }
765
- } else {
766
- args = undefined;
767
- }
735
+ function getOnError(options) {
736
+ return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
737
+ }
768
738
 
769
- if (!this.currentInstance) {
770
- createAutorun(this);
771
- }
772
- return this.currentInstance.schedule(queueName, target, method, args, false, stack);
773
- },
739
+ function createAutorun(backburner) {
740
+ backburner.begin();
741
+ backburner._autorun = backburner._platform.setTimeout(function () {
742
+ backburner._autorun = null;
743
+ backburner.end();
744
+ });
745
+ }
774
746
 
775
- deferOnce: function (queueName /* , target, method, args */) {
776
- var length = arguments.length;
777
- var method, target, args;
747
+ function findDebouncee(target, method, debouncees) {
748
+ return findItem(target, method, debouncees);
749
+ }
778
750
 
779
- if (length === 2) {
780
- method = arguments[1];
781
- target = null;
782
- } else {
783
- target = arguments[1];
784
- method = arguments[2];
785
- }
751
+ function findThrottler(target, method, throttlers) {
752
+ return findItem(target, method, throttlers);
753
+ }
786
754
 
787
- if (_backburnerUtils.isString(method)) {
788
- method = target[method];
755
+ function findItem(target, method, collection) {
756
+ var item;
757
+ var index = -1;
758
+
759
+ for (var i = 0, l = collection.length; i < l; i++) {
760
+ item = collection[i];
761
+ if (item[0] === target && item[1] === method) {
762
+ index = i;
763
+ break;
789
764
  }
765
+ }
790
766
 
791
- var stack = this.DEBUG ? new Error() : undefined;
792
-
793
- if (length > 3) {
794
- args = new Array(length - 3);
795
- for (var i = 3; i < length; i++) {
796
- args[i - 3] = arguments[i];
797
- }
798
- } else {
799
- args = undefined;
800
- }
767
+ return index;
768
+ }
801
769
 
802
- if (!this.currentInstance) {
803
- createAutorun(this);
804
- }
805
- return this.currentInstance.schedule(queueName, target, method, args, true, stack);
806
- },
770
+ function clearItems(item) {
771
+ this._platform.clearTimeout(item[2]);
772
+ }
773
+ });
774
+ enifed("backburner/binary-search", ["exports"], function (exports) {
775
+ "use strict";
807
776
 
808
- setTimeout: function () {
809
- var l = arguments.length;
810
- var args = new Array(l);
777
+ exports.default = binarySearch;
811
778
 
812
- for (var x = 0; x < l; x++) {
813
- args[x] = arguments[x];
814
- }
779
+ function binarySearch(time, timers) {
780
+ var start = 0;
781
+ var end = timers.length - 2;
782
+ var middle, l;
815
783
 
816
- var length = args.length,
817
- method,
818
- wait,
819
- target,
820
- methodOrTarget,
821
- methodOrWait,
822
- methodOrArgs;
784
+ while (start < end) {
785
+ // since timers is an array of pairs 'l' will always
786
+ // be an integer
787
+ l = (end - start) / 2;
823
788
 
824
- if (length === 0) {
825
- return;
826
- } else if (length === 1) {
827
- method = args.shift();
828
- wait = 0;
829
- } else if (length === 2) {
830
- methodOrTarget = args[0];
831
- methodOrWait = args[1];
789
+ // compensate for the index in case even number
790
+ // of pairs inside timers
791
+ middle = start + l - l % 2;
832
792
 
833
- if (_backburnerUtils.isFunction(methodOrWait) || _backburnerUtils.isFunction(methodOrTarget[methodOrWait])) {
834
- target = args.shift();
835
- method = args.shift();
836
- wait = 0;
837
- } else if (_backburnerUtils.isCoercableNumber(methodOrWait)) {
838
- method = args.shift();
839
- wait = args.shift();
840
- } else {
841
- method = args.shift();
842
- wait = 0;
843
- }
793
+ if (time >= timers[middle]) {
794
+ start = middle + 2;
844
795
  } else {
845
- var last = args[args.length - 1];
846
-
847
- if (_backburnerUtils.isCoercableNumber(last)) {
848
- wait = args.pop();
849
- } else {
850
- wait = 0;
851
- }
852
-
853
- methodOrTarget = args[0];
854
- methodOrArgs = args[1];
855
-
856
- if (_backburnerUtils.isFunction(methodOrArgs) || _backburnerUtils.isString(methodOrArgs) && methodOrTarget !== null && methodOrArgs in methodOrTarget) {
857
- target = args.shift();
858
- method = args.shift();
859
- } else {
860
- method = args.shift();
861
- }
796
+ end = middle;
862
797
  }
798
+ }
863
799
 
864
- var executeAt = Date.now() + parseInt(wait !== wait ? 0 : wait, 10);
800
+ return time >= timers[start] ? start + 2 : start;
801
+ }
802
+ });
803
+ enifed('backburner/deferred-action-queues', ['exports', 'backburner/utils', 'backburner/queue'], function (exports, _backburnerUtils, _backburnerQueue) {
804
+ 'use strict';
865
805
 
866
- if (_backburnerUtils.isString(method)) {
867
- method = target[method];
868
- }
806
+ exports.default = DeferredActionQueues;
869
807
 
870
- var onError = getOnError(this.options);
808
+ function DeferredActionQueues(queueNames, options) {
809
+ var queues = this.queues = {};
810
+ this.queueNames = queueNames = queueNames || [];
871
811
 
872
- function fn() {
873
- if (onError) {
874
- try {
875
- method.apply(target, args);
876
- } catch (e) {
877
- onError(e);
878
- }
879
- } else {
880
- method.apply(target, args);
881
- }
882
- }
812
+ this.options = options;
883
813
 
884
- return this._setTimeout(fn, executeAt);
885
- },
814
+ _backburnerUtils.each(queueNames, function (queueName) {
815
+ queues[queueName] = new _backburnerQueue.default(queueName, options[queueName], options);
816
+ });
817
+ }
886
818
 
887
- _setTimeout: function (fn, executeAt) {
888
- if (this._timers.length === 0) {
889
- this._timers.push(executeAt, fn);
890
- this._installTimerTimeout();
891
- return fn;
892
- }
819
+ function noSuchQueue(name) {
820
+ throw new Error('You attempted to schedule an action in a queue (' + name + ') that doesn\'t exist');
821
+ }
893
822
 
894
- // find position to insert
895
- var i = _backburnerBinarySearch.default(executeAt, this._timers);
823
+ function noSuchMethod(name) {
824
+ throw new Error('You attempted to schedule an action in a queue (' + name + ') for a method that doesn\'t exist');
825
+ }
896
826
 
897
- this._timers.splice(i, 0, executeAt, fn);
827
+ DeferredActionQueues.prototype = {
828
+ schedule: function (name, target, method, args, onceFlag, stack) {
829
+ var queues = this.queues;
830
+ var queue = queues[name];
898
831
 
899
- // we should be the new earliest timer if i == 0
900
- if (i === 0) {
901
- this._reinstallTimerTimeout();
832
+ if (!queue) {
833
+ noSuchQueue(name);
902
834
  }
903
835
 
904
- return fn;
905
- },
906
-
907
- throttle: function (target, method /* , args, wait, [immediate] */) {
908
- var backburner = this;
909
- var args = new Array(arguments.length);
910
- for (var i = 0; i < arguments.length; i++) {
911
- args[i] = arguments[i];
836
+ if (!method) {
837
+ noSuchMethod(name);
912
838
  }
913
- var immediate = args.pop();
914
- var wait, throttler, index, timer;
915
839
 
916
- if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
917
- wait = immediate;
918
- immediate = true;
840
+ if (onceFlag) {
841
+ return queue.pushUnique(target, method, args, stack);
919
842
  } else {
920
- wait = args.pop();
843
+ return queue.push(target, method, args, stack);
921
844
  }
845
+ },
922
846
 
923
- wait = parseInt(wait, 10);
847
+ flush: function () {
848
+ var queues = this.queues;
849
+ var queueNames = this.queueNames;
850
+ var queueName, queue;
851
+ var queueNameIndex = 0;
852
+ var numberOfQueues = queueNames.length;
924
853
 
925
- index = findThrottler(target, method, this._throttlers);
926
- if (index > -1) {
927
- return this._throttlers[index];
928
- } // throttled
854
+ while (queueNameIndex < numberOfQueues) {
855
+ queueName = queueNames[queueNameIndex];
856
+ queue = queues[queueName];
929
857
 
930
- timer = this._platform.setTimeout(function () {
931
- if (!immediate) {
932
- backburner.run.apply(backburner, args);
933
- }
934
- var index = findThrottler(target, method, backburner._throttlers);
935
- if (index > -1) {
936
- backburner._throttlers.splice(index, 1);
937
- }
938
- }, wait);
858
+ var numberOfQueueItems = queue._queue.length;
939
859
 
940
- if (immediate) {
941
- this.run.apply(this, args);
860
+ if (numberOfQueueItems === 0) {
861
+ queueNameIndex++;
862
+ } else {
863
+ queue.flush(false /* async */);
864
+ queueNameIndex = 0;
865
+ }
942
866
  }
867
+ }
868
+ };
869
+ });
870
+ enifed('backburner/platform', ['exports'], function (exports) {
871
+ 'use strict';
943
872
 
944
- throttler = [target, method, timer];
873
+ var GlobalContext;
945
874
 
946
- this._throttlers.push(throttler);
875
+ /* global self */
876
+ if (typeof self === 'object') {
877
+ GlobalContext = self;
947
878
 
948
- return throttler;
949
- },
879
+ /* global global */
880
+ } else if (typeof global === 'object') {
881
+ GlobalContext = global;
950
882
 
951
- debounce: function (target, method /* , args, wait, [immediate] */) {
952
- var backburner = this;
953
- var args = new Array(arguments.length);
954
- for (var i = 0; i < arguments.length; i++) {
955
- args[i] = arguments[i];
883
+ /* global window */
884
+ } else if (typeof window === 'object') {
885
+ GlobalContext = window;
886
+ } else {
887
+ throw new Error('no global: `self`, `global` nor `window` was found');
956
888
  }
957
889
 
958
- var immediate = args.pop();
959
- var wait, index, debouncee, timer;
890
+ exports.default = GlobalContext;
891
+ });
892
+ enifed('backburner/queue', ['exports', 'backburner/utils'], function (exports, _backburnerUtils) {
893
+ 'use strict';
960
894
 
961
- if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
962
- wait = immediate;
963
- immediate = false;
964
- } else {
965
- wait = args.pop();
966
- }
895
+ exports.default = Queue;
967
896
 
968
- wait = parseInt(wait, 10);
969
- // Remove debouncee
970
- index = findDebouncee(target, method, this._debouncees);
897
+ function Queue(name, options, globalOptions) {
898
+ this.name = name;
899
+ this.globalOptions = globalOptions || {};
900
+ this.options = options;
901
+ this._queue = [];
902
+ this.targetQueues = {};
903
+ this._queueBeingFlushed = undefined;
904
+ }
971
905
 
972
- if (index > -1) {
973
- debouncee = this._debouncees[index];
974
- this._debouncees.splice(index, 1);
975
- this._platform.clearTimeout(debouncee[2]);
976
- }
906
+ Queue.prototype = {
907
+ push: function (target, method, args, stack) {
908
+ var queue = this._queue;
909
+ queue.push(target, method, args, stack);
977
910
 
978
- timer = this._platform.setTimeout(function () {
979
- if (!immediate) {
980
- backburner.run.apply(backburner, args);
981
- }
982
- var index = findDebouncee(target, method, backburner._debouncees);
983
- if (index > -1) {
984
- backburner._debouncees.splice(index, 1);
985
- }
986
- }, wait);
987
-
988
- if (immediate && index === -1) {
989
- backburner.run.apply(backburner, args);
990
- }
991
-
992
- debouncee = [target, method, timer];
993
-
994
- backburner._debouncees.push(debouncee);
995
-
996
- return debouncee;
911
+ return {
912
+ queue: this,
913
+ target: target,
914
+ method: method
915
+ };
997
916
  },
998
917
 
999
- cancelTimers: function () {
1000
- _backburnerUtils.each(this._throttlers, this._boundClearItems);
1001
- this._throttlers = [];
1002
-
1003
- _backburnerUtils.each(this._debouncees, this._boundClearItems);
1004
- this._debouncees = [];
918
+ pushUniqueWithoutGuid: function (target, method, args, stack) {
919
+ var queue = this._queue;
1005
920
 
1006
- this._clearTimerTimeout();
1007
- this._timers = [];
921
+ for (var i = 0, l = queue.length; i < l; i += 4) {
922
+ var currentTarget = queue[i];
923
+ var currentMethod = queue[i + 1];
1008
924
 
1009
- if (this._autorun) {
1010
- this._platform.clearTimeout(this._autorun);
1011
- this._autorun = null;
925
+ if (currentTarget === target && currentMethod === method) {
926
+ queue[i + 2] = args; // replace args
927
+ queue[i + 3] = stack; // replace stack
928
+ return;
929
+ }
1012
930
  }
1013
- },
1014
931
 
1015
- hasTimers: function () {
1016
- return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
932
+ queue.push(target, method, args, stack);
1017
933
  },
1018
934
 
1019
- cancel: function (timer) {
1020
- var timerType = typeof timer;
935
+ targetQueue: function (targetQueue, target, method, args, stack) {
936
+ var queue = this._queue;
1021
937
 
1022
- if (timer && timerType === 'object' && timer.queue && timer.method) {
1023
- // we're cancelling a deferOnce
1024
- return timer.queue.cancel(timer);
1025
- } else if (timerType === 'function') {
1026
- // we're cancelling a setTimeout
1027
- for (var i = 0, l = this._timers.length; i < l; i += 2) {
1028
- if (this._timers[i + 1] === timer) {
1029
- this._timers.splice(i, 2); // remove the two elements
1030
- if (i === 0) {
1031
- this._reinstallTimerTimeout();
1032
- }
1033
- return true;
1034
- }
938
+ for (var i = 0, l = targetQueue.length; i < l; i += 2) {
939
+ var currentMethod = targetQueue[i];
940
+ var currentIndex = targetQueue[i + 1];
941
+
942
+ if (currentMethod === method) {
943
+ queue[currentIndex + 2] = args; // replace args
944
+ queue[currentIndex + 3] = stack; // replace stack
945
+ return;
1035
946
  }
1036
- } else if (Object.prototype.toString.call(timer) === '[object Array]') {
1037
- // we're cancelling a throttle or debounce
1038
- return this._cancelItem(findThrottler, this._throttlers, timer) || this._cancelItem(findDebouncee, this._debouncees, timer);
1039
- } else {
1040
- return; // timer was null or not a timer
1041
947
  }
948
+
949
+ targetQueue.push(method, queue.push(target, method, args, stack) - 4);
1042
950
  },
1043
951
 
1044
- _cancelItem: function (findMethod, array, timer) {
1045
- var item, index;
952
+ pushUniqueWithGuid: function (guid, target, method, args, stack) {
953
+ var hasLocalQueue = this.targetQueues[guid];
1046
954
 
1047
- if (timer.length < 3) {
1048
- return false;
955
+ if (hasLocalQueue) {
956
+ this.targetQueue(hasLocalQueue, target, method, args, stack);
957
+ } else {
958
+ this.targetQueues[guid] = [method, this._queue.push(target, method, args, stack) - 4];
1049
959
  }
1050
960
 
1051
- index = findMethod(timer[0], timer[1], array);
1052
-
1053
- if (index > -1) {
961
+ return {
962
+ queue: this,
963
+ target: target,
964
+ method: method
965
+ };
966
+ },
1054
967
 
1055
- item = array[index];
968
+ pushUnique: function (target, method, args, stack) {
969
+ var KEY = this.globalOptions.GUID_KEY;
1056
970
 
1057
- if (item[2] === timer[2]) {
1058
- array.splice(index, 1);
1059
- this._platform.clearTimeout(timer[2]);
1060
- return true;
971
+ if (target && KEY) {
972
+ var guid = target[KEY];
973
+ if (guid) {
974
+ return this.pushUniqueWithGuid(guid, target, method, args, stack);
1061
975
  }
1062
976
  }
1063
977
 
1064
- return false;
978
+ this.pushUniqueWithoutGuid(target, method, args, stack);
979
+
980
+ return {
981
+ queue: this,
982
+ target: target,
983
+ method: method
984
+ };
1065
985
  },
1066
986
 
1067
- _runExpiredTimers: function () {
1068
- this._timerTimeoutId = undefined;
1069
- this.run(this, this._scheduleExpiredTimers);
987
+ invoke: function (target, method, args, _, _errorRecordedForStack) {
988
+ if (args && args.length > 0) {
989
+ method.apply(target, args);
990
+ } else {
991
+ method.call(target);
992
+ }
1070
993
  },
1071
994
 
1072
- _scheduleExpiredTimers: function () {
1073
- var n = Date.now();
1074
- var timers = this._timers;
1075
- var i = 0;
1076
- var l = timers.length;
1077
- for (; i < l; i += 2) {
1078
- var executeAt = timers[i];
1079
- var fn = timers[i + 1];
1080
- if (executeAt <= n) {
1081
- this.schedule(this.options.defaultQueue, null, fn);
995
+ invokeWithOnError: function (target, method, args, onError, errorRecordedForStack) {
996
+ try {
997
+ if (args && args.length > 0) {
998
+ method.apply(target, args);
1082
999
  } else {
1083
- break;
1000
+ method.call(target);
1084
1001
  }
1002
+ } catch (error) {
1003
+ onError(error, errorRecordedForStack);
1085
1004
  }
1086
- timers.splice(0, i);
1087
- this._installTimerTimeout();
1088
- },
1089
-
1090
- _reinstallTimerTimeout: function () {
1091
- this._clearTimerTimeout();
1092
- this._installTimerTimeout();
1093
1005
  },
1094
1006
 
1095
- _clearTimerTimeout: function () {
1096
- if (!this._timerTimeoutId) {
1097
- return;
1098
- }
1099
- this._platform.clearTimeout(this._timerTimeoutId);
1100
- this._timerTimeoutId = undefined;
1101
- },
1007
+ flush: function (sync) {
1008
+ var queue = this._queue;
1009
+ var length = queue.length;
1102
1010
 
1103
- _installTimerTimeout: function () {
1104
- if (!this._timers.length) {
1011
+ if (length === 0) {
1105
1012
  return;
1106
1013
  }
1107
- var minExpiresAt = this._timers[0];
1108
- var n = Date.now();
1109
- var wait = Math.max(0, minExpiresAt - n);
1110
- this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
1111
- }
1112
- };
1113
-
1114
- Backburner.prototype.schedule = Backburner.prototype.defer;
1115
- Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
1116
- Backburner.prototype.later = Backburner.prototype.setTimeout;
1117
1014
 
1118
- function getOnError(options) {
1119
- return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
1120
- }
1015
+ var globalOptions = this.globalOptions;
1016
+ var options = this.options;
1017
+ var before = options && options.before;
1018
+ var after = options && options.after;
1019
+ var onError = globalOptions.onError || globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod];
1020
+ var target, method, args, errorRecordedForStack;
1021
+ var invoke = onError ? this.invokeWithOnError : this.invoke;
1121
1022
 
1122
- function createAutorun(backburner) {
1123
- backburner.begin();
1124
- backburner._autorun = backburner._platform.setTimeout(function () {
1125
- backburner._autorun = null;
1126
- backburner.end();
1127
- });
1128
- }
1023
+ this.targetQueues = Object.create(null);
1024
+ var queueItems = this._queueBeingFlushed = this._queue.slice();
1025
+ this._queue = [];
1129
1026
 
1130
- function findDebouncee(target, method, debouncees) {
1131
- return findItem(target, method, debouncees);
1132
- }
1027
+ if (before) {
1028
+ before();
1029
+ }
1133
1030
 
1134
- function findThrottler(target, method, throttlers) {
1135
- return findItem(target, method, throttlers);
1136
- }
1031
+ for (var i = 0; i < length; i += 4) {
1032
+ target = queueItems[i];
1033
+ method = queueItems[i + 1];
1034
+ args = queueItems[i + 2];
1035
+ errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
1137
1036
 
1138
- function findItem(target, method, collection) {
1139
- var item;
1140
- var index = -1;
1037
+ if (_backburnerUtils.isString(method)) {
1038
+ method = target[method];
1039
+ }
1141
1040
 
1142
- for (var i = 0, l = collection.length; i < l; i++) {
1143
- item = collection[i];
1144
- if (item[0] === target && item[1] === method) {
1145
- index = i;
1146
- break;
1041
+ // method could have been nullified / canceled during flush
1042
+ if (method) {
1043
+ //
1044
+ // ** Attention intrepid developer **
1045
+ //
1046
+ // To find out the stack of this task when it was scheduled onto
1047
+ // the run loop, add the following to your app.js:
1048
+ //
1049
+ // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
1050
+ //
1051
+ // Once that is in place, when you are at a breakpoint and navigate
1052
+ // here in the stack explorer, you can look at `errorRecordedForStack.stack`,
1053
+ // which will be the captured stack when this job was scheduled.
1054
+ //
1055
+ invoke(target, method, args, onError, errorRecordedForStack);
1056
+ }
1147
1057
  }
1148
- }
1149
1058
 
1150
- return index;
1151
- }
1059
+ if (after) {
1060
+ after();
1061
+ }
1152
1062
 
1153
- function clearItems(item) {
1154
- this._platform.clearTimeout(item[2]);
1155
- }
1156
- });
1157
- enifed('container/container', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/features', 'container/owner', 'ember-runtime/mixins/container_proxy', 'ember-metal/symbol'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalDictionary, _emberMetalFeatures, _containerOwner, _emberRuntimeMixinsContainer_proxy, _emberMetalSymbol) {
1158
- 'use strict';
1063
+ this._queueBeingFlushed = undefined;
1159
1064
 
1160
- var CONTAINER_OVERRIDE = _emberMetalSymbol.default('CONTAINER_OVERRIDE');
1065
+ if (sync !== false && this._queue.length > 0) {
1066
+ // check if new items have been added
1067
+ this.flush(true);
1068
+ }
1069
+ },
1161
1070
 
1162
- /**
1071
+ cancel: function (actionToCancel) {
1072
+ var queue = this._queue,
1073
+ currentTarget,
1074
+ currentMethod,
1075
+ i,
1076
+ l;
1077
+ var target = actionToCancel.target;
1078
+ var method = actionToCancel.method;
1079
+ var GUID_KEY = this.globalOptions.GUID_KEY;
1080
+
1081
+ if (GUID_KEY && this.targetQueues && target) {
1082
+ var targetQueue = this.targetQueues[target[GUID_KEY]];
1083
+
1084
+ if (targetQueue) {
1085
+ for (i = 0, l = targetQueue.length; i < l; i++) {
1086
+ if (targetQueue[i] === method) {
1087
+ targetQueue.splice(i, 1);
1088
+ }
1089
+ }
1090
+ }
1091
+ }
1092
+
1093
+ for (i = 0, l = queue.length; i < l; i += 4) {
1094
+ currentTarget = queue[i];
1095
+ currentMethod = queue[i + 1];
1096
+
1097
+ if (currentTarget === target && currentMethod === method) {
1098
+ queue.splice(i, 4);
1099
+ return true;
1100
+ }
1101
+ }
1102
+
1103
+ // if not found in current queue
1104
+ // could be in the queue that is being flushed
1105
+ queue = this._queueBeingFlushed;
1106
+
1107
+ if (!queue) {
1108
+ return;
1109
+ }
1110
+
1111
+ for (i = 0, l = queue.length; i < l; i += 4) {
1112
+ currentTarget = queue[i];
1113
+ currentMethod = queue[i + 1];
1114
+
1115
+ if (currentTarget === target && currentMethod === method) {
1116
+ // don't mess with array during flush
1117
+ // just nullify the method
1118
+ queue[i + 1] = null;
1119
+ return true;
1120
+ }
1121
+ }
1122
+ }
1123
+ };
1124
+ });
1125
+ enifed('backburner/utils', ['exports'], function (exports) {
1126
+ 'use strict';
1127
+
1128
+ exports.each = each;
1129
+ exports.isString = isString;
1130
+ exports.isFunction = isFunction;
1131
+ exports.isNumber = isNumber;
1132
+ exports.isCoercableNumber = isCoercableNumber;
1133
+ var NUMBER = /\d+/;
1134
+
1135
+ function each(collection, callback) {
1136
+ for (var i = 0; i < collection.length; i++) {
1137
+ callback(collection[i]);
1138
+ }
1139
+ }
1140
+
1141
+ function isString(suspect) {
1142
+ return typeof suspect === 'string';
1143
+ }
1144
+
1145
+ function isFunction(suspect) {
1146
+ return typeof suspect === 'function';
1147
+ }
1148
+
1149
+ function isNumber(suspect) {
1150
+ return typeof suspect === 'number';
1151
+ }
1152
+
1153
+ function isCoercableNumber(number) {
1154
+ return isNumber(number) || NUMBER.test(number);
1155
+ }
1156
+ });
1157
+ enifed('container/container', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/features', 'container/owner', 'ember-runtime/mixins/container_proxy', 'ember-metal/symbol'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalDictionary, _emberMetalFeatures, _containerOwner, _emberRuntimeMixinsContainer_proxy, _emberMetalSymbol) {
1158
+ 'use strict';
1159
+
1160
+ var CONTAINER_OVERRIDE = _emberMetalSymbol.default('CONTAINER_OVERRIDE');
1161
+
1162
+ /**
1163
1163
  A container used to instantiate and cache objects.
1164
1164
 
1165
1165
  Every `Container` must be associated with a `Registry`, which is referenced
@@ -4783,7 +4783,7 @@ enifed('ember-metal/core', ['exports', 'require'], function (exports, _require)
4783
4783
 
4784
4784
  @class Ember
4785
4785
  @static
4786
- @version 2.6.1
4786
+ @version 2.6.2
4787
4787
  @public
4788
4788
  */
4789
4789
 
@@ -4825,11 +4825,11 @@ enifed('ember-metal/core', ['exports', 'require'], function (exports, _require)
4825
4825
 
4826
4826
  @property VERSION
4827
4827
  @type String
4828
- @default '2.6.1'
4828
+ @default '2.6.2'
4829
4829
  @static
4830
4830
  @public
4831
4831
  */
4832
- Ember.VERSION = '2.6.1';
4832
+ Ember.VERSION = '2.6.2';
4833
4833
 
4834
4834
  /**
4835
4835
  The hash of environment variables used to control various configuration
@@ -5317,13 +5317,11 @@ enifed('ember-metal/events', ['exports', 'ember-metal/debug', 'ember-metal/utils
5317
5317
  function addListener(obj, eventName, target, method, once) {
5318
5318
  _emberMetalDebug.assert('You must pass at least an object and event name to Ember.addListener', !!obj && !!eventName);
5319
5319
 
5320
- if (eventName === 'didInitAttrs' && obj.isComponent) {
5321
- _emberMetalDebug.deprecate('[DEPRECATED] didInitAttrs called in ' + obj.toString() + '.', false, {
5322
- id: 'ember-views.did-init-attrs',
5323
- until: '3.0.0',
5324
- url: 'http://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs'
5325
- });
5326
- }
5320
+ _emberMetalDebug.deprecate('didInitAttrs called in ' + (obj && obj.toString && obj.toString()) + '.', eventName !== 'didInitAttrs', {
5321
+ id: 'ember-views.did-init-attrs',
5322
+ until: '3.0.0',
5323
+ url: 'http://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs'
5324
+ });
5327
5325
 
5328
5326
  if (!method && 'function' === typeof target) {
5329
5327
  method = target;
@@ -20412,6 +20410,93 @@ enifed('ember-runtime/utils', ['exports', 'ember-runtime/mixins/array', 'ember-r
20412
20410
  return ret;
20413
20411
  }
20414
20412
  });
20413
+ enifed('rsvp', ['exports', 'rsvp/promise', 'rsvp/events', 'rsvp/node', 'rsvp/all', 'rsvp/all-settled', 'rsvp/race', 'rsvp/hash', 'rsvp/hash-settled', 'rsvp/rethrow', 'rsvp/defer', 'rsvp/config', 'rsvp/map', 'rsvp/resolve', 'rsvp/reject', 'rsvp/filter', 'rsvp/asap'], function (exports, _rsvpPromise, _rsvpEvents, _rsvpNode, _rsvpAll, _rsvpAllSettled, _rsvpRace, _rsvpHash, _rsvpHashSettled, _rsvpRethrow, _rsvpDefer, _rsvpConfig, _rsvpMap, _rsvpResolve, _rsvpReject, _rsvpFilter, _rsvpAsap) {
20414
+ 'use strict';
20415
+
20416
+ // defaults
20417
+ _rsvpConfig.config.async = _rsvpAsap.default;
20418
+ _rsvpConfig.config.after = function (cb) {
20419
+ setTimeout(cb, 0);
20420
+ };
20421
+ var cast = _rsvpResolve.default;
20422
+ function async(callback, arg) {
20423
+ _rsvpConfig.config.async(callback, arg);
20424
+ }
20425
+
20426
+ function on() {
20427
+ _rsvpConfig.config['on'].apply(_rsvpConfig.config, arguments);
20428
+ }
20429
+
20430
+ function off() {
20431
+ _rsvpConfig.config['off'].apply(_rsvpConfig.config, arguments);
20432
+ }
20433
+
20434
+ // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
20435
+ if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
20436
+ var callbacks = window['__PROMISE_INSTRUMENTATION__'];
20437
+ _rsvpConfig.configure('instrument', true);
20438
+ for (var eventName in callbacks) {
20439
+ if (callbacks.hasOwnProperty(eventName)) {
20440
+ on(eventName, callbacks[eventName]);
20441
+ }
20442
+ }
20443
+ }
20444
+
20445
+ exports.cast = cast;
20446
+ exports.Promise = _rsvpPromise.default;
20447
+ exports.EventTarget = _rsvpEvents.default;
20448
+ exports.all = _rsvpAll.default;
20449
+ exports.allSettled = _rsvpAllSettled.default;
20450
+ exports.race = _rsvpRace.default;
20451
+ exports.hash = _rsvpHash.default;
20452
+ exports.hashSettled = _rsvpHashSettled.default;
20453
+ exports.rethrow = _rsvpRethrow.default;
20454
+ exports.defer = _rsvpDefer.default;
20455
+ exports.denodeify = _rsvpNode.default;
20456
+ exports.configure = _rsvpConfig.configure;
20457
+ exports.on = on;
20458
+ exports.off = off;
20459
+ exports.resolve = _rsvpResolve.default;
20460
+ exports.reject = _rsvpReject.default;
20461
+ exports.async = async;
20462
+ exports.map = _rsvpMap.default;
20463
+ exports.filter = _rsvpFilter.default;
20464
+ });
20465
+ enifed('rsvp.umd', ['exports', 'rsvp/platform', 'rsvp'], function (exports, _rsvpPlatform, _rsvp) {
20466
+ 'use strict';
20467
+
20468
+ var RSVP = {
20469
+ 'race': _rsvp.race,
20470
+ 'Promise': _rsvp.Promise,
20471
+ 'allSettled': _rsvp.allSettled,
20472
+ 'hash': _rsvp.hash,
20473
+ 'hashSettled': _rsvp.hashSettled,
20474
+ 'denodeify': _rsvp.denodeify,
20475
+ 'on': _rsvp.on,
20476
+ 'off': _rsvp.off,
20477
+ 'map': _rsvp.map,
20478
+ 'filter': _rsvp.filter,
20479
+ 'resolve': _rsvp.resolve,
20480
+ 'reject': _rsvp.reject,
20481
+ 'all': _rsvp.all,
20482
+ 'rethrow': _rsvp.rethrow,
20483
+ 'defer': _rsvp.defer,
20484
+ 'EventTarget': _rsvp.EventTarget,
20485
+ 'configure': _rsvp.configure,
20486
+ 'async': _rsvp.async
20487
+ };
20488
+
20489
+ /* global define:true module:true window: true */
20490
+ if (typeof define === 'function' && define['amd']) {
20491
+ define(function () {
20492
+ return RSVP;
20493
+ });
20494
+ } else if (typeof module !== 'undefined' && module['exports']) {
20495
+ module['exports'] = RSVP;
20496
+ } else if (typeof _rsvpPlatform.default !== 'undefined') {
20497
+ _rsvpPlatform.default['RSVP'] = RSVP;
20498
+ }
20499
+ });
20415
20500
  enifed('rsvp/-internal', ['exports', 'rsvp/utils', 'rsvp/instrument', 'rsvp/config'], function (exports, _rsvpUtils, _rsvpInstrument, _rsvpConfig) {
20416
20501
  'use strict';
20417
20502
 
@@ -22061,281 +22146,24 @@ enifed('rsvp/platform', ['exports'], function (exports) {
22061
22146
 
22062
22147
  exports.default = platform;
22063
22148
  });
22064
- enifed('rsvp/promise/all', ['exports', 'rsvp/enumerator'], function (exports, _rsvpEnumerator) {
22149
+ enifed('rsvp/promise-hash', ['exports', 'rsvp/enumerator', 'rsvp/-internal', 'rsvp/utils'], function (exports, _rsvpEnumerator, _rsvpInternal, _rsvpUtils) {
22065
22150
  'use strict';
22066
22151
 
22067
- exports.default = all;
22152
+ function PromiseHash(Constructor, object, label) {
22153
+ this._superConstructor(Constructor, object, true, label);
22154
+ }
22068
22155
 
22069
- /**
22070
- `RSVP.Promise.all` accepts an array of promises, and returns a new promise which
22071
- is fulfilled with an array of fulfillment values for the passed promises, or
22072
- rejected with the reason of the first passed promise to be rejected. It casts all
22073
- elements of the passed iterable to promises as it runs this algorithm.
22074
-
22075
- Example:
22076
-
22077
- ```javascript
22078
- var promise1 = RSVP.resolve(1);
22079
- var promise2 = RSVP.resolve(2);
22080
- var promise3 = RSVP.resolve(3);
22081
- var promises = [ promise1, promise2, promise3 ];
22082
-
22083
- RSVP.Promise.all(promises).then(function(array){
22084
- // The array here would be [ 1, 2, 3 ];
22085
- });
22086
- ```
22087
-
22088
- If any of the `promises` given to `RSVP.all` are rejected, the first promise
22089
- that is rejected will be given as an argument to the returned promises's
22090
- rejection handler. For example:
22091
-
22092
- Example:
22093
-
22094
- ```javascript
22095
- var promise1 = RSVP.resolve(1);
22096
- var promise2 = RSVP.reject(new Error("2"));
22097
- var promise3 = RSVP.reject(new Error("3"));
22098
- var promises = [ promise1, promise2, promise3 ];
22099
-
22100
- RSVP.Promise.all(promises).then(function(array){
22101
- // Code here never runs because there are rejected promises!
22102
- }, function(error) {
22103
- // error.message === "2"
22104
- });
22105
- ```
22106
-
22107
- @method all
22108
- @static
22109
- @param {Array} entries array of promises
22110
- @param {String} label optional string for labeling the promise.
22111
- Useful for tooling.
22112
- @return {Promise} promise that is fulfilled when all `promises` have been
22113
- fulfilled, or rejected if any of them become rejected.
22114
- @static
22115
- */
22156
+ exports.default = PromiseHash;
22116
22157
 
22117
- function all(entries, label) {
22118
- return new _rsvpEnumerator.default(this, entries, true, /* abort on reject */label).promise;
22119
- }
22120
- });
22121
- enifed('rsvp/promise/race', ['exports', 'rsvp/utils', 'rsvp/-internal'], function (exports, _rsvpUtils, _rsvpInternal) {
22122
- 'use strict';
22158
+ PromiseHash.prototype = _rsvpUtils.o_create(_rsvpEnumerator.default.prototype);
22159
+ PromiseHash.prototype._superConstructor = _rsvpEnumerator.default;
22160
+ PromiseHash.prototype._init = function () {
22161
+ this._result = {};
22162
+ };
22123
22163
 
22124
- exports.default = race;
22125
-
22126
- /**
22127
- `RSVP.Promise.race` returns a new promise which is settled in the same way as the
22128
- first passed promise to settle.
22129
-
22130
- Example:
22131
-
22132
- ```javascript
22133
- var promise1 = new RSVP.Promise(function(resolve, reject){
22134
- setTimeout(function(){
22135
- resolve('promise 1');
22136
- }, 200);
22137
- });
22138
-
22139
- var promise2 = new RSVP.Promise(function(resolve, reject){
22140
- setTimeout(function(){
22141
- resolve('promise 2');
22142
- }, 100);
22143
- });
22144
-
22145
- RSVP.Promise.race([promise1, promise2]).then(function(result){
22146
- // result === 'promise 2' because it was resolved before promise1
22147
- // was resolved.
22148
- });
22149
- ```
22150
-
22151
- `RSVP.Promise.race` is deterministic in that only the state of the first
22152
- settled promise matters. For example, even if other promises given to the
22153
- `promises` array argument are resolved, but the first settled promise has
22154
- become rejected before the other promises became fulfilled, the returned
22155
- promise will become rejected:
22156
-
22157
- ```javascript
22158
- var promise1 = new RSVP.Promise(function(resolve, reject){
22159
- setTimeout(function(){
22160
- resolve('promise 1');
22161
- }, 200);
22162
- });
22163
-
22164
- var promise2 = new RSVP.Promise(function(resolve, reject){
22165
- setTimeout(function(){
22166
- reject(new Error('promise 2'));
22167
- }, 100);
22168
- });
22169
-
22170
- RSVP.Promise.race([promise1, promise2]).then(function(result){
22171
- // Code here never runs
22172
- }, function(reason){
22173
- // reason.message === 'promise 2' because promise 2 became rejected before
22174
- // promise 1 became fulfilled
22175
- });
22176
- ```
22177
-
22178
- An example real-world use case is implementing timeouts:
22179
-
22180
- ```javascript
22181
- RSVP.Promise.race([ajax('foo.json'), timeout(5000)])
22182
- ```
22183
-
22184
- @method race
22185
- @static
22186
- @param {Array} entries array of promises to observe
22187
- @param {String} label optional string for describing the promise returned.
22188
- Useful for tooling.
22189
- @return {Promise} a promise which settles in the same way as the first passed
22190
- promise to settle.
22191
- */
22192
-
22193
- function race(entries, label) {
22194
- /*jshint validthis:true */
22195
- var Constructor = this;
22196
-
22197
- var promise = new Constructor(_rsvpInternal.noop, label);
22198
-
22199
- if (!_rsvpUtils.isArray(entries)) {
22200
- _rsvpInternal.reject(promise, new TypeError('You must pass an array to race.'));
22201
- return promise;
22202
- }
22203
-
22204
- var length = entries.length;
22205
-
22206
- function onFulfillment(value) {
22207
- _rsvpInternal.resolve(promise, value);
22208
- }
22209
-
22210
- function onRejection(reason) {
22211
- _rsvpInternal.reject(promise, reason);
22212
- }
22213
-
22214
- for (var i = 0; promise._state === _rsvpInternal.PENDING && i < length; i++) {
22215
- _rsvpInternal.subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
22216
- }
22217
-
22218
- return promise;
22219
- }
22220
- });
22221
- enifed('rsvp/promise/reject', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
22222
- 'use strict';
22223
-
22224
- exports.default = reject;
22225
-
22226
- /**
22227
- `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
22228
- It is shorthand for the following:
22229
-
22230
- ```javascript
22231
- var promise = new RSVP.Promise(function(resolve, reject){
22232
- reject(new Error('WHOOPS'));
22233
- });
22234
-
22235
- promise.then(function(value){
22236
- // Code here doesn't run because the promise is rejected!
22237
- }, function(reason){
22238
- // reason.message === 'WHOOPS'
22239
- });
22240
- ```
22241
-
22242
- Instead of writing the above, your code now simply becomes the following:
22243
-
22244
- ```javascript
22245
- var promise = RSVP.Promise.reject(new Error('WHOOPS'));
22246
-
22247
- promise.then(function(value){
22248
- // Code here doesn't run because the promise is rejected!
22249
- }, function(reason){
22250
- // reason.message === 'WHOOPS'
22251
- });
22252
- ```
22253
-
22254
- @method reject
22255
- @static
22256
- @param {*} reason value that the returned promise will be rejected with.
22257
- @param {String} label optional string for identifying the returned promise.
22258
- Useful for tooling.
22259
- @return {Promise} a promise rejected with the given `reason`.
22260
- */
22261
-
22262
- function reject(reason, label) {
22263
- /*jshint validthis:true */
22264
- var Constructor = this;
22265
- var promise = new Constructor(_rsvpInternal.noop, label);
22266
- _rsvpInternal.reject(promise, reason);
22267
- return promise;
22268
- }
22269
- });
22270
- enifed('rsvp/promise/resolve', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
22271
- 'use strict';
22272
-
22273
- exports.default = resolve;
22274
-
22275
- /**
22276
- `RSVP.Promise.resolve` returns a promise that will become resolved with the
22277
- passed `value`. It is shorthand for the following:
22278
-
22279
- ```javascript
22280
- var promise = new RSVP.Promise(function(resolve, reject){
22281
- resolve(1);
22282
- });
22283
-
22284
- promise.then(function(value){
22285
- // value === 1
22286
- });
22287
- ```
22288
-
22289
- Instead of writing the above, your code now simply becomes the following:
22290
-
22291
- ```javascript
22292
- var promise = RSVP.Promise.resolve(1);
22293
-
22294
- promise.then(function(value){
22295
- // value === 1
22296
- });
22297
- ```
22298
-
22299
- @method resolve
22300
- @static
22301
- @param {*} object value that the returned promise will be resolved with
22302
- @param {String} label optional string for identifying the returned promise.
22303
- Useful for tooling.
22304
- @return {Promise} a promise that will become fulfilled with the given
22305
- `value`
22306
- */
22307
-
22308
- function resolve(object, label) {
22309
- /*jshint validthis:true */
22310
- var Constructor = this;
22311
-
22312
- if (object && typeof object === 'object' && object.constructor === Constructor) {
22313
- return object;
22314
- }
22315
-
22316
- var promise = new Constructor(_rsvpInternal.noop, label);
22317
- _rsvpInternal.resolve(promise, object);
22318
- return promise;
22319
- }
22320
- });
22321
- enifed('rsvp/promise-hash', ['exports', 'rsvp/enumerator', 'rsvp/-internal', 'rsvp/utils'], function (exports, _rsvpEnumerator, _rsvpInternal, _rsvpUtils) {
22322
- 'use strict';
22323
-
22324
- function PromiseHash(Constructor, object, label) {
22325
- this._superConstructor(Constructor, object, true, label);
22326
- }
22327
-
22328
- exports.default = PromiseHash;
22329
-
22330
- PromiseHash.prototype = _rsvpUtils.o_create(_rsvpEnumerator.default.prototype);
22331
- PromiseHash.prototype._superConstructor = _rsvpEnumerator.default;
22332
- PromiseHash.prototype._init = function () {
22333
- this._result = {};
22334
- };
22335
-
22336
- PromiseHash.prototype._validateInput = function (input) {
22337
- return input && typeof input === 'object';
22338
- };
22164
+ PromiseHash.prototype._validateInput = function (input) {
22165
+ return input && typeof input === 'object';
22166
+ };
22339
22167
 
22340
22168
  PromiseHash.prototype._validationError = function () {
22341
22169
  return new Error('Promise.hash must be called with an object');
@@ -22747,105 +22575,362 @@ enifed('rsvp/promise', ['exports', 'rsvp/config', 'rsvp/instrument', 'rsvp/utils
22747
22575
  _rsvpInstrument.default('chained', parent, child);
22748
22576
  }
22749
22577
 
22750
- if (state) {
22751
- var callback = arguments[state - 1];
22752
- _rsvpConfig.config.async(function () {
22753
- _rsvpInternal.invokeCallback(state, child, callback, result);
22754
- });
22755
- } else {
22756
- _rsvpInternal.subscribe(parent, child, onFulfillment, onRejection);
22757
- }
22578
+ if (state) {
22579
+ var callback = arguments[state - 1];
22580
+ _rsvpConfig.config.async(function () {
22581
+ _rsvpInternal.invokeCallback(state, child, callback, result);
22582
+ });
22583
+ } else {
22584
+ _rsvpInternal.subscribe(parent, child, onFulfillment, onRejection);
22585
+ }
22586
+
22587
+ return child;
22588
+ },
22589
+
22590
+ /**
22591
+ `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
22592
+ as the catch block of a try/catch statement.
22593
+
22594
+ ```js
22595
+ function findAuthor(){
22596
+ throw new Error('couldn't find that author');
22597
+ }
22598
+
22599
+ // synchronous
22600
+ try {
22601
+ findAuthor();
22602
+ } catch(reason) {
22603
+ // something went wrong
22604
+ }
22605
+
22606
+ // async with promises
22607
+ findAuthor().catch(function(reason){
22608
+ // something went wrong
22609
+ });
22610
+ ```
22611
+
22612
+ @method catch
22613
+ @param {Function} onRejection
22614
+ @param {String} label optional string for labeling the promise.
22615
+ Useful for tooling.
22616
+ @return {Promise}
22617
+ */
22618
+ 'catch': function (onRejection, label) {
22619
+ return this.then(undefined, onRejection, label);
22620
+ },
22621
+
22622
+ /**
22623
+ `finally` will be invoked regardless of the promise's fate just as native
22624
+ try/catch/finally behaves
22625
+
22626
+ Synchronous example:
22627
+
22628
+ ```js
22629
+ findAuthor() {
22630
+ if (Math.random() > 0.5) {
22631
+ throw new Error();
22632
+ }
22633
+ return new Author();
22634
+ }
22635
+
22636
+ try {
22637
+ return findAuthor(); // succeed or fail
22638
+ } catch(error) {
22639
+ return findOtherAuther();
22640
+ } finally {
22641
+ // always runs
22642
+ // doesn't affect the return value
22643
+ }
22644
+ ```
22645
+
22646
+ Asynchronous example:
22647
+
22648
+ ```js
22649
+ findAuthor().catch(function(reason){
22650
+ return findOtherAuther();
22651
+ }).finally(function(){
22652
+ // author was either found, or not
22653
+ });
22654
+ ```
22655
+
22656
+ @method finally
22657
+ @param {Function} callback
22658
+ @param {String} label optional string for labeling the promise.
22659
+ Useful for tooling.
22660
+ @return {Promise}
22661
+ */
22662
+ 'finally': function (callback, label) {
22663
+ var promise = this;
22664
+ var constructor = promise.constructor;
22665
+
22666
+ return promise.then(function (value) {
22667
+ return constructor.resolve(callback()).then(function () {
22668
+ return value;
22669
+ });
22670
+ }, function (reason) {
22671
+ return constructor.resolve(callback()).then(function () {
22672
+ throw reason;
22673
+ });
22674
+ }, label);
22675
+ }
22676
+ };
22677
+ });
22678
+ enifed('rsvp/promise/all', ['exports', 'rsvp/enumerator'], function (exports, _rsvpEnumerator) {
22679
+ 'use strict';
22680
+
22681
+ exports.default = all;
22682
+
22683
+ /**
22684
+ `RSVP.Promise.all` accepts an array of promises, and returns a new promise which
22685
+ is fulfilled with an array of fulfillment values for the passed promises, or
22686
+ rejected with the reason of the first passed promise to be rejected. It casts all
22687
+ elements of the passed iterable to promises as it runs this algorithm.
22688
+
22689
+ Example:
22690
+
22691
+ ```javascript
22692
+ var promise1 = RSVP.resolve(1);
22693
+ var promise2 = RSVP.resolve(2);
22694
+ var promise3 = RSVP.resolve(3);
22695
+ var promises = [ promise1, promise2, promise3 ];
22696
+
22697
+ RSVP.Promise.all(promises).then(function(array){
22698
+ // The array here would be [ 1, 2, 3 ];
22699
+ });
22700
+ ```
22701
+
22702
+ If any of the `promises` given to `RSVP.all` are rejected, the first promise
22703
+ that is rejected will be given as an argument to the returned promises's
22704
+ rejection handler. For example:
22705
+
22706
+ Example:
22707
+
22708
+ ```javascript
22709
+ var promise1 = RSVP.resolve(1);
22710
+ var promise2 = RSVP.reject(new Error("2"));
22711
+ var promise3 = RSVP.reject(new Error("3"));
22712
+ var promises = [ promise1, promise2, promise3 ];
22713
+
22714
+ RSVP.Promise.all(promises).then(function(array){
22715
+ // Code here never runs because there are rejected promises!
22716
+ }, function(error) {
22717
+ // error.message === "2"
22718
+ });
22719
+ ```
22720
+
22721
+ @method all
22722
+ @static
22723
+ @param {Array} entries array of promises
22724
+ @param {String} label optional string for labeling the promise.
22725
+ Useful for tooling.
22726
+ @return {Promise} promise that is fulfilled when all `promises` have been
22727
+ fulfilled, or rejected if any of them become rejected.
22728
+ @static
22729
+ */
22730
+
22731
+ function all(entries, label) {
22732
+ return new _rsvpEnumerator.default(this, entries, true, /* abort on reject */label).promise;
22733
+ }
22734
+ });
22735
+ enifed('rsvp/promise/race', ['exports', 'rsvp/utils', 'rsvp/-internal'], function (exports, _rsvpUtils, _rsvpInternal) {
22736
+ 'use strict';
22737
+
22738
+ exports.default = race;
22739
+
22740
+ /**
22741
+ `RSVP.Promise.race` returns a new promise which is settled in the same way as the
22742
+ first passed promise to settle.
22743
+
22744
+ Example:
22745
+
22746
+ ```javascript
22747
+ var promise1 = new RSVP.Promise(function(resolve, reject){
22748
+ setTimeout(function(){
22749
+ resolve('promise 1');
22750
+ }, 200);
22751
+ });
22752
+
22753
+ var promise2 = new RSVP.Promise(function(resolve, reject){
22754
+ setTimeout(function(){
22755
+ resolve('promise 2');
22756
+ }, 100);
22757
+ });
22758
+
22759
+ RSVP.Promise.race([promise1, promise2]).then(function(result){
22760
+ // result === 'promise 2' because it was resolved before promise1
22761
+ // was resolved.
22762
+ });
22763
+ ```
22764
+
22765
+ `RSVP.Promise.race` is deterministic in that only the state of the first
22766
+ settled promise matters. For example, even if other promises given to the
22767
+ `promises` array argument are resolved, but the first settled promise has
22768
+ become rejected before the other promises became fulfilled, the returned
22769
+ promise will become rejected:
22770
+
22771
+ ```javascript
22772
+ var promise1 = new RSVP.Promise(function(resolve, reject){
22773
+ setTimeout(function(){
22774
+ resolve('promise 1');
22775
+ }, 200);
22776
+ });
22777
+
22778
+ var promise2 = new RSVP.Promise(function(resolve, reject){
22779
+ setTimeout(function(){
22780
+ reject(new Error('promise 2'));
22781
+ }, 100);
22782
+ });
22783
+
22784
+ RSVP.Promise.race([promise1, promise2]).then(function(result){
22785
+ // Code here never runs
22786
+ }, function(reason){
22787
+ // reason.message === 'promise 2' because promise 2 became rejected before
22788
+ // promise 1 became fulfilled
22789
+ });
22790
+ ```
22791
+
22792
+ An example real-world use case is implementing timeouts:
22793
+
22794
+ ```javascript
22795
+ RSVP.Promise.race([ajax('foo.json'), timeout(5000)])
22796
+ ```
22797
+
22798
+ @method race
22799
+ @static
22800
+ @param {Array} entries array of promises to observe
22801
+ @param {String} label optional string for describing the promise returned.
22802
+ Useful for tooling.
22803
+ @return {Promise} a promise which settles in the same way as the first passed
22804
+ promise to settle.
22805
+ */
22806
+
22807
+ function race(entries, label) {
22808
+ /*jshint validthis:true */
22809
+ var Constructor = this;
22810
+
22811
+ var promise = new Constructor(_rsvpInternal.noop, label);
22812
+
22813
+ if (!_rsvpUtils.isArray(entries)) {
22814
+ _rsvpInternal.reject(promise, new TypeError('You must pass an array to race.'));
22815
+ return promise;
22816
+ }
22817
+
22818
+ var length = entries.length;
22819
+
22820
+ function onFulfillment(value) {
22821
+ _rsvpInternal.resolve(promise, value);
22822
+ }
22823
+
22824
+ function onRejection(reason) {
22825
+ _rsvpInternal.reject(promise, reason);
22826
+ }
22827
+
22828
+ for (var i = 0; promise._state === _rsvpInternal.PENDING && i < length; i++) {
22829
+ _rsvpInternal.subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
22830
+ }
22831
+
22832
+ return promise;
22833
+ }
22834
+ });
22835
+ enifed('rsvp/promise/reject', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
22836
+ 'use strict';
22837
+
22838
+ exports.default = reject;
22839
+
22840
+ /**
22841
+ `RSVP.Promise.reject` returns a promise rejected with the passed `reason`.
22842
+ It is shorthand for the following:
22843
+
22844
+ ```javascript
22845
+ var promise = new RSVP.Promise(function(resolve, reject){
22846
+ reject(new Error('WHOOPS'));
22847
+ });
22848
+
22849
+ promise.then(function(value){
22850
+ // Code here doesn't run because the promise is rejected!
22851
+ }, function(reason){
22852
+ // reason.message === 'WHOOPS'
22853
+ });
22854
+ ```
22855
+
22856
+ Instead of writing the above, your code now simply becomes the following:
22857
+
22858
+ ```javascript
22859
+ var promise = RSVP.Promise.reject(new Error('WHOOPS'));
22860
+
22861
+ promise.then(function(value){
22862
+ // Code here doesn't run because the promise is rejected!
22863
+ }, function(reason){
22864
+ // reason.message === 'WHOOPS'
22865
+ });
22866
+ ```
22867
+
22868
+ @method reject
22869
+ @static
22870
+ @param {*} reason value that the returned promise will be rejected with.
22871
+ @param {String} label optional string for identifying the returned promise.
22872
+ Useful for tooling.
22873
+ @return {Promise} a promise rejected with the given `reason`.
22874
+ */
22875
+
22876
+ function reject(reason, label) {
22877
+ /*jshint validthis:true */
22878
+ var Constructor = this;
22879
+ var promise = new Constructor(_rsvpInternal.noop, label);
22880
+ _rsvpInternal.reject(promise, reason);
22881
+ return promise;
22882
+ }
22883
+ });
22884
+ enifed('rsvp/promise/resolve', ['exports', 'rsvp/-internal'], function (exports, _rsvpInternal) {
22885
+ 'use strict';
22758
22886
 
22759
- return child;
22760
- },
22887
+ exports.default = resolve;
22761
22888
 
22762
- /**
22763
- `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
22764
- as the catch block of a try/catch statement.
22765
-
22766
- ```js
22767
- function findAuthor(){
22768
- throw new Error('couldn't find that author');
22769
- }
22770
-
22771
- // synchronous
22772
- try {
22773
- findAuthor();
22774
- } catch(reason) {
22775
- // something went wrong
22776
- }
22777
-
22778
- // async with promises
22779
- findAuthor().catch(function(reason){
22780
- // something went wrong
22781
- });
22782
- ```
22783
-
22784
- @method catch
22785
- @param {Function} onRejection
22786
- @param {String} label optional string for labeling the promise.
22787
- Useful for tooling.
22788
- @return {Promise}
22789
- */
22790
- 'catch': function (onRejection, label) {
22791
- return this.then(undefined, onRejection, label);
22792
- },
22889
+ /**
22890
+ `RSVP.Promise.resolve` returns a promise that will become resolved with the
22891
+ passed `value`. It is shorthand for the following:
22892
+
22893
+ ```javascript
22894
+ var promise = new RSVP.Promise(function(resolve, reject){
22895
+ resolve(1);
22896
+ });
22897
+
22898
+ promise.then(function(value){
22899
+ // value === 1
22900
+ });
22901
+ ```
22902
+
22903
+ Instead of writing the above, your code now simply becomes the following:
22904
+
22905
+ ```javascript
22906
+ var promise = RSVP.Promise.resolve(1);
22907
+
22908
+ promise.then(function(value){
22909
+ // value === 1
22910
+ });
22911
+ ```
22912
+
22913
+ @method resolve
22914
+ @static
22915
+ @param {*} object value that the returned promise will be resolved with
22916
+ @param {String} label optional string for identifying the returned promise.
22917
+ Useful for tooling.
22918
+ @return {Promise} a promise that will become fulfilled with the given
22919
+ `value`
22920
+ */
22793
22921
 
22794
- /**
22795
- `finally` will be invoked regardless of the promise's fate just as native
22796
- try/catch/finally behaves
22797
-
22798
- Synchronous example:
22799
-
22800
- ```js
22801
- findAuthor() {
22802
- if (Math.random() > 0.5) {
22803
- throw new Error();
22804
- }
22805
- return new Author();
22806
- }
22807
-
22808
- try {
22809
- return findAuthor(); // succeed or fail
22810
- } catch(error) {
22811
- return findOtherAuther();
22812
- } finally {
22813
- // always runs
22814
- // doesn't affect the return value
22815
- }
22816
- ```
22817
-
22818
- Asynchronous example:
22819
-
22820
- ```js
22821
- findAuthor().catch(function(reason){
22822
- return findOtherAuther();
22823
- }).finally(function(){
22824
- // author was either found, or not
22825
- });
22826
- ```
22827
-
22828
- @method finally
22829
- @param {Function} callback
22830
- @param {String} label optional string for labeling the promise.
22831
- Useful for tooling.
22832
- @return {Promise}
22833
- */
22834
- 'finally': function (callback, label) {
22835
- var promise = this;
22836
- var constructor = promise.constructor;
22922
+ function resolve(object, label) {
22923
+ /*jshint validthis:true */
22924
+ var Constructor = this;
22837
22925
 
22838
- return promise.then(function (value) {
22839
- return constructor.resolve(callback()).then(function () {
22840
- return value;
22841
- });
22842
- }, function (reason) {
22843
- return constructor.resolve(callback()).then(function () {
22844
- throw reason;
22845
- });
22846
- }, label);
22926
+ if (object && typeof object === 'object' && object.constructor === Constructor) {
22927
+ return object;
22847
22928
  }
22848
- };
22929
+
22930
+ var promise = new Constructor(_rsvpInternal.noop, label);
22931
+ _rsvpInternal.resolve(promise, object);
22932
+ return promise;
22933
+ }
22849
22934
  });
22850
22935
  enifed('rsvp/race', ['exports', 'rsvp/promise'], function (exports, _rsvpPromise) {
22851
22936
  'use strict';
@@ -23014,93 +23099,6 @@ enifed('rsvp/utils', ['exports'], function (exports) {
23014
23099
  };
23015
23100
  exports.o_create = o_create;
23016
23101
  });
23017
- enifed('rsvp', ['exports', 'rsvp/promise', 'rsvp/events', 'rsvp/node', 'rsvp/all', 'rsvp/all-settled', 'rsvp/race', 'rsvp/hash', 'rsvp/hash-settled', 'rsvp/rethrow', 'rsvp/defer', 'rsvp/config', 'rsvp/map', 'rsvp/resolve', 'rsvp/reject', 'rsvp/filter', 'rsvp/asap'], function (exports, _rsvpPromise, _rsvpEvents, _rsvpNode, _rsvpAll, _rsvpAllSettled, _rsvpRace, _rsvpHash, _rsvpHashSettled, _rsvpRethrow, _rsvpDefer, _rsvpConfig, _rsvpMap, _rsvpResolve, _rsvpReject, _rsvpFilter, _rsvpAsap) {
23018
- 'use strict';
23019
-
23020
- // defaults
23021
- _rsvpConfig.config.async = _rsvpAsap.default;
23022
- _rsvpConfig.config.after = function (cb) {
23023
- setTimeout(cb, 0);
23024
- };
23025
- var cast = _rsvpResolve.default;
23026
- function async(callback, arg) {
23027
- _rsvpConfig.config.async(callback, arg);
23028
- }
23029
-
23030
- function on() {
23031
- _rsvpConfig.config['on'].apply(_rsvpConfig.config, arguments);
23032
- }
23033
-
23034
- function off() {
23035
- _rsvpConfig.config['off'].apply(_rsvpConfig.config, arguments);
23036
- }
23037
-
23038
- // Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
23039
- if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
23040
- var callbacks = window['__PROMISE_INSTRUMENTATION__'];
23041
- _rsvpConfig.configure('instrument', true);
23042
- for (var eventName in callbacks) {
23043
- if (callbacks.hasOwnProperty(eventName)) {
23044
- on(eventName, callbacks[eventName]);
23045
- }
23046
- }
23047
- }
23048
-
23049
- exports.cast = cast;
23050
- exports.Promise = _rsvpPromise.default;
23051
- exports.EventTarget = _rsvpEvents.default;
23052
- exports.all = _rsvpAll.default;
23053
- exports.allSettled = _rsvpAllSettled.default;
23054
- exports.race = _rsvpRace.default;
23055
- exports.hash = _rsvpHash.default;
23056
- exports.hashSettled = _rsvpHashSettled.default;
23057
- exports.rethrow = _rsvpRethrow.default;
23058
- exports.defer = _rsvpDefer.default;
23059
- exports.denodeify = _rsvpNode.default;
23060
- exports.configure = _rsvpConfig.configure;
23061
- exports.on = on;
23062
- exports.off = off;
23063
- exports.resolve = _rsvpResolve.default;
23064
- exports.reject = _rsvpReject.default;
23065
- exports.async = async;
23066
- exports.map = _rsvpMap.default;
23067
- exports.filter = _rsvpFilter.default;
23068
- });
23069
- enifed('rsvp.umd', ['exports', 'rsvp/platform', 'rsvp'], function (exports, _rsvpPlatform, _rsvp) {
23070
- 'use strict';
23071
-
23072
- var RSVP = {
23073
- 'race': _rsvp.race,
23074
- 'Promise': _rsvp.Promise,
23075
- 'allSettled': _rsvp.allSettled,
23076
- 'hash': _rsvp.hash,
23077
- 'hashSettled': _rsvp.hashSettled,
23078
- 'denodeify': _rsvp.denodeify,
23079
- 'on': _rsvp.on,
23080
- 'off': _rsvp.off,
23081
- 'map': _rsvp.map,
23082
- 'filter': _rsvp.filter,
23083
- 'resolve': _rsvp.resolve,
23084
- 'reject': _rsvp.reject,
23085
- 'all': _rsvp.all,
23086
- 'rethrow': _rsvp.rethrow,
23087
- 'defer': _rsvp.defer,
23088
- 'EventTarget': _rsvp.EventTarget,
23089
- 'configure': _rsvp.configure,
23090
- 'async': _rsvp.async
23091
- };
23092
-
23093
- /* global define:true module:true window: true */
23094
- if (typeof define === 'function' && define['amd']) {
23095
- define(function () {
23096
- return RSVP;
23097
- });
23098
- } else if (typeof module !== 'undefined' && module['exports']) {
23099
- module['exports'] = RSVP;
23100
- } else if (typeof _rsvpPlatform.default !== 'undefined') {
23101
- _rsvpPlatform.default['RSVP'] = RSVP;
23102
- }
23103
- });
23104
23102
  requireModule("ember-runtime");
23105
23103
 
23106
23104
  }());