rasputin 0.11.1 → 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,11 @@
1
- (function() {
1
+
2
+ (function(exports) {
2
3
  // ==========================================================================
3
4
  // Project: Ember - JavaScript Application Framework
4
5
  // Copyright: ©2006-2011 Strobe Inc. and contributors.
5
6
  // Portions ©2008-2011 Apple Inc. All rights reserved.
6
7
  // License: Licensed under MIT license (see license.js)
7
8
  // ==========================================================================
8
-
9
9
  var get = Ember.get, set = Ember.set;
10
10
 
11
11
  // simple copy op needed for just this code.
@@ -24,7 +24,7 @@ function copy(opts) {
24
24
  @constant
25
25
  @type Error
26
26
  */
27
- Ember.EmberANNER_OUT_OF_BOUNDS_ERROR = "Out of bounds.";
27
+ Ember.SCANNER_OUT_OF_BOUNDS_ERROR = "Out of bounds.";
28
28
 
29
29
  /**
30
30
  Standard error thrown by `Ember.Scanner` when you pass a value not an integer.
@@ -33,7 +33,7 @@ Ember.EmberANNER_OUT_OF_BOUNDS_ERROR = "Out of bounds.";
33
33
  @constant
34
34
  @type Error
35
35
  */
36
- Ember.EmberANNER_INT_ERROR = "Not an int.";
36
+ Ember.SCANNER_INT_ERROR = "Not an int.";
37
37
 
38
38
  /**
39
39
  Standard error thrown by `Ember.Scanner` when it cannot find a string to skip.
@@ -42,7 +42,7 @@ Ember.EmberANNER_INT_ERROR = "Not an int.";
42
42
  @constant
43
43
  @type Error
44
44
  */
45
- Ember.EmberANNER_SKIP_ERROR = "Did not find the string to skip.";
45
+ Ember.SCANNER_SKIP_ERROR = "Did not find the string to skip.";
46
46
 
47
47
  /**
48
48
  Standard error thrown by `Ember.Scanner` when it can any kind a string in the
@@ -52,7 +52,7 @@ Ember.EmberANNER_SKIP_ERROR = "Did not find the string to skip.";
52
52
  @constant
53
53
  @type Error
54
54
  */
55
- Ember.EmberANNER_EmberAN_ARRAY_ERROR = "Did not find any string of the given array to scan.";
55
+ Ember.SCANNER_SCAN_ARRAY_ERROR = "Did not find any string of the given array to scan.";
56
56
 
57
57
  /**
58
58
  Standard error thrown when trying to compare two dates in different
@@ -87,7 +87,7 @@ Ember.DATETIME_ISO8601 = '%Y-%m-%dT%H:%M:%S%Z';
87
87
  Scanners are used by `DateTime` to convert strings into `DateTime` objects.
88
88
 
89
89
  @extends Ember.Object
90
- @since SproutCore 1.0
90
+ @since Ember 0.9
91
91
  @author Martin Ottenwaelter
92
92
  */
93
93
  var Scanner = Ember.Object.extend({
@@ -115,12 +115,12 @@ var Scanner = Ember.Object.extend({
115
115
  accordingly.
116
116
 
117
117
  @param {Integer} len The amount of characters to read
118
- @throws {Ember.EmberANNER_OUT_OF_BOUNDS_ERROR} If asked to read too many characters
118
+ @throws {Ember.SCANNER_OUT_OF_BOUNDS_ERROR} If asked to read too many characters
119
119
  @returns {String} The characters
120
120
  */
121
121
  scan: function(len) {
122
122
  if (this.scanLocation + len > this.length) {
123
- throw new Error(Ember.EmberANNER_OUT_OF_BOUNDS_ERROR);
123
+ throw new Error(Ember.SCANNER_OUT_OF_BOUNDS_ERROR);
124
124
  }
125
125
  var str = this.string.substr(this.scanLocation, len);
126
126
  this.scanLocation += len;
@@ -132,7 +132,7 @@ var Scanner = Ember.Object.extend({
132
132
 
133
133
  @param {Integer} min_len The minimum amount of characters to read
134
134
  @param {Integer} [max_len] The maximum amount of characters to read (defaults to the minimum)
135
- @throws {Ember.EmberANNER_INT_ERROR} If asked to read non numeric characters
135
+ @throws {Ember.SCANNER_INT_ERROR} If asked to read non numeric characters
136
136
  @returns {Integer} The scanned integer
137
137
  */
138
138
  scanInt: function(min_len, max_len) {
@@ -140,7 +140,7 @@ var Scanner = Ember.Object.extend({
140
140
  var str = this.scan(max_len);
141
141
  var re = new RegExp("^\\d{" + min_len + "," + max_len + "}");
142
142
  var match = str.match(re);
143
- if (!match) throw new Error(Ember.EmberANNER_INT_ERROR);
143
+ if (!match) throw new Error(Ember.SCANNER_INT_ERROR);
144
144
  if (match[0].length < max_len) {
145
145
  this.scanLocation += match[0].length - max_len;
146
146
  }
@@ -151,12 +151,12 @@ var Scanner = Ember.Object.extend({
151
151
  Attempts to skip a given string.
152
152
 
153
153
  @param {String} str The string to skip
154
- @throws {Ember.EmberANNER_SKIP_ERROR} If the given string could not be scanned
154
+ @throws {Ember.SCANNER_SKIP_ERROR} If the given string could not be scanned
155
155
  @returns {Boolean} YES if the given string was successfully scanned, NO otherwise
156
156
  */
157
157
  skipString: function(str) {
158
158
  if (this.scan(str.length) !== str) {
159
- throw new Error(Ember.EmberANNER_SKIP_ERROR);
159
+ throw new Error(Ember.SCANNER_SKIP_ERROR);
160
160
  }
161
161
 
162
162
  return YES;
@@ -166,7 +166,7 @@ var Scanner = Ember.Object.extend({
166
166
  Attempts to scan any string in a given array.
167
167
 
168
168
  @param {Array} ary the array of strings to scan
169
- @throws {Ember.EmberANNER_EmberAN_ARRAY_ERROR} If no string of the given array is found
169
+ @throws {Ember.SCANNER_SCAN_ARRAY_ERROR} If no string of the given array is found
170
170
  @returns {Integer} The index of the scanned string of the given array
171
171
  */
172
172
  scanArray: function(ary) {
@@ -176,7 +176,7 @@ var Scanner = Ember.Object.extend({
176
176
  }
177
177
  this.scanLocation -= ary[i].length;
178
178
  }
179
- throw new Error(Ember.EmberANNER_EmberAN_ARRAY_ERROR);
179
+ throw new Error(Ember.SCANNER_SCAN_ARRAY_ERROR);
180
180
  }
181
181
 
182
182
  });
@@ -218,7 +218,7 @@ var Scanner = Ember.Object.extend({
218
218
  @author Martin Ottenwaelter
219
219
  @author Jonathan Lewis
220
220
  @author Josh Holt
221
- @since SproutCore 1.0
221
+ @since Ember 1.0
222
222
  */
223
223
  Ember.DateTime = Ember.Object.extend(Ember.Freezable, Ember.Copyable,
224
224
  /** @scope Ember.DateTime.prototype */ {
@@ -1175,12 +1175,13 @@ Ember.Binding.dateTime = function(format) {
1175
1175
  };
1176
1176
 
1177
1177
 
1178
- })();
1179
- (function() {
1178
+ })({});
1179
+
1180
+
1181
+ (function(exports) {
1180
1182
  // ==========================================================================
1181
- // Project: SproutCore DateTime
1183
+ // Project: Ember DateTime
1182
1184
  // Copyright: ©2010 Strobe Inc. and contributors
1183
1185
  // License: Licensed under MIT license (see license.js)
1184
1186
  // ==========================================================================
1185
-
1186
- })();
1187
+ })({});
@@ -1608,7 +1608,7 @@ if ('undefined' === typeof Ember) {
1608
1608
  /**
1609
1609
  @namespace
1610
1610
  @name Ember
1611
- @version 0.9
1611
+ @version 0.9.3
1612
1612
 
1613
1613
  All Ember methods and functions are defined inside of this namespace.
1614
1614
  You generally should not add new properties to this namespace as it may be
@@ -1625,7 +1625,10 @@ if ('undefined' === typeof Ember) {
1625
1625
  The core Runtime framework is based on the jQuery API with a number of
1626
1626
  performance optimizations.
1627
1627
  */
1628
- Ember = {};
1628
+
1629
+ // Create core object. Make it act like an instance of Ember.Namespace so that
1630
+ // objects assigned to it are given a sane string representation.
1631
+ Ember = { isNamespace: true, toString: function() { return "Ember"; } };
1629
1632
 
1630
1633
  // aliases needed to keep minifiers from removing the global context
1631
1634
  if ('undefined' !== typeof window) {
@@ -1637,10 +1640,10 @@ if ('undefined' !== typeof window) {
1637
1640
  /**
1638
1641
  @static
1639
1642
  @type String
1640
- @default '0.9'
1643
+ @default '0.9.3'
1641
1644
  @constant
1642
1645
  */
1643
- Ember.VERSION = '0.9';
1646
+ Ember.VERSION = '0.9.3';
1644
1647
 
1645
1648
  /**
1646
1649
  @static
@@ -1692,7 +1695,7 @@ Ember.K = function() { return this; };
1692
1695
  will be executed. If the function returns false an exception will be
1693
1696
  thrown.
1694
1697
  */
1695
- window.ember_assert = function ember_assert(desc, test) {
1698
+ window.ember_assert = window.sc_assert = function ember_assert(desc, test) {
1696
1699
  if ('function' === typeof test) test = test()!==false;
1697
1700
  if (!test) throw new Error("assertion failed: "+desc);
1698
1701
  };
@@ -2542,8 +2545,7 @@ Ember.trySetPath = function(root, path, value) {
2542
2545
  */
2543
2546
  Ember.isGlobalPath = function(path) {
2544
2547
  return !HAS_THIS.test(path) && IS_GLOBAL.test(path);
2545
- }
2546
-
2548
+ };
2547
2549
 
2548
2550
  })({});
2549
2551
 
@@ -2632,7 +2634,7 @@ var array_Slice = Array.prototype.slice;
2632
2634
  var ObserverSet = function(iterateable) {
2633
2635
  this.set = {};
2634
2636
  if (iterateable) { this.array = []; }
2635
- }
2637
+ };
2636
2638
 
2637
2639
  ObserverSet.prototype.add = function(target, name) {
2638
2640
  var set = this.set, guid = Ember.guidFor(target), array;
@@ -2707,11 +2709,11 @@ Ember.endPropertyChanges = function() {
2707
2709
  Ember.changeProperties = function(cb){
2708
2710
  Ember.beginPropertyChanges();
2709
2711
  try {
2710
- cb()
2712
+ cb();
2711
2713
  } finally {
2712
2714
  Ember.endPropertyChanges();
2713
2715
  }
2714
- }
2716
+ };
2715
2717
 
2716
2718
  function changeEvent(keyName) {
2717
2719
  return keyName+AFTER_OBSERVERS;
@@ -2736,7 +2738,7 @@ function xformForArgs(args) {
2736
2738
  if (method.length>2) val = Ember.getPath(obj, keyName);
2737
2739
  copy_args.unshift(obj, keyName, val);
2738
2740
  method.apply(target, copy_args);
2739
- }
2741
+ };
2740
2742
  }
2741
2743
 
2742
2744
  var xformChange = xformForArgs([]);
@@ -3825,13 +3827,16 @@ var RunLoop = function(prev) {
3825
3827
  self.onceTimers = {};
3826
3828
 
3827
3829
  return self;
3828
- }
3830
+ };
3829
3831
 
3830
3832
  K.prototype = RunLoop.prototype;
3831
3833
 
3832
3834
  RunLoop.prototype = {
3833
3835
  end: function() {
3834
3836
  this.flush();
3837
+ },
3838
+
3839
+ prev: function() {
3835
3840
  return this._prev;
3836
3841
  },
3837
3842
 
@@ -3968,7 +3973,12 @@ Ember.run.begin = function() {
3968
3973
  */
3969
3974
  Ember.run.end = function() {
3970
3975
  ember_assert('must have a current run loop', run.currentRunLoop);
3971
- run.currentRunLoop = run.currentRunLoop.end();
3976
+ try {
3977
+ run.currentRunLoop.end();
3978
+ }
3979
+ finally {
3980
+ run.currentRunLoop = run.currentRunLoop.prev();
3981
+ }
3972
3982
  };
3973
3983
 
3974
3984
  /**
@@ -4973,7 +4983,7 @@ function mixinProperties(to, from) {
4973
4983
  to[key] = from[key];
4974
4984
  }
4975
4985
  }
4976
- };
4986
+ }
4977
4987
 
4978
4988
  mixinProperties(Binding, {
4979
4989
 
@@ -5119,7 +5129,7 @@ Ember.bind = function(obj, to, from) {
5119
5129
 
5120
5130
  Ember.oneWay = function(obj, to, from) {
5121
5131
  return new Ember.Binding(to, from).oneWay().connect(obj);
5122
- }
5132
+ };
5123
5133
 
5124
5134
  })({});
5125
5135
 
@@ -5459,7 +5469,7 @@ function invokeEvents(targetSet, params) {
5459
5469
  for(var methodGuid in actionSet) {
5460
5470
  if (SKIP_PROPERTIES[methodGuid]) { continue; }
5461
5471
 
5462
- var action = actionSet[methodGuid]
5472
+ var action = actionSet[methodGuid];
5463
5473
  if (!action) { continue; }
5464
5474
 
5465
5475
  // Extract target and method for each action
@@ -5988,6 +5998,7 @@ Mixin.prototype.keys = function() {
5988
5998
  /** @private - make Mixin's have nice displayNames */
5989
5999
 
5990
6000
  var NAME_KEY = Ember.GUID_KEY+'_name';
6001
+ var get = Ember.get;
5991
6002
 
5992
6003
  function processNames(paths, root, seen) {
5993
6004
  var idx = paths.length;
@@ -5998,7 +6009,7 @@ function processNames(paths, root, seen) {
5998
6009
 
5999
6010
  if (obj && obj.toString === classToString) {
6000
6011
  obj[NAME_KEY] = paths.join('.');
6001
- } else if (key==='Ember' || (Ember.Namespace && obj instanceof Ember.Namespace)) {
6012
+ } else if (obj && get(obj, 'isNamespace')) {
6002
6013
  if (seen[Ember.guidFor(obj)]) continue;
6003
6014
  seen[Ember.guidFor(obj)] = true;
6004
6015
  processNames(paths, obj, seen);
@@ -6019,7 +6030,7 @@ function findNamespaces() {
6019
6030
 
6020
6031
  obj = window[prop];
6021
6032
 
6022
- if (obj && obj instanceof Namespace) {
6033
+ if (obj && get(obj, 'isNamespace')) {
6023
6034
  obj[NAME_KEY] = prop;
6024
6035
  }
6025
6036
  }
@@ -6030,12 +6041,12 @@ Ember.identifyNamespaces = findNamespaces;
6030
6041
  superClassString = function(mixin) {
6031
6042
  var superclass = mixin.superclass;
6032
6043
  if (superclass) {
6033
- if (superclass[NAME_KEY]) { return superclass[NAME_KEY] }
6044
+ if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
6034
6045
  else { return superClassString(superclass); }
6035
6046
  } else {
6036
6047
  return;
6037
6048
  }
6038
- }
6049
+ };
6039
6050
 
6040
6051
  classToString = function() {
6041
6052
  var Namespace = Ember.Namespace, namespace;
@@ -8484,6 +8495,7 @@ Ember.Error = function() {
8484
8495
  for (var p in tmp) {
8485
8496
  if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
8486
8497
  }
8498
+ this.message = tmp.message;
8487
8499
  };
8488
8500
 
8489
8501
  Ember.Error.prototype = Ember.create(Error.prototype);
@@ -9670,6 +9682,8 @@ Ember.TargetActionSupport = Ember.Mixin.create({
9670
9682
 
9671
9683
  */
9672
9684
  Ember.Namespace = Ember.Object.extend({
9685
+ isNamespace: true,
9686
+
9673
9687
  init: function() {
9674
9688
  Ember.Namespace.NAMESPACES.push(this);
9675
9689
  Ember.Namespace.PROCESSED = false;
@@ -9688,8 +9702,8 @@ Ember.Namespace = Ember.Object.extend({
9688
9702
  }
9689
9703
  });
9690
9704
 
9691
- Ember.Namespace.NAMESPACES = [];
9692
- Ember.Namespace.PROCESSED = true;
9705
+ Ember.Namespace.NAMESPACES = [Ember];
9706
+ Ember.Namespace.PROCESSED = false;
9693
9707
 
9694
9708
  })({});
9695
9709
 
@@ -10520,7 +10534,7 @@ Ember.EventDispatcher = Ember.Object.extend(
10520
10534
  ember_assert('You cannot make a new Ember.Application using a root element that is a descendent of an existing Ember.Application', !rootElement.closest('.ember-application').length);
10521
10535
  ember_assert('You cannot make a new Ember.Application using a root element that is an ancestor of an existing Ember.Application', !rootElement.find('.ember-application').length);
10522
10536
 
10523
- rootElement.addClass('ember-application')
10537
+ rootElement.addClass('ember-application');
10524
10538
 
10525
10539
  for (event in events) {
10526
10540
  if (events.hasOwnProperty(event)) {
@@ -11339,6 +11353,28 @@ Ember.View = Ember.Object.extend(
11339
11353
  return this;
11340
11354
  },
11341
11355
 
11356
+ /**
11357
+ Replaces the view's element to the specified parent element.
11358
+ If the view does not have an HTML representation yet, `createElement()`
11359
+ will be called automatically.
11360
+ If the parent element already has some content, it will be removed.
11361
+
11362
+ Note that this method just schedules the view to be appended; the DOM
11363
+ element will not be appended to the given element until all bindings have
11364
+ finished synchronizing
11365
+
11366
+ @param {String|DOMElement|jQuery} A selector, element, HTML string, or jQuery object
11367
+ @returns {Ember.View} received
11368
+ */
11369
+ replaceIn: function(target) {
11370
+ this._insertElementLater(function() {
11371
+ Ember.$(target).empty();
11372
+ this.$().appendTo(target);
11373
+ });
11374
+
11375
+ return this;
11376
+ },
11377
+
11342
11378
  /**
11343
11379
  @private
11344
11380
 
@@ -11390,7 +11426,9 @@ Ember.View = Ember.Object.extend(
11390
11426
  // In the interim, we will just re-render if that happens. It is more
11391
11427
  // important than elements get garbage collected.
11392
11428
  this.destroyElement();
11393
- this.clearRenderedChildren();
11429
+ this.invokeRecursively(function(view) {
11430
+ view.clearRenderedChildren();
11431
+ });
11394
11432
  },
11395
11433
 
11396
11434
  /**
@@ -12086,8 +12124,8 @@ Ember.View.states.preRender = {
12086
12124
  // a view leaves the preRender state once its element has been
12087
12125
  // created (createElement).
12088
12126
  insertElement: function(view, fn) {
12089
- view._notifyWillInsertElement(true);
12090
12127
  view.createElement();
12128
+ view._notifyWillInsertElement(true);
12091
12129
  // after createElement, the view will be in the hasElement state.
12092
12130
  fn.call(view);
12093
12131
  view.transitionTo('inDOM');
@@ -12523,7 +12561,7 @@ Ember.ContainerView.states = {
12523
12561
 
12524
12562
  Ember.ContainerView.states.inDOM = {
12525
12563
  parentState: Ember.ContainerView.states.hasElement
12526
- }
12564
+ };
12527
12565
 
12528
12566
  Ember.ContainerView.reopen({
12529
12567
  states: Ember.ContainerView.states
@@ -12673,7 +12711,7 @@ Ember.CollectionView = Ember.ContainerView.extend(
12673
12711
  var emptyView = get(this, 'emptyView');
12674
12712
  if (!emptyView) { return; }
12675
12713
 
12676
- emptyView = this.createChildView(emptyView)
12714
+ emptyView = this.createChildView(emptyView);
12677
12715
  addedViews.push(emptyView);
12678
12716
  set(this, 'emptyView', emptyView);
12679
12717
  }
@@ -12803,6 +12841,27 @@ Ember.StateManager = Ember.State.extend({
12803
12841
 
12804
12842
  currentState: null,
12805
12843
 
12844
+ /**
12845
+ If the current state is a view state or the descendent of a view state,
12846
+ this property will be the view associated with it. If there is no
12847
+ view state active in this state manager, this value will be null.
12848
+ */
12849
+ currentView: SC.computed(function() {
12850
+ var currentState = get(this, 'currentState'),
12851
+ view;
12852
+
12853
+ while (currentState) {
12854
+ if (get(currentState, 'isViewState')) {
12855
+ view = get(currentState, 'view');
12856
+ if (view) { return view; }
12857
+ }
12858
+
12859
+ currentState = get(currentState, 'parentState');
12860
+ }
12861
+
12862
+ return null;
12863
+ }).property('currentState').cacheable(),
12864
+
12806
12865
  send: function(event, context) {
12807
12866
  this.sendRecursively(event, get(this, 'currentState'), context);
12808
12867
  },
@@ -12832,9 +12891,9 @@ Ember.StateManager = Ember.State.extend({
12832
12891
  if (!newState) {
12833
12892
  while (state && !newState) {
12834
12893
  exitStates[Ember.guidFor(state)] = state;
12835
- exitStates.push(state)
12894
+ exitStates.push(state);
12836
12895
 
12837
- state = get(state, 'parentState')
12896
+ state = get(state, 'parentState');
12838
12897
  if (!state) {
12839
12898
  state = get(this, 'states');
12840
12899
  }
@@ -12872,7 +12931,7 @@ Ember.StateManager = Ember.State.extend({
12872
12931
  resume: function() {
12873
12932
  self.asyncEach(tail, callback, doneCallback);
12874
12933
  }
12875
- }
12934
+ };
12876
12935
 
12877
12936
  callback.call(this, head, transition);
12878
12937
 
@@ -12927,6 +12986,8 @@ Ember.StateManager = Ember.State.extend({
12927
12986
  var get = Ember.get, set = Ember.set;
12928
12987
 
12929
12988
  Ember.ViewState = Ember.State.extend({
12989
+ isViewState: true,
12990
+
12930
12991
  enter: function(stateManager) {
12931
12992
  var view = get(this, 'view');
12932
12993
 
@@ -13005,7 +13066,7 @@ Ember.ViewState = Ember.State.extend({
13005
13066
 
13006
13067
  K.prototype = Metamorph.prototype;
13007
13068
 
13008
- var rangeFor, htmlFunc, removeFunc, outerHTMLFunc, appendToFunc, startTagFunc, endTagFunc;
13069
+ var rangeFor, htmlFunc, removeFunc, outerHTMLFunc, appendToFunc, afterFunc, prependFunc, startTagFunc, endTagFunc;
13009
13070
 
13010
13071
  outerHTMLFunc = function() {
13011
13072
  return this.startTag() + this.innerHTML + this.endTag();
@@ -13062,7 +13123,7 @@ Ember.ViewState = Ember.State.extend({
13062
13123
  // create a new document fragment for the HTML
13063
13124
  var fragment = range.createContextualFragment(html);
13064
13125
 
13065
- // inser the fragment into the range
13126
+ // insert the fragment into the range
13066
13127
  range.insertNode(fragment);
13067
13128
  };
13068
13129
 
@@ -13082,6 +13143,29 @@ Ember.ViewState = Ember.State.extend({
13082
13143
  var frag = range.createContextualFragment(this.outerHTML());
13083
13144
  node.appendChild(frag);
13084
13145
  };
13146
+
13147
+ afterFunc = function(html) {
13148
+ var range = document.createRange();
13149
+ var after = document.getElementById(this.end);
13150
+
13151
+ range.setStartAfter(after);
13152
+ range.setEndAfter(after);
13153
+
13154
+ var fragment = range.createContextualFragment(html);
13155
+ range.insertNode(fragment);
13156
+ };
13157
+
13158
+ prependFunc = function(html) {
13159
+ var range = document.createRange();
13160
+ var start = document.getElementById(this.start);
13161
+
13162
+ range.setStartAfter(start);
13163
+ range.setEndAfter(start);
13164
+
13165
+ var fragment = range.createContextualFragment(html);
13166
+ range.insertNode(fragment);
13167
+ };
13168
+
13085
13169
  } else {
13086
13170
  /**
13087
13171
  * This code is mostly taken from jQuery, with one exception. In jQuery's case, we
@@ -13266,6 +13350,43 @@ Ember.ViewState = Ember.State.extend({
13266
13350
  node = nextSibling;
13267
13351
  }
13268
13352
  };
13353
+
13354
+ afterFunc = function(html) {
13355
+ // get the real starting node. see realNode for details.
13356
+ var end = document.getElementById(this.end);
13357
+ var parentNode = end.parentNode;
13358
+ var nextSibling;
13359
+ var node;
13360
+
13361
+ // get the first node for the HTML string, even in cases like
13362
+ // tables and lists where a simple innerHTML on a div would
13363
+ // swallow some of the content.
13364
+ node = firstNodeFor(parentNode, html);
13365
+
13366
+ // copy the nodes for the HTML between the starting and ending
13367
+ // placeholder.
13368
+ while (node) {
13369
+ nextSibling = node.nextSibling;
13370
+ parentNode.insertBefore(node, end.nextSibling);
13371
+ node = nextSibling;
13372
+ }
13373
+ };
13374
+
13375
+ prependFunc = function(html) {
13376
+ var start = document.getElementById(this.start);
13377
+ var parentNode = start.parentNode;
13378
+ var nextSibling;
13379
+ var node;
13380
+
13381
+ node = firstNodeFor(parentNode, html);
13382
+ var insertBefore = start.nextSibling;
13383
+
13384
+ while (node) {
13385
+ nextSibling = node.nextSibling;
13386
+ parentNode.insertBefore(node, insertBefore);
13387
+ node = nextSibling;
13388
+ }
13389
+ }
13269
13390
  }
13270
13391
 
13271
13392
  Metamorph.prototype.html = function(html) {
@@ -13285,6 +13406,8 @@ Ember.ViewState = Ember.State.extend({
13285
13406
  Metamorph.prototype.remove = removeFunc;
13286
13407
  Metamorph.prototype.outerHTML = outerHTMLFunc;
13287
13408
  Metamorph.prototype.appendTo = appendToFunc;
13409
+ Metamorph.prototype.after = afterFunc;
13410
+ Metamorph.prototype.prepend = prependFunc;
13288
13411
  Metamorph.prototype.startTag = startTagFunc;
13289
13412
  Metamorph.prototype.endTag = endTagFunc;
13290
13413
 
@@ -13675,6 +13798,48 @@ Ember.TextArea = Ember.View.extend(Ember.TextSupport, {
13675
13798
  })({});
13676
13799
 
13677
13800
 
13801
+ (function(exports) {
13802
+ Ember.TabContainerView = Ember.View.extend();
13803
+
13804
+ })({});
13805
+
13806
+
13807
+ (function(exports) {
13808
+ var get = Ember.get, getPath = Ember.getPath;
13809
+
13810
+ Ember.TabPaneView = Ember.View.extend({
13811
+ tabsContainer: SC.computed(function() {
13812
+ return this.nearestInstanceOf(Ember.TabContainerView);
13813
+ }).property(),
13814
+
13815
+ isVisible: SC.computed(function() {
13816
+ return get(this, 'viewName') === getPath(this, 'tabsContainer.currentView');
13817
+ }).property('tabsContainer.currentView')
13818
+ });
13819
+
13820
+ })({});
13821
+
13822
+
13823
+ (function(exports) {
13824
+ var get = Ember.get, setPath = Ember.setPath;
13825
+
13826
+ Ember.TabView = Ember.View.extend({
13827
+ tabsContainer: SC.computed(function() {
13828
+ return this.nearestInstanceOf(Ember.TabContainerView);
13829
+ }).property(),
13830
+
13831
+ mouseUp: function() {
13832
+ setPath(this, 'tabsContainer.currentView', get(this, 'value'));
13833
+ }
13834
+ });
13835
+
13836
+ })({});
13837
+
13838
+
13839
+ (function(exports) {
13840
+ })({});
13841
+
13842
+
13678
13843
  (function(exports) {
13679
13844
  // ==========================================================================
13680
13845
  // Project: Ember Handlebar Views
@@ -13724,8 +13889,7 @@ Ember.Metamorph = Ember.Mixin.create({
13724
13889
 
13725
13890
  childView._insertElementLater(function() {
13726
13891
  var morph = get(view, 'morph');
13727
- var script = Ember.$("#" + morph.start);
13728
- script.after(get(childView, 'outerHTML'));
13892
+ morph.prepend(get(childView, 'outerHTML'));
13729
13893
  childView.set('outerHTML', null);
13730
13894
  });
13731
13895
  },
@@ -13735,8 +13899,7 @@ Ember.Metamorph = Ember.Mixin.create({
13735
13899
 
13736
13900
  nextView._insertElementLater(function() {
13737
13901
  var morph = get(view, 'morph');
13738
- var script = Ember.$("#" + morph.end);
13739
- script.after(get(nextView, 'outerHTML'));
13902
+ morph.after(get(nextView, 'outerHTML'));
13740
13903
  nextView.set('outerHTML', null);
13741
13904
  });
13742
13905
  },
@@ -14141,7 +14304,7 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
14141
14304
 
14142
14305
  ember_assert(fmt("Attributes must be numbers, strings or booleans, not %@", [result]), result == null || typeof result === 'number' || typeof result === 'string' || typeof result === 'boolean');
14143
14306
 
14144
- var elem = view.$("[data-handlebars-id='" + dataId + "']");
14307
+ var elem = view.$("[data-bindAttr-" + dataId + "='" + dataId + "']");
14145
14308
 
14146
14309
  // If we aren't able to find the element, it means the element
14147
14310
  // to which we were bound has been removed from the view.
@@ -14190,7 +14353,7 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
14190
14353
  }, this);
14191
14354
 
14192
14355
  // Add the unique identifier
14193
- ret.push('data-handlebars-id="' + dataId + '"');
14356
+ ret.push('data-bindAttr-' + dataId + '="' + dataId + '"');
14194
14357
  return new Ember.Handlebars.SafeString(ret.join(' '));
14195
14358
  });
14196
14359
 
@@ -14215,12 +14378,12 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
14215
14378
  @param {Ember.View} view
14216
14379
  The view in which observers should look for the element to update
14217
14380
 
14218
- @param {String} id
14219
- Optional id use to lookup elements
14381
+ @param {Srting} bindAttrId
14382
+ Optional bindAttr id used to lookup elements
14220
14383
 
14221
14384
  @returns {Array} An array of class names to add
14222
14385
  */
14223
- Ember.Handlebars.bindClasses = function(context, classBindings, view, id) {
14386
+ Ember.Handlebars.bindClasses = function(context, classBindings, view, bindAttrId) {
14224
14387
  var ret = [], newClass, value, elem;
14225
14388
 
14226
14389
  // Helper method to retrieve the property from the context and
@@ -14272,7 +14435,7 @@ Ember.Handlebars.bindClasses = function(context, classBindings, view, id) {
14272
14435
  observer = function() {
14273
14436
  // Get the current value of the property
14274
14437
  newClass = classStringForProperty(binding);
14275
- elem = id ? view.$("[data-handlebars-id='" + id + "']") : view.$();
14438
+ elem = bindAttrId ? view.$("[data-bindAttr-" + bindAttrId + "='" + bindAttrId + "']") : view.$();
14276
14439
 
14277
14440
  // If we can't find the element anymore, a parent template has been
14278
14441
  // re-rendered and we've been nuked. Remove the observer.
@@ -14377,14 +14540,10 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
14377
14540
  if (Ember.IS_BINDING.test(prop)) {
14378
14541
  path = options[prop];
14379
14542
  if (!Ember.isGlobalPath(path)) {
14380
-
14381
- // Deprecation warning for users of beta 2 and lower, where
14382
- // this facility was not available. The workaround was to bind
14383
- // to parentViews; since this is no longer necessary, issue
14384
- // a notice.
14385
- if (PARENT_VIEW_PATH.test(path)) {
14386
- Ember.Logger.warn("As of SproutCore 2.0 beta 3, it is no longer necessary to bind to parentViews. Instead, please provide binding paths relative to the current Handlebars context.");
14387
- } else {
14543
+ // Binding to parentViews was previously deprecated. In most cases it shouldn't be necessary, but since
14544
+ // there are a few valid use cases and most people have broken the parentView habit, we're no longer
14545
+ // providing a warning about it.
14546
+ if (!PARENT_VIEW_PATH.test(path)) {
14388
14547
  if (path === 'this') {
14389
14548
  options[prop] = 'bindingContext';
14390
14549
  } else {
@@ -14687,16 +14846,24 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
14687
14846
  // Find templates stored in the head tag as script tags and make them available
14688
14847
  // to Ember.CoreView in the global Ember.TEMPLATES object. This will be run as as
14689
14848
  // jQuery DOM-ready callback.
14849
+ //
14850
+ // Script tags with type="text/html" or "text/x-handlebars" will be compiled
14851
+ // with Ember's Handlebars and are suitable for use as a view's template.
14852
+ // Those with type="text/x-raw-handlebars" will be compiled with regular
14853
+ // Handlebars and are suitable for use in views' computed properties.
14690
14854
  Ember.Handlebars.bootstrap = function() {
14691
- Ember.$('script[type="text/html"], script[type="text/x-handlebars"]')
14855
+ Ember.$('script[type="text/html"], script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]')
14692
14856
  .each(function() {
14693
14857
  // Get a reference to the script tag
14694
14858
  var script = Ember.$(this),
14859
+ compile = (script.attr('type') === 'text/x-raw-handlebars') ?
14860
+ Ember.$.proxy(Handlebars.compile, Handlebars) :
14861
+ Ember.$.proxy(Ember.Handlebars.compile, Ember.Handlebars),
14695
14862
  // Get the name of the script, used by Ember.View's templateName property.
14696
14863
  // First look for data-template-name attribute, then fall back to its
14697
14864
  // id if no name is found.
14698
14865
  templateName = script.attr('data-template-name') || script.attr('id'),
14699
- template = Ember.Handlebars.compile(script.html()),
14866
+ template = compile(script.html()),
14700
14867
  view, viewPath;
14701
14868
 
14702
14869
  if (templateName) {