ember-source 1.8.0.beta.2 → 1.8.0.beta.3

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.
@@ -5,7 +5,7 @@
5
5
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
6
  * @license Licensed under MIT license
7
7
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
- * @version 1.8.0-beta.2
8
+ * @version 1.8.0-beta.3
9
9
  */
10
10
 
11
11
  (function() {
@@ -6336,7 +6336,7 @@ define("ember-handlebars/controls/text_area",
6336
6336
  classNames: ['ember-text-area'],
6337
6337
 
6338
6338
  tagName: "textarea",
6339
- attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap'],
6339
+ attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap', 'lang', 'dir'],
6340
6340
  rows: null,
6341
6341
  cols: null,
6342
6342
 
@@ -6395,7 +6395,7 @@ define("ember-handlebars/controls/text_field",
6395
6395
  attributeBindings: ['type', 'value', 'size', 'pattern', 'name', 'min', 'max',
6396
6396
  'accept', 'autocomplete', 'autosave', 'formaction',
6397
6397
  'formenctype', 'formmethod', 'formnovalidate', 'formtarget',
6398
- 'height', 'inputmode', 'list', 'multiple', 'step',
6398
+ 'height', 'inputmode', 'list', 'multiple', 'step', 'lang', 'dir',
6399
6399
  'width'],
6400
6400
 
6401
6401
  /**
@@ -8513,8 +8513,6 @@ define("ember-handlebars/helpers/collection",
8513
8513
  var viewOptions = ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this);
8514
8514
  hash.itemViewClass = itemViewClass.extend(viewOptions);
8515
8515
 
8516
- options.helperName = options.helperName || 'collection';
8517
-
8518
8516
  return helpers.view.call(this, collectionClass, options);
8519
8517
  }
8520
8518
 
@@ -9413,7 +9411,7 @@ define("ember-handlebars/helpers/unbound",
9413
9411
  }
9414
9412
  });
9415
9413
  define("ember-handlebars/helpers/view",
9416
- ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-views/system/jquery","ember-views/views/view","ember-metal/binding","ember-metal/merge","ember-handlebars/ext","ember-runtime/system/string","exports"],
9414
+ ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-views/system/jquery","ember-views/views/view","ember-metal/binding","ember-metal/keys","ember-handlebars/ext","ember-runtime/system/string","exports"],
9417
9415
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
9418
9416
  "use strict";
9419
9417
  /*globals Handlebars */
@@ -9434,7 +9432,7 @@ define("ember-handlebars/helpers/view",
9434
9432
  var jQuery = __dependency6__["default"];
9435
9433
  var View = __dependency7__["default"];
9436
9434
  var isGlobalPath = __dependency8__.isGlobalPath;
9437
- var merge = __dependency9__["default"];
9435
+ var keys = __dependency9__["default"];
9438
9436
  var normalizePath = __dependency10__.normalizePath;
9439
9437
  var handlebarsGet = __dependency10__.handlebarsGet;
9440
9438
  var handlebarsGetView = __dependency10__.handlebarsGetView;
@@ -9474,92 +9472,90 @@ define("ember-handlebars/helpers/view",
9474
9472
  }
9475
9473
 
9476
9474
  var ViewHelper = EmberObject.create({
9477
-
9478
9475
  propertiesFromHTMLOptions: function(options) {
9479
- var hash = options.hash, data = options.data;
9480
- var extensions = {};
9476
+ var hash = options.hash;
9477
+ var data = options.data;
9478
+ var extensions = {
9479
+ classNameBindings: [],
9480
+ helperName: options.helperName || ''
9481
+ };
9481
9482
  var classes = hash['class'];
9482
- var dup = false;
9483
9483
 
9484
9484
  if (hash.id) {
9485
9485
  extensions.elementId = hash.id;
9486
- dup = true;
9487
9486
  }
9488
9487
 
9489
9488
  if (hash.tag) {
9490
9489
  extensions.tagName = hash.tag;
9491
- dup = true;
9492
9490
  }
9493
9491
 
9494
9492
  if (classes) {
9495
9493
  classes = classes.split(' ');
9496
9494
  extensions.classNames = classes;
9497
- dup = true;
9498
9495
  }
9499
9496
 
9500
9497
  if (hash.classBinding) {
9501
9498
  extensions.classNameBindings = hash.classBinding.split(' ');
9502
- dup = true;
9503
9499
  }
9504
9500
 
9505
9501
  if (hash.classNameBindings) {
9506
- if (extensions.classNameBindings === undefined) extensions.classNameBindings = [];
9507
9502
  extensions.classNameBindings = extensions.classNameBindings.concat(hash.classNameBindings.split(' '));
9508
- dup = true;
9509
9503
  }
9510
9504
 
9511
9505
  if (hash.attributeBindings) {
9512
9506
  Ember.assert("Setting 'attributeBindings' via Handlebars is not allowed. Please subclass Ember.View and set it there instead.");
9513
9507
  extensions.attributeBindings = null;
9514
- dup = true;
9515
- }
9516
-
9517
- if (dup) {
9518
- hash = merge({}, hash);
9519
- delete hash.id;
9520
- delete hash.tag;
9521
- delete hash['class'];
9522
- delete hash.classBinding;
9523
9508
  }
9524
9509
 
9525
9510
  // Set the proper context for all bindings passed to the helper. This applies to regular attribute bindings
9526
9511
  // as well as class name bindings. If the bindings are local, make them relative to the current context
9527
9512
  // instead of the view.
9528
9513
  var path;
9514
+ var hashKeys = keys(hash);
9529
9515
 
9530
- // Evaluate the context of regular attribute bindings:
9531
- for (var prop in hash) {
9532
- if (!hash.hasOwnProperty(prop)) { continue; }
9516
+ for (var i = 0, l = hashKeys.length; i < l; i++) {
9517
+ var prop = hashKeys[i];
9518
+ var isBinding = IS_BINDING.test(prop);
9519
+
9520
+ if (prop !== 'classNameBindings') {
9521
+ extensions[prop] = hash[prop];
9522
+ }
9533
9523
 
9534
9524
  // Test if the property ends in "Binding"
9535
- if (IS_BINDING.test(prop) && typeof hash[prop] === 'string') {
9525
+ if (isBinding && typeof extensions[prop] === 'string') {
9536
9526
  path = this.contextualizeBindingPath(hash[prop], data);
9537
- if (path) { hash[prop] = path; }
9527
+ if (path) {
9528
+ extensions[prop] = path;
9529
+ }
9538
9530
  }
9539
9531
  }
9540
9532
 
9541
9533
  // Evaluate the context of class name bindings:
9542
- if (extensions.classNameBindings) {
9543
- for (var b in extensions.classNameBindings) {
9544
- var full = extensions.classNameBindings[b];
9545
- if (typeof full === 'string') {
9546
- // Contextualize the path of classNameBinding so this:
9547
- //
9548
- // classNameBinding="isGreen:green"
9549
- //
9550
- // is converted to this:
9551
- //
9552
- // classNameBinding="_parentView.context.isGreen:green"
9553
- var parsedPath = View._parsePropertyPath(full);
9554
- if(parsedPath.path !== '') {
9555
- path = this.contextualizeBindingPath(parsedPath.path, data);
9556
- if (path) { extensions.classNameBindings[b] = path + parsedPath.classNames; }
9534
+ var classNameBindingsKeys = keys(extensions.classNameBindings);
9535
+
9536
+ for (var j = 0, k = classNameBindingsKeys.length; j < k; j++) {
9537
+ var classKey = classNameBindingsKeys[j];
9538
+ var full = extensions.classNameBindings[classKey];
9539
+
9540
+ if (typeof full === 'string') {
9541
+ // Contextualize the path of classNameBinding so this:
9542
+ //
9543
+ // classNameBinding="isGreen:green"
9544
+ //
9545
+ // is converted to this:
9546
+ //
9547
+ // classNameBinding="_parentView.context.isGreen:green"
9548
+ var parsedPath = View._parsePropertyPath(full);
9549
+ if (parsedPath.path !== '') {
9550
+ path = this.contextualizeBindingPath(parsedPath.path, data);
9551
+ if (path) {
9552
+ extensions.classNameBindings[classKey] = path + parsedPath.classNames;
9557
9553
  }
9558
9554
  }
9559
9555
  }
9560
9556
  }
9561
9557
 
9562
- return merge(hash, extensions);
9558
+ return extensions;
9563
9559
  },
9564
9560
 
9565
9561
  // Transform bindings from the current context to a context that can be evaluated within the view.
@@ -9581,7 +9577,7 @@ define("ember-handlebars/helpers/view",
9581
9577
 
9582
9578
  helper: function(thisContext, path, options) {
9583
9579
  var data = options.data;
9584
- var fn = options.fn;
9580
+ var fn = options.fn;
9585
9581
  var newView;
9586
9582
 
9587
9583
  makeBindings(thisContext, options);
@@ -9605,17 +9601,12 @@ define("ember-handlebars/helpers/view",
9605
9601
  viewOptions._context = thisContext;
9606
9602
  }
9607
9603
 
9608
- // for instrumentation
9609
- if (options.helperName) {
9610
- viewOptions.helperName = options.helperName;
9611
- }
9612
-
9613
9604
  currentView.appendChild(newView, viewOptions);
9614
9605
  },
9615
9606
 
9616
9607
  instanceHelper: function(thisContext, newView, options) {
9617
- var data = options.data,
9618
- fn = options.fn;
9608
+ var data = options.data;
9609
+ var fn = options.fn;
9619
9610
 
9620
9611
  makeBindings(thisContext, options);
9621
9612
 
@@ -9639,11 +9630,6 @@ define("ember-handlebars/helpers/view",
9639
9630
  viewOptions._context = thisContext;
9640
9631
  }
9641
9632
 
9642
- // for instrumentation
9643
- if (options.helperName) {
9644
- viewOptions.helperName = options.helperName;
9645
- }
9646
-
9647
9633
  currentView.appendChild(newView, viewOptions);
9648
9634
  }
9649
9635
  });
@@ -10559,9 +10545,10 @@ define("ember-metal-views/renderer",
10559
10545
 
10560
10546
  var parentIndex = -1;
10561
10547
  var parents = this._parents;
10562
- var parent = null;
10548
+ var parent = _parentView || null;
10563
10549
  var elements = this._elements;
10564
10550
  var element = null;
10551
+ var contextualElement = null;
10565
10552
  var level = 0;
10566
10553
 
10567
10554
  var view = _view;
@@ -10580,7 +10567,18 @@ define("ember-metal-views/renderer",
10580
10567
  }
10581
10568
 
10582
10569
  this.willCreateElement(view);
10583
- element = this.createElement(view);
10570
+
10571
+ contextualElement = view._morph && view._morph.contextualElement;
10572
+ if (!contextualElement && parent && parent._childViewsMorph) {
10573
+ contextualElement = parent._childViewsMorph.contextualElement;
10574
+ }
10575
+ if (!contextualElement && view._didCreateElementWithoutMorph) {
10576
+ // This code path is only used by createElement and rerender when createElement
10577
+ // was previously called on a view.
10578
+ contextualElement = document.body;
10579
+ }
10580
+ Ember.assert("Required contextualElement for view "+_view+" is missing", contextualElement);
10581
+ element = this.createElement(view, contextualElement);
10584
10582
 
10585
10583
  parents[level++] = parentIndex;
10586
10584
  parentIndex = index;
@@ -10617,7 +10615,7 @@ define("ember-metal-views/renderer",
10617
10615
  }
10618
10616
 
10619
10617
  parentIndex = parents[level];
10620
- parent = views[parentIndex];
10618
+ parent = parentIndex === -1 ? _parentView : views[parentIndex];
10621
10619
  this.insertElement(view, parent, element, -1);
10622
10620
  index = queue[--length];
10623
10621
  view = views[index];
@@ -10650,8 +10648,9 @@ define("ember-metal-views/renderer",
10650
10648
  Renderer.prototype.scheduleInsert =
10651
10649
  function Renderer_scheduleInsert(view, morph) {
10652
10650
  if (view._morph || view._elementCreated) {
10653
- throw new Error("You can't insert a View that has already been rendered");
10651
+ throw new Error("You cannot insert a View that has already been rendered");
10654
10652
  }
10653
+ Ember.assert("You cannot insert a View without a morph", morph);
10655
10654
  view._morph = morph;
10656
10655
  var viewId = this.uuid(view);
10657
10656
  this._inserts[viewId] = this.scheduleRender(this, function() {
@@ -12234,12 +12233,26 @@ define("ember-metal/chains",
12234
12233
 
12235
12234
  function finishChains(obj) {
12236
12235
  // We only create meta if we really have to
12237
- var m = obj['__ember_meta__'], chains = m && m.chains;
12238
- if (chains) {
12239
- if (chains.value() !== obj) {
12236
+ var m = obj['__ember_meta__'],
12237
+ chains, chainWatchers, chainNodes;
12238
+ if (m) {
12239
+ // finish any current chains node watchers that reference obj
12240
+ chainWatchers = m.chainWatchers;
12241
+ if (chainWatchers) {
12242
+ for(var key in chainWatchers) {
12243
+ if (!chainWatchers.hasOwnProperty(key)) { continue; }
12244
+ chainNodes = chainWatchers[key];
12245
+ if (chainNodes) {
12246
+ for (var i=0,l=chainNodes.length;i<l;i++) {
12247
+ chainNodes[i].didChange(null);
12248
+ }
12249
+ }
12250
+ }
12251
+ }
12252
+ // copy chains from prototype
12253
+ chains = m.chains;
12254
+ if (chains && chains.value() !== obj) {
12240
12255
  metaFor(obj).chains = chains = chains.copy(obj);
12241
- } else {
12242
- chains.didChange(null);
12243
12256
  }
12244
12257
  }
12245
12258
  }
@@ -13589,7 +13602,7 @@ define("ember-metal/core",
13589
13602
 
13590
13603
  @class Ember
13591
13604
  @static
13592
- @version 1.8.0-beta.2
13605
+ @version 1.8.0-beta.3
13593
13606
  */
13594
13607
 
13595
13608
  if ('undefined' === typeof Ember) {
@@ -13616,10 +13629,10 @@ define("ember-metal/core",
13616
13629
  /**
13617
13630
  @property VERSION
13618
13631
  @type String
13619
- @default '1.8.0-beta.2'
13632
+ @default '1.8.0-beta.3'
13620
13633
  @static
13621
13634
  */
13622
- Ember.VERSION = '1.8.0-beta.2';
13635
+ Ember.VERSION = '1.8.0-beta.3';
13623
13636
 
13624
13637
  /**
13625
13638
  Standard environmental variables. You can define these in a global `EmberENV`
@@ -15145,11 +15158,10 @@ define("ember-metal/is_present",
15145
15158
  __exports__["default"] = isPresent;
15146
15159
  });
15147
15160
  define("ember-metal/keys",
15148
- ["ember-metal/array","ember-metal/platform","exports"],
15149
- function(__dependency1__, __dependency2__, __exports__) {
15161
+ ["ember-metal/platform","exports"],
15162
+ function(__dependency1__, __exports__) {
15150
15163
  "use strict";
15151
- var indexOf = __dependency1__.indexOf;
15152
- var canDefineNonEnumerableProperties = __dependency2__.canDefineNonEnumerableProperties;
15164
+ var canDefineNonEnumerableProperties = __dependency1__.canDefineNonEnumerableProperties;
15153
15165
 
15154
15166
  /**
15155
15167
  Returns all of the keys defined on an object or hash. This is useful
@@ -15164,54 +15176,47 @@ define("ember-metal/keys",
15164
15176
  var keys = Object.keys;
15165
15177
 
15166
15178
  if (!keys || !canDefineNonEnumerableProperties) {
15167
- var prototypeProperties = [
15168
- 'constructor',
15169
- 'hasOwnProperty',
15170
- 'isPrototypeOf',
15171
- 'propertyIsEnumerable',
15172
- 'valueOf',
15173
- 'toLocaleString',
15174
- 'toString'
15175
- ];
15176
- var pushPropertyName = function(obj, array, key) {
15177
- // Prevents browsers that don't respect non-enumerability from
15178
- // copying internal Ember properties
15179
- if (key.substring(0, 2) === '__') {
15180
- return;
15181
- }
15182
-
15183
- if (key === '_super') {
15184
- return;
15185
- }
15186
-
15187
- if (indexOf(array, key) >= 0) {
15188
- return;
15189
- }
15190
-
15191
- if (!Object.prototype.hasOwnProperty.call(obj, key)) {
15192
- return;
15193
- }
15194
-
15195
- array.push(key);
15196
- };
15197
-
15198
- keys = function keys(obj) {
15199
- var ret = [];
15200
- var key;
15201
-
15202
- for (key in obj) {
15203
- pushPropertyName(obj, ret, key);
15204
- }
15205
-
15206
- // IE8 doesn't enumerate property that named the same as prototype properties.
15207
- for (var i = 0, l = prototypeProperties.length; i < l; i++) {
15208
- key = prototypeProperties[i];
15209
-
15210
- pushPropertyName(obj, ret, key);
15211
- }
15179
+ // modified from
15180
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
15181
+ keys = (function () {
15182
+ var hasOwnProperty = Object.prototype.hasOwnProperty,
15183
+ hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
15184
+ dontEnums = [
15185
+ 'toString',
15186
+ 'toLocaleString',
15187
+ 'valueOf',
15188
+ 'hasOwnProperty',
15189
+ 'isPrototypeOf',
15190
+ 'propertyIsEnumerable',
15191
+ 'constructor'
15192
+ ],
15193
+ dontEnumsLength = dontEnums.length;
15194
+
15195
+ return function keys(obj) {
15196
+ if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
15197
+ throw new TypeError('Object.keys called on non-object');
15198
+ }
15199
+
15200
+ var result = [], prop, i;
15201
+
15202
+ for (prop in obj) {
15203
+ if (prop !== '_super' &&
15204
+ prop.lastIndexOf('__',0) !== 0 &&
15205
+ hasOwnProperty.call(obj, prop)) {
15206
+ result.push(prop);
15207
+ }
15208
+ }
15212
15209
 
15213
- return ret;
15214
- };
15210
+ if (hasDontEnumBug) {
15211
+ for (i = 0; i < dontEnumsLength; i++) {
15212
+ if (hasOwnProperty.call(obj, dontEnums[i])) {
15213
+ result.push(dontEnums[i]);
15214
+ }
15215
+ }
15216
+ }
15217
+ return result;
15218
+ };
15219
+ }());
15215
15220
  }
15216
15221
 
15217
15222
  __exports__["default"] = keys;
@@ -15413,8 +15418,8 @@ define("ember-metal/logger",
15413
15418
  };
15414
15419
  });
15415
15420
  define("ember-metal/map",
15416
- ["ember-metal/property_set","ember-metal/utils","ember-metal/array","ember-metal/platform","exports"],
15417
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
15421
+ ["ember-metal/utils","ember-metal/array","ember-metal/platform","exports"],
15422
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
15418
15423
  "use strict";
15419
15424
  /**
15420
15425
  @module ember-metal
@@ -15440,13 +15445,20 @@ define("ember-metal/map",
15440
15445
  `Ember.Map.create()` for symmetry with other Ember classes.
15441
15446
  */
15442
15447
 
15443
- var set = __dependency1__.set;
15444
- var guidFor = __dependency2__.guidFor;
15445
- var indexOf = __dependency3__.indexOf;
15446
- var create = __dependency4__.create;
15448
+ var guidFor = __dependency1__.guidFor;
15449
+ var indexOf = __dependency2__.indexOf;
15450
+ var create = __dependency3__.create;
15447
15451
 
15448
- function copy(obj) {
15449
- var output = {};
15452
+ function missingFunction(fn) {
15453
+ throw new TypeError('' + Object.prototype.toString.call(fn) + " is not a function");
15454
+ }
15455
+
15456
+ function missingNew(name) {
15457
+ throw new TypeError("Constructor " + name + "requires 'new'");
15458
+ }
15459
+
15460
+ function copyNull(obj) {
15461
+ var output = Object.create(null);
15450
15462
 
15451
15463
  for (var prop in obj) {
15452
15464
  // hasOwnPropery is not needed because obj is Object.create(null);
@@ -15458,11 +15470,11 @@ define("ember-metal/map",
15458
15470
 
15459
15471
  function copyMap(original, newObject) {
15460
15472
  var keys = original.keys.copy();
15461
- var values = copy(original.values);
15473
+ var values = copyNull(original.values);
15462
15474
 
15463
15475
  newObject.keys = keys;
15464
15476
  newObject.values = values;
15465
- newObject.length = original.length;
15477
+ newObject.size = original.size;
15466
15478
 
15467
15479
  return newObject;
15468
15480
  }
@@ -15478,7 +15490,12 @@ define("ember-metal/map",
15478
15490
  @private
15479
15491
  */
15480
15492
  function OrderedSet() {
15481
- this.clear();
15493
+
15494
+ if (this instanceof OrderedSet) {
15495
+ this.clear();
15496
+ } else {
15497
+ missingNew("OrderedSet");
15498
+ }
15482
15499
  }
15483
15500
 
15484
15501
  /**
@@ -15487,47 +15504,77 @@ define("ember-metal/map",
15487
15504
  @return {Ember.OrderedSet}
15488
15505
  */
15489
15506
  OrderedSet.create = function() {
15490
- return new OrderedSet();
15507
+ var Constructor = this;
15508
+
15509
+ return new Constructor();
15491
15510
  };
15492
15511
 
15493
15512
  OrderedSet.prototype = {
15513
+ constructor: OrderedSet,
15494
15514
  /**
15495
15515
  @method clear
15496
15516
  */
15497
15517
  clear: function() {
15498
15518
  this.presenceSet = Object.create(null);
15499
15519
  this.list = [];
15520
+ this.size = 0;
15500
15521
  },
15501
15522
 
15502
15523
  /**
15503
15524
  @method add
15504
15525
  @param obj
15526
+ @param guid (optional, and for internal use)
15527
+ @return {Ember.OrderedSet}
15505
15528
  */
15506
- add: function(obj) {
15507
- var guid = guidFor(obj);
15529
+ add: function(obj, _guid) {
15530
+ var guid = _guid || guidFor(obj);
15508
15531
  var presenceSet = this.presenceSet;
15509
15532
  var list = this.list;
15510
15533
 
15511
- if (presenceSet[guid]) { return; }
15534
+ if (presenceSet[guid]) {
15535
+ return;
15536
+ }
15512
15537
 
15513
15538
  presenceSet[guid] = true;
15514
15539
  list.push(obj);
15540
+ this.size++;
15541
+
15542
+ return this;
15515
15543
  },
15516
15544
 
15517
15545
  /**
15546
+ @deprecated
15547
+
15518
15548
  @method remove
15519
15549
  @param obj
15550
+ @param _guid (optional and for internal use only)
15551
+ @return {Boolean}
15520
15552
  */
15521
- remove: function(obj) {
15522
- var guid = guidFor(obj);
15553
+ remove: function(obj, _guid) {
15554
+ return this['delete'](obj, _guid);
15555
+ },
15556
+
15557
+ /**
15558
+ @method delete
15559
+ @param obj
15560
+ @param _guid (optional and for internal use only)
15561
+ @return {Boolean}
15562
+ */
15563
+ 'delete': function(obj, _guid) {
15564
+ var guid = _guid || guidFor(obj);
15523
15565
  var presenceSet = this.presenceSet;
15524
15566
  var list = this.list;
15525
15567
 
15526
- delete presenceSet[guid];
15527
-
15528
- var index = indexOf.call(list, obj);
15529
- if (index > -1) {
15530
- list.splice(index, 1);
15568
+ if (presenceSet[guid] !== undefined) {
15569
+ delete presenceSet[guid];
15570
+ var index = indexOf.call(list, obj);
15571
+ if (index > -1) {
15572
+ list.splice(index, 1);
15573
+ }
15574
+ this.size--;
15575
+ return true;
15576
+ } else {
15577
+ return false;
15531
15578
  }
15532
15579
  },
15533
15580
 
@@ -15536,7 +15583,7 @@ define("ember-metal/map",
15536
15583
  @return {Boolean}
15537
15584
  */
15538
15585
  isEmpty: function() {
15539
- return this.list.length === 0;
15586
+ return this.size === 0;
15540
15587
  },
15541
15588
 
15542
15589
  /**
@@ -15548,7 +15595,7 @@ define("ember-metal/map",
15548
15595
  var guid = guidFor(obj);
15549
15596
  var presenceSet = this.presenceSet;
15550
15597
 
15551
- return presenceSet[guid];
15598
+ return !!presenceSet[guid];
15552
15599
  },
15553
15600
 
15554
15601
  /**
@@ -15556,12 +15603,19 @@ define("ember-metal/map",
15556
15603
  @param {Function} fn
15557
15604
  @param self
15558
15605
  */
15559
- forEach: function(fn, self) {
15560
- // allow mutation during iteration
15561
- var list = this.toArray();
15606
+ forEach: function(fn, thisArg) {
15607
+ var list = this.list;
15608
+ var length = arguments.length;
15609
+ var i;
15562
15610
 
15563
- for (var i = 0, j = list.length; i < j; i++) {
15564
- fn.call(self, list[i]);
15611
+ if (length === 2) {
15612
+ for (i = 0; i < list.length; i++) {
15613
+ fn.call(thisArg, list[i]);
15614
+ }
15615
+ } else {
15616
+ for (i = 0; i < list.length; i++) {
15617
+ fn(list[i]);
15618
+ }
15565
15619
  }
15566
15620
  },
15567
15621
 
@@ -15578,9 +15632,10 @@ define("ember-metal/map",
15578
15632
  @return {Ember.OrderedSet}
15579
15633
  */
15580
15634
  copy: function() {
15581
- var set = new OrderedSet();
15635
+ var Constructor = this.constructor;
15636
+ var set = new Constructor();
15582
15637
 
15583
- set.presenceSet = copy(this.presenceSet);
15638
+ set.presenceSet = copyNull(this.presenceSet);
15584
15639
  set.list = this.toArray();
15585
15640
 
15586
15641
  return set;
@@ -15608,8 +15663,13 @@ define("ember-metal/map",
15608
15663
  @constructor
15609
15664
  */
15610
15665
  function Map() {
15611
- this.keys = OrderedSet.create();
15612
- this.values = Object.create(null);
15666
+ if (this instanceof this.constructor) {
15667
+ this.keys = OrderedSet.create();
15668
+ this.values = Object.create(null);
15669
+ this.size = 0;
15670
+ } else {
15671
+ missingNew("OrderedSet");
15672
+ }
15613
15673
  }
15614
15674
 
15615
15675
  Ember.Map = Map;
@@ -15619,18 +15679,21 @@ define("ember-metal/map",
15619
15679
  @static
15620
15680
  */
15621
15681
  Map.create = function() {
15622
- return new Map();
15682
+ var Constructor = this;
15683
+ return new Constructor();
15623
15684
  };
15624
15685
 
15625
15686
  Map.prototype = {
15687
+ constructor: Map,
15688
+
15626
15689
  /**
15627
15690
  This property will change as the number of objects in the map changes.
15628
15691
 
15629
- @property length
15692
+ @property size
15630
15693
  @type number
15631
15694
  @default 0
15632
15695
  */
15633
- length: 0,
15696
+ size: 0,
15634
15697
 
15635
15698
  /**
15636
15699
  Retrieve the value associated with a given key.
@@ -15653,18 +15716,23 @@ define("ember-metal/map",
15653
15716
  @method set
15654
15717
  @param {*} key
15655
15718
  @param {*} value
15719
+ @return {Ember.Map}
15656
15720
  */
15657
15721
  set: function(key, value) {
15658
15722
  var keys = this.keys;
15659
15723
  var values = this.values;
15660
15724
  var guid = guidFor(key);
15661
15725
 
15662
- keys.add(key);
15726
+ keys.add(key, guid);
15663
15727
  values[guid] = value;
15664
- set(this, 'length', keys.list.length);
15728
+
15729
+ this.size = keys.size;
15730
+
15731
+ return this;
15665
15732
  },
15666
15733
 
15667
15734
  /**
15735
+ @deprecated see delete
15668
15736
  Removes a value from the map for an associated key.
15669
15737
 
15670
15738
  @method remove
@@ -15672,6 +15740,17 @@ define("ember-metal/map",
15672
15740
  @return {Boolean} true if an item was removed, false otherwise
15673
15741
  */
15674
15742
  remove: function(key) {
15743
+ return this['delete'](key);
15744
+ },
15745
+
15746
+ /**
15747
+ Removes a value from the map for an associated key.
15748
+
15749
+ @method delete
15750
+ @param {*} key
15751
+ @return {Boolean} true if an item was removed, false otherwise
15752
+ */
15753
+ 'delete': function(key) {
15675
15754
  // don't use ES6 "delete" because it will be annoying
15676
15755
  // to use in browsers that are not ES6 friendly;
15677
15756
  var keys = this.keys;
@@ -15679,9 +15758,9 @@ define("ember-metal/map",
15679
15758
  var guid = guidFor(key);
15680
15759
 
15681
15760
  if (values[guid]) {
15682
- keys.remove(key);
15761
+ keys.remove(key, guid);
15683
15762
  delete values[guid];
15684
- set(this, 'length', keys.list.length);
15763
+ this.size = keys.size;
15685
15764
  return true;
15686
15765
  } else {
15687
15766
  return false;
@@ -15696,10 +15775,7 @@ define("ember-metal/map",
15696
15775
  @return {Boolean} true if the item was present, false otherwise
15697
15776
  */
15698
15777
  has: function(key) {
15699
- var values = this.values;
15700
- var guid = guidFor(key);
15701
-
15702
- return !!values[guid];
15778
+ return this.keys.has(key);
15703
15779
  },
15704
15780
 
15705
15781
  /**
@@ -15713,14 +15789,26 @@ define("ember-metal/map",
15713
15789
  @param {*} self if passed, the `this` value inside the
15714
15790
  callback. By default, `this` is the map.
15715
15791
  */
15716
- forEach: function(callback, self) {
15717
- var keys = this.keys;
15718
- var values = this.values;
15792
+ forEach: function(callback, thisArg) {
15793
+ if (typeof callback !== 'function') {
15794
+ missingFunction(callback);
15795
+ }
15719
15796
 
15720
- keys.forEach(function(key) {
15721
- var guid = guidFor(key);
15722
- callback.call(self, key, values[guid]);
15723
- });
15797
+ var length = arguments.length;
15798
+ var map = this;
15799
+ var cb;
15800
+
15801
+ if (length === 2) {
15802
+ cb = function(key) {
15803
+ callback.call(thisArg, map.get(key), key);
15804
+ };
15805
+ } else {
15806
+ cb = function(key) {
15807
+ callback(map.get(key), key);
15808
+ };
15809
+ }
15810
+
15811
+ this.keys.forEach(cb);
15724
15812
  },
15725
15813
 
15726
15814
  /**
@@ -15791,7 +15879,8 @@ define("ember-metal/map",
15791
15879
  @return {Ember.MapWithDefault}
15792
15880
  */
15793
15881
  MapWithDefault.prototype.copy = function() {
15794
- return copyMap(this, new MapWithDefault({
15882
+ var Constructor = this.constructor;
15883
+ return copyMap(this, new Constructor({
15795
15884
  defaultValue: this.defaultValue
15796
15885
  }));
15797
15886
  };
@@ -15801,9 +15890,11 @@ define("ember-metal/map",
15801
15890
  __exports__.MapWithDefault = MapWithDefault;
15802
15891
  });
15803
15892
  define("ember-metal/merge",
15804
- ["exports"],
15805
- function(__exports__) {
15893
+ ["ember-metal/keys","exports"],
15894
+ function(__dependency1__, __exports__) {
15806
15895
  "use strict";
15896
+ var keys = __dependency1__["default"];
15897
+
15807
15898
  /**
15808
15899
  Merge the contents of two objects together into the first object.
15809
15900
 
@@ -15820,10 +15911,19 @@ define("ember-metal/merge",
15820
15911
  @return {Object}
15821
15912
  */
15822
15913
  __exports__["default"] = function merge(original, updates) {
15823
- for (var prop in updates) {
15824
- if (!updates.hasOwnProperty(prop)) { continue; }
15914
+ if (!updates || typeof updates !== 'object') {
15915
+ return original;
15916
+ }
15917
+
15918
+ var props = keys(updates);
15919
+ var prop;
15920
+ var length = props.length;
15921
+
15922
+ for (var i = 0; i < length; i++) {
15923
+ prop = props[i];
15825
15924
  original[prop] = updates[prop];
15826
15925
  }
15926
+
15827
15927
  return original;
15828
15928
  }
15829
15929
  });
@@ -29603,8 +29703,8 @@ define("ember-runtime/mixins/action_handler",
29603
29703
  __exports__["default"] = ActionHandler;
29604
29704
  });
29605
29705
  define("ember-runtime/mixins/array",
29606
- ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/is_none","ember-runtime/mixins/enumerable","ember-metal/enumerable_utils","ember-metal/mixin","ember-metal/property_events","ember-metal/events","ember-metal/watching","exports"],
29607
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) {
29706
+ ["ember-metal/core","ember-metal/property_get","ember-metal/computed","ember-metal/is_none","ember-runtime/mixins/enumerable","ember-metal/enumerable_utils","ember-metal/mixin","ember-metal/property_events","ember-metal/events","ember-metal/watching","exports"],
29707
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
29608
29708
  "use strict";
29609
29709
  /**
29610
29710
  @module ember
@@ -29616,24 +29716,22 @@ define("ember-runtime/mixins/array",
29616
29716
  //
29617
29717
  var Ember = __dependency1__["default"];
29618
29718
  // ES6TODO: Ember.A
29619
-
29620
29719
  var get = __dependency2__.get;
29621
- var set = __dependency3__.set;
29622
- var computed = __dependency4__.computed;
29623
- var cacheFor = __dependency4__.cacheFor;
29624
- var isNone = __dependency5__.isNone;
29625
- var none = __dependency5__.none;
29626
- var Enumerable = __dependency6__["default"];
29627
- var map = __dependency7__.map;
29628
- var Mixin = __dependency8__.Mixin;
29629
- var required = __dependency8__.required;
29630
- var propertyWillChange = __dependency9__.propertyWillChange;
29631
- var propertyDidChange = __dependency9__.propertyDidChange;
29632
- var addListener = __dependency10__.addListener;
29633
- var removeListener = __dependency10__.removeListener;
29634
- var sendEvent = __dependency10__.sendEvent;
29635
- var hasListeners = __dependency10__.hasListeners;
29636
- var isWatching = __dependency11__.isWatching;
29720
+ var computed = __dependency3__.computed;
29721
+ var cacheFor = __dependency3__.cacheFor;
29722
+ var isNone = __dependency4__.isNone;
29723
+ var none = __dependency4__.none;
29724
+ var Enumerable = __dependency5__["default"];
29725
+ var map = __dependency6__.map;
29726
+ var Mixin = __dependency7__.Mixin;
29727
+ var required = __dependency7__.required;
29728
+ var propertyWillChange = __dependency8__.propertyWillChange;
29729
+ var propertyDidChange = __dependency8__.propertyDidChange;
29730
+ var addListener = __dependency9__.addListener;
29731
+ var removeListener = __dependency9__.removeListener;
29732
+ var sendEvent = __dependency9__.sendEvent;
29733
+ var hasListeners = __dependency9__.hasListeners;
29734
+ var isWatching = __dependency10__.isWatching;
29637
29735
 
29638
29736
  function arrayObserversHelper(obj, target, opts, operation, notify) {
29639
29737
  var willChange = (opts && opts.willChange) || 'arrayWillChange';
@@ -29650,6 +29748,7 @@ define("ember-runtime/mixins/array",
29650
29748
  if (hasObservers === notify) {
29651
29749
  propertyDidChange(obj, 'hasArrayObservers');
29652
29750
  }
29751
+
29653
29752
  return obj;
29654
29753
  }
29655
29754
 
@@ -29713,8 +29812,9 @@ define("ember-runtime/mixins/array",
29713
29812
 
29714
29813
  ```javascript
29715
29814
  var arr = ['a', 'b', 'c', 'd'];
29716
- arr.objectAt(0); // "a"
29717
- arr.objectAt(3); // "d"
29815
+
29816
+ arr.objectAt(0); // 'a'
29817
+ arr.objectAt(3); // 'd'
29718
29818
  arr.objectAt(-1); // undefined
29719
29819
  arr.objectAt(4); // undefined
29720
29820
  arr.objectAt(5); // undefined
@@ -29725,7 +29825,10 @@ define("ember-runtime/mixins/array",
29725
29825
  @return {*} item at index or undefined
29726
29826
  */
29727
29827
  objectAt: function(idx) {
29728
- if (idx < 0 || idx >= get(this, 'length')) return undefined;
29828
+ if (idx < 0 || idx >= get(this, 'length')) {
29829
+ return undefined;
29830
+ }
29831
+
29729
29832
  return get(this, idx);
29730
29833
  },
29731
29834
 
@@ -29734,8 +29837,9 @@ define("ember-runtime/mixins/array",
29734
29837
 
29735
29838
  ```javascript
29736
29839
  var arr = ['a', 'b', 'c', 'd'];
29737
- arr.objectsAt([0, 1, 2]); // ["a", "b", "c"]
29738
- arr.objectsAt([2, 3, 4]); // ["c", "d", undefined]
29840
+
29841
+ arr.objectsAt([0, 1, 2]); // ['a', 'b', 'c']
29842
+ arr.objectsAt([2, 3, 4]); // ['c', 'd', undefined]
29739
29843
  ```
29740
29844
 
29741
29845
  @method objectsAt
@@ -29744,7 +29848,10 @@ define("ember-runtime/mixins/array",
29744
29848
  */
29745
29849
  objectsAt: function(indexes) {
29746
29850
  var self = this;
29747
- return map(indexes, function(idx) { return self.objectAt(idx); });
29851
+
29852
+ return map(indexes, function(idx) {
29853
+ return self.objectAt(idx);
29854
+ });
29748
29855
  },
29749
29856
 
29750
29857
  // overrides Ember.Enumerable version
@@ -29763,7 +29870,10 @@ define("ember-runtime/mixins/array",
29763
29870
  @return this
29764
29871
  */
29765
29872
  '[]': computed(function(key, value) {
29766
- if (value !== undefined) this.replace(0, get(this, 'length'), value) ;
29873
+ if (value !== undefined) {
29874
+ this.replace(0, get(this, 'length'), value);
29875
+ }
29876
+
29767
29877
  return this;
29768
29878
  }),
29769
29879
 
@@ -29772,7 +29882,7 @@ define("ember-runtime/mixins/array",
29772
29882
  }),
29773
29883
 
29774
29884
  lastObject: computed(function() {
29775
- return this.objectAt(get(this, 'length')-1);
29885
+ return this.objectAt(get(this, 'length') - 1);
29776
29886
  }),
29777
29887
 
29778
29888
  // optimized version from Enumerable
@@ -29788,6 +29898,7 @@ define("ember-runtime/mixins/array",
29788
29898
 
29789
29899
  ```javascript
29790
29900
  var arr = ['red', 'green', 'blue'];
29901
+
29791
29902
  arr.slice(0); // ['red', 'green', 'blue']
29792
29903
  arr.slice(0, 2); // ['red', 'green']
29793
29904
  arr.slice(1, 100); // ['green', 'blue']
@@ -29800,17 +29911,29 @@ define("ember-runtime/mixins/array",
29800
29911
  */
29801
29912
  slice: function(beginIndex, endIndex) {
29802
29913
  var ret = Ember.A();
29803
- var length = get(this, 'length') ;
29804
- if (isNone(beginIndex)) beginIndex = 0 ;
29805
- if (isNone(endIndex) || (endIndex > length)) endIndex = length ;
29914
+ var length = get(this, 'length');
29915
+
29916
+ if (isNone(beginIndex)) {
29917
+ beginIndex = 0;
29918
+ }
29806
29919
 
29807
- if (beginIndex < 0) beginIndex = length + beginIndex;
29808
- if (endIndex < 0) endIndex = length + endIndex;
29920
+ if (isNone(endIndex) || (endIndex > length)) {
29921
+ endIndex = length;
29922
+ }
29809
29923
 
29810
- while(beginIndex < endIndex) {
29811
- ret[ret.length] = this.objectAt(beginIndex++) ;
29924
+ if (beginIndex < 0) {
29925
+ beginIndex = length + beginIndex;
29812
29926
  }
29813
- return ret ;
29927
+
29928
+ if (endIndex < 0) {
29929
+ endIndex = length + endIndex;
29930
+ }
29931
+
29932
+ while (beginIndex < endIndex) {
29933
+ ret[ret.length] = this.objectAt(beginIndex++);
29934
+ }
29935
+
29936
+ return ret;
29814
29937
  },
29815
29938
 
29816
29939
  /**
@@ -29820,13 +29943,14 @@ define("ember-runtime/mixins/array",
29820
29943
  the end of the array. Returns -1 if no match is found.
29821
29944
 
29822
29945
  ```javascript
29823
- var arr = ["a", "b", "c", "d", "a"];
29824
- arr.indexOf("a"); // 0
29825
- arr.indexOf("z"); // -1
29826
- arr.indexOf("a", 2); // 4
29827
- arr.indexOf("a", -1); // 4
29828
- arr.indexOf("b", 3); // -1
29829
- arr.indexOf("a", 100); // -1
29946
+ var arr = ['a', 'b', 'c', 'd', 'a'];
29947
+
29948
+ arr.indexOf('a'); // 0
29949
+ arr.indexOf('z'); // -1
29950
+ arr.indexOf('a', 2); // 4
29951
+ arr.indexOf('a', -1); // 4
29952
+ arr.indexOf('b', 3); // -1
29953
+ arr.indexOf('a', 100); // -1
29830
29954
  ```
29831
29955
 
29832
29956
  @method indexOf
@@ -29835,14 +29959,23 @@ define("ember-runtime/mixins/array",
29835
29959
  @return {Number} index or -1 if not found
29836
29960
  */
29837
29961
  indexOf: function(object, startAt) {
29838
- var idx, len = get(this, 'length');
29962
+ var len = get(this, 'length');
29963
+ var idx;
29839
29964
 
29840
- if (startAt === undefined) startAt = 0;
29841
- if (startAt < 0) startAt += len;
29965
+ if (startAt === undefined) {
29966
+ startAt = 0;
29967
+ }
29842
29968
 
29843
- for(idx = startAt; idx < len; idx++) {
29844
- if (this.objectAt(idx) === object) return idx;
29969
+ if (startAt < 0) {
29970
+ startAt += len;
29971
+ }
29972
+
29973
+ for (idx = startAt; idx < len; idx++) {
29974
+ if (this.objectAt(idx) === object) {
29975
+ return idx;
29976
+ }
29845
29977
  }
29978
+
29846
29979
  return -1;
29847
29980
  },
29848
29981
 
@@ -29853,13 +29986,14 @@ define("ember-runtime/mixins/array",
29853
29986
  from the end of the array. Returns -1 if no match is found.
29854
29987
 
29855
29988
  ```javascript
29856
- var arr = ["a", "b", "c", "d", "a"];
29857
- arr.lastIndexOf("a"); // 4
29858
- arr.lastIndexOf("z"); // -1
29859
- arr.lastIndexOf("a", 2); // 0
29860
- arr.lastIndexOf("a", -1); // 4
29861
- arr.lastIndexOf("b", 3); // 1
29862
- arr.lastIndexOf("a", 100); // 4
29989
+ var arr = ['a', 'b', 'c', 'd', 'a'];
29990
+
29991
+ arr.lastIndexOf('a'); // 4
29992
+ arr.lastIndexOf('z'); // -1
29993
+ arr.lastIndexOf('a', 2); // 0
29994
+ arr.lastIndexOf('a', -1); // 4
29995
+ arr.lastIndexOf('b', 3); // 1
29996
+ arr.lastIndexOf('a', 100); // 4
29863
29997
  ```
29864
29998
 
29865
29999
  @method lastIndexOf
@@ -29868,14 +30002,23 @@ define("ember-runtime/mixins/array",
29868
30002
  @return {Number} index or -1 if not found
29869
30003
  */
29870
30004
  lastIndexOf: function(object, startAt) {
29871
- var idx, len = get(this, 'length');
30005
+ var len = get(this, 'length');
30006
+ var idx;
30007
+
30008
+ if (startAt === undefined || startAt >= len) {
30009
+ startAt = len-1;
30010
+ }
29872
30011
 
29873
- if (startAt === undefined || startAt >= len) startAt = len-1;
29874
- if (startAt < 0) startAt += len;
30012
+ if (startAt < 0) {
30013
+ startAt += len;
30014
+ }
29875
30015
 
29876
- for(idx = startAt; idx >= 0; idx--) {
29877
- if (this.objectAt(idx) === object) return idx;
30016
+ for (idx = startAt; idx >= 0; idx--) {
30017
+ if (this.objectAt(idx) === object) {
30018
+ return idx;
30019
+ }
29878
30020
  }
30021
+
29879
30022
  return -1;
29880
30023
  },
29881
30024
 
@@ -29952,26 +30095,36 @@ define("ember-runtime/mixins/array",
29952
30095
  @return {Ember.Array} receiver
29953
30096
  */
29954
30097
  arrayContentWillChange: function(startIdx, removeAmt, addAmt) {
30098
+ var removing, lim;
29955
30099
 
29956
30100
  // if no args are passed assume everything changes
29957
- if (startIdx===undefined) {
30101
+ if (startIdx === undefined) {
29958
30102
  startIdx = 0;
29959
30103
  removeAmt = addAmt = -1;
29960
30104
  } else {
29961
- if (removeAmt === undefined) removeAmt=-1;
29962
- if (addAmt === undefined) addAmt=-1;
30105
+ if (removeAmt === undefined) {
30106
+ removeAmt = -1;
30107
+ }
30108
+
30109
+ if (addAmt === undefined) {
30110
+ addAmt = -1;
30111
+ }
29963
30112
  }
29964
30113
 
29965
30114
  // Make sure the @each proxy is set up if anyone is observing @each
29966
- if (isWatching(this, '@each')) { get(this, '@each'); }
30115
+ if (isWatching(this, '@each')) {
30116
+ get(this, '@each');
30117
+ }
29967
30118
 
29968
30119
  sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]);
29969
30120
 
29970
- var removing, lim;
29971
- if (startIdx>=0 && removeAmt>=0 && get(this, 'hasEnumerableObservers')) {
30121
+ if (startIdx >= 0 && removeAmt >= 0 && get(this, 'hasEnumerableObservers')) {
29972
30122
  removing = [];
29973
- lim = startIdx+removeAmt;
29974
- for(var idx=startIdx;idx<lim;idx++) removing.push(this.objectAt(idx));
30123
+ lim = startIdx + removeAmt;
30124
+
30125
+ for (var idx = startIdx; idx < lim; idx++) {
30126
+ removing.push(this.objectAt(idx));
30127
+ }
29975
30128
  } else {
29976
30129
  removing = removeAmt;
29977
30130
  }
@@ -29996,21 +30149,29 @@ define("ember-runtime/mixins/array",
29996
30149
  @return {Ember.Array} receiver
29997
30150
  */
29998
30151
  arrayContentDidChange: function(startIdx, removeAmt, addAmt) {
30152
+ var adding, lim;
29999
30153
 
30000
30154
  // if no args are passed assume everything changes
30001
- if (startIdx===undefined) {
30155
+ if (startIdx === undefined) {
30002
30156
  startIdx = 0;
30003
30157
  removeAmt = addAmt = -1;
30004
30158
  } else {
30005
- if (removeAmt === undefined) removeAmt=-1;
30006
- if (addAmt === undefined) addAmt=-1;
30159
+ if (removeAmt === undefined) {
30160
+ removeAmt = -1;
30161
+ }
30162
+
30163
+ if (addAmt === undefined) {
30164
+ addAmt = -1;
30165
+ }
30007
30166
  }
30008
30167
 
30009
- var adding, lim;
30010
- if (startIdx>=0 && addAmt>=0 && get(this, 'hasEnumerableObservers')) {
30168
+ if (startIdx >= 0 && addAmt >= 0 && get(this, 'hasEnumerableObservers')) {
30011
30169
  adding = [];
30012
- lim = startIdx+addAmt;
30013
- for(var idx=startIdx;idx<lim;idx++) adding.push(this.objectAt(idx));
30170
+ lim = startIdx + addAmt;
30171
+
30172
+ for (var idx = startIdx; idx < lim; idx++) {
30173
+ adding.push(this.objectAt(idx));
30174
+ }
30014
30175
  } else {
30015
30176
  adding = addAmt;
30016
30177
  }
@@ -30018,13 +30179,15 @@ define("ember-runtime/mixins/array",
30018
30179
  this.enumerableContentDidChange(removeAmt, adding);
30019
30180
  sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]);
30020
30181
 
30021
- var length = get(this, 'length');
30182
+ var length = get(this, 'length');
30022
30183
  var cachedFirst = cacheFor(this, 'firstObject');
30023
- var cachedLast = cacheFor(this, 'lastObject');
30184
+ var cachedLast = cacheFor(this, 'lastObject');
30185
+
30024
30186
  if (this.objectAt(0) !== cachedFirst) {
30025
30187
  propertyWillChange(this, 'firstObject');
30026
30188
  propertyDidChange(this, 'firstObject');
30027
30189
  }
30190
+
30028
30191
  if (this.objectAt(length-1) !== cachedLast) {
30029
30192
  propertyWillChange(this, 'lastObject');
30030
30193
  propertyDidChange(this, 'lastObject');
@@ -37944,7 +38107,6 @@ define("ember-views",
37944
38107
  // BEGIN IMPORTS
37945
38108
  var Ember = __dependency1__["default"];
37946
38109
  var jQuery = __dependency2__["default"];
37947
- var setInnerHTML = __dependency3__.setInnerHTML;
37948
38110
  var isSimpleClick = __dependency3__.isSimpleClick;
37949
38111
  var RenderBuffer = __dependency4__["default"];
37950
38112
  // for the side effect of extending Ember.run.queues
@@ -37975,7 +38137,6 @@ define("ember-views",
37975
38137
  Ember.RenderBuffer = RenderBuffer;
37976
38138
 
37977
38139
  var ViewUtils = Ember.ViewUtils = {};
37978
- ViewUtils.setInnerHTML = setInnerHTML;
37979
38140
  ViewUtils.isSimpleClick = isSimpleClick;
37980
38141
 
37981
38142
  Ember.CoreView = CoreView;
@@ -38459,22 +38620,63 @@ define("ember-views/system/jquery",
38459
38620
  __exports__["default"] = jQuery;
38460
38621
  });
38461
38622
  define("ember-views/system/render_buffer",
38462
- ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-views/system/utils","ember-views/system/jquery","morph","exports"],
38463
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) {
38623
+ ["ember-views/system/jquery","morph","ember-metal/core","exports"],
38624
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
38464
38625
  "use strict";
38465
38626
  /**
38466
38627
  @module ember
38467
38628
  @submodule ember-views
38468
38629
  */
38469
38630
 
38470
- var Ember = __dependency1__["default"];
38471
- // jQuery
38631
+ var jQuery = __dependency1__["default"];
38632
+ var DOMHelper = __dependency2__.DOMHelper;
38633
+ var Ember = __dependency3__["default"];
38472
38634
 
38473
- var get = __dependency2__.get;
38474
- var set = __dependency3__.set;
38475
- var setInnerHTML = __dependency4__.setInnerHTML;
38476
- var jQuery = __dependency5__["default"];
38477
- var DOMHelper = __dependency6__.DOMHelper;
38635
+ // The HTML spec allows for "omitted start tags". These tags are optional
38636
+ // when their intended child is the first thing in the parent tag. For
38637
+ // example, this is a tbody start tag:
38638
+ //
38639
+ // <table>
38640
+ // <tbody>
38641
+ // <tr>
38642
+ //
38643
+ // The tbody may be omitted, and the browser will accept and render:
38644
+ //
38645
+ // <table>
38646
+ // <tr>
38647
+ //
38648
+ // However, the omitted start tag will still be added to the DOM. Here
38649
+ // we test the string and context to see if the browser is about to
38650
+ // perform this cleanup, but with a special allowance for disregarding
38651
+ // <script tags. This disregarding of <script being the first child item
38652
+ // may bend the offical spec a bit, and is only needed for Handlebars
38653
+ // templates.
38654
+ //
38655
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
38656
+ // describes which tags are omittable. The spec for tbody and colgroup
38657
+ // explains this behavior:
38658
+ //
38659
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-tbody-element
38660
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-colgroup-element
38661
+ //
38662
+ var omittedStartTagChildren = {
38663
+ tr: document.createElement('tbody'),
38664
+ col: document.createElement('colgroup')
38665
+ };
38666
+
38667
+ var omittedStartTagChildTest = /(?:<script)*.*?<([\w:]+)/i;
38668
+
38669
+ function detectOmittedStartTag(string, contextualElement){
38670
+ // Omitted start tags are only inside table tags.
38671
+ if (contextualElement.tagName === 'TABLE') {
38672
+ var omittedStartTagChildMatch = omittedStartTagChildTest.exec(string);
38673
+ if (omittedStartTagChildMatch) {
38674
+ // It is already asserted that the contextual element is a table
38675
+ // and not the proper start tag. Just look up the start tag.
38676
+ return omittedStartTagChildren[omittedStartTagChildMatch[1].toLowerCase()];
38677
+ }
38678
+ }
38679
+ }
38478
38680
 
38479
38681
  function ClassSet() {
38480
38682
  this.seen = {};
@@ -38552,19 +38754,20 @@ define("ember-views/system/render_buffer",
38552
38754
  to the DOM.
38553
38755
 
38554
38756
  ```javascript
38555
- var buffer = Ember.renderBuffer('div');
38757
+ var buffer = Ember.renderBuffer('div', contextualElement);
38556
38758
  ```
38557
38759
 
38558
38760
  @method renderBuffer
38559
38761
  @namespace Ember
38560
38762
  @param {String} tagName tag name (such as 'div' or 'p') used for the buffer
38561
38763
  */
38562
- __exports__["default"] = function renderBuffer(tagName) {
38563
- return new _RenderBuffer(tagName); // jshint ignore:line
38764
+ __exports__["default"] = function renderBuffer(tagName, contextualElement) {
38765
+ return new _RenderBuffer(tagName, contextualElement); // jshint ignore:line
38564
38766
  }
38565
38767
 
38566
- function _RenderBuffer(tagName) {
38768
+ function _RenderBuffer(tagName, contextualElement) {
38567
38769
  this.tagName = tagName;
38770
+ this._contextualElement = contextualElement;
38568
38771
  this.buffer = null;
38569
38772
  this.childViews = [];
38570
38773
  this.dom = new DOMHelper();
@@ -38572,10 +38775,11 @@ define("ember-views/system/render_buffer",
38572
38775
 
38573
38776
  _RenderBuffer.prototype = {
38574
38777
 
38575
- reset: function(tagName) {
38778
+ reset: function(tagName, contextualElement) {
38576
38779
  this.tagName = tagName;
38577
38780
  this.buffer = null;
38578
38781
  this._element = null;
38782
+ this._contextualElement = contextualElement;
38579
38783
  this.elementClasses = null;
38580
38784
  this.elementId = null;
38581
38785
  this.elementAttributes = null;
@@ -38588,6 +38792,9 @@ define("ember-views/system/render_buffer",
38588
38792
  // The root view's element
38589
38793
  _element: null,
38590
38794
 
38795
+ // The root view's contextualElement
38796
+ _contextualElement: null,
38797
+
38591
38798
  /**
38592
38799
  An internal set used to de-dupe class names when `addClass()` is
38593
38800
  used. After each call to `addClass()`, the `classes` property
@@ -38661,7 +38868,7 @@ define("ember-views/system/render_buffer",
38661
38868
  example, if you wanted to create a `p` tag, then you would call
38662
38869
 
38663
38870
  ```javascript
38664
- Ember.RenderBuffer('p')
38871
+ Ember.RenderBuffer('p', contextualElement)
38665
38872
  ```
38666
38873
 
38667
38874
  @property elementTag
@@ -38691,7 +38898,7 @@ define("ember-views/system/render_buffer",
38691
38898
  this.push("<script id='morph-"+index+"' type='text/x-placeholder'>\x3C/script>");
38692
38899
  },
38693
38900
 
38694
- hydrateMorphs: function () {
38901
+ hydrateMorphs: function (contextualElement) {
38695
38902
  var childViews = this.childViews;
38696
38903
  var el = this._element;
38697
38904
  for (var i=0,l=childViews.length; i<l; i++) {
@@ -38699,7 +38906,11 @@ define("ember-views/system/render_buffer",
38699
38906
  var ref = el.querySelector('#morph-'+i);
38700
38907
  var parent = ref.parentNode;
38701
38908
 
38702
- childView._morph = this.dom.insertMorphBefore(parent, ref);
38909
+ childView._morph = this.dom.insertMorphBefore(
38910
+ parent,
38911
+ ref,
38912
+ parent.nodeType === 1 ? parent : contextualElement
38913
+ );
38703
38914
  parent.removeChild(ref);
38704
38915
  }
38705
38916
  },
@@ -38861,7 +39072,7 @@ define("ember-views/system/render_buffer",
38861
39072
  tagString = tagName;
38862
39073
  }
38863
39074
 
38864
- var element = document.createElement(tagString);
39075
+ var element = this.dom.createElement(tagString);
38865
39076
  var $element = jQuery(element);
38866
39077
 
38867
39078
  if (id) {
@@ -38915,21 +39126,31 @@ define("ember-views/system/render_buffer",
38915
39126
  of this buffer
38916
39127
  */
38917
39128
  element: function() {
39129
+ if (!this._contextualElement) {
39130
+ Ember.deprecate("buffer.element expects a contextualElement to exist. This ensures DOM that requires context is correctly generated (tr, SVG tags). Defaulting to document.body, but this will be removed in the future");
39131
+ this._contextualElement = document.body;
39132
+ }
38918
39133
  var html = this.innerString();
38919
39134
 
39135
+ var nodes;
38920
39136
  if (this._element) {
38921
39137
  if (html) {
38922
- this._element = setInnerHTML(this._element, html);
38923
- this.hydrateMorphs();
39138
+ nodes = this.dom.parseHTML(html, this._element);
39139
+ while (nodes[0]) {
39140
+ this._element.appendChild(nodes[0]);
39141
+ }
39142
+ this.hydrateMorphs(this._element);
38924
39143
  }
38925
39144
  } else {
38926
39145
  if (html) {
39146
+ var omittedStartTag = detectOmittedStartTag(html, this._contextualElement);
39147
+ var contextualElement = omittedStartTag || this._contextualElement;
39148
+ nodes = this.dom.parseHTML(html, contextualElement);
38927
39149
  var frag = this._element = document.createDocumentFragment();
38928
- var parsed = jQuery.parseHTML(html);
38929
- for (var i=0,l=parsed.length; i<l; i++) {
38930
- frag.appendChild(parsed[i]);
39150
+ while (nodes[0]) {
39151
+ frag.appendChild(nodes[0]);
38931
39152
  }
38932
- this.hydrateMorphs();
39153
+ this.hydrateMorphs(contextualElement);
38933
39154
  } else if (html === '') {
38934
39155
  this._element = html;
38935
39156
  }
@@ -39026,7 +39247,7 @@ define("ember-views/system/renderer",
39026
39247
  };
39027
39248
 
39028
39249
  EmberRenderer.prototype.createElement =
39029
- function EmberRenderer_createElement(view) {
39250
+ function EmberRenderer_createElement(view, contextualElement) {
39030
39251
  // If this is the top-most view, start a new buffer. Otherwise,
39031
39252
  // create a new buffer relative to the original using the
39032
39253
  // provided buffer operation (for example, `insertAfter` will
@@ -39037,7 +39258,7 @@ define("ember-views/system/renderer",
39037
39258
  }
39038
39259
 
39039
39260
  var buffer = view.buffer = this.buffer;
39040
- buffer.reset(tagName);
39261
+ buffer.reset(tagName, contextualElement);
39041
39262
 
39042
39263
  if (view.beforeRender) {
39043
39264
  view.beforeRender(buffer);
@@ -39129,162 +39350,15 @@ define("ember-views/system/renderer",
39129
39350
  __exports__["default"] = EmberRenderer;
39130
39351
  });
39131
39352
  define("ember-views/system/utils",
39132
- ["ember-metal/core","ember-views/system/jquery","exports"],
39133
- function(__dependency1__, __dependency2__, __exports__) {
39353
+ ["exports"],
39354
+ function(__exports__) {
39134
39355
  "use strict";
39135
- /* globals XMLSerializer */
39136
-
39137
- var Ember = __dependency1__["default"];
39138
- // Ember.assert
39139
- var jQuery = __dependency2__["default"];
39140
-
39141
39356
  /**
39142
39357
  @module ember
39143
39358
  @submodule ember-views
39144
39359
  */
39145
39360
 
39146
- /* BEGIN METAMORPH HELPERS */
39147
-
39148
- // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
39149
- // is a "zero-scope" element. This problem can be worked around by making
39150
- // the first node an invisible text node. We, like Modernizr, use &shy;
39151
-
39152
- var needsShy = typeof document !== 'undefined' && (function() {
39153
- var testEl = document.createElement('div');
39154
- testEl.innerHTML = "<div></div>";
39155
- testEl.firstChild.innerHTML = "<script></script>";
39156
- return testEl.firstChild.innerHTML === '';
39157
- })();
39158
-
39159
- // IE 8 (and likely earlier) likes to move whitespace preceeding
39160
- // a script tag to appear after it. This means that we can
39161
- // accidentally remove whitespace when updating a morph.
39162
- var movesWhitespace = typeof document !== 'undefined' && (function() {
39163
- var testEl = document.createElement('div');
39164
- testEl.innerHTML = "Test: <script type='text/x-placeholder'></script>Value";
39165
- return testEl.childNodes[0].nodeValue === 'Test:' &&
39166
- testEl.childNodes[2].nodeValue === ' Value';
39167
- })();
39168
-
39169
- // Use this to find children by ID instead of using jQuery
39170
- var findChildById = function(element, id) {
39171
- if (element.getAttribute('id') === id) { return element; }
39172
-
39173
- var len = element.childNodes.length;
39174
- var idx, node, found;
39175
- for (idx=0; idx<len; idx++) {
39176
- node = element.childNodes[idx];
39177
- found = node.nodeType === 1 && findChildById(node, id);
39178
- if (found) { return found; }
39179
- }
39180
- };
39181
-
39182
- var setInnerHTMLWithoutFix = function(element, html) {
39183
- if (needsShy) {
39184
- html = '&shy;' + html;
39185
- }
39186
-
39187
- var matches = [];
39188
- if (movesWhitespace) {
39189
- // Right now we only check for script tags with ids with the
39190
- // goal of targeting morphs.
39191
- html = html.replace(/(\s+)(<script id='([^']+)')/g, function(match, spaces, tag, id) {
39192
- matches.push([id, spaces]);
39193
- return tag;
39194
- });
39195
- }
39196
-
39197
- element.innerHTML = html;
39198
-
39199
- // If we have to do any whitespace adjustments do them now
39200
- if (matches.length > 0) {
39201
- var len = matches.length;
39202
- var idx;
39203
- for (idx=0; idx<len; idx++) {
39204
- var script = findChildById(element, matches[idx][0]);
39205
- var node = document.createTextNode(matches[idx][1]);
39206
- script.parentNode.insertBefore(node, script);
39207
- }
39208
- }
39209
-
39210
- if (needsShy) {
39211
- var shyElement = element.firstChild;
39212
- while (shyElement.nodeType === 1 && !shyElement.nodeName) {
39213
- shyElement = shyElement.firstChild;
39214
- }
39215
- if (shyElement.nodeType === 3 && shyElement.nodeValue.charAt(0) === "\u00AD") {
39216
- shyElement.nodeValue = shyElement.nodeValue.slice(1);
39217
- }
39218
- }
39219
- };
39220
-
39221
- /* END METAMORPH HELPERS */
39222
-
39223
- function setInnerHTMLTestFactory(tagName, childTagName, ChildConstructor) {
39224
- return function() {
39225
- var el = document.createElement(tagName);
39226
- setInnerHTMLWithoutFix(el, '<' + childTagName + '>Content</' + childTagName + '>');
39227
- return el.firstChild instanceof ChildConstructor;
39228
- };
39229
- }
39230
-
39231
-
39232
- var innerHTMLTags = {
39233
- // IE 8 and earlier don't allow us to do innerHTML on select
39234
- select: function() {
39235
- var el = document.createElement('select');
39236
- setInnerHTMLWithoutFix(el, '<option value="test">Test</option>');
39237
- return el.options.length === 1;
39238
- },
39239
-
39240
- // IE 9 and earlier don't allow us to set innerHTML on col, colgroup, frameset,
39241
- // html, style, table, tbody, tfoot, thead, title, tr.
39242
- col: setInnerHTMLTestFactory('col', 'span', window.HTMLSpanElement),
39243
- colgroup: setInnerHTMLTestFactory('colgroup', 'col', window.HTMLTableColElement),
39244
- frameset: setInnerHTMLTestFactory('frameset', 'frame', window.HTMLFrameElement),
39245
- table: setInnerHTMLTestFactory('table', 'tbody', window.HTMLTableSectionElement),
39246
- tbody: setInnerHTMLTestFactory('tbody', 'tr', window.HTMLTableRowElement),
39247
- tfoot: setInnerHTMLTestFactory('tfoot', 'tr', window.HTMLTableRowElement),
39248
- thead: setInnerHTMLTestFactory('thead', 'tr', window.HTMLTableRowElement),
39249
- tr: setInnerHTMLTestFactory('tr', 'td', window.HTMLTableCellElement)
39250
- };
39251
-
39252
- var canSetInnerHTML = function(tagName) {
39253
- tagName = tagName.toLowerCase();
39254
- var canSet = innerHTMLTags[tagName];
39255
-
39256
- if (typeof canSet === 'function') {
39257
- canSet = innerHTMLTags[tagName] = canSet();
39258
- }
39259
-
39260
- return canSet === undefined ? true : canSet;
39261
- };
39262
-
39263
- function setInnerHTML(element, html) {
39264
- var tagName = element.tagName;
39265
-
39266
- if (canSetInnerHTML(tagName)) {
39267
- setInnerHTMLWithoutFix(element, html);
39268
- } else {
39269
- // Firefox versions < 11 do not have support for element.outerHTML.
39270
- var outerHTML = element.outerHTML || new XMLSerializer().serializeToString(element);
39271
- Ember.assert("Can't set innerHTML on "+element.tagName+" in this browser", outerHTML);
39272
-
39273
- var startTag = outerHTML.match(new RegExp("<"+tagName+"([^>]*)>", 'i'))[0];
39274
- var endTag = '</'+tagName+'>';
39275
-
39276
- var wrapper = document.createElement('div');
39277
- jQuery(startTag + html + endTag).appendTo(wrapper);
39278
- element = wrapper.firstChild;
39279
- while (element.tagName !== tagName) {
39280
- element = element.nextSibling;
39281
- }
39282
- }
39283
-
39284
- return element;
39285
- }
39286
-
39287
- __exports__.setInnerHTML = setInnerHTML;function isSimpleClick(event) {
39361
+ function isSimpleClick(event) {
39288
39362
  var modifier = event.shiftKey || event.metaKey || event.altKey || event.ctrlKey;
39289
39363
  var secondaryClick = event.which > 1; // IE9 may return undefined
39290
39364
 
@@ -42353,6 +42427,7 @@ define("ember-views/views/view",
42353
42427
  createElement: function() {
42354
42428
  if (this.element) { return this; }
42355
42429
 
42430
+ this._didCreateElementWithoutMorph = true;
42356
42431
  this.constructor.renderer.renderTree(this);
42357
42432
 
42358
42433
  return this;
@@ -42370,6 +42445,9 @@ define("ember-views/views/view",
42370
42445
  or after the view was re-rendered. Override this function to do any
42371
42446
  set up that requires an element in the document body.
42372
42447
 
42448
+ When a view has children, didInsertElement will be called on the
42449
+ child view(s) first, bubbling upwards through the hierarchy.
42450
+
42373
42451
  @event didInsertElement
42374
42452
  */
42375
42453
  didInsertElement: Ember.K,
@@ -43122,12 +43200,11 @@ define("morph",
43122
43200
  __exports__.DOMHelper = DOMHelper;
43123
43201
  });
43124
43202
  define("morph/dom-helper",
43125
- ["../morph/morph","exports"],
43126
- function(__dependency1__, __exports__) {
43203
+ ["../morph/morph","./dom-helper/build-html-dom","exports"],
43204
+ function(__dependency1__, __dependency2__, __exports__) {
43127
43205
  "use strict";
43128
43206
  var Morph = __dependency1__["default"];
43129
-
43130
- var emptyString = '';
43207
+ var buildHTMLDOM = __dependency2__.buildHTMLDOM;
43131
43208
 
43132
43209
  var deletesBlankTextNodes = (function(){
43133
43210
  var element = document.createElement('div');
@@ -43144,7 +43221,7 @@ define("morph/dom-helper",
43144
43221
  })();
43145
43222
 
43146
43223
  var svgNamespace = 'http://www.w3.org/2000/svg',
43147
- svgHTMLIntegrationPoints = ['foreignObject', 'desc', 'title'];
43224
+ svgHTMLIntegrationPoints = {foreignObject: 1, desc: 1, title: 1};
43148
43225
 
43149
43226
  function isSVG(ns){
43150
43227
  return ns === svgNamespace;
@@ -43156,7 +43233,7 @@ define("morph/dom-helper",
43156
43233
  if (
43157
43234
  element &&
43158
43235
  element.namespaceURI === svgNamespace &&
43159
- svgHTMLIntegrationPoints.indexOf(element.tagName) === -1
43236
+ !svgHTMLIntegrationPoints[element.tagName]
43160
43237
  ) {
43161
43238
  return svgNamespace;
43162
43239
  } else {
@@ -43164,6 +43241,52 @@ define("morph/dom-helper",
43164
43241
  }
43165
43242
  }
43166
43243
 
43244
+ // The HTML spec allows for "omitted start tags". These tags are optional
43245
+ // when their intended child is the first thing in the parent tag. For
43246
+ // example, this is a tbody start tag:
43247
+ //
43248
+ // <table>
43249
+ // <tbody>
43250
+ // <tr>
43251
+ //
43252
+ // The tbody may be omitted, and the browser will accept and render:
43253
+ //
43254
+ // <table>
43255
+ // <tr>
43256
+ //
43257
+ // However, the omitted start tag will still be added to the DOM. Here
43258
+ // we test the string and context to see if the browser is about to
43259
+ // perform this cleanup.
43260
+ //
43261
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags
43262
+ // describes which tags are omittable. The spec for tbody and colgroup
43263
+ // explains this behavior:
43264
+ //
43265
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-tbody-element
43266
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-colgroup-element
43267
+ //
43268
+
43269
+ var omittedStartTagChildTest = /<([\w:]+)/;
43270
+ function detectOmittedStartTag(string, contextualElement){
43271
+ // Omitted start tags are only inside table tags.
43272
+ if (contextualElement.tagName === 'TABLE') {
43273
+ var omittedStartTagChildMatch = omittedStartTagChildTest.exec(string);
43274
+ if (omittedStartTagChildMatch) {
43275
+ var omittedStartTagChild = omittedStartTagChildMatch[1];
43276
+ // It is already asserted that the contextual element is a table
43277
+ // and not the proper start tag. Just see if a tag was omitted.
43278
+ return omittedStartTagChild === 'tr' ||
43279
+ omittedStartTagChild === 'col';
43280
+ }
43281
+ }
43282
+ }
43283
+
43284
+ function buildSVGDOM(html, dom){
43285
+ var div = dom.document.createElement('div');
43286
+ div.innerHTML = '<svg>'+html+'</svg>';
43287
+ return div.firstChild.childNodes;
43288
+ }
43289
+
43167
43290
  /*
43168
43291
  * A class wrapping DOM functions to address environment compatibility,
43169
43292
  * namespaces, contextual elements for morph un-escaped content
@@ -43205,13 +43328,19 @@ define("morph/dom-helper",
43205
43328
  element.setAttribute(name, value);
43206
43329
  };
43207
43330
 
43208
- prototype.createElement = function(tagName) {
43209
- if (this.namespace) {
43210
- return this.document.createElementNS(this.namespace, tagName);
43211
- } else {
43331
+ if (document.createElementNS) {
43332
+ prototype.createElement = function(tagName) {
43333
+ if (this.namespace) {
43334
+ return this.document.createElementNS(this.namespace, tagName);
43335
+ } else {
43336
+ return this.document.createElement(tagName);
43337
+ }
43338
+ };
43339
+ } else {
43340
+ prototype.createElement = function(tagName) {
43212
43341
  return this.document.createElement(tagName);
43213
- }
43214
- };
43342
+ };
43343
+ }
43215
43344
 
43216
43345
  prototype.setNamespace = function(ns) {
43217
43346
  this.namespace = ns;
@@ -43232,7 +43361,7 @@ define("morph/dom-helper",
43232
43361
  prototype.repairClonedNode = function(element, blankChildTextNodes, isChecked){
43233
43362
  if (deletesBlankTextNodes && blankChildTextNodes.length > 0) {
43234
43363
  for (var i=0, len=blankChildTextNodes.length;i<len;i++){
43235
- var textNode = document.createTextNode(emptyString),
43364
+ var textNode = this.document.createTextNode(''),
43236
43365
  offset = blankChildTextNodes[i],
43237
43366
  before = element.childNodes[offset];
43238
43367
  if (before) {
@@ -43253,12 +43382,9 @@ define("morph/dom-helper",
43253
43382
  };
43254
43383
 
43255
43384
  prototype.createMorph = function(parent, start, end, contextualElement){
43256
- if (!contextualElement && parent.nodeType === Node.ELEMENT_NODE) {
43385
+ if (!contextualElement && parent.nodeType === 1) {
43257
43386
  contextualElement = parent;
43258
43387
  }
43259
- if (!contextualElement) {
43260
- contextualElement = this.document.body;
43261
- }
43262
43388
  return new Morph(parent, start, end, this, contextualElement);
43263
43389
  };
43264
43390
 
@@ -43272,39 +43398,243 @@ define("morph/dom-helper",
43272
43398
  };
43273
43399
 
43274
43400
  prototype.insertMorphBefore = function(element, referenceChild, contextualElement) {
43275
- var start = document.createTextNode('');
43276
- var end = document.createTextNode('');
43401
+ var start = this.document.createTextNode('');
43402
+ var end = this.document.createTextNode('');
43277
43403
  element.insertBefore(start, referenceChild);
43278
43404
  element.insertBefore(end, referenceChild);
43279
43405
  return this.createMorph(element, start, end, contextualElement);
43280
43406
  };
43281
43407
 
43282
43408
  prototype.appendMorph = function(element, contextualElement) {
43283
- var start = document.createTextNode('');
43284
- var end = document.createTextNode('');
43409
+ var start = this.document.createTextNode('');
43410
+ var end = this.document.createTextNode('');
43285
43411
  element.appendChild(start);
43286
43412
  element.appendChild(end);
43287
43413
  return this.createMorph(element, start, end, contextualElement);
43288
43414
  };
43289
43415
 
43290
- prototype.parseHTML = function(html, contextualElement){
43291
- var element;
43292
- if (isSVG(this.namespace) && svgHTMLIntegrationPoints.indexOf(contextualElement.tagName) === -1) {
43293
- html = '<svg>'+html+'</svg>';
43294
- element = document.createElement('div');
43295
- } else {
43296
- element = this.cloneNode(contextualElement, false);
43297
- }
43298
- element.innerHTML = html;
43299
- if (isSVG(this.namespace)) {
43300
- return element.firstChild.childNodes;
43416
+ prototype.parseHTML = function(html, contextualElement) {
43417
+ var isSVGContent = (
43418
+ isSVG(this.namespace) &&
43419
+ !svgHTMLIntegrationPoints[contextualElement.tagName]
43420
+ );
43421
+
43422
+ if (isSVGContent) {
43423
+ return buildSVGDOM(html, this);
43301
43424
  } else {
43302
- return element.childNodes;
43425
+ var nodes = buildHTMLDOM(html, contextualElement, this);
43426
+ if (detectOmittedStartTag(html, contextualElement)) {
43427
+ var node = nodes[0];
43428
+ while (node && node.nodeType !== 1) {
43429
+ node = node.nextSibling;
43430
+ }
43431
+ return node.childNodes;
43432
+ } else {
43433
+ return nodes;
43434
+ }
43303
43435
  }
43304
43436
  };
43305
43437
 
43306
43438
  __exports__["default"] = DOMHelper;
43307
43439
  });
43440
+ define("morph/dom-helper/build-html-dom",
43441
+ ["exports"],
43442
+ function(__exports__) {
43443
+ "use strict";
43444
+ // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
43445
+ // is a "zero-scope" element. This problem can be worked around by making
43446
+ // the first node an invisible text node. We, like Modernizr, use &shy;
43447
+ var needsShy = (function() {
43448
+ var testEl = document.createElement('div');
43449
+ testEl.innerHTML = "<div></div>";
43450
+ testEl.firstChild.innerHTML = "<script><\/script>";
43451
+ return testEl.firstChild.innerHTML === '';
43452
+ })();
43453
+
43454
+ // IE 8 (and likely earlier) likes to move whitespace preceeding
43455
+ // a script tag to appear after it. This means that we can
43456
+ // accidentally remove whitespace when updating a morph.
43457
+ var movesWhitespace = document && (function() {
43458
+ var testEl = document.createElement('div');
43459
+ testEl.innerHTML = "Test: <script type='text/x-placeholder'><\/script>Value";
43460
+ return testEl.childNodes[0].nodeValue === 'Test:' &&
43461
+ testEl.childNodes[2].nodeValue === ' Value';
43462
+ })();
43463
+
43464
+ // IE 9 and earlier don't allow us to set innerHTML on col, colgroup, frameset,
43465
+ // html, style, table, tbody, tfoot, thead, title, tr. Detect this and add
43466
+ // them to an initial list of corrected tags.
43467
+ //
43468
+ // Here we are only dealing with the ones which can have child nodes.
43469
+ //
43470
+ var tagNamesRequiringInnerHTMLFix, tableNeedsInnerHTMLFix;
43471
+ var tableInnerHTMLTestElement = document.createElement('table');
43472
+ try {
43473
+ tableInnerHTMLTestElement.innerHTML = '<tbody></tbody>';
43474
+ } catch (e) {
43475
+ } finally {
43476
+ tableNeedsInnerHTMLFix = (tableInnerHTMLTestElement.childNodes.length === 0);
43477
+ }
43478
+ if (tableNeedsInnerHTMLFix) {
43479
+ tagNamesRequiringInnerHTMLFix = {
43480
+ colgroup: ['table'],
43481
+ table: [],
43482
+ tbody: ['table'],
43483
+ tfoot: ['table'],
43484
+ thead: ['table'],
43485
+ tr: ['table', 'tbody']
43486
+ };
43487
+ } else {
43488
+ tagNamesRequiringInnerHTMLFix = {};
43489
+ }
43490
+
43491
+ // IE 8 doesn't allow setting innerHTML on a select tag. Detect this and
43492
+ // add it to the list of corrected tags.
43493
+ //
43494
+ var selectInnerHTMLTestElement = document.createElement('select');
43495
+ selectInnerHTMLTestElement.innerHTML = '<option></option>';
43496
+ if (selectInnerHTMLTestElement) {
43497
+ tagNamesRequiringInnerHTMLFix.select = [];
43498
+ }
43499
+
43500
+ function scriptSafeInnerHTML(element, html) {
43501
+ // without a leading text node, IE will drop a leading script tag.
43502
+ html = '&shy;'+html;
43503
+
43504
+ element.innerHTML = html;
43505
+
43506
+ var nodes = element.childNodes;
43507
+
43508
+ // Look for &shy; to remove it.
43509
+ var shyElement = nodes[0];
43510
+ while (shyElement.nodeType === 1 && !shyElement.nodeName) {
43511
+ shyElement = shyElement.firstChild;
43512
+ }
43513
+ // At this point it's the actual unicode character.
43514
+ if (shyElement.nodeType === 3 && shyElement.nodeValue.charAt(0) === "\u00AD") {
43515
+ var newValue = shyElement.nodeValue.slice(1);
43516
+ if (newValue.length) {
43517
+ shyElement.nodeValue = shyElement.nodeValue.slice(1);
43518
+ } else {
43519
+ shyElement.parentNode.removeChild(shyElement);
43520
+ }
43521
+ }
43522
+
43523
+ return nodes;
43524
+ }
43525
+
43526
+ function buildDOMWithFix(html, contextualElement){
43527
+ var tagName = contextualElement.tagName;
43528
+
43529
+ // Firefox versions < 11 do not have support for element.outerHTML.
43530
+ var outerHTML = contextualElement.outerHTML || new XMLSerializer().serializeToString(contextualElement);
43531
+ if (!outerHTML) {
43532
+ throw "Can't set innerHTML on "+tagName+" in this browser";
43533
+ }
43534
+
43535
+ var wrappingTags = tagNamesRequiringInnerHTMLFix[tagName.toLowerCase()];
43536
+ var startTag = outerHTML.match(new RegExp("<"+tagName+"([^>]*)>", 'i'))[0];
43537
+ var endTag = '</'+tagName+'>';
43538
+
43539
+ var wrappedHTML = [startTag, html, endTag];
43540
+
43541
+ var i = wrappingTags.length;
43542
+ var wrappedDepth = 1 + i;
43543
+ while(i--) {
43544
+ wrappedHTML.unshift('<'+wrappingTags[i]+'>');
43545
+ wrappedHTML.push('</'+wrappingTags[i]+'>');
43546
+ }
43547
+
43548
+ var wrapper = document.createElement('div');
43549
+ scriptSafeInnerHTML(wrapper, wrappedHTML.join(''));
43550
+ var element = wrapper;
43551
+ while (wrappedDepth--) {
43552
+ element = element.firstChild;
43553
+ while (element && element.nodeType !== 1) {
43554
+ element = element.nextSibling;
43555
+ }
43556
+ }
43557
+ while (element && element.tagName !== tagName) {
43558
+ element = element.nextSibling;
43559
+ }
43560
+ return element ? element.childNodes : [];
43561
+ }
43562
+
43563
+ function buildDOM(html, contextualElement, dom){
43564
+ contextualElement = dom.cloneNode(contextualElement, false);
43565
+ scriptSafeInnerHTML(contextualElement, html);
43566
+ return contextualElement.childNodes;
43567
+ }
43568
+
43569
+ var buildHTMLDOM;
43570
+ // Really, this just means IE8 and IE9 get a slower buildHTMLDOM
43571
+ if (tagNamesRequiringInnerHTMLFix.length > 0 || needsShy || movesWhitespace) {
43572
+ buildHTMLDOM = function buildHTMLDOM(html, contextualElement, dom) {
43573
+ // Make a list of the leading text on script nodes. Include
43574
+ // script tags without any whitespace for easier processing later.
43575
+ var spacesBefore = [];
43576
+ var spacesAfter = [];
43577
+ html = html.replace(/(\s*)(<script)/g, function(match, spaces, tag) {
43578
+ spacesBefore.push(spaces);
43579
+ return tag;
43580
+ });
43581
+
43582
+ html = html.replace(/(<\/script>)(\s*)/g, function(match, tag, spaces) {
43583
+ spacesAfter.push(spaces);
43584
+ return tag;
43585
+ });
43586
+
43587
+ // Fetch nodes
43588
+ var nodes;
43589
+ if (tagNamesRequiringInnerHTMLFix[contextualElement.tagName.toLowerCase()]) {
43590
+ // buildDOMWithFix uses string wrappers for problematic innerHTML.
43591
+ nodes = buildDOMWithFix(html, contextualElement);
43592
+ } else {
43593
+ nodes = buildDOM(html, contextualElement, dom);
43594
+ }
43595
+
43596
+ // Build a list of script tags, the nodes themselves will be
43597
+ // mutated as we add test nodes.
43598
+ var i, j, node, nodeScriptNodes;
43599
+ var scriptNodes = [];
43600
+ for (i=0;node=nodes[i];i++) {
43601
+ if (node.nodeType !== 1) {
43602
+ continue;
43603
+ }
43604
+ if (node.tagName === 'SCRIPT') {
43605
+ scriptNodes.push(node);
43606
+ } else {
43607
+ nodeScriptNodes = node.getElementsByTagName('script');
43608
+ for (j=0;j<nodeScriptNodes.length;j++) {
43609
+ scriptNodes.push(nodeScriptNodes[j]);
43610
+ }
43611
+ }
43612
+ }
43613
+
43614
+ // Walk the script tags and put back their leading text nodes.
43615
+ var textNode, spaceBefore, spaceAfter;
43616
+ for (i=0;scriptNode=scriptNodes[i];i++) {
43617
+ spaceBefore = spacesBefore[i];
43618
+ if (spaceBefore && spaceBefore.length > 0) {
43619
+ textNode = dom.document.createTextNode(spaceBefore);
43620
+ scriptNode.parentNode.insertBefore(textNode, scriptNode);
43621
+ }
43622
+
43623
+ spaceAfter = spacesAfter[i];
43624
+ if (spaceAfter && spaceAfter.length > 0) {
43625
+ textNode = dom.document.createTextNode(spaceAfter);
43626
+ scriptNode.parentNode.insertBefore(textNode, scriptNode.nextSibling);
43627
+ }
43628
+ }
43629
+
43630
+ return nodes;
43631
+ };
43632
+ } else {
43633
+ buildHTMLDOM = buildDOM;
43634
+ }
43635
+
43636
+ __exports__.buildHTMLDOM = buildHTMLDOM;
43637
+ });
43308
43638
  define("morph/morph",
43309
43639
  ["exports"],
43310
43640
  function(__exports__) {
@@ -43318,7 +43648,7 @@ define("morph/morph",
43318
43648
  }
43319
43649
 
43320
43650
  function ensureContext(contextualElement) {
43321
- if (!contextualElement || contextualElement.nodeType !== Node.ELEMENT_NODE) {
43651
+ if (!contextualElement || contextualElement.nodeType !== 1) {
43322
43652
  throw new Error('An element node must be provided for a contextualElement, you provided ' +
43323
43653
  (contextualElement ? 'nodeType ' + contextualElement.nodeType : 'nothing'));
43324
43654
  }
@@ -44589,6 +44919,58 @@ define("router/router",
44589
44919
  this.reset();
44590
44920
  }
44591
44921
 
44922
+ function getTransitionByIntent(intent, isIntermediate) {
44923
+ var wasTransitioning = !!this.activeTransition;
44924
+ var oldState = wasTransitioning ? this.activeTransition.state : this.state;
44925
+ var newTransition;
44926
+
44927
+ var newState = intent.applyToState(oldState, this.recognizer, this.getHandler, isIntermediate);
44928
+ var queryParamChangelist = getChangelist(oldState.queryParams, newState.queryParams);
44929
+
44930
+ if (handlerInfosEqual(newState.handlerInfos, oldState.handlerInfos)) {
44931
+
44932
+ // This is a no-op transition. See if query params changed.
44933
+ if (queryParamChangelist) {
44934
+ newTransition = this.queryParamsTransition(queryParamChangelist, wasTransitioning, oldState, newState);
44935
+ if (newTransition) {
44936
+ return newTransition;
44937
+ }
44938
+ }
44939
+
44940
+ // No-op. No need to create a new transition.
44941
+ return new Transition(this);
44942
+ }
44943
+
44944
+ if (isIntermediate) {
44945
+ setupContexts(this, newState);
44946
+ return;
44947
+ }
44948
+
44949
+ // Create a new transition to the destination route.
44950
+ newTransition = new Transition(this, intent, newState);
44951
+
44952
+ // Abort and usurp any previously active transition.
44953
+ if (this.activeTransition) {
44954
+ this.activeTransition.abort();
44955
+ }
44956
+ this.activeTransition = newTransition;
44957
+
44958
+ // Transition promises by default resolve with resolved state.
44959
+ // For our purposes, swap out the promise to resolve
44960
+ // after the transition has been finalized.
44961
+ newTransition.promise = newTransition.promise.then(function(result) {
44962
+ return finalizeTransition(newTransition, result.state);
44963
+ }, null, promiseLabel("Settle transition promise when transition is finalized"));
44964
+
44965
+ if (!wasTransitioning) {
44966
+ notifyExistingHandlers(this, newState, newTransition);
44967
+ }
44968
+
44969
+ fireQueryParamDidChange(this, newState, queryParamChangelist);
44970
+
44971
+ return newTransition;
44972
+ }
44973
+
44592
44974
  Router.prototype = {
44593
44975
 
44594
44976
  /**
@@ -44653,58 +45035,8 @@ define("router/router",
44653
45035
  // it shall remain until our ES6 transpiler can
44654
45036
  // handle cyclical deps.
44655
45037
  transitionByIntent: function(intent, isIntermediate) {
44656
-
44657
- var wasTransitioning = !!this.activeTransition;
44658
- var oldState = wasTransitioning ? this.activeTransition.state : this.state;
44659
- var newTransition;
44660
- var router = this;
44661
-
44662
45038
  try {
44663
- var newState = intent.applyToState(oldState, this.recognizer, this.getHandler, isIntermediate);
44664
- var queryParamChangelist = getChangelist(oldState.queryParams, newState.queryParams);
44665
-
44666
- if (handlerInfosEqual(newState.handlerInfos, oldState.handlerInfos)) {
44667
-
44668
- // This is a no-op transition. See if query params changed.
44669
- if (queryParamChangelist) {
44670
- newTransition = this.queryParamsTransition(queryParamChangelist, wasTransitioning, oldState, newState);
44671
- if (newTransition) {
44672
- return newTransition;
44673
- }
44674
- }
44675
-
44676
- // No-op. No need to create a new transition.
44677
- return new Transition(this);
44678
- }
44679
-
44680
- if (isIntermediate) {
44681
- setupContexts(this, newState);
44682
- return;
44683
- }
44684
-
44685
- // Create a new transition to the destination route.
44686
- newTransition = new Transition(this, intent, newState);
44687
-
44688
- // Abort and usurp any previously active transition.
44689
- if (this.activeTransition) {
44690
- this.activeTransition.abort();
44691
- }
44692
- this.activeTransition = newTransition;
44693
-
44694
- // Transition promises by default resolve with resolved state.
44695
- // For our purposes, swap out the promise to resolve
44696
- // after the transition has been finalized.
44697
- newTransition.promise = newTransition.promise.then(function(result) {
44698
- return finalizeTransition(newTransition, result.state);
44699
- }, null, promiseLabel("Settle transition promise when transition is finalized"));
44700
-
44701
- if (!wasTransitioning) {
44702
- notifyExistingHandlers(this, newState, newTransition);
44703
- }
44704
-
44705
- fireQueryParamDidChange(this, newState, queryParamChangelist);
44706
-
44707
- return newTransition;
45039
+ return getTransitionByIntent.apply(this, arguments);
44708
45040
  } catch(e) {
44709
45041
  return new Transition(this, intent, null, e);
44710
45042
  }
@@ -45046,7 +45378,9 @@ define("router/router",
45046
45378
  var handler = handlerInfo.handler,
45047
45379
  context = handlerInfo.context;
45048
45380
 
45049
- callHook(handler, 'enter', transition);
45381
+ if (enter) {
45382
+ callHook(handler, 'enter', transition);
45383
+ }
45050
45384
  if (transition && transition.isAborted) {
45051
45385
  throw new TransitionAborted();
45052
45386
  }