ember-source 2.7.0.beta.3 → 2.7.0.beta.4

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.
@@ -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.7.0-beta.3
9
+ * @version 2.7.0-beta.4
10
10
  */
11
11
 
12
12
  var enifed, requireModule, require, Ember;
@@ -112,1057 +112,1047 @@ var mainContext = this;
112
112
  }
113
113
  })();
114
114
 
115
- enifed("backburner/binary-search", ["exports"], function (exports) {
116
- "use strict";
115
+ enifed('backburner', ['exports', 'backburner/utils', 'backburner/platform', 'backburner/binary-search', 'backburner/deferred-action-queues'], function (exports, _backburnerUtils, _backburnerPlatform, _backburnerBinarySearch, _backburnerDeferredActionQueues) {
116
+ 'use strict';
117
117
 
118
- exports.default = binarySearch;
118
+ exports.default = Backburner;
119
119
 
120
- function binarySearch(time, timers) {
121
- var start = 0;
122
- var end = timers.length - 2;
123
- var middle, l;
120
+ function Backburner(queueNames, options) {
121
+ this.queueNames = queueNames;
122
+ this.options = options || {};
123
+ if (!this.options.defaultQueue) {
124
+ this.options.defaultQueue = queueNames[0];
125
+ }
126
+ this.instanceStack = [];
127
+ this._debouncees = [];
128
+ this._throttlers = [];
129
+ this._eventCallbacks = {
130
+ end: [],
131
+ begin: []
132
+ };
124
133
 
125
- while (start < end) {
126
- // since timers is an array of pairs 'l' will always
127
- // be an integer
128
- l = (end - start) / 2;
134
+ var _this = this;
135
+ this._boundClearItems = function () {
136
+ clearItems();
137
+ };
129
138
 
130
- // compensate for the index in case even number
131
- // of pairs inside timers
132
- middle = start + l - l % 2;
139
+ this._timerTimeoutId = undefined;
140
+ this._timers = [];
133
141
 
134
- if (time >= timers[middle]) {
135
- start = middle + 2;
136
- } else {
137
- end = middle;
138
- }
139
- }
142
+ this._platform = this.options._platform || _backburnerPlatform.default;
140
143
 
141
- return time >= timers[start] ? start + 2 : start;
144
+ this._boundRunExpiredTimers = function () {
145
+ _this._runExpiredTimers();
146
+ };
142
147
  }
143
- });
144
- enifed('backburner/deferred-action-queues', ['exports', 'backburner/utils', 'backburner/queue'], function (exports, _backburnerUtils, _backburnerQueue) {
145
- 'use strict';
146
-
147
- exports.default = DeferredActionQueues;
148
148
 
149
- function DeferredActionQueues(queueNames, options) {
150
- var queues = this.queues = {};
151
- this.queueNames = queueNames = queueNames || [];
149
+ Backburner.prototype = {
150
+ begin: function () {
151
+ var options = this.options;
152
+ var onBegin = options && options.onBegin;
153
+ var previousInstance = this.currentInstance;
152
154
 
153
- this.options = options;
155
+ if (previousInstance) {
156
+ this.instanceStack.push(previousInstance);
157
+ }
154
158
 
155
- _backburnerUtils.each(queueNames, function (queueName) {
156
- queues[queueName] = new _backburnerQueue.default(queueName, options[queueName], options);
157
- });
158
- }
159
+ this.currentInstance = new _backburnerDeferredActionQueues.default(this.queueNames, options);
160
+ this._trigger('begin', this.currentInstance, previousInstance);
161
+ if (onBegin) {
162
+ onBegin(this.currentInstance, previousInstance);
163
+ }
164
+ },
159
165
 
160
- function noSuchQueue(name) {
161
- throw new Error('You attempted to schedule an action in a queue (' + name + ') that doesn\'t exist');
162
- }
166
+ end: function () {
167
+ var options = this.options;
168
+ var onEnd = options && options.onEnd;
169
+ var currentInstance = this.currentInstance;
170
+ var nextInstance = null;
163
171
 
164
- function noSuchMethod(name) {
165
- throw new Error('You attempted to schedule an action in a queue (' + name + ') for a method that doesn\'t exist');
166
- }
172
+ // Prevent double-finally bug in Safari 6.0.2 and iOS 6
173
+ // This bug appears to be resolved in Safari 6.0.5 and iOS 7
174
+ var finallyAlreadyCalled = false;
175
+ try {
176
+ currentInstance.flush();
177
+ } finally {
178
+ if (!finallyAlreadyCalled) {
179
+ finallyAlreadyCalled = true;
167
180
 
168
- DeferredActionQueues.prototype = {
169
- schedule: function (name, target, method, args, onceFlag, stack) {
170
- var queues = this.queues;
171
- var queue = queues[name];
181
+ this.currentInstance = null;
172
182
 
173
- if (!queue) {
174
- noSuchQueue(name);
183
+ if (this.instanceStack.length) {
184
+ nextInstance = this.instanceStack.pop();
185
+ this.currentInstance = nextInstance;
186
+ }
187
+ this._trigger('end', currentInstance, nextInstance);
188
+ if (onEnd) {
189
+ onEnd(currentInstance, nextInstance);
190
+ }
191
+ }
175
192
  }
193
+ },
176
194
 
177
- if (!method) {
178
- noSuchMethod(name);
195
+ /**
196
+ Trigger an event. Supports up to two arguments. Designed around
197
+ triggering transition events from one run loop instance to the
198
+ next, which requires an argument for the first instance and then
199
+ an argument for the next instance.
200
+ @private
201
+ @method _trigger
202
+ @param {String} eventName
203
+ @param {any} arg1
204
+ @param {any} arg2
205
+ */
206
+ _trigger: function (eventName, arg1, arg2) {
207
+ var callbacks = this._eventCallbacks[eventName];
208
+ if (callbacks) {
209
+ for (var i = 0; i < callbacks.length; i++) {
210
+ callbacks[i](arg1, arg2);
211
+ }
179
212
  }
213
+ },
180
214
 
181
- if (onceFlag) {
182
- return queue.pushUnique(target, method, args, stack);
215
+ on: function (eventName, callback) {
216
+ if (typeof callback !== 'function') {
217
+ throw new TypeError('Callback must be a function');
218
+ }
219
+ var callbacks = this._eventCallbacks[eventName];
220
+ if (callbacks) {
221
+ callbacks.push(callback);
183
222
  } else {
184
- return queue.push(target, method, args, stack);
223
+ throw new TypeError('Cannot on() event "' + eventName + '" because it does not exist');
185
224
  }
186
225
  },
187
226
 
188
- flush: function () {
189
- var queues = this.queues;
190
- var queueNames = this.queueNames;
191
- var queueName, queue;
192
- var queueNameIndex = 0;
193
- var numberOfQueues = queueNames.length;
194
-
195
- while (queueNameIndex < numberOfQueues) {
196
- queueName = queueNames[queueNameIndex];
197
- queue = queues[queueName];
198
-
199
- var numberOfQueueItems = queue._queue.length;
200
-
201
- if (numberOfQueueItems === 0) {
202
- queueNameIndex++;
203
- } else {
204
- queue.flush(false /* async */);
205
- queueNameIndex = 0;
227
+ off: function (eventName, callback) {
228
+ if (eventName) {
229
+ var callbacks = this._eventCallbacks[eventName];
230
+ var callbackFound = false;
231
+ if (!callbacks) return;
232
+ if (callback) {
233
+ for (var i = 0; i < callbacks.length; i++) {
234
+ if (callbacks[i] === callback) {
235
+ callbackFound = true;
236
+ callbacks.splice(i, 1);
237
+ i--;
238
+ }
239
+ }
240
+ }
241
+ if (!callbackFound) {
242
+ throw new TypeError('Cannot off() callback that does not exist');
206
243
  }
244
+ } else {
245
+ throw new TypeError('Cannot off() event "' + eventName + '" because it does not exist');
207
246
  }
208
- }
209
- };
210
- });
211
- enifed('backburner/platform', ['exports'], function (exports) {
212
- 'use strict';
213
-
214
- var GlobalContext;
215
-
216
- /* global self */
217
- if (typeof self === 'object') {
218
- GlobalContext = self;
247
+ },
219
248
 
220
- /* global global */
221
- } else if (typeof global === 'object') {
222
- GlobalContext = global;
249
+ run: function () /* target, method, args */{
250
+ var length = arguments.length;
251
+ var method, target, args;
223
252
 
224
- /* global window */
225
- } else if (typeof window === 'object') {
226
- GlobalContext = window;
253
+ if (length === 1) {
254
+ method = arguments[0];
255
+ target = null;
227
256
  } else {
228
- throw new Error('no global: `self`, `global` nor `window` was found');
257
+ target = arguments[0];
258
+ method = arguments[1];
229
259
  }
230
260
 
231
- exports.default = GlobalContext;
232
- });
233
- enifed('backburner/queue', ['exports', 'backburner/utils'], function (exports, _backburnerUtils) {
234
- 'use strict';
235
-
236
- exports.default = Queue;
237
-
238
- function Queue(name, options, globalOptions) {
239
- this.name = name;
240
- this.globalOptions = globalOptions || {};
241
- this.options = options;
242
- this._queue = [];
243
- this.targetQueues = {};
244
- this._queueBeingFlushed = undefined;
245
- }
261
+ if (_backburnerUtils.isString(method)) {
262
+ method = target[method];
263
+ }
246
264
 
247
- Queue.prototype = {
248
- push: function (target, method, args, stack) {
249
- var queue = this._queue;
250
- queue.push(target, method, args, stack);
265
+ if (length > 2) {
266
+ args = new Array(length - 2);
267
+ for (var i = 0, l = length - 2; i < l; i++) {
268
+ args[i] = arguments[i + 2];
269
+ }
270
+ } else {
271
+ args = [];
272
+ }
251
273
 
252
- return {
253
- queue: this,
254
- target: target,
255
- method: method
256
- };
257
- },
274
+ var onError = getOnError(this.options);
258
275
 
259
- pushUniqueWithoutGuid: function (target, method, args, stack) {
260
- var queue = this._queue;
276
+ this.begin();
261
277
 
262
- for (var i = 0, l = queue.length; i < l; i += 4) {
263
- var currentTarget = queue[i];
264
- var currentMethod = queue[i + 1];
278
+ // guard against Safari 6's double-finally bug
279
+ var didFinally = false;
265
280
 
266
- if (currentTarget === target && currentMethod === method) {
267
- queue[i + 2] = args; // replace args
268
- queue[i + 3] = stack; // replace stack
269
- return;
281
+ if (onError) {
282
+ try {
283
+ return method.apply(target, args);
284
+ } catch (error) {
285
+ onError(error);
286
+ } finally {
287
+ if (!didFinally) {
288
+ didFinally = true;
289
+ this.end();
290
+ }
291
+ }
292
+ } else {
293
+ try {
294
+ return method.apply(target, args);
295
+ } finally {
296
+ if (!didFinally) {
297
+ didFinally = true;
298
+ this.end();
299
+ }
270
300
  }
271
301
  }
272
-
273
- queue.push(target, method, args, stack);
274
302
  },
275
303
 
276
- targetQueue: function (targetQueue, target, method, args, stack) {
277
- var queue = this._queue;
304
+ /*
305
+ Join the passed method with an existing queue and execute immediately,
306
+ if there isn't one use `Backburner#run`.
307
+ The join method is like the run method except that it will schedule into
308
+ an existing queue if one already exists. In either case, the join method will
309
+ immediately execute the passed in function and return its result.
310
+ @method join
311
+ @param {Object} target
312
+ @param {Function} method The method to be executed
313
+ @param {any} args The method arguments
314
+ @return method result
315
+ */
316
+ join: function () /* target, method, args */{
317
+ if (!this.currentInstance) {
318
+ return this.run.apply(this, arguments);
319
+ }
278
320
 
279
- for (var i = 0, l = targetQueue.length; i < l; i += 2) {
280
- var currentMethod = targetQueue[i];
281
- var currentIndex = targetQueue[i + 1];
321
+ var length = arguments.length;
322
+ var method, target;
282
323
 
283
- if (currentMethod === method) {
284
- queue[currentIndex + 2] = args; // replace args
285
- queue[currentIndex + 3] = stack; // replace stack
286
- return;
287
- }
324
+ if (length === 1) {
325
+ method = arguments[0];
326
+ target = null;
327
+ } else {
328
+ target = arguments[0];
329
+ method = arguments[1];
288
330
  }
289
331
 
290
- targetQueue.push(method, queue.push(target, method, args, stack) - 4);
291
- },
292
-
293
- pushUniqueWithGuid: function (guid, target, method, args, stack) {
294
- var hasLocalQueue = this.targetQueues[guid];
332
+ if (_backburnerUtils.isString(method)) {
333
+ method = target[method];
334
+ }
295
335
 
296
- if (hasLocalQueue) {
297
- this.targetQueue(hasLocalQueue, target, method, args, stack);
336
+ if (length === 1) {
337
+ return method();
338
+ } else if (length === 2) {
339
+ return method.call(target);
298
340
  } else {
299
- this.targetQueues[guid] = [method, this._queue.push(target, method, args, stack) - 4];
341
+ var args = new Array(length - 2);
342
+ for (var i = 0, l = length - 2; i < l; i++) {
343
+ args[i] = arguments[i + 2];
344
+ }
345
+ return method.apply(target, args);
300
346
  }
301
-
302
- return {
303
- queue: this,
304
- target: target,
305
- method: method
306
- };
307
347
  },
308
348
 
309
- pushUnique: function (target, method, args, stack) {
310
- var KEY = this.globalOptions.GUID_KEY;
349
+ /*
350
+ Defer the passed function to run inside the specified queue.
351
+ @method defer
352
+ @param {String} queueName
353
+ @param {Object} target
354
+ @param {Function|String} method The method or method name to be executed
355
+ @param {any} args The method arguments
356
+ @return method result
357
+ */
358
+ defer: function (queueName /* , target, method, args */) {
359
+ var length = arguments.length;
360
+ var method, target, args;
311
361
 
312
- if (target && KEY) {
313
- var guid = target[KEY];
314
- if (guid) {
315
- return this.pushUniqueWithGuid(guid, target, method, args, stack);
316
- }
362
+ if (length === 2) {
363
+ method = arguments[1];
364
+ target = null;
365
+ } else {
366
+ target = arguments[1];
367
+ method = arguments[2];
317
368
  }
318
369
 
319
- this.pushUniqueWithoutGuid(target, method, args, stack);
370
+ if (_backburnerUtils.isString(method)) {
371
+ method = target[method];
372
+ }
320
373
 
321
- return {
322
- queue: this,
323
- target: target,
324
- method: method
325
- };
326
- },
374
+ var stack = this.DEBUG ? new Error() : undefined;
327
375
 
328
- invoke: function (target, method, args, _, _errorRecordedForStack) {
329
- if (args && args.length > 0) {
330
- method.apply(target, args);
376
+ if (length > 3) {
377
+ args = new Array(length - 3);
378
+ for (var i = 3; i < length; i++) {
379
+ args[i - 3] = arguments[i];
380
+ }
331
381
  } else {
332
- method.call(target);
382
+ args = undefined;
333
383
  }
334
- },
335
384
 
336
- invokeWithOnError: function (target, method, args, onError, errorRecordedForStack) {
337
- try {
338
- if (args && args.length > 0) {
339
- method.apply(target, args);
340
- } else {
341
- method.call(target);
342
- }
343
- } catch (error) {
344
- onError(error, errorRecordedForStack);
385
+ if (!this.currentInstance) {
386
+ createAutorun(this);
345
387
  }
388
+ return this.currentInstance.schedule(queueName, target, method, args, false, stack);
346
389
  },
347
390
 
348
- flush: function (sync) {
349
- var queue = this._queue;
350
- var length = queue.length;
391
+ deferOnce: function (queueName /* , target, method, args */) {
392
+ var length = arguments.length;
393
+ var method, target, args;
351
394
 
352
- if (length === 0) {
353
- return;
395
+ if (length === 2) {
396
+ method = arguments[1];
397
+ target = null;
398
+ } else {
399
+ target = arguments[1];
400
+ method = arguments[2];
354
401
  }
355
402
 
356
- var globalOptions = this.globalOptions;
357
- var options = this.options;
358
- var before = options && options.before;
359
- var after = options && options.after;
360
- var onError = globalOptions.onError || globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod];
361
- var target, method, args, errorRecordedForStack;
362
- var invoke = onError ? this.invokeWithOnError : this.invoke;
363
-
364
- this.targetQueues = Object.create(null);
365
- var queueItems = this._queueBeingFlushed = this._queue.slice();
366
- this._queue = [];
367
-
368
- if (before) {
369
- before();
403
+ if (_backburnerUtils.isString(method)) {
404
+ method = target[method];
370
405
  }
371
406
 
372
- for (var i = 0; i < length; i += 4) {
373
- target = queueItems[i];
374
- method = queueItems[i + 1];
375
- args = queueItems[i + 2];
376
- errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
377
-
378
- if (_backburnerUtils.isString(method)) {
379
- method = target[method];
380
- }
407
+ var stack = this.DEBUG ? new Error() : undefined;
381
408
 
382
- // method could have been nullified / canceled during flush
383
- if (method) {
384
- //
385
- // ** Attention intrepid developer **
386
- //
387
- // To find out the stack of this task when it was scheduled onto
388
- // the run loop, add the following to your app.js:
389
- //
390
- // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
391
- //
392
- // Once that is in place, when you are at a breakpoint and navigate
393
- // here in the stack explorer, you can look at `errorRecordedForStack.stack`,
394
- // which will be the captured stack when this job was scheduled.
395
- //
396
- invoke(target, method, args, onError, errorRecordedForStack);
409
+ if (length > 3) {
410
+ args = new Array(length - 3);
411
+ for (var i = 3; i < length; i++) {
412
+ args[i - 3] = arguments[i];
397
413
  }
414
+ } else {
415
+ args = undefined;
398
416
  }
399
417
 
400
- if (after) {
401
- after();
418
+ if (!this.currentInstance) {
419
+ createAutorun(this);
402
420
  }
421
+ return this.currentInstance.schedule(queueName, target, method, args, true, stack);
422
+ },
403
423
 
404
- this._queueBeingFlushed = undefined;
424
+ setTimeout: function () {
425
+ var l = arguments.length;
426
+ var args = new Array(l);
405
427
 
406
- if (sync !== false && this._queue.length > 0) {
407
- // check if new items have been added
408
- this.flush(true);
428
+ for (var x = 0; x < l; x++) {
429
+ args[x] = arguments[x];
409
430
  }
410
- },
411
431
 
412
- cancel: function (actionToCancel) {
413
- var queue = this._queue,
414
- currentTarget,
415
- currentMethod,
416
- i,
417
- l;
418
- var target = actionToCancel.target;
419
- var method = actionToCancel.method;
420
- var GUID_KEY = this.globalOptions.GUID_KEY;
432
+ var length = args.length,
433
+ method,
434
+ wait,
435
+ target,
436
+ methodOrTarget,
437
+ methodOrWait,
438
+ methodOrArgs;
421
439
 
422
- if (GUID_KEY && this.targetQueues && target) {
423
- var targetQueue = this.targetQueues[target[GUID_KEY]];
440
+ if (length === 0) {
441
+ return;
442
+ } else if (length === 1) {
443
+ method = args.shift();
444
+ wait = 0;
445
+ } else if (length === 2) {
446
+ methodOrTarget = args[0];
447
+ methodOrWait = args[1];
424
448
 
425
- if (targetQueue) {
426
- for (i = 0, l = targetQueue.length; i < l; i++) {
427
- if (targetQueue[i] === method) {
428
- targetQueue.splice(i, 1);
429
- }
430
- }
449
+ if (_backburnerUtils.isFunction(methodOrWait) || _backburnerUtils.isFunction(methodOrTarget[methodOrWait])) {
450
+ target = args.shift();
451
+ method = args.shift();
452
+ wait = 0;
453
+ } else if (_backburnerUtils.isCoercableNumber(methodOrWait)) {
454
+ method = args.shift();
455
+ wait = args.shift();
456
+ } else {
457
+ method = args.shift();
458
+ wait = 0;
459
+ }
460
+ } else {
461
+ var last = args[args.length - 1];
462
+
463
+ if (_backburnerUtils.isCoercableNumber(last)) {
464
+ wait = args.pop();
465
+ } else {
466
+ wait = 0;
431
467
  }
432
- }
433
468
 
434
- for (i = 0, l = queue.length; i < l; i += 4) {
435
- currentTarget = queue[i];
436
- currentMethod = queue[i + 1];
469
+ methodOrTarget = args[0];
470
+ methodOrArgs = args[1];
437
471
 
438
- if (currentTarget === target && currentMethod === method) {
439
- queue.splice(i, 4);
440
- return true;
472
+ if (_backburnerUtils.isFunction(methodOrArgs) || _backburnerUtils.isString(methodOrArgs) && methodOrTarget !== null && methodOrArgs in methodOrTarget) {
473
+ target = args.shift();
474
+ method = args.shift();
475
+ } else {
476
+ method = args.shift();
441
477
  }
442
478
  }
443
479
 
444
- // if not found in current queue
445
- // could be in the queue that is being flushed
446
- queue = this._queueBeingFlushed;
480
+ var executeAt = Date.now() + parseInt(wait !== wait ? 0 : wait, 10);
447
481
 
448
- if (!queue) {
449
- return;
482
+ if (_backburnerUtils.isString(method)) {
483
+ method = target[method];
450
484
  }
451
485
 
452
- for (i = 0, l = queue.length; i < l; i += 4) {
453
- currentTarget = queue[i];
454
- currentMethod = queue[i + 1];
486
+ var onError = getOnError(this.options);
455
487
 
456
- if (currentTarget === target && currentMethod === method) {
457
- // don't mess with array during flush
458
- // just nullify the method
459
- queue[i + 1] = null;
460
- return true;
488
+ function fn() {
489
+ if (onError) {
490
+ try {
491
+ method.apply(target, args);
492
+ } catch (e) {
493
+ onError(e);
494
+ }
495
+ } else {
496
+ method.apply(target, args);
461
497
  }
462
498
  }
463
- }
464
- };
465
- });
466
- enifed('backburner/utils', ['exports'], function (exports) {
467
- 'use strict';
468
499
 
469
- exports.each = each;
470
- exports.isString = isString;
471
- exports.isFunction = isFunction;
472
- exports.isNumber = isNumber;
473
- exports.isCoercableNumber = isCoercableNumber;
474
- var NUMBER = /\d+/;
500
+ return this._setTimeout(fn, executeAt);
501
+ },
475
502
 
476
- function each(collection, callback) {
477
- for (var i = 0; i < collection.length; i++) {
478
- callback(collection[i]);
479
- }
480
- }
503
+ _setTimeout: function (fn, executeAt) {
504
+ if (this._timers.length === 0) {
505
+ this._timers.push(executeAt, fn);
506
+ this._installTimerTimeout();
507
+ return fn;
508
+ }
481
509
 
482
- function isString(suspect) {
483
- return typeof suspect === 'string';
484
- }
510
+ // find position to insert
511
+ var i = _backburnerBinarySearch.default(executeAt, this._timers);
485
512
 
486
- function isFunction(suspect) {
487
- return typeof suspect === 'function';
488
- }
513
+ this._timers.splice(i, 0, executeAt, fn);
489
514
 
490
- function isNumber(suspect) {
491
- return typeof suspect === 'number';
492
- }
515
+ // we should be the new earliest timer if i == 0
516
+ if (i === 0) {
517
+ this._reinstallTimerTimeout();
518
+ }
493
519
 
494
- function isCoercableNumber(number) {
495
- return isNumber(number) || NUMBER.test(number);
496
- }
497
- });
498
- enifed('backburner', ['exports', 'backburner/utils', 'backburner/platform', 'backburner/binary-search', 'backburner/deferred-action-queues'], function (exports, _backburnerUtils, _backburnerPlatform, _backburnerBinarySearch, _backburnerDeferredActionQueues) {
499
- 'use strict';
520
+ return fn;
521
+ },
500
522
 
501
- exports.default = Backburner;
523
+ throttle: function (target, method /* , args, wait, [immediate] */) {
524
+ var backburner = this;
525
+ var args = new Array(arguments.length);
526
+ for (var i = 0; i < arguments.length; i++) {
527
+ args[i] = arguments[i];
528
+ }
529
+ var immediate = args.pop();
530
+ var wait, throttler, index, timer;
502
531
 
503
- function Backburner(queueNames, options) {
504
- this.queueNames = queueNames;
505
- this.options = options || {};
506
- if (!this.options.defaultQueue) {
507
- this.options.defaultQueue = queueNames[0];
508
- }
509
- this.instanceStack = [];
510
- this._debouncees = [];
511
- this._throttlers = [];
512
- this._eventCallbacks = {
513
- end: [],
514
- begin: []
515
- };
532
+ if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
533
+ wait = immediate;
534
+ immediate = true;
535
+ } else {
536
+ wait = args.pop();
537
+ }
516
538
 
517
- var _this = this;
518
- this._boundClearItems = function () {
519
- clearItems();
520
- };
539
+ wait = parseInt(wait, 10);
521
540
 
522
- this._timerTimeoutId = undefined;
523
- this._timers = [];
541
+ index = findThrottler(target, method, this._throttlers);
542
+ if (index > -1) {
543
+ return this._throttlers[index];
544
+ } // throttled
524
545
 
525
- this._platform = this.options._platform || _backburnerPlatform.default;
546
+ timer = this._platform.setTimeout(function () {
547
+ if (!immediate) {
548
+ backburner.run.apply(backburner, args);
549
+ }
550
+ var index = findThrottler(target, method, backburner._throttlers);
551
+ if (index > -1) {
552
+ backburner._throttlers.splice(index, 1);
553
+ }
554
+ }, wait);
526
555
 
527
- this._boundRunExpiredTimers = function () {
528
- _this._runExpiredTimers();
529
- };
530
- }
556
+ if (immediate) {
557
+ this.run.apply(this, args);
558
+ }
531
559
 
532
- Backburner.prototype = {
533
- begin: function () {
534
- var options = this.options;
535
- var onBegin = options && options.onBegin;
536
- var previousInstance = this.currentInstance;
560
+ throttler = [target, method, timer];
537
561
 
538
- if (previousInstance) {
539
- this.instanceStack.push(previousInstance);
540
- }
562
+ this._throttlers.push(throttler);
541
563
 
542
- this.currentInstance = new _backburnerDeferredActionQueues.default(this.queueNames, options);
543
- this._trigger('begin', this.currentInstance, previousInstance);
544
- if (onBegin) {
545
- onBegin(this.currentInstance, previousInstance);
546
- }
564
+ return throttler;
547
565
  },
548
566
 
549
- end: function () {
550
- var options = this.options;
551
- var onEnd = options && options.onEnd;
552
- var currentInstance = this.currentInstance;
553
- var nextInstance = null;
567
+ debounce: function (target, method /* , args, wait, [immediate] */) {
568
+ var backburner = this;
569
+ var args = new Array(arguments.length);
570
+ for (var i = 0; i < arguments.length; i++) {
571
+ args[i] = arguments[i];
572
+ }
554
573
 
555
- // Prevent double-finally bug in Safari 6.0.2 and iOS 6
556
- // This bug appears to be resolved in Safari 6.0.5 and iOS 7
557
- var finallyAlreadyCalled = false;
558
- try {
559
- currentInstance.flush();
560
- } finally {
561
- if (!finallyAlreadyCalled) {
562
- finallyAlreadyCalled = true;
574
+ var immediate = args.pop();
575
+ var wait, index, debouncee, timer;
563
576
 
564
- this.currentInstance = null;
577
+ if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
578
+ wait = immediate;
579
+ immediate = false;
580
+ } else {
581
+ wait = args.pop();
582
+ }
565
583
 
566
- if (this.instanceStack.length) {
567
- nextInstance = this.instanceStack.pop();
568
- this.currentInstance = nextInstance;
569
- }
570
- this._trigger('end', currentInstance, nextInstance);
571
- if (onEnd) {
572
- onEnd(currentInstance, nextInstance);
573
- }
584
+ wait = parseInt(wait, 10);
585
+ // Remove debouncee
586
+ index = findDebouncee(target, method, this._debouncees);
587
+
588
+ if (index > -1) {
589
+ debouncee = this._debouncees[index];
590
+ this._debouncees.splice(index, 1);
591
+ this._platform.clearTimeout(debouncee[2]);
592
+ }
593
+
594
+ timer = this._platform.setTimeout(function () {
595
+ if (!immediate) {
596
+ backburner.run.apply(backburner, args);
597
+ }
598
+ var index = findDebouncee(target, method, backburner._debouncees);
599
+ if (index > -1) {
600
+ backburner._debouncees.splice(index, 1);
574
601
  }
602
+ }, wait);
603
+
604
+ if (immediate && index === -1) {
605
+ backburner.run.apply(backburner, args);
575
606
  }
607
+
608
+ debouncee = [target, method, timer];
609
+
610
+ backburner._debouncees.push(debouncee);
611
+
612
+ return debouncee;
576
613
  },
577
614
 
578
- /**
579
- Trigger an event. Supports up to two arguments. Designed around
580
- triggering transition events from one run loop instance to the
581
- next, which requires an argument for the first instance and then
582
- an argument for the next instance.
583
- @private
584
- @method _trigger
585
- @param {String} eventName
586
- @param {any} arg1
587
- @param {any} arg2
588
- */
589
- _trigger: function (eventName, arg1, arg2) {
590
- var callbacks = this._eventCallbacks[eventName];
591
- if (callbacks) {
592
- for (var i = 0; i < callbacks.length; i++) {
593
- callbacks[i](arg1, arg2);
594
- }
615
+ cancelTimers: function () {
616
+ _backburnerUtils.each(this._throttlers, this._boundClearItems);
617
+ this._throttlers = [];
618
+
619
+ _backburnerUtils.each(this._debouncees, this._boundClearItems);
620
+ this._debouncees = [];
621
+
622
+ this._clearTimerTimeout();
623
+ this._timers = [];
624
+
625
+ if (this._autorun) {
626
+ this._platform.clearTimeout(this._autorun);
627
+ this._autorun = null;
595
628
  }
596
629
  },
597
630
 
598
- on: function (eventName, callback) {
599
- if (typeof callback !== 'function') {
600
- throw new TypeError('Callback must be a function');
601
- }
602
- var callbacks = this._eventCallbacks[eventName];
603
- if (callbacks) {
604
- callbacks.push(callback);
605
- } else {
606
- throw new TypeError('Cannot on() event "' + eventName + '" because it does not exist');
607
- }
631
+ hasTimers: function () {
632
+ return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
608
633
  },
609
634
 
610
- off: function (eventName, callback) {
611
- if (eventName) {
612
- var callbacks = this._eventCallbacks[eventName];
613
- var callbackFound = false;
614
- if (!callbacks) return;
615
- if (callback) {
616
- for (var i = 0; i < callbacks.length; i++) {
617
- if (callbacks[i] === callback) {
618
- callbackFound = true;
619
- callbacks.splice(i, 1);
620
- i--;
635
+ cancel: function (timer) {
636
+ var timerType = typeof timer;
637
+
638
+ if (timer && timerType === 'object' && timer.queue && timer.method) {
639
+ // we're cancelling a deferOnce
640
+ return timer.queue.cancel(timer);
641
+ } else if (timerType === 'function') {
642
+ // we're cancelling a setTimeout
643
+ for (var i = 0, l = this._timers.length; i < l; i += 2) {
644
+ if (this._timers[i + 1] === timer) {
645
+ this._timers.splice(i, 2); // remove the two elements
646
+ if (i === 0) {
647
+ this._reinstallTimerTimeout();
621
648
  }
649
+ return true;
622
650
  }
623
651
  }
624
- if (!callbackFound) {
625
- throw new TypeError('Cannot off() callback that does not exist');
626
- }
652
+ } else if (Object.prototype.toString.call(timer) === '[object Array]') {
653
+ // we're cancelling a throttle or debounce
654
+ return this._cancelItem(findThrottler, this._throttlers, timer) || this._cancelItem(findDebouncee, this._debouncees, timer);
627
655
  } else {
628
- throw new TypeError('Cannot off() event "' + eventName + '" because it does not exist');
656
+ return; // timer was null or not a timer
629
657
  }
630
658
  },
631
659
 
632
- run: function () /* target, method, args */{
633
- var length = arguments.length;
634
- var method, target, args;
660
+ _cancelItem: function (findMethod, array, timer) {
661
+ var item, index;
635
662
 
636
- if (length === 1) {
637
- method = arguments[0];
638
- target = null;
639
- } else {
640
- target = arguments[0];
641
- method = arguments[1];
663
+ if (timer.length < 3) {
664
+ return false;
642
665
  }
643
666
 
644
- if (_backburnerUtils.isString(method)) {
645
- method = target[method];
646
- }
667
+ index = findMethod(timer[0], timer[1], array);
647
668
 
648
- if (length > 2) {
649
- args = new Array(length - 2);
650
- for (var i = 0, l = length - 2; i < l; i++) {
651
- args[i] = arguments[i + 2];
669
+ if (index > -1) {
670
+
671
+ item = array[index];
672
+
673
+ if (item[2] === timer[2]) {
674
+ array.splice(index, 1);
675
+ this._platform.clearTimeout(timer[2]);
676
+ return true;
652
677
  }
653
- } else {
654
- args = [];
655
678
  }
656
679
 
657
- var onError = getOnError(this.options);
658
-
659
- this.begin();
680
+ return false;
681
+ },
660
682
 
661
- // guard against Safari 6's double-finally bug
662
- var didFinally = false;
683
+ _runExpiredTimers: function () {
684
+ this._timerTimeoutId = undefined;
685
+ this.run(this, this._scheduleExpiredTimers);
686
+ },
663
687
 
664
- if (onError) {
665
- try {
666
- return method.apply(target, args);
667
- } catch (error) {
668
- onError(error);
669
- } finally {
670
- if (!didFinally) {
671
- didFinally = true;
672
- this.end();
673
- }
674
- }
675
- } else {
676
- try {
677
- return method.apply(target, args);
678
- } finally {
679
- if (!didFinally) {
680
- didFinally = true;
681
- this.end();
682
- }
688
+ _scheduleExpiredTimers: function () {
689
+ var n = Date.now();
690
+ var timers = this._timers;
691
+ var i = 0;
692
+ var l = timers.length;
693
+ for (; i < l; i += 2) {
694
+ var executeAt = timers[i];
695
+ var fn = timers[i + 1];
696
+ if (executeAt <= n) {
697
+ this.schedule(this.options.defaultQueue, null, fn);
698
+ } else {
699
+ break;
683
700
  }
684
701
  }
702
+ timers.splice(0, i);
703
+ this._installTimerTimeout();
685
704
  },
686
705
 
687
- /*
688
- Join the passed method with an existing queue and execute immediately,
689
- if there isn't one use `Backburner#run`.
690
- The join method is like the run method except that it will schedule into
691
- an existing queue if one already exists. In either case, the join method will
692
- immediately execute the passed in function and return its result.
693
- @method join
694
- @param {Object} target
695
- @param {Function} method The method to be executed
696
- @param {any} args The method arguments
697
- @return method result
698
- */
699
- join: function () /* target, method, args */{
700
- if (!this.currentInstance) {
701
- return this.run.apply(this, arguments);
702
- }
703
-
704
- var length = arguments.length;
705
- var method, target;
706
+ _reinstallTimerTimeout: function () {
707
+ this._clearTimerTimeout();
708
+ this._installTimerTimeout();
709
+ },
706
710
 
707
- if (length === 1) {
708
- method = arguments[0];
709
- target = null;
710
- } else {
711
- target = arguments[0];
712
- method = arguments[1];
711
+ _clearTimerTimeout: function () {
712
+ if (!this._timerTimeoutId) {
713
+ return;
713
714
  }
715
+ this._platform.clearTimeout(this._timerTimeoutId);
716
+ this._timerTimeoutId = undefined;
717
+ },
714
718
 
715
- if (_backburnerUtils.isString(method)) {
716
- method = target[method];
719
+ _installTimerTimeout: function () {
720
+ if (!this._timers.length) {
721
+ return;
717
722
  }
723
+ var minExpiresAt = this._timers[0];
724
+ var n = Date.now();
725
+ var wait = Math.max(0, minExpiresAt - n);
726
+ this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
727
+ }
728
+ };
718
729
 
719
- if (length === 1) {
720
- return method();
721
- } else if (length === 2) {
722
- return method.call(target);
723
- } else {
724
- var args = new Array(length - 2);
725
- for (var i = 0, l = length - 2; i < l; i++) {
726
- args[i] = arguments[i + 2];
727
- }
728
- return method.apply(target, args);
729
- }
730
- },
730
+ Backburner.prototype.schedule = Backburner.prototype.defer;
731
+ Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
732
+ Backburner.prototype.later = Backburner.prototype.setTimeout;
731
733
 
732
- /*
733
- Defer the passed function to run inside the specified queue.
734
- @method defer
735
- @param {String} queueName
736
- @param {Object} target
737
- @param {Function|String} method The method or method name to be executed
738
- @param {any} args The method arguments
739
- @return method result
740
- */
741
- defer: function (queueName /* , target, method, args */) {
742
- var length = arguments.length;
743
- var method, target, args;
734
+ function getOnError(options) {
735
+ return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
736
+ }
744
737
 
745
- if (length === 2) {
746
- method = arguments[1];
747
- target = null;
748
- } else {
749
- target = arguments[1];
750
- method = arguments[2];
751
- }
738
+ function createAutorun(backburner) {
739
+ backburner.begin();
740
+ backburner._autorun = backburner._platform.setTimeout(function () {
741
+ backburner._autorun = null;
742
+ backburner.end();
743
+ });
744
+ }
752
745
 
753
- if (_backburnerUtils.isString(method)) {
754
- method = target[method];
755
- }
746
+ function findDebouncee(target, method, debouncees) {
747
+ return findItem(target, method, debouncees);
748
+ }
756
749
 
757
- var stack = this.DEBUG ? new Error() : undefined;
750
+ function findThrottler(target, method, throttlers) {
751
+ return findItem(target, method, throttlers);
752
+ }
758
753
 
759
- if (length > 3) {
760
- args = new Array(length - 3);
761
- for (var i = 3; i < length; i++) {
762
- args[i - 3] = arguments[i];
763
- }
764
- } else {
765
- args = undefined;
766
- }
754
+ function findItem(target, method, collection) {
755
+ var item;
756
+ var index = -1;
767
757
 
768
- if (!this.currentInstance) {
769
- createAutorun(this);
758
+ for (var i = 0, l = collection.length; i < l; i++) {
759
+ item = collection[i];
760
+ if (item[0] === target && item[1] === method) {
761
+ index = i;
762
+ break;
770
763
  }
771
- return this.currentInstance.schedule(queueName, target, method, args, false, stack);
772
- },
764
+ }
773
765
 
774
- deferOnce: function (queueName /* , target, method, args */) {
775
- var length = arguments.length;
776
- var method, target, args;
766
+ return index;
767
+ }
768
+
769
+ function clearItems(item) {
770
+ this._platform.clearTimeout(item[2]);
771
+ }
772
+ });
773
+ enifed("backburner/binary-search", ["exports"], function (exports) {
774
+ "use strict";
775
+
776
+ exports.default = binarySearch;
777
777
 
778
- if (length === 2) {
779
- method = arguments[1];
780
- target = null;
781
- } else {
782
- target = arguments[1];
783
- method = arguments[2];
784
- }
778
+ function binarySearch(time, timers) {
779
+ var start = 0;
780
+ var end = timers.length - 2;
781
+ var middle, l;
785
782
 
786
- if (_backburnerUtils.isString(method)) {
787
- method = target[method];
788
- }
783
+ while (start < end) {
784
+ // since timers is an array of pairs 'l' will always
785
+ // be an integer
786
+ l = (end - start) / 2;
789
787
 
790
- var stack = this.DEBUG ? new Error() : undefined;
788
+ // compensate for the index in case even number
789
+ // of pairs inside timers
790
+ middle = start + l - l % 2;
791
791
 
792
- if (length > 3) {
793
- args = new Array(length - 3);
794
- for (var i = 3; i < length; i++) {
795
- args[i - 3] = arguments[i];
796
- }
792
+ if (time >= timers[middle]) {
793
+ start = middle + 2;
797
794
  } else {
798
- args = undefined;
795
+ end = middle;
799
796
  }
797
+ }
800
798
 
801
- if (!this.currentInstance) {
802
- createAutorun(this);
803
- }
804
- return this.currentInstance.schedule(queueName, target, method, args, true, stack);
805
- },
799
+ return time >= timers[start] ? start + 2 : start;
800
+ }
801
+ });
802
+ enifed('backburner/deferred-action-queues', ['exports', 'backburner/utils', 'backburner/queue'], function (exports, _backburnerUtils, _backburnerQueue) {
803
+ 'use strict';
806
804
 
807
- setTimeout: function () {
808
- var l = arguments.length;
809
- var args = new Array(l);
805
+ exports.default = DeferredActionQueues;
810
806
 
811
- for (var x = 0; x < l; x++) {
812
- args[x] = arguments[x];
813
- }
807
+ function DeferredActionQueues(queueNames, options) {
808
+ var queues = this.queues = {};
809
+ this.queueNames = queueNames = queueNames || [];
814
810
 
815
- var length = args.length,
816
- method,
817
- wait,
818
- target,
819
- methodOrTarget,
820
- methodOrWait,
821
- methodOrArgs;
811
+ this.options = options;
822
812
 
823
- if (length === 0) {
824
- return;
825
- } else if (length === 1) {
826
- method = args.shift();
827
- wait = 0;
828
- } else if (length === 2) {
829
- methodOrTarget = args[0];
830
- methodOrWait = args[1];
813
+ _backburnerUtils.each(queueNames, function (queueName) {
814
+ queues[queueName] = new _backburnerQueue.default(queueName, options[queueName], options);
815
+ });
816
+ }
831
817
 
832
- if (_backburnerUtils.isFunction(methodOrWait) || _backburnerUtils.isFunction(methodOrTarget[methodOrWait])) {
833
- target = args.shift();
834
- method = args.shift();
835
- wait = 0;
836
- } else if (_backburnerUtils.isCoercableNumber(methodOrWait)) {
837
- method = args.shift();
838
- wait = args.shift();
839
- } else {
840
- method = args.shift();
841
- wait = 0;
842
- }
843
- } else {
844
- var last = args[args.length - 1];
818
+ function noSuchQueue(name) {
819
+ throw new Error('You attempted to schedule an action in a queue (' + name + ') that doesn\'t exist');
820
+ }
845
821
 
846
- if (_backburnerUtils.isCoercableNumber(last)) {
847
- wait = args.pop();
848
- } else {
849
- wait = 0;
850
- }
822
+ function noSuchMethod(name) {
823
+ throw new Error('You attempted to schedule an action in a queue (' + name + ') for a method that doesn\'t exist');
824
+ }
851
825
 
852
- methodOrTarget = args[0];
853
- methodOrArgs = args[1];
826
+ DeferredActionQueues.prototype = {
827
+ schedule: function (name, target, method, args, onceFlag, stack) {
828
+ var queues = this.queues;
829
+ var queue = queues[name];
854
830
 
855
- if (_backburnerUtils.isFunction(methodOrArgs) || _backburnerUtils.isString(methodOrArgs) && methodOrTarget !== null && methodOrArgs in methodOrTarget) {
856
- target = args.shift();
857
- method = args.shift();
858
- } else {
859
- method = args.shift();
860
- }
831
+ if (!queue) {
832
+ noSuchQueue(name);
861
833
  }
862
834
 
863
- var executeAt = Date.now() + parseInt(wait !== wait ? 0 : wait, 10);
835
+ if (!method) {
836
+ noSuchMethod(name);
837
+ }
864
838
 
865
- if (_backburnerUtils.isString(method)) {
866
- method = target[method];
839
+ if (onceFlag) {
840
+ return queue.pushUnique(target, method, args, stack);
841
+ } else {
842
+ return queue.push(target, method, args, stack);
867
843
  }
844
+ },
868
845
 
869
- var onError = getOnError(this.options);
846
+ flush: function () {
847
+ var queues = this.queues;
848
+ var queueNames = this.queueNames;
849
+ var queueName, queue;
850
+ var queueNameIndex = 0;
851
+ var numberOfQueues = queueNames.length;
870
852
 
871
- function fn() {
872
- if (onError) {
873
- try {
874
- method.apply(target, args);
875
- } catch (e) {
876
- onError(e);
877
- }
853
+ while (queueNameIndex < numberOfQueues) {
854
+ queueName = queueNames[queueNameIndex];
855
+ queue = queues[queueName];
856
+
857
+ var numberOfQueueItems = queue._queue.length;
858
+
859
+ if (numberOfQueueItems === 0) {
860
+ queueNameIndex++;
878
861
  } else {
879
- method.apply(target, args);
862
+ queue.flush(false /* async */);
863
+ queueNameIndex = 0;
880
864
  }
881
865
  }
866
+ }
867
+ };
868
+ });
869
+ enifed('backburner/platform', ['exports'], function (exports) {
870
+ 'use strict';
882
871
 
883
- return this._setTimeout(fn, executeAt);
884
- },
872
+ var GlobalContext;
885
873
 
886
- _setTimeout: function (fn, executeAt) {
887
- if (this._timers.length === 0) {
888
- this._timers.push(executeAt, fn);
889
- this._installTimerTimeout();
890
- return fn;
874
+ /* global self */
875
+ if (typeof self === 'object') {
876
+ GlobalContext = self;
877
+
878
+ /* global global */
879
+ } else if (typeof global === 'object') {
880
+ GlobalContext = global;
881
+
882
+ /* global window */
883
+ } else if (typeof window === 'object') {
884
+ GlobalContext = window;
885
+ } else {
886
+ throw new Error('no global: `self`, `global` nor `window` was found');
891
887
  }
892
888
 
893
- // find position to insert
894
- var i = _backburnerBinarySearch.default(executeAt, this._timers);
889
+ exports.default = GlobalContext;
890
+ });
891
+ enifed('backburner/queue', ['exports', 'backburner/utils'], function (exports, _backburnerUtils) {
892
+ 'use strict';
895
893
 
896
- this._timers.splice(i, 0, executeAt, fn);
894
+ exports.default = Queue;
897
895
 
898
- // we should be the new earliest timer if i == 0
899
- if (i === 0) {
900
- this._reinstallTimerTimeout();
901
- }
896
+ function Queue(name, options, globalOptions) {
897
+ this.name = name;
898
+ this.globalOptions = globalOptions || {};
899
+ this.options = options;
900
+ this._queue = [];
901
+ this.targetQueues = {};
902
+ this._queueBeingFlushed = undefined;
903
+ }
902
904
 
903
- return fn;
905
+ Queue.prototype = {
906
+ push: function (target, method, args, stack) {
907
+ var queue = this._queue;
908
+ queue.push(target, method, args, stack);
909
+
910
+ return {
911
+ queue: this,
912
+ target: target,
913
+ method: method
914
+ };
904
915
  },
905
916
 
906
- throttle: function (target, method /* , args, wait, [immediate] */) {
907
- var backburner = this;
908
- var args = new Array(arguments.length);
909
- for (var i = 0; i < arguments.length; i++) {
910
- args[i] = arguments[i];
911
- }
912
- var immediate = args.pop();
913
- var wait, throttler, index, timer;
917
+ pushUniqueWithoutGuid: function (target, method, args, stack) {
918
+ var queue = this._queue;
914
919
 
915
- if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
916
- wait = immediate;
917
- immediate = true;
918
- } else {
919
- wait = args.pop();
920
+ for (var i = 0, l = queue.length; i < l; i += 4) {
921
+ var currentTarget = queue[i];
922
+ var currentMethod = queue[i + 1];
923
+
924
+ if (currentTarget === target && currentMethod === method) {
925
+ queue[i + 2] = args; // replace args
926
+ queue[i + 3] = stack; // replace stack
927
+ return;
928
+ }
920
929
  }
921
930
 
922
- wait = parseInt(wait, 10);
931
+ queue.push(target, method, args, stack);
932
+ },
923
933
 
924
- index = findThrottler(target, method, this._throttlers);
925
- if (index > -1) {
926
- return this._throttlers[index];
927
- } // throttled
934
+ targetQueue: function (targetQueue, target, method, args, stack) {
935
+ var queue = this._queue;
928
936
 
929
- timer = this._platform.setTimeout(function () {
930
- if (!immediate) {
931
- backburner.run.apply(backburner, args);
932
- }
933
- var index = findThrottler(target, method, backburner._throttlers);
934
- if (index > -1) {
935
- backburner._throttlers.splice(index, 1);
936
- }
937
- }, wait);
937
+ for (var i = 0, l = targetQueue.length; i < l; i += 2) {
938
+ var currentMethod = targetQueue[i];
939
+ var currentIndex = targetQueue[i + 1];
938
940
 
939
- if (immediate) {
940
- this.run.apply(this, args);
941
+ if (currentMethod === method) {
942
+ queue[currentIndex + 2] = args; // replace args
943
+ queue[currentIndex + 3] = stack; // replace stack
944
+ return;
945
+ }
941
946
  }
942
947
 
943
- throttler = [target, method, timer];
944
-
945
- this._throttlers.push(throttler);
946
-
947
- return throttler;
948
+ targetQueue.push(method, queue.push(target, method, args, stack) - 4);
948
949
  },
949
950
 
950
- debounce: function (target, method /* , args, wait, [immediate] */) {
951
- var backburner = this;
952
- var args = new Array(arguments.length);
953
- for (var i = 0; i < arguments.length; i++) {
954
- args[i] = arguments[i];
955
- }
956
-
957
- var immediate = args.pop();
958
- var wait, index, debouncee, timer;
951
+ pushUniqueWithGuid: function (guid, target, method, args, stack) {
952
+ var hasLocalQueue = this.targetQueues[guid];
959
953
 
960
- if (_backburnerUtils.isNumber(immediate) || _backburnerUtils.isString(immediate)) {
961
- wait = immediate;
962
- immediate = false;
954
+ if (hasLocalQueue) {
955
+ this.targetQueue(hasLocalQueue, target, method, args, stack);
963
956
  } else {
964
- wait = args.pop();
957
+ this.targetQueues[guid] = [method, this._queue.push(target, method, args, stack) - 4];
965
958
  }
966
959
 
967
- wait = parseInt(wait, 10);
968
- // Remove debouncee
969
- index = findDebouncee(target, method, this._debouncees);
960
+ return {
961
+ queue: this,
962
+ target: target,
963
+ method: method
964
+ };
965
+ },
970
966
 
971
- if (index > -1) {
972
- debouncee = this._debouncees[index];
973
- this._debouncees.splice(index, 1);
974
- this._platform.clearTimeout(debouncee[2]);
975
- }
967
+ pushUnique: function (target, method, args, stack) {
968
+ var KEY = this.globalOptions.GUID_KEY;
976
969
 
977
- timer = this._platform.setTimeout(function () {
978
- if (!immediate) {
979
- backburner.run.apply(backburner, args);
980
- }
981
- var index = findDebouncee(target, method, backburner._debouncees);
982
- if (index > -1) {
983
- backburner._debouncees.splice(index, 1);
970
+ if (target && KEY) {
971
+ var guid = target[KEY];
972
+ if (guid) {
973
+ return this.pushUniqueWithGuid(guid, target, method, args, stack);
984
974
  }
985
- }, wait);
986
-
987
- if (immediate && index === -1) {
988
- backburner.run.apply(backburner, args);
989
975
  }
990
976
 
991
- debouncee = [target, method, timer];
977
+ this.pushUniqueWithoutGuid(target, method, args, stack);
992
978
 
993
- backburner._debouncees.push(debouncee);
979
+ return {
980
+ queue: this,
981
+ target: target,
982
+ method: method
983
+ };
984
+ },
994
985
 
995
- return debouncee;
986
+ invoke: function (target, method, args, _, _errorRecordedForStack) {
987
+ if (args && args.length > 0) {
988
+ method.apply(target, args);
989
+ } else {
990
+ method.call(target);
991
+ }
996
992
  },
997
993
 
998
- cancelTimers: function () {
999
- _backburnerUtils.each(this._throttlers, this._boundClearItems);
1000
- this._throttlers = [];
994
+ invokeWithOnError: function (target, method, args, onError, errorRecordedForStack) {
995
+ try {
996
+ if (args && args.length > 0) {
997
+ method.apply(target, args);
998
+ } else {
999
+ method.call(target);
1000
+ }
1001
+ } catch (error) {
1002
+ onError(error, errorRecordedForStack);
1003
+ }
1004
+ },
1001
1005
 
1002
- _backburnerUtils.each(this._debouncees, this._boundClearItems);
1003
- this._debouncees = [];
1006
+ flush: function (sync) {
1007
+ var queue = this._queue;
1008
+ var length = queue.length;
1004
1009
 
1005
- this._clearTimerTimeout();
1006
- this._timers = [];
1010
+ if (length === 0) {
1011
+ return;
1012
+ }
1007
1013
 
1008
- if (this._autorun) {
1009
- this._platform.clearTimeout(this._autorun);
1010
- this._autorun = null;
1014
+ var globalOptions = this.globalOptions;
1015
+ var options = this.options;
1016
+ var before = options && options.before;
1017
+ var after = options && options.after;
1018
+ var onError = globalOptions.onError || globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod];
1019
+ var target, method, args, errorRecordedForStack;
1020
+ var invoke = onError ? this.invokeWithOnError : this.invoke;
1021
+
1022
+ this.targetQueues = Object.create(null);
1023
+ var queueItems = this._queueBeingFlushed = this._queue.slice();
1024
+ this._queue = [];
1025
+
1026
+ if (before) {
1027
+ before();
1011
1028
  }
1012
- },
1013
1029
 
1014
- hasTimers: function () {
1015
- return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
1016
- },
1030
+ for (var i = 0; i < length; i += 4) {
1031
+ target = queueItems[i];
1032
+ method = queueItems[i + 1];
1033
+ args = queueItems[i + 2];
1034
+ errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
1017
1035
 
1018
- cancel: function (timer) {
1019
- var timerType = typeof timer;
1036
+ if (_backburnerUtils.isString(method)) {
1037
+ method = target[method];
1038
+ }
1020
1039
 
1021
- if (timer && timerType === 'object' && timer.queue && timer.method) {
1022
- // we're cancelling a deferOnce
1023
- return timer.queue.cancel(timer);
1024
- } else if (timerType === 'function') {
1025
- // we're cancelling a setTimeout
1026
- for (var i = 0, l = this._timers.length; i < l; i += 2) {
1027
- if (this._timers[i + 1] === timer) {
1028
- this._timers.splice(i, 2); // remove the two elements
1029
- if (i === 0) {
1030
- this._reinstallTimerTimeout();
1031
- }
1032
- return true;
1033
- }
1040
+ // method could have been nullified / canceled during flush
1041
+ if (method) {
1042
+ //
1043
+ // ** Attention intrepid developer **
1044
+ //
1045
+ // To find out the stack of this task when it was scheduled onto
1046
+ // the run loop, add the following to your app.js:
1047
+ //
1048
+ // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
1049
+ //
1050
+ // Once that is in place, when you are at a breakpoint and navigate
1051
+ // here in the stack explorer, you can look at `errorRecordedForStack.stack`,
1052
+ // which will be the captured stack when this job was scheduled.
1053
+ //
1054
+ invoke(target, method, args, onError, errorRecordedForStack);
1034
1055
  }
1035
- } else if (Object.prototype.toString.call(timer) === '[object Array]') {
1036
- // we're cancelling a throttle or debounce
1037
- return this._cancelItem(findThrottler, this._throttlers, timer) || this._cancelItem(findDebouncee, this._debouncees, timer);
1038
- } else {
1039
- return; // timer was null or not a timer
1040
1056
  }
1041
- },
1042
1057
 
1043
- _cancelItem: function (findMethod, array, timer) {
1044
- var item, index;
1045
-
1046
- if (timer.length < 3) {
1047
- return false;
1058
+ if (after) {
1059
+ after();
1048
1060
  }
1049
1061
 
1050
- index = findMethod(timer[0], timer[1], array);
1062
+ this._queueBeingFlushed = undefined;
1051
1063
 
1052
- if (index > -1) {
1064
+ if (sync !== false && this._queue.length > 0) {
1065
+ // check if new items have been added
1066
+ this.flush(true);
1067
+ }
1068
+ },
1053
1069
 
1054
- item = array[index];
1070
+ cancel: function (actionToCancel) {
1071
+ var queue = this._queue,
1072
+ currentTarget,
1073
+ currentMethod,
1074
+ i,
1075
+ l;
1076
+ var target = actionToCancel.target;
1077
+ var method = actionToCancel.method;
1078
+ var GUID_KEY = this.globalOptions.GUID_KEY;
1055
1079
 
1056
- if (item[2] === timer[2]) {
1057
- array.splice(index, 1);
1058
- this._platform.clearTimeout(timer[2]);
1059
- return true;
1080
+ if (GUID_KEY && this.targetQueues && target) {
1081
+ var targetQueue = this.targetQueues[target[GUID_KEY]];
1082
+
1083
+ if (targetQueue) {
1084
+ for (i = 0, l = targetQueue.length; i < l; i++) {
1085
+ if (targetQueue[i] === method) {
1086
+ targetQueue.splice(i, 1);
1087
+ }
1088
+ }
1060
1089
  }
1061
1090
  }
1062
1091
 
1063
- return false;
1064
- },
1065
-
1066
- _runExpiredTimers: function () {
1067
- this._timerTimeoutId = undefined;
1068
- this.run(this, this._scheduleExpiredTimers);
1069
- },
1092
+ for (i = 0, l = queue.length; i < l; i += 4) {
1093
+ currentTarget = queue[i];
1094
+ currentMethod = queue[i + 1];
1070
1095
 
1071
- _scheduleExpiredTimers: function () {
1072
- var n = Date.now();
1073
- var timers = this._timers;
1074
- var i = 0;
1075
- var l = timers.length;
1076
- for (; i < l; i += 2) {
1077
- var executeAt = timers[i];
1078
- var fn = timers[i + 1];
1079
- if (executeAt <= n) {
1080
- this.schedule(this.options.defaultQueue, null, fn);
1081
- } else {
1082
- break;
1096
+ if (currentTarget === target && currentMethod === method) {
1097
+ queue.splice(i, 4);
1098
+ return true;
1083
1099
  }
1084
1100
  }
1085
- timers.splice(0, i);
1086
- this._installTimerTimeout();
1087
- },
1088
1101
 
1089
- _reinstallTimerTimeout: function () {
1090
- this._clearTimerTimeout();
1091
- this._installTimerTimeout();
1092
- },
1102
+ // if not found in current queue
1103
+ // could be in the queue that is being flushed
1104
+ queue = this._queueBeingFlushed;
1093
1105
 
1094
- _clearTimerTimeout: function () {
1095
- if (!this._timerTimeoutId) {
1106
+ if (!queue) {
1096
1107
  return;
1097
1108
  }
1098
- this._platform.clearTimeout(this._timerTimeoutId);
1099
- this._timerTimeoutId = undefined;
1100
- },
1101
1109
 
1102
- _installTimerTimeout: function () {
1103
- if (!this._timers.length) {
1104
- return;
1110
+ for (i = 0, l = queue.length; i < l; i += 4) {
1111
+ currentTarget = queue[i];
1112
+ currentMethod = queue[i + 1];
1113
+
1114
+ if (currentTarget === target && currentMethod === method) {
1115
+ // don't mess with array during flush
1116
+ // just nullify the method
1117
+ queue[i + 1] = null;
1118
+ return true;
1119
+ }
1105
1120
  }
1106
- var minExpiresAt = this._timers[0];
1107
- var n = Date.now();
1108
- var wait = Math.max(0, minExpiresAt - n);
1109
- this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
1110
1121
  }
1111
1122
  };
1123
+ });
1124
+ enifed('backburner/utils', ['exports'], function (exports) {
1125
+ 'use strict';
1112
1126
 
1113
- Backburner.prototype.schedule = Backburner.prototype.defer;
1114
- Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
1115
- Backburner.prototype.later = Backburner.prototype.setTimeout;
1116
-
1117
- function getOnError(options) {
1118
- return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
1119
- }
1127
+ exports.each = each;
1128
+ exports.isString = isString;
1129
+ exports.isFunction = isFunction;
1130
+ exports.isNumber = isNumber;
1131
+ exports.isCoercableNumber = isCoercableNumber;
1132
+ var NUMBER = /\d+/;
1120
1133
 
1121
- function createAutorun(backburner) {
1122
- backburner.begin();
1123
- backburner._autorun = backburner._platform.setTimeout(function () {
1124
- backburner._autorun = null;
1125
- backburner.end();
1126
- });
1134
+ function each(collection, callback) {
1135
+ for (var i = 0; i < collection.length; i++) {
1136
+ callback(collection[i]);
1137
+ }
1127
1138
  }
1128
1139
 
1129
- function findDebouncee(target, method, debouncees) {
1130
- return findItem(target, method, debouncees);
1140
+ function isString(suspect) {
1141
+ return typeof suspect === 'string';
1131
1142
  }
1132
1143
 
1133
- function findThrottler(target, method, throttlers) {
1134
- return findItem(target, method, throttlers);
1144
+ function isFunction(suspect) {
1145
+ return typeof suspect === 'function';
1135
1146
  }
1136
1147
 
1137
- function findItem(target, method, collection) {
1138
- var item;
1139
- var index = -1;
1140
-
1141
- for (var i = 0, l = collection.length; i < l; i++) {
1142
- item = collection[i];
1143
- if (item[0] === target && item[1] === method) {
1144
- index = i;
1145
- break;
1146
- }
1147
- }
1148
-
1149
- return index;
1148
+ function isNumber(suspect) {
1149
+ return typeof suspect === 'number';
1150
1150
  }
1151
1151
 
1152
- function clearItems(item) {
1153
- this._platform.clearTimeout(item[2]);
1152
+ function isCoercableNumber(number) {
1153
+ return isNumber(number) || NUMBER.test(number);
1154
1154
  }
1155
1155
  });
1156
- enifed("ember/features", ["exports"], function (exports) {
1157
- "use strict";
1158
-
1159
- exports.default = {};
1160
- });
1161
- enifed("ember/version", ["exports"], function (exports) {
1162
- "use strict";
1163
-
1164
- exports.default = "2.7.0-beta.3";
1165
- });
1166
1156
  enifed('ember-console/index', ['exports', 'ember-environment'], function (exports, _emberEnvironment) {
1167
1157
  'use strict';
1168
1158
 
@@ -4493,13 +4483,11 @@ enifed('ember-metal/events', ['exports', 'ember-metal/debug', 'ember-metal/utils
4493
4483
  function addListener(obj, eventName, target, method, once) {
4494
4484
  _emberMetalDebug.assert('You must pass at least an object and event name to Ember.addListener', !!obj && !!eventName);
4495
4485
 
4496
- if (eventName === 'didInitAttrs' && obj.isComponent) {
4497
- _emberMetalDebug.deprecate('[DEPRECATED] didInitAttrs called in ' + obj.toString() + '.', false, {
4498
- id: 'ember-views.did-init-attrs',
4499
- until: '3.0.0',
4500
- url: 'http://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs'
4501
- });
4502
- }
4486
+ _emberMetalDebug.deprecate('didInitAttrs called in ' + (obj && obj.toString && obj.toString()) + '.', eventName !== 'didInitAttrs', {
4487
+ id: 'ember-views.did-init-attrs',
4488
+ until: '3.0.0',
4489
+ url: 'http://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs'
4490
+ });
4503
4491
 
4504
4492
  if (!method && 'function' === typeof target) {
4505
4493
  method = target;
@@ -10607,6 +10595,25 @@ enifed('ember-metal/weak_map', ['exports', 'ember-metal/debug', 'ember-metal/uti
10607
10595
  }
10608
10596
  };
10609
10597
  });
10598
+ enifed('ember-template-compiler/compat', ['exports', 'ember-metal/core', 'ember-template-compiler/compiler'], function (exports, _emberMetalCore, _emberTemplateCompilerCompiler) {
10599
+ 'use strict';
10600
+
10601
+ var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {};
10602
+ var EmberHTMLBars = _emberMetalCore.default.HTMLBars = _emberMetalCore.default.HTMLBars || {};
10603
+
10604
+ var _compiler = _emberTemplateCompilerCompiler.default();
10605
+
10606
+ var precompile = _compiler.precompile;
10607
+ var compile = _compiler.compile;
10608
+ var template = _compiler.template;
10609
+ var registerPlugin = _compiler.registerPlugin;
10610
+
10611
+ EmberHTMLBars.precompile = EmberHandlebars.precompile = precompile;
10612
+ EmberHTMLBars.compile = EmberHandlebars.compile = compile;
10613
+ EmberHTMLBars.template = EmberHandlebars.template = template;
10614
+ EmberHTMLBars.registerPlugin = registerPlugin;
10615
+ });
10616
+ // reexports
10610
10617
  enifed('ember-template-compiler/compat/precompile', ['exports', 'require', 'ember-metal/features'], function (exports, _require, _emberMetalFeatures) {
10611
10618
  /**
10612
10619
  @module ember
@@ -10641,25 +10648,6 @@ enifed('ember-template-compiler/compat/precompile', ['exports', 'require', 'embe
10641
10648
  return compileFunc(string, compileOptions());
10642
10649
  };
10643
10650
  });
10644
- enifed('ember-template-compiler/compat', ['exports', 'ember-metal/core', 'ember-template-compiler/compiler'], function (exports, _emberMetalCore, _emberTemplateCompilerCompiler) {
10645
- 'use strict';
10646
-
10647
- var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {};
10648
- var EmberHTMLBars = _emberMetalCore.default.HTMLBars = _emberMetalCore.default.HTMLBars || {};
10649
-
10650
- var _compiler = _emberTemplateCompilerCompiler.default();
10651
-
10652
- var precompile = _compiler.precompile;
10653
- var compile = _compiler.compile;
10654
- var template = _compiler.template;
10655
- var registerPlugin = _compiler.registerPlugin;
10656
-
10657
- EmberHTMLBars.precompile = EmberHandlebars.precompile = precompile;
10658
- EmberHTMLBars.compile = EmberHandlebars.compile = compile;
10659
- EmberHTMLBars.template = EmberHandlebars.template = template;
10660
- EmberHTMLBars.registerPlugin = registerPlugin;
10661
- });
10662
- // reexports
10663
10651
  enifed('ember-template-compiler/compiler', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) {
10664
10652
  'use strict';
10665
10653
 
@@ -11245,6 +11233,23 @@ enifed('ember-template-compiler/system/template', ['exports', 'ember-template-co
11245
11233
  var template = _compiler.template;
11246
11234
  exports.default = template;
11247
11235
  });
11236
+ enifed("ember/features", ["exports"], function (exports) {
11237
+ "use strict";
11238
+
11239
+ exports.default = {};
11240
+ });
11241
+ enifed("ember/version", ["exports"], function (exports) {
11242
+ "use strict";
11243
+
11244
+ exports.default = "2.7.0-beta.4";
11245
+ });
11246
+ enifed("htmlbars-compiler", ["exports", "htmlbars-compiler/compiler"], function (exports, _htmlbarsCompilerCompiler) {
11247
+ "use strict";
11248
+
11249
+ exports.compile = _htmlbarsCompilerCompiler.compile;
11250
+ exports.compileSpec = _htmlbarsCompilerCompiler.compileSpec;
11251
+ exports.template = _htmlbarsCompilerCompiler.template;
11252
+ });
11248
11253
  enifed("htmlbars-compiler/compiler", ["exports", "htmlbars-syntax/parser", "htmlbars-compiler/template-compiler", "htmlbars-runtime/hooks", "htmlbars-runtime/render"], function (exports, _htmlbarsSyntaxParser, _htmlbarsCompilerTemplateCompiler, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender) {
11249
11254
  /*jshint evil:true*/
11250
11255
  "use strict";
@@ -12507,12 +12512,23 @@ enifed("htmlbars-compiler/utils", ["exports"], function (exports) {
12507
12512
  }
12508
12513
  }
12509
12514
  });
12510
- enifed("htmlbars-compiler", ["exports", "htmlbars-compiler/compiler"], function (exports, _htmlbarsCompilerCompiler) {
12511
- "use strict";
12515
+ enifed('htmlbars-runtime', ['exports', 'htmlbars-runtime/hooks', 'htmlbars-runtime/render', 'htmlbars-util/morph-utils', 'htmlbars-util/template-utils'], function (exports, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) {
12516
+ 'use strict';
12512
12517
 
12513
- exports.compile = _htmlbarsCompilerCompiler.compile;
12514
- exports.compileSpec = _htmlbarsCompilerCompiler.compileSpec;
12515
- exports.template = _htmlbarsCompilerCompiler.template;
12518
+ var internal = {
12519
+ blockFor: _htmlbarsUtilTemplateUtils.blockFor,
12520
+ manualElement: _htmlbarsRuntimeRender.manualElement,
12521
+ hostBlock: _htmlbarsRuntimeHooks.hostBlock,
12522
+ continueBlock: _htmlbarsRuntimeHooks.continueBlock,
12523
+ hostYieldWithShadowTemplate: _htmlbarsRuntimeHooks.hostYieldWithShadowTemplate,
12524
+ visitChildren: _htmlbarsUtilMorphUtils.visitChildren,
12525
+ validateChildMorphs: _htmlbarsUtilMorphUtils.validateChildMorphs,
12526
+ clearMorph: _htmlbarsUtilTemplateUtils.clearMorph
12527
+ };
12528
+
12529
+ exports.hooks = _htmlbarsRuntimeHooks.default;
12530
+ exports.render = _htmlbarsRuntimeRender.default;
12531
+ exports.internal = internal;
12516
12532
  });
12517
12533
  enifed('htmlbars-runtime/expression-visitor', ['exports'], function (exports) {
12518
12534
  /**
@@ -14382,23 +14398,14 @@ enifed("htmlbars-runtime/render", ["exports", "htmlbars-util/morph-utils", "html
14382
14398
  return fragment;
14383
14399
  }
14384
14400
  });
14385
- enifed('htmlbars-runtime', ['exports', 'htmlbars-runtime/hooks', 'htmlbars-runtime/render', 'htmlbars-util/morph-utils', 'htmlbars-util/template-utils'], function (exports, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) {
14386
- 'use strict';
14387
-
14388
- var internal = {
14389
- blockFor: _htmlbarsUtilTemplateUtils.blockFor,
14390
- manualElement: _htmlbarsRuntimeRender.manualElement,
14391
- hostBlock: _htmlbarsRuntimeHooks.hostBlock,
14392
- continueBlock: _htmlbarsRuntimeHooks.continueBlock,
14393
- hostYieldWithShadowTemplate: _htmlbarsRuntimeHooks.hostYieldWithShadowTemplate,
14394
- visitChildren: _htmlbarsUtilMorphUtils.visitChildren,
14395
- validateChildMorphs: _htmlbarsUtilMorphUtils.validateChildMorphs,
14396
- clearMorph: _htmlbarsUtilTemplateUtils.clearMorph
14397
- };
14401
+ enifed("htmlbars-syntax", ["exports", "htmlbars-syntax/builders", "htmlbars-syntax/parser", "htmlbars-syntax/generation/print", "htmlbars-syntax/traversal/traverse", "htmlbars-syntax/traversal/walker"], function (exports, _htmlbarsSyntaxBuilders, _htmlbarsSyntaxParser, _htmlbarsSyntaxGenerationPrint, _htmlbarsSyntaxTraversalTraverse, _htmlbarsSyntaxTraversalWalker) {
14402
+ "use strict";
14398
14403
 
14399
- exports.hooks = _htmlbarsRuntimeHooks.default;
14400
- exports.render = _htmlbarsRuntimeRender.default;
14401
- exports.internal = internal;
14404
+ exports.builders = _htmlbarsSyntaxBuilders.default;
14405
+ exports.parse = _htmlbarsSyntaxParser.default;
14406
+ exports.print = _htmlbarsSyntaxGenerationPrint.default;
14407
+ exports.traverse = _htmlbarsSyntaxTraversalTraverse.default;
14408
+ exports.Walker = _htmlbarsSyntaxTraversalWalker.default;
14402
14409
  });
14403
14410
  enifed("htmlbars-syntax/builders", ["exports"], function (exports) {
14404
14411
  // Statements
@@ -16332,16 +16339,105 @@ enifed('htmlbars-syntax/handlebars/utils', ['exports'], function (exports) {
16332
16339
  } else {
16333
16340
  return false;
16334
16341
  }
16335
- }
16336
-
16337
- function blockParams(params, ids) {
16338
- params.path = ids;
16339
- return params;
16340
- }
16342
+ }
16343
+
16344
+ function blockParams(params, ids) {
16345
+ params.path = ids;
16346
+ return params;
16347
+ }
16348
+
16349
+ function appendContextPath(contextPath, id) {
16350
+ return (contextPath ? contextPath + '.' : '') + id;
16351
+ }
16352
+ });
16353
+ enifed("htmlbars-syntax/parser", ["exports", "htmlbars-syntax/handlebars/compiler/base", "htmlbars-syntax", "simple-html-tokenizer/evented-tokenizer", "simple-html-tokenizer/entity-parser", "simple-html-tokenizer/html5-named-char-refs", "htmlbars-syntax/parser/handlebars-node-visitors", "htmlbars-syntax/parser/tokenizer-event-handlers"], function (exports, _htmlbarsSyntaxHandlebarsCompilerBase, _htmlbarsSyntax, _simpleHtmlTokenizerEventedTokenizer, _simpleHtmlTokenizerEntityParser, _simpleHtmlTokenizerHtml5NamedCharRefs, _htmlbarsSyntaxParserHandlebarsNodeVisitors, _htmlbarsSyntaxParserTokenizerEventHandlers) {
16354
+ "use strict";
16355
+
16356
+ exports.preprocess = preprocess;
16357
+ exports.Parser = Parser;
16358
+
16359
+ function preprocess(html, options) {
16360
+ var ast = typeof html === 'object' ? html : _htmlbarsSyntaxHandlebarsCompilerBase.parse(html);
16361
+ var combined = new Parser(html, options).acceptNode(ast);
16362
+
16363
+ if (options && options.plugins && options.plugins.ast) {
16364
+ for (var i = 0, l = options.plugins.ast.length; i < l; i++) {
16365
+ var plugin = new options.plugins.ast[i](options);
16366
+
16367
+ plugin.syntax = _htmlbarsSyntax;
16368
+
16369
+ combined = plugin.transform(combined);
16370
+ }
16371
+ }
16372
+
16373
+ return combined;
16374
+ }
16375
+
16376
+ exports.default = preprocess;
16377
+
16378
+ var entityParser = new _simpleHtmlTokenizerEntityParser.default(_simpleHtmlTokenizerHtml5NamedCharRefs.default);
16379
+
16380
+ function Parser(source, options) {
16381
+ this.options = options || {};
16382
+ this.elementStack = [];
16383
+ this.tokenizer = new _simpleHtmlTokenizerEventedTokenizer.default(this, entityParser);
16384
+
16385
+ this.currentNode = null;
16386
+ this.currentAttribute = null;
16387
+
16388
+ if (typeof source === 'string') {
16389
+ this.source = source.split(/(?:\r\n?|\n)/g);
16390
+ }
16391
+ }
16392
+
16393
+ for (var key in _htmlbarsSyntaxParserHandlebarsNodeVisitors.default) {
16394
+ Parser.prototype[key] = _htmlbarsSyntaxParserHandlebarsNodeVisitors.default[key];
16395
+ }
16396
+
16397
+ for (var key in _htmlbarsSyntaxParserTokenizerEventHandlers.default) {
16398
+ Parser.prototype[key] = _htmlbarsSyntaxParserTokenizerEventHandlers.default[key];
16399
+ }
16400
+
16401
+ Parser.prototype.acceptNode = function (node) {
16402
+ return this[node.type](node);
16403
+ };
16404
+
16405
+ Parser.prototype.currentElement = function () {
16406
+ return this.elementStack[this.elementStack.length - 1];
16407
+ };
16408
+
16409
+ Parser.prototype.sourceForMustache = function (mustache) {
16410
+ var firstLine = mustache.loc.start.line - 1;
16411
+ var lastLine = mustache.loc.end.line - 1;
16412
+ var currentLine = firstLine - 1;
16413
+ var firstColumn = mustache.loc.start.column + 2;
16414
+ var lastColumn = mustache.loc.end.column - 2;
16415
+ var string = [];
16416
+ var line;
16417
+
16418
+ if (!this.source) {
16419
+ return '{{' + mustache.path.id.original + '}}';
16420
+ }
16421
+
16422
+ while (currentLine < lastLine) {
16423
+ currentLine++;
16424
+ line = this.source[currentLine];
16425
+
16426
+ if (currentLine === firstLine) {
16427
+ if (firstLine === lastLine) {
16428
+ string.push(line.slice(firstColumn, lastColumn));
16429
+ } else {
16430
+ string.push(line.slice(firstColumn));
16431
+ }
16432
+ } else if (currentLine === lastLine) {
16433
+ string.push(line.slice(0, lastColumn));
16434
+ } else {
16435
+ string.push(line);
16436
+ }
16437
+ }
16341
16438
 
16342
- function appendContextPath(contextPath, id) {
16343
- return (contextPath ? contextPath + '.' : '') + id;
16344
- }
16439
+ return string.join('\n');
16440
+ };
16345
16441
  });
16346
16442
  enifed("htmlbars-syntax/parser/handlebars-node-visitors", ["exports", "htmlbars-syntax/builders", "htmlbars-syntax/utils"], function (exports, _htmlbarsSyntaxBuilders, _htmlbarsSyntaxUtils) {
16347
16443
  "use strict";
@@ -16837,95 +16933,6 @@ enifed("htmlbars-syntax/parser/tokenizer-event-handlers", ["exports", "htmlbars-
16837
16933
  return "`" + tag.name + "` (on line " + tag.loc.end.line + ")";
16838
16934
  }
16839
16935
  });
16840
- enifed("htmlbars-syntax/parser", ["exports", "htmlbars-syntax/handlebars/compiler/base", "htmlbars-syntax", "simple-html-tokenizer/evented-tokenizer", "simple-html-tokenizer/entity-parser", "simple-html-tokenizer/html5-named-char-refs", "htmlbars-syntax/parser/handlebars-node-visitors", "htmlbars-syntax/parser/tokenizer-event-handlers"], function (exports, _htmlbarsSyntaxHandlebarsCompilerBase, _htmlbarsSyntax, _simpleHtmlTokenizerEventedTokenizer, _simpleHtmlTokenizerEntityParser, _simpleHtmlTokenizerHtml5NamedCharRefs, _htmlbarsSyntaxParserHandlebarsNodeVisitors, _htmlbarsSyntaxParserTokenizerEventHandlers) {
16841
- "use strict";
16842
-
16843
- exports.preprocess = preprocess;
16844
- exports.Parser = Parser;
16845
-
16846
- function preprocess(html, options) {
16847
- var ast = typeof html === 'object' ? html : _htmlbarsSyntaxHandlebarsCompilerBase.parse(html);
16848
- var combined = new Parser(html, options).acceptNode(ast);
16849
-
16850
- if (options && options.plugins && options.plugins.ast) {
16851
- for (var i = 0, l = options.plugins.ast.length; i < l; i++) {
16852
- var plugin = new options.plugins.ast[i](options);
16853
-
16854
- plugin.syntax = _htmlbarsSyntax;
16855
-
16856
- combined = plugin.transform(combined);
16857
- }
16858
- }
16859
-
16860
- return combined;
16861
- }
16862
-
16863
- exports.default = preprocess;
16864
-
16865
- var entityParser = new _simpleHtmlTokenizerEntityParser.default(_simpleHtmlTokenizerHtml5NamedCharRefs.default);
16866
-
16867
- function Parser(source, options) {
16868
- this.options = options || {};
16869
- this.elementStack = [];
16870
- this.tokenizer = new _simpleHtmlTokenizerEventedTokenizer.default(this, entityParser);
16871
-
16872
- this.currentNode = null;
16873
- this.currentAttribute = null;
16874
-
16875
- if (typeof source === 'string') {
16876
- this.source = source.split(/(?:\r\n?|\n)/g);
16877
- }
16878
- }
16879
-
16880
- for (var key in _htmlbarsSyntaxParserHandlebarsNodeVisitors.default) {
16881
- Parser.prototype[key] = _htmlbarsSyntaxParserHandlebarsNodeVisitors.default[key];
16882
- }
16883
-
16884
- for (var key in _htmlbarsSyntaxParserTokenizerEventHandlers.default) {
16885
- Parser.prototype[key] = _htmlbarsSyntaxParserTokenizerEventHandlers.default[key];
16886
- }
16887
-
16888
- Parser.prototype.acceptNode = function (node) {
16889
- return this[node.type](node);
16890
- };
16891
-
16892
- Parser.prototype.currentElement = function () {
16893
- return this.elementStack[this.elementStack.length - 1];
16894
- };
16895
-
16896
- Parser.prototype.sourceForMustache = function (mustache) {
16897
- var firstLine = mustache.loc.start.line - 1;
16898
- var lastLine = mustache.loc.end.line - 1;
16899
- var currentLine = firstLine - 1;
16900
- var firstColumn = mustache.loc.start.column + 2;
16901
- var lastColumn = mustache.loc.end.column - 2;
16902
- var string = [];
16903
- var line;
16904
-
16905
- if (!this.source) {
16906
- return '{{' + mustache.path.id.original + '}}';
16907
- }
16908
-
16909
- while (currentLine < lastLine) {
16910
- currentLine++;
16911
- line = this.source[currentLine];
16912
-
16913
- if (currentLine === firstLine) {
16914
- if (firstLine === lastLine) {
16915
- string.push(line.slice(firstColumn, lastColumn));
16916
- } else {
16917
- string.push(line.slice(firstColumn));
16918
- }
16919
- } else if (currentLine === lastLine) {
16920
- string.push(line.slice(0, lastColumn));
16921
- } else {
16922
- string.push(line);
16923
- }
16924
- }
16925
-
16926
- return string.join('\n');
16927
- };
16928
- });
16929
16936
  enifed("htmlbars-syntax/traversal/errors", ["exports"], function (exports) {
16930
16937
  "use strict";
16931
16938
 
@@ -17274,15 +17281,6 @@ enifed('htmlbars-syntax/utils', ['exports', 'htmlbars-util/array-utils'], functi
17274
17281
  }
17275
17282
  }
17276
17283
  });
17277
- enifed("htmlbars-syntax", ["exports", "htmlbars-syntax/builders", "htmlbars-syntax/parser", "htmlbars-syntax/generation/print", "htmlbars-syntax/traversal/traverse", "htmlbars-syntax/traversal/walker"], function (exports, _htmlbarsSyntaxBuilders, _htmlbarsSyntaxParser, _htmlbarsSyntaxGenerationPrint, _htmlbarsSyntaxTraversalTraverse, _htmlbarsSyntaxTraversalWalker) {
17278
- "use strict";
17279
-
17280
- exports.builders = _htmlbarsSyntaxBuilders.default;
17281
- exports.parse = _htmlbarsSyntaxParser.default;
17282
- exports.print = _htmlbarsSyntaxGenerationPrint.default;
17283
- exports.traverse = _htmlbarsSyntaxTraversalTraverse.default;
17284
- exports.Walker = _htmlbarsSyntaxTraversalWalker.default;
17285
- });
17286
17284
  enifed("htmlbars-test-helpers", ["exports", "simple-html-tokenizer/index", "htmlbars-util/array-utils"], function (exports, _simpleHtmlTokenizerIndex, _htmlbarsUtilArrayUtils) {
17287
17285
  "use strict";
17288
17286
 
@@ -17410,6 +17408,16 @@ enifed("htmlbars-test-helpers", ["exports", "simple-html-tokenizer/index", "html
17410
17408
  }
17411
17409
  }
17412
17410
  });
17411
+ enifed('htmlbars-util', ['exports', 'htmlbars-util/safe-string', 'htmlbars-util/handlebars/utils', 'htmlbars-util/namespaces', 'htmlbars-util/morph-utils'], function (exports, _htmlbarsUtilSafeString, _htmlbarsUtilHandlebarsUtils, _htmlbarsUtilNamespaces, _htmlbarsUtilMorphUtils) {
17412
+ 'use strict';
17413
+
17414
+ exports.SafeString = _htmlbarsUtilSafeString.default;
17415
+ exports.escapeExpression = _htmlbarsUtilHandlebarsUtils.escapeExpression;
17416
+ exports.getAttrNamespace = _htmlbarsUtilNamespaces.getAttrNamespace;
17417
+ exports.validateChildMorphs = _htmlbarsUtilMorphUtils.validateChildMorphs;
17418
+ exports.linkParams = _htmlbarsUtilMorphUtils.linkParams;
17419
+ exports.dump = _htmlbarsUtilMorphUtils.dump;
17420
+ });
17413
17421
  enifed('htmlbars-util/array-utils', ['exports'], function (exports) {
17414
17422
  'use strict';
17415
17423
 
@@ -17976,222 +17984,73 @@ enifed("htmlbars-util/template-utils", ["exports", "htmlbars-util/morph-utils",
17976
17984
  destroy(node);
17977
17985
  }
17978
17986
  }
17979
-
17980
- if (willCleanup) {
17981
- willCleanup(env, morph, destroySelf);
17982
- }
17983
- if (cleanup) {
17984
- cleanup(morph);
17985
- }
17986
- if (destroySelf && destroy) {
17987
- destroy(morph);
17988
- }
17989
-
17990
- _htmlbarsUtilMorphUtils.visitChildren(morph.childNodes, destroyNode);
17991
-
17992
- // TODO: Deal with logical children that are not in the DOM tree
17993
- morph.clear();
17994
- if (didCleanup) {
17995
- didCleanup(env, morph, destroySelf);
17996
- }
17997
-
17998
- morph.lastResult = null;
17999
- morph.lastYielded = null;
18000
- morph.childNodes = null;
18001
- }
18002
-
18003
- function clearMorphList(morphList, morph, env) {
18004
- var item = morphList.firstChildMorph;
18005
-
18006
- while (item) {
18007
- var next = item.nextMorph;
18008
- morph.morphMap[item.key] = undefined;
18009
- clearMorph(item, env, true);
18010
- item.destroy();
18011
-
18012
- item = next;
18013
- }
18014
-
18015
- // Remove the MorphList from the morph.
18016
- morphList.clear();
18017
- morph.morphList = null;
18018
- }
18019
-
18020
- function buildStatement() {
18021
- var statement = [].concat(_slice.call(arguments));
18022
-
18023
- // ensure array length is 7 by padding with 0
18024
- for (var i = arguments.length; i < 7; i++) {
18025
- statement[i] = 0;
18026
- }
18027
-
18028
- return statement;
18029
- }
18030
- });
18031
- enifed("htmlbars-util/void-tag-names", ["exports", "htmlbars-util/array-utils"], function (exports, _htmlbarsUtilArrayUtils) {
18032
- "use strict";
18033
-
18034
- // The HTML elements in this list are speced by
18035
- // http://www.w3.org/TR/html-markup/syntax.html#syntax-elements,
18036
- // and will be forced to close regardless of if they have a
18037
- // self-closing /> at the end.
18038
- var voidTagNames = "area base br col command embed hr img input keygen link meta param source track wbr";
18039
- var voidMap = {};
18040
-
18041
- _htmlbarsUtilArrayUtils.forEach(voidTagNames.split(" "), function (tagName) {
18042
- voidMap[tagName] = true;
18043
- });
18044
-
18045
- exports.default = voidMap;
18046
- });
18047
- enifed('htmlbars-util', ['exports', 'htmlbars-util/safe-string', 'htmlbars-util/handlebars/utils', 'htmlbars-util/namespaces', 'htmlbars-util/morph-utils'], function (exports, _htmlbarsUtilSafeString, _htmlbarsUtilHandlebarsUtils, _htmlbarsUtilNamespaces, _htmlbarsUtilMorphUtils) {
18048
- 'use strict';
18049
-
18050
- exports.SafeString = _htmlbarsUtilSafeString.default;
18051
- exports.escapeExpression = _htmlbarsUtilHandlebarsUtils.escapeExpression;
18052
- exports.getAttrNamespace = _htmlbarsUtilNamespaces.getAttrNamespace;
18053
- exports.validateChildMorphs = _htmlbarsUtilMorphUtils.validateChildMorphs;
18054
- exports.linkParams = _htmlbarsUtilMorphUtils.linkParams;
18055
- exports.dump = _htmlbarsUtilMorphUtils.dump;
18056
- });
18057
- enifed('morph-range/morph-list', ['exports', 'morph-range/utils'], function (exports, _morphRangeUtils) {
18058
- 'use strict';
18059
-
18060
- function MorphList() {
18061
- // morph graph
18062
- this.firstChildMorph = null;
18063
- this.lastChildMorph = null;
18064
-
18065
- this.mountedMorph = null;
18066
- }
18067
-
18068
- var prototype = MorphList.prototype;
18069
-
18070
- prototype.clear = function MorphList$clear() {
18071
- var current = this.firstChildMorph;
18072
-
18073
- while (current) {
18074
- var next = current.nextMorph;
18075
- current.previousMorph = null;
18076
- current.nextMorph = null;
18077
- current.parentMorphList = null;
18078
- current = next;
18079
- }
18080
-
18081
- this.firstChildMorph = this.lastChildMorph = null;
18082
- };
18083
-
18084
- prototype.destroy = function MorphList$destroy() {};
18085
-
18086
- prototype.appendMorph = function MorphList$appendMorph(morph) {
18087
- this.insertBeforeMorph(morph, null);
18088
- };
18089
-
18090
- prototype.insertBeforeMorph = function MorphList$insertBeforeMorph(morph, referenceMorph) {
18091
- if (morph.parentMorphList !== null) {
18092
- morph.unlink();
18093
- }
18094
- if (referenceMorph && referenceMorph.parentMorphList !== this) {
18095
- throw new Error('The morph before which the new morph is to be inserted is not a child of this morph.');
18096
- }
18097
-
18098
- var mountedMorph = this.mountedMorph;
18099
-
18100
- if (mountedMorph) {
18101
-
18102
- var parentNode = mountedMorph.firstNode.parentNode;
18103
- var referenceNode = referenceMorph ? referenceMorph.firstNode : mountedMorph.lastNode.nextSibling;
18104
-
18105
- _morphRangeUtils.insertBefore(parentNode, morph.firstNode, morph.lastNode, referenceNode);
18106
-
18107
- // was not in list mode replace current content
18108
- if (!this.firstChildMorph) {
18109
- _morphRangeUtils.clear(this.mountedMorph.firstNode.parentNode, this.mountedMorph.firstNode, this.mountedMorph.lastNode);
18110
- }
17987
+
17988
+ if (willCleanup) {
17989
+ willCleanup(env, morph, destroySelf);
17990
+ }
17991
+ if (cleanup) {
17992
+ cleanup(morph);
17993
+ }
17994
+ if (destroySelf && destroy) {
17995
+ destroy(morph);
18111
17996
  }
18112
17997
 
18113
- morph.parentMorphList = this;
17998
+ _htmlbarsUtilMorphUtils.visitChildren(morph.childNodes, destroyNode);
18114
17999
 
18115
- var previousMorph = referenceMorph ? referenceMorph.previousMorph : this.lastChildMorph;
18116
- if (previousMorph) {
18117
- previousMorph.nextMorph = morph;
18118
- morph.previousMorph = previousMorph;
18119
- } else {
18120
- this.firstChildMorph = morph;
18000
+ // TODO: Deal with logical children that are not in the DOM tree
18001
+ morph.clear();
18002
+ if (didCleanup) {
18003
+ didCleanup(env, morph, destroySelf);
18121
18004
  }
18122
18005
 
18123
- if (referenceMorph) {
18124
- referenceMorph.previousMorph = morph;
18125
- morph.nextMorph = referenceMorph;
18126
- } else {
18127
- this.lastChildMorph = morph;
18128
- }
18006
+ morph.lastResult = null;
18007
+ morph.lastYielded = null;
18008
+ morph.childNodes = null;
18009
+ }
18129
18010
 
18130
- this.firstChildMorph._syncFirstNode();
18131
- this.lastChildMorph._syncLastNode();
18132
- };
18011
+ function clearMorphList(morphList, morph, env) {
18012
+ var item = morphList.firstChildMorph;
18133
18013
 
18134
- prototype.removeChildMorph = function MorphList$removeChildMorph(morph) {
18135
- if (morph.parentMorphList !== this) {
18136
- throw new Error("Cannot remove a morph from a parent it is not inside of");
18014
+ while (item) {
18015
+ var next = item.nextMorph;
18016
+ morph.morphMap[item.key] = undefined;
18017
+ clearMorph(item, env, true);
18018
+ item.destroy();
18019
+
18020
+ item = next;
18137
18021
  }
18138
18022
 
18139
- morph.destroy();
18140
- };
18023
+ // Remove the MorphList from the morph.
18024
+ morphList.clear();
18025
+ morph.morphList = null;
18026
+ }
18141
18027
 
18142
- exports.default = MorphList;
18143
- });
18144
- enifed('morph-range/morph-list.umd', ['exports', 'morph-range/morph-list'], function (exports, _morphRangeMorphList) {
18145
- 'use strict';
18028
+ function buildStatement() {
18029
+ var statement = [].concat(_slice.call(arguments));
18146
18030
 
18147
- (function (root, factory) {
18148
- if (typeof define === 'function' && define.amd) {
18149
- define([], factory);
18150
- } else if (typeof exports === 'object') {
18151
- module.exports = factory();
18152
- } else {
18153
- root.MorphList = factory();
18031
+ // ensure array length is 7 by padding with 0
18032
+ for (var i = arguments.length; i < 7; i++) {
18033
+ statement[i] = 0;
18154
18034
  }
18155
- })(undefined, function () {
18156
- return _morphRangeMorphList.default;
18157
- });
18035
+
18036
+ return statement;
18037
+ }
18158
18038
  });
18159
- enifed("morph-range/utils", ["exports"], function (exports) {
18160
- // inclusive of both nodes
18039
+ enifed("htmlbars-util/void-tag-names", ["exports", "htmlbars-util/array-utils"], function (exports, _htmlbarsUtilArrayUtils) {
18161
18040
  "use strict";
18162
18041
 
18163
- exports.clear = clear;
18164
- exports.insertBefore = insertBefore;
18165
-
18166
- function clear(parentNode, firstNode, lastNode) {
18167
- if (!parentNode) {
18168
- return;
18169
- }
18042
+ // The HTML elements in this list are speced by
18043
+ // http://www.w3.org/TR/html-markup/syntax.html#syntax-elements,
18044
+ // and will be forced to close regardless of if they have a
18045
+ // self-closing /> at the end.
18046
+ var voidTagNames = "area base br col command embed hr img input keygen link meta param source track wbr";
18047
+ var voidMap = {};
18170
18048
 
18171
- var node = firstNode;
18172
- var nextNode;
18173
- do {
18174
- nextNode = node.nextSibling;
18175
- parentNode.removeChild(node);
18176
- if (node === lastNode) {
18177
- break;
18178
- }
18179
- node = nextNode;
18180
- } while (node);
18181
- }
18049
+ _htmlbarsUtilArrayUtils.forEach(voidTagNames.split(" "), function (tagName) {
18050
+ voidMap[tagName] = true;
18051
+ });
18182
18052
 
18183
- function insertBefore(parentNode, firstNode, lastNode, refNode) {
18184
- var node = firstNode;
18185
- var nextNode;
18186
- do {
18187
- nextNode = node.nextSibling;
18188
- parentNode.insertBefore(node, refNode);
18189
- if (node === lastNode) {
18190
- break;
18191
- }
18192
- node = nextNode;
18193
- } while (node);
18194
- }
18053
+ exports.default = voidMap;
18195
18054
  });
18196
18055
  enifed('morph-range', ['exports', 'morph-range/utils'], function (exports, _morphRangeUtils) {
18197
18056
  'use strict';
@@ -18472,6 +18331,145 @@ enifed('morph-range', ['exports', 'morph-range/utils'], function (exports, _morp
18472
18331
 
18473
18332
  exports.default = Morph;
18474
18333
  });
18334
+ enifed('morph-range/morph-list', ['exports', 'morph-range/utils'], function (exports, _morphRangeUtils) {
18335
+ 'use strict';
18336
+
18337
+ function MorphList() {
18338
+ // morph graph
18339
+ this.firstChildMorph = null;
18340
+ this.lastChildMorph = null;
18341
+
18342
+ this.mountedMorph = null;
18343
+ }
18344
+
18345
+ var prototype = MorphList.prototype;
18346
+
18347
+ prototype.clear = function MorphList$clear() {
18348
+ var current = this.firstChildMorph;
18349
+
18350
+ while (current) {
18351
+ var next = current.nextMorph;
18352
+ current.previousMorph = null;
18353
+ current.nextMorph = null;
18354
+ current.parentMorphList = null;
18355
+ current = next;
18356
+ }
18357
+
18358
+ this.firstChildMorph = this.lastChildMorph = null;
18359
+ };
18360
+
18361
+ prototype.destroy = function MorphList$destroy() {};
18362
+
18363
+ prototype.appendMorph = function MorphList$appendMorph(morph) {
18364
+ this.insertBeforeMorph(morph, null);
18365
+ };
18366
+
18367
+ prototype.insertBeforeMorph = function MorphList$insertBeforeMorph(morph, referenceMorph) {
18368
+ if (morph.parentMorphList !== null) {
18369
+ morph.unlink();
18370
+ }
18371
+ if (referenceMorph && referenceMorph.parentMorphList !== this) {
18372
+ throw new Error('The morph before which the new morph is to be inserted is not a child of this morph.');
18373
+ }
18374
+
18375
+ var mountedMorph = this.mountedMorph;
18376
+
18377
+ if (mountedMorph) {
18378
+
18379
+ var parentNode = mountedMorph.firstNode.parentNode;
18380
+ var referenceNode = referenceMorph ? referenceMorph.firstNode : mountedMorph.lastNode.nextSibling;
18381
+
18382
+ _morphRangeUtils.insertBefore(parentNode, morph.firstNode, morph.lastNode, referenceNode);
18383
+
18384
+ // was not in list mode replace current content
18385
+ if (!this.firstChildMorph) {
18386
+ _morphRangeUtils.clear(this.mountedMorph.firstNode.parentNode, this.mountedMorph.firstNode, this.mountedMorph.lastNode);
18387
+ }
18388
+ }
18389
+
18390
+ morph.parentMorphList = this;
18391
+
18392
+ var previousMorph = referenceMorph ? referenceMorph.previousMorph : this.lastChildMorph;
18393
+ if (previousMorph) {
18394
+ previousMorph.nextMorph = morph;
18395
+ morph.previousMorph = previousMorph;
18396
+ } else {
18397
+ this.firstChildMorph = morph;
18398
+ }
18399
+
18400
+ if (referenceMorph) {
18401
+ referenceMorph.previousMorph = morph;
18402
+ morph.nextMorph = referenceMorph;
18403
+ } else {
18404
+ this.lastChildMorph = morph;
18405
+ }
18406
+
18407
+ this.firstChildMorph._syncFirstNode();
18408
+ this.lastChildMorph._syncLastNode();
18409
+ };
18410
+
18411
+ prototype.removeChildMorph = function MorphList$removeChildMorph(morph) {
18412
+ if (morph.parentMorphList !== this) {
18413
+ throw new Error("Cannot remove a morph from a parent it is not inside of");
18414
+ }
18415
+
18416
+ morph.destroy();
18417
+ };
18418
+
18419
+ exports.default = MorphList;
18420
+ });
18421
+ enifed('morph-range/morph-list.umd', ['exports', 'morph-range/morph-list'], function (exports, _morphRangeMorphList) {
18422
+ 'use strict';
18423
+
18424
+ (function (root, factory) {
18425
+ if (typeof define === 'function' && define.amd) {
18426
+ define([], factory);
18427
+ } else if (typeof exports === 'object') {
18428
+ module.exports = factory();
18429
+ } else {
18430
+ root.MorphList = factory();
18431
+ }
18432
+ })(undefined, function () {
18433
+ return _morphRangeMorphList.default;
18434
+ });
18435
+ });
18436
+ enifed("morph-range/utils", ["exports"], function (exports) {
18437
+ // inclusive of both nodes
18438
+ "use strict";
18439
+
18440
+ exports.clear = clear;
18441
+ exports.insertBefore = insertBefore;
18442
+
18443
+ function clear(parentNode, firstNode, lastNode) {
18444
+ if (!parentNode) {
18445
+ return;
18446
+ }
18447
+
18448
+ var node = firstNode;
18449
+ var nextNode;
18450
+ do {
18451
+ nextNode = node.nextSibling;
18452
+ parentNode.removeChild(node);
18453
+ if (node === lastNode) {
18454
+ break;
18455
+ }
18456
+ node = nextNode;
18457
+ } while (node);
18458
+ }
18459
+
18460
+ function insertBefore(parentNode, firstNode, lastNode, refNode) {
18461
+ var node = firstNode;
18462
+ var nextNode;
18463
+ do {
18464
+ nextNode = node.nextSibling;
18465
+ parentNode.insertBefore(node, refNode);
18466
+ if (node === lastNode) {
18467
+ break;
18468
+ }
18469
+ node = nextNode;
18470
+ } while (node);
18471
+ }
18472
+ });
18475
18473
  enifed("simple-html-tokenizer/entity-parser", ["exports"], function (exports) {
18476
18474
  "use strict";
18477
18475