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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.6.0-beta.2
8
+ * @version 1.6.0-beta.3
9
9
  */
10
10
 
11
11
 
@@ -1174,11 +1174,11 @@ define("ember-metal/computed",
1174
1174
  });
1175
1175
 
1176
1176
  var tom = Person.create({
1177
- firstName: "Tom",
1178
- lastName: "Dale"
1177
+ firstName: 'Tom',
1178
+ lastName: 'Dale'
1179
1179
  });
1180
1180
 
1181
- tom.get('fullName') // "Tom Dale"
1181
+ tom.get('fullName') // 'Tom Dale'
1182
1182
  ```
1183
1183
 
1184
1184
  You can also define what Ember should do when setting a computed property.
@@ -1214,9 +1214,9 @@ define("ember-metal/computed",
1214
1214
  });
1215
1215
 
1216
1216
  var person = Person.create();
1217
- person.set('fullName', "Peter Wagenet");
1218
- person.get('firstName') // Peter
1219
- person.get('lastName') // Wagenet
1217
+ person.set('fullName', 'Peter Wagenet');
1218
+ person.get('firstName') // 'Peter'
1219
+ person.get('lastName') // 'Wagenet'
1220
1220
  ```
1221
1221
 
1222
1222
  @class ComputedProperty
@@ -1323,7 +1323,8 @@ define("ember-metal/computed",
1323
1323
  firstName: 'Barack',
1324
1324
  lastName: 'Obama',
1325
1325
  });
1326
- MyApp.president.get('fullName'); // Barack Obama
1326
+
1327
+ MyApp.president.get('fullName'); // 'Barack Obama'
1327
1328
  ```
1328
1329
 
1329
1330
  @method property
@@ -1417,11 +1418,11 @@ define("ember-metal/computed",
1417
1418
 
1418
1419
 
1419
1420
  var tom = Person.create({
1420
- firstName: "Tom",
1421
- lastName: "Dale"
1421
+ firstName: 'Tom',
1422
+ lastName: 'Dale'
1422
1423
  });
1423
1424
 
1424
- tom.get('fullName') // "Tom Dale"
1425
+ tom.get('fullName') // 'Tom Dale'
1425
1426
  ```
1426
1427
 
1427
1428
  @method get
@@ -1495,7 +1496,7 @@ define("ember-metal/computed",
1495
1496
  hadCachedValue = true;
1496
1497
  }
1497
1498
 
1498
- // Check if the CP has been wrapped. If if has, use the
1499
+ // Check if the CP has been wrapped. If it has, use the
1499
1500
  // length from the wrapped function.
1500
1501
 
1501
1502
  funcArgLength = func.wrappedFunction ? func.wrappedFunction.__ember_arity__ : func.__ember_arity__;
@@ -1565,6 +1566,7 @@ define("ember-metal/computed",
1565
1566
  The function should accept two parameters, key and value. If value is not
1566
1567
  undefined you should set the value first. In either case return the
1567
1568
  current value of the property.
1569
+
1568
1570
  @method computed
1569
1571
  @for Ember
1570
1572
  @param {Function} func The computed property function.
@@ -1671,7 +1673,9 @@ define("ember-metal/computed",
1671
1673
  var ToDoList = Ember.Object.extend({
1672
1674
  done: Ember.computed.empty('todos')
1673
1675
  });
1676
+
1674
1677
  var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
1678
+
1675
1679
  todoList.get('done'); // false
1676
1680
  todoList.get('todos').clear();
1677
1681
  todoList.get('done'); // true
@@ -1701,9 +1705,11 @@ define("ember-metal/computed",
1701
1705
 
1702
1706
  ```javascript
1703
1707
  var Hamster = Ember.Object.extend({
1704
- hasStuff: computed.notEmpty('backpack.[]')
1708
+ hasStuff: Ember.computed.notEmpty('backpack.[]')
1705
1709
  });
1710
+
1706
1711
  var hamster = Hamster.create({backpack: ['Food', 'Sleeping Bag', 'Tent']});
1712
+
1707
1713
  hamster.get('hasStuff'); // true
1708
1714
  hamster.get('backpack').clear(); // []
1709
1715
  hamster.get('hasStuff'); // false
@@ -1728,9 +1734,11 @@ define("ember-metal/computed",
1728
1734
 
1729
1735
  ```javascript
1730
1736
  var Hamster = Ember.Object.extend({
1731
- isHungry: computed.none('food')
1737
+ isHungry: Ember.computed.none('food')
1732
1738
  });
1739
+
1733
1740
  var hamster = Hamster.create();
1741
+
1734
1742
  hamster.get('isHungry'); // true
1735
1743
  hamster.set('food', 'Banana');
1736
1744
  hamster.get('isHungry'); // false
@@ -1756,9 +1764,11 @@ define("ember-metal/computed",
1756
1764
 
1757
1765
  ```javascript
1758
1766
  var User = Ember.Object.extend({
1759
- isAnonymous: computed.not('loggedIn')
1767
+ isAnonymous: Ember.computed.not('loggedIn')
1760
1768
  });
1769
+
1761
1770
  var user = User.create({loggedIn: false});
1771
+
1762
1772
  user.get('isAnonymous'); // true
1763
1773
  user.set('loggedIn', true);
1764
1774
  user.get('isAnonymous'); // false
@@ -1780,9 +1790,11 @@ define("ember-metal/computed",
1780
1790
 
1781
1791
  ```javascript
1782
1792
  var Hamster = Ember.Object.extend({
1783
- hasBananas: computed.bool('numBananas')
1793
+ hasBananas: Ember.computed.bool('numBananas')
1784
1794
  });
1795
+
1785
1796
  var hamster = Hamster.create();
1797
+
1786
1798
  hamster.get('hasBananas'); // false
1787
1799
  hamster.set('numBananas', 0);
1788
1800
  hamster.get('hasBananas'); // false
@@ -1811,9 +1823,11 @@ define("ember-metal/computed",
1811
1823
 
1812
1824
  ```javascript
1813
1825
  var User = Ember.Object.extend({
1814
- hasValidEmail: computed.match('email', /^.+@.+\..+$/)
1826
+ hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
1815
1827
  });
1828
+
1816
1829
  var user = User.create({loggedIn: false});
1830
+
1817
1831
  user.get('hasValidEmail'); // false
1818
1832
  user.set('email', '');
1819
1833
  user.get('hasValidEmail'); // false
@@ -1841,9 +1855,11 @@ define("ember-metal/computed",
1841
1855
 
1842
1856
  ```javascript
1843
1857
  var Hamster = Ember.Object.extend({
1844
- napTime: computed.equal('state', 'sleepy')
1858
+ napTime: Ember.computed.equal('state', 'sleepy')
1845
1859
  });
1860
+
1846
1861
  var hamster = Hamster.create();
1862
+
1847
1863
  hamster.get('napTime'); // false
1848
1864
  hamster.set('state', 'sleepy');
1849
1865
  hamster.get('napTime'); // true
@@ -1870,9 +1886,11 @@ define("ember-metal/computed",
1870
1886
 
1871
1887
  ```javascript
1872
1888
  var Hamster = Ember.Object.extend({
1873
- hasTooManyBananas: computed.gt('numBananas', 10)
1889
+ hasTooManyBananas: Ember.computed.gt('numBananas', 10)
1874
1890
  });
1891
+
1875
1892
  var hamster = Hamster.create();
1893
+
1876
1894
  hamster.get('hasTooManyBananas'); // false
1877
1895
  hamster.set('numBananas', 3);
1878
1896
  hamster.get('hasTooManyBananas'); // false
@@ -1899,9 +1917,11 @@ define("ember-metal/computed",
1899
1917
 
1900
1918
  ```javascript
1901
1919
  var Hamster = Ember.Object.extend({
1902
- hasTooManyBananas: computed.gte('numBananas', 10)
1920
+ hasTooManyBananas: Ember.computed.gte('numBananas', 10)
1903
1921
  });
1922
+
1904
1923
  var hamster = Hamster.create();
1924
+
1905
1925
  hamster.get('hasTooManyBananas'); // false
1906
1926
  hamster.set('numBananas', 3);
1907
1927
  hamster.get('hasTooManyBananas'); // false
@@ -1928,9 +1948,11 @@ define("ember-metal/computed",
1928
1948
 
1929
1949
  ```javascript
1930
1950
  var Hamster = Ember.Object.extend({
1931
- needsMoreBananas: computed.lt('numBananas', 3)
1951
+ needsMoreBananas: Ember.computed.lt('numBananas', 3)
1932
1952
  });
1953
+
1933
1954
  var hamster = Hamster.create();
1955
+
1934
1956
  hamster.get('needsMoreBananas'); // true
1935
1957
  hamster.set('numBananas', 3);
1936
1958
  hamster.get('needsMoreBananas'); // false
@@ -1957,9 +1979,11 @@ define("ember-metal/computed",
1957
1979
 
1958
1980
  ```javascript
1959
1981
  var Hamster = Ember.Object.extend({
1960
- needsMoreBananas: computed.lte('numBananas', 3)
1982
+ needsMoreBananas: Ember.computed.lte('numBananas', 3)
1961
1983
  });
1984
+
1962
1985
  var hamster = Hamster.create();
1986
+
1963
1987
  hamster.get('needsMoreBananas'); // true
1964
1988
  hamster.set('numBananas', 5);
1965
1989
  hamster.get('needsMoreBananas'); // false
@@ -1986,9 +2010,11 @@ define("ember-metal/computed",
1986
2010
 
1987
2011
  ```javascript
1988
2012
  var Hamster = Ember.Object.extend({
1989
- readyForCamp: computed.and('hasTent', 'hasBackpack')
2013
+ readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
1990
2014
  });
2015
+
1991
2016
  var hamster = Hamster.create();
2017
+
1992
2018
  hamster.get('readyForCamp'); // false
1993
2019
  hamster.set('hasTent', true);
1994
2020
  hamster.get('readyForCamp'); // false
@@ -2019,9 +2045,11 @@ define("ember-metal/computed",
2019
2045
 
2020
2046
  ```javascript
2021
2047
  var Hamster = Ember.Object.extend({
2022
- readyForRain: computed.or('hasJacket', 'hasUmbrella')
2048
+ readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella')
2023
2049
  });
2050
+
2024
2051
  var hamster = Hamster.create();
2052
+
2025
2053
  hamster.get('readyForRain'); // false
2026
2054
  hamster.set('hasJacket', true);
2027
2055
  hamster.get('readyForRain'); // true
@@ -2050,9 +2078,11 @@ define("ember-metal/computed",
2050
2078
 
2051
2079
  ```javascript
2052
2080
  var Hamster = Ember.Object.extend({
2053
- hasClothes: computed.any('hat', 'shirt')
2081
+ hasClothes: Ember.computed.any('hat', 'shirt')
2054
2082
  });
2083
+
2055
2084
  var hamster = Hamster.create();
2085
+
2056
2086
  hamster.get('hasClothes'); // null
2057
2087
  hamster.set('shirt', 'Hawaiian Shirt');
2058
2088
  hamster.get('hasClothes'); // 'Hawaiian Shirt'
@@ -2081,9 +2111,11 @@ define("ember-metal/computed",
2081
2111
 
2082
2112
  ```javascript
2083
2113
  var Hamster = Ember.Object.extend({
2084
- clothes: computed.collect('hat', 'shirt')
2114
+ clothes: Ember.computed.collect('hat', 'shirt')
2085
2115
  });
2116
+
2086
2117
  var hamster = Hamster.create();
2118
+
2087
2119
  hamster.get('clothes'); // [null, null]
2088
2120
  hamster.set('hat', 'Camp Hat');
2089
2121
  hamster.set('shirt', 'Camp Shirt');
@@ -2118,16 +2150,18 @@ define("ember-metal/computed",
2118
2150
  ```javascript
2119
2151
  Person = Ember.Object.extend({
2120
2152
  name: 'Alex Matchneer',
2121
- nomen: computed.alias('name')
2153
+ nomen: Ember.computed.alias('name')
2122
2154
  });
2123
2155
 
2124
2156
  alex = Person.create();
2157
+
2125
2158
  alex.get('nomen'); // 'Alex Matchneer'
2126
2159
  alex.get('name'); // 'Alex Matchneer'
2127
2160
 
2128
2161
  alex.set('nomen', '@machty');
2129
2162
  alex.get('name'); // '@machty'
2130
2163
  ```
2164
+
2131
2165
  @method computed.alias
2132
2166
  @for Ember
2133
2167
  @param {String} dependentKey
@@ -2149,31 +2183,26 @@ define("ember-metal/computed",
2149
2183
  Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
2150
2184
  data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
2151
2185
  not mutate the upstream property, rather causes the current property to
2152
- become the value set. This causes the downstream property to permentantly
2186
+ become the value set. This causes the downstream property to permanently
2153
2187
  diverge from the upstream property.
2154
2188
 
2155
2189
  Example
2156
2190
 
2157
2191
  ```javascript
2158
- User = Ember.Object.extend({
2192
+ var User = Ember.Object.extend({
2159
2193
  firstName: null,
2160
2194
  lastName: null,
2161
- nickName: computed.oneWay('firstName')
2195
+ nickName: Ember.computed.oneWay('firstName')
2162
2196
  });
2163
2197
 
2164
- user = User.create({
2198
+ var teddy = User.create({
2165
2199
  firstName: 'Teddy',
2166
2200
  lastName: 'Zeenny'
2167
2201
  });
2168
2202
 
2169
- user.get('nickName');
2170
- # 'Teddy'
2171
-
2172
- user.set('nickName', 'TeddyBear');
2173
- # 'TeddyBear'
2174
-
2175
- user.get('firstName');
2176
- # 'Teddy'
2203
+ teddy.get('nickName'); // 'Teddy'
2204
+ teddy.set('nickName', 'TeddyBear'); // 'TeddyBear'
2205
+ teddy.get('firstName'); // 'Teddy'
2177
2206
  ```
2178
2207
 
2179
2208
  @method computed.oneWay
@@ -2212,26 +2241,21 @@ define("ember-metal/computed",
2212
2241
  Example
2213
2242
 
2214
2243
  ```javascript
2215
- User = Ember.Object.extend({
2244
+ var User = Ember.Object.extend({
2216
2245
  firstName: null,
2217
2246
  lastName: null,
2218
- nickName: computed.readOnly('firstName')
2247
+ nickName: Ember.computed.readOnly('firstName')
2219
2248
  });
2220
2249
 
2221
- user = User.create({
2250
+ var teddy = User.create({
2222
2251
  firstName: 'Teddy',
2223
2252
  lastName: 'Zeenny'
2224
2253
  });
2225
2254
 
2226
- user.get('nickName');
2227
- # 'Teddy'
2228
-
2229
- user.set('nickName', 'TeddyBear');
2230
- # throws Exception
2231
- # throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );`
2232
-
2233
- user.get('firstName');
2234
- # 'Teddy'
2255
+ teddy.get('nickName'); // 'Teddy'
2256
+ teddy.set('nickName', 'TeddyBear'); // throws Exception
2257
+ // throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );`
2258
+ teddy.get('firstName'); // 'Teddy'
2235
2259
  ```
2236
2260
 
2237
2261
  @method computed.readOnly
@@ -2239,6 +2263,7 @@ define("ember-metal/computed",
2239
2263
  @param {String} dependentKey
2240
2264
  @return {Ember.ComputedProperty} computed property which creates a
2241
2265
  one way computed property to the original value for property.
2266
+ @since 1.5.0
2242
2267
  */
2243
2268
  computed.readOnly = function(dependentKey) {
2244
2269
  return computed(dependentKey, function() {
@@ -2254,9 +2279,11 @@ define("ember-metal/computed",
2254
2279
 
2255
2280
  ```javascript
2256
2281
  var Hamster = Ember.Object.extend({
2257
- wishList: computed.defaultTo('favoriteFood')
2282
+ wishList: Ember.computed.defaultTo('favoriteFood')
2258
2283
  });
2284
+
2259
2285
  var hamster = Hamster.create({favoriteFood: 'Banana'});
2286
+
2260
2287
  hamster.get('wishList'); // 'Banana'
2261
2288
  hamster.set('wishList', 'More Unit Tests');
2262
2289
  hamster.get('wishList'); // 'More Unit Tests'
@@ -2311,7 +2338,7 @@ define("ember-metal/core",
2311
2338
 
2312
2339
  @class Ember
2313
2340
  @static
2314
- @version 1.6.0-beta.2
2341
+ @version 1.6.0-beta.3
2315
2342
  */
2316
2343
 
2317
2344
  if ('undefined' === typeof Ember) {
@@ -2338,10 +2365,10 @@ define("ember-metal/core",
2338
2365
  /**
2339
2366
  @property VERSION
2340
2367
  @type String
2341
- @default '1.6.0-beta.2'
2368
+ @default '1.6.0-beta.3'
2342
2369
  @static
2343
2370
  */
2344
- Ember.VERSION = '1.6.0-beta.2';
2371
+ Ember.VERSION = '1.6.0-beta.3';
2345
2372
 
2346
2373
  /**
2347
2374
  Standard environmental variables. You can define these in a global `EmberENV`
@@ -2382,8 +2409,10 @@ define("ember-metal/core",
2382
2409
 
2383
2410
  You can also define `ENV.FEATURES` if you need to enable features flagged at runtime.
2384
2411
 
2385
- @property FEATURES
2386
- @type Hash
2412
+ @class FEATURES
2413
+ @namespace Ember
2414
+ @static
2415
+ @since 1.1.0
2387
2416
  */
2388
2417
 
2389
2418
  Ember.FEATURES = Ember.ENV.FEATURES || {};
@@ -2399,7 +2428,10 @@ define("ember-metal/core",
2399
2428
  enabled/disabled.
2400
2429
 
2401
2430
  @method isEnabled
2402
- @param {string} feature
2431
+ @param {String} feature
2432
+ @return {Boolean}
2433
+ @for Ember.FEATURES
2434
+ @since 1.1.0
2403
2435
  */
2404
2436
 
2405
2437
  Ember.FEATURES.isEnabled = function(feature) {
@@ -2433,6 +2465,7 @@ define("ember-metal/core",
2433
2465
  @property EXTEND_PROTOTYPES
2434
2466
  @type Boolean
2435
2467
  @default true
2468
+ @for Ember
2436
2469
  */
2437
2470
  Ember.EXTEND_PROTOTYPES = Ember.ENV.EXTEND_PROTOTYPES;
2438
2471
 
@@ -2566,6 +2599,7 @@ define("ember-metal/enumerable_utils",
2566
2599
  * @param {Object} thisArg Value to use as this when executing *callback*
2567
2600
  *
2568
2601
  * @return {Array} An array containing the filtered values
2602
+ * @since 1.4.0
2569
2603
  */
2570
2604
  filter: function(obj, callback, thisArg) {
2571
2605
  return obj.filter ? obj.filter.call(obj, callback, thisArg) : filter.call(obj, callback, thisArg);
@@ -3532,6 +3566,7 @@ define("ember-metal/is_blank",
3532
3566
  @for Ember
3533
3567
  @param {Object} obj Value to test
3534
3568
  @return {Boolean}
3569
+ @since 1.5.0
3535
3570
  */
3536
3571
  function isBlank(obj) {
3537
3572
  return isEmpty(obj) || (typeof obj === 'string' && obj.match(/\S/) === null);
@@ -3988,6 +4023,8 @@ define("ember-metal",
3988
4023
  };
3989
4024
  ```
3990
4025
 
4026
+ Internally, `Ember.onerror` is used as Backburner's error handler.
4027
+
3991
4028
  @event onerror
3992
4029
  @for Ember
3993
4030
  @param {Exception} error the error object
@@ -6357,7 +6394,9 @@ define("ember-metal/run_loop",
6357
6394
  },
6358
6395
  defaultQueue: 'actions',
6359
6396
  onBegin: onBegin,
6360
- onEnd: onEnd
6397
+ onEnd: onEnd,
6398
+ onErrorTarget: Ember,
6399
+ onErrorMethod: 'onerror'
6361
6400
  }),
6362
6401
  slice = [].slice,
6363
6402
  concat = [].concat;
@@ -6394,20 +6433,9 @@ define("ember-metal/run_loop",
6394
6433
  @return {Object} return value from invoking the passed function.
6395
6434
  */
6396
6435
  var run = function() {
6397
- if (Ember.onerror) {
6398
- return onerror(arguments);
6399
- } else {
6400
- return apply(backburner, backburner.run, arguments);
6401
- }
6436
+ return apply(backburner, backburner.run, arguments);
6402
6437
  };
6403
6438
 
6404
- function onerror(args) {
6405
- try {
6406
- return apply(backburner, backburner.run, args);
6407
- } catch(error) {
6408
- Ember.onerror(error);
6409
- }
6410
- }
6411
6439
  /**
6412
6440
  If no run-loop is present, it creates a new one. If a run loop is
6413
6441
  present it will queue itself to run on the existing run-loops action
@@ -6494,6 +6522,7 @@ define("ember-metal/run_loop",
6494
6522
  @param {Object} [args*] Any additional arguments you wish to pass to the method.
6495
6523
  @return {Object} return value from invoking the passed function. Please note,
6496
6524
  when called within an existing loop, no return value is possible.
6525
+ @since 1.4.0
6497
6526
  */
6498
6527
  run.bind = function(target, method /* args*/) {
6499
6528
  var args = slice.call(arguments);
@@ -7017,6 +7046,10 @@ define("ember-metal/utils",
7017
7046
  /**
7018
7047
  Prefix used for guids through out Ember.
7019
7048
  @private
7049
+ @property GUID_PREFIX
7050
+ @for Ember
7051
+ @type String
7052
+ @final
7020
7053
  */
7021
7054
  var GUID_PREFIX = 'ember';
7022
7055
 
@@ -7392,7 +7425,7 @@ define("ember-metal/utils",
7392
7425
  if (!obj || obj.setInterval) { return false; }
7393
7426
  if (Array.isArray && Array.isArray(obj)) { return true; }
7394
7427
  if (EmberArray && EmberArray.detect(obj)) { return true; }
7395
- if ((obj.length !== undefined) && 'object'===typeof obj) { return true; }
7428
+ if ((obj.length !== undefined) && 'object'=== typeOf(obj)) { return true; }
7396
7429
  return false;
7397
7430
  };
7398
7431
 
@@ -7722,6 +7755,7 @@ define("ember-metal/utils",
7722
7755
  @for Ember
7723
7756
  @param {Object} obj The object you want to inspect.
7724
7757
  @return {String} A description of the object
7758
+ @since 1.4.0
7725
7759
  */
7726
7760
  function inspect(obj) {
7727
7761
  var type = typeOf(obj);
@@ -7796,219 +7830,7 @@ define("ember-metal/utils",
7796
7830
  __exports__.applyStr = applyStr;
7797
7831
  __exports__.apply = apply;
7798
7832
  });
7799
- define("backburner/queue",
7800
- ["exports"],
7801
- function(__exports__) {
7802
- "use strict";
7803
- function Queue(daq, name, options) {
7804
- this.daq = daq;
7805
- this.name = name;
7806
- this.options = options;
7807
- this._queue = [];
7808
- }
7809
-
7810
- Queue.prototype = {
7811
- daq: null,
7812
- name: null,
7813
- options: null,
7814
- _queue: null,
7815
-
7816
- push: function(target, method, args, stack) {
7817
- var queue = this._queue;
7818
- queue.push(target, method, args, stack);
7819
- return {queue: this, target: target, method: method};
7820
- },
7821
-
7822
- pushUnique: function(target, method, args, stack) {
7823
- var queue = this._queue, currentTarget, currentMethod, i, l;
7824
-
7825
- for (i = 0, l = queue.length; i < l; i += 4) {
7826
- currentTarget = queue[i];
7827
- currentMethod = queue[i+1];
7828
-
7829
- if (currentTarget === target && currentMethod === method) {
7830
- queue[i+2] = args; // replace args
7831
- queue[i+3] = stack; // replace stack
7832
- return {queue: this, target: target, method: method}; // TODO: test this code path
7833
- }
7834
- }
7835
-
7836
- this._queue.push(target, method, args, stack);
7837
- return {queue: this, target: target, method: method};
7838
- },
7839
-
7840
- // TODO: remove me, only being used for Ember.run.sync
7841
- flush: function() {
7842
- var queue = this._queue,
7843
- options = this.options,
7844
- before = options && options.before,
7845
- after = options && options.after,
7846
- target, method, args, stack, i, l = queue.length;
7847
-
7848
- if (l && before) { before(); }
7849
- for (i = 0; i < l; i += 4) {
7850
- target = queue[i];
7851
- method = queue[i+1];
7852
- args = queue[i+2];
7853
- stack = queue[i+3]; // Debugging assistance
7854
-
7855
- // TODO: error handling
7856
- if (args && args.length > 0) {
7857
- method.apply(target, args);
7858
- } else {
7859
- method.call(target);
7860
- }
7861
- }
7862
- if (l && after) { after(); }
7863
-
7864
- // check if new items have been added
7865
- if (queue.length > l) {
7866
- this._queue = queue.slice(l);
7867
- this.flush();
7868
- } else {
7869
- this._queue.length = 0;
7870
- }
7871
- },
7872
-
7873
- cancel: function(actionToCancel) {
7874
- var queue = this._queue, currentTarget, currentMethod, i, l;
7875
-
7876
- for (i = 0, l = queue.length; i < l; i += 4) {
7877
- currentTarget = queue[i];
7878
- currentMethod = queue[i+1];
7879
-
7880
- if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
7881
- queue.splice(i, 4);
7882
- return true;
7883
- }
7884
- }
7885
-
7886
- // if not found in current queue
7887
- // could be in the queue that is being flushed
7888
- queue = this._queueBeingFlushed;
7889
- if (!queue) {
7890
- return;
7891
- }
7892
- for (i = 0, l = queue.length; i < l; i += 4) {
7893
- currentTarget = queue[i];
7894
- currentMethod = queue[i+1];
7895
-
7896
- if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
7897
- // don't mess with array during flush
7898
- // just nullify the method
7899
- queue[i+1] = null;
7900
- return true;
7901
- }
7902
- }
7903
- }
7904
- };
7905
-
7906
- __exports__.Queue = Queue;
7907
- });
7908
-
7909
- define("backburner/deferred_action_queues",
7910
- ["backburner/queue","exports"],
7911
- function(__dependency1__, __exports__) {
7912
- "use strict";
7913
- var Queue = __dependency1__.Queue;
7914
-
7915
- function DeferredActionQueues(queueNames, options) {
7916
- var queues = this.queues = {};
7917
- this.queueNames = queueNames = queueNames || [];
7918
-
7919
- var queueName;
7920
- for (var i = 0, l = queueNames.length; i < l; i++) {
7921
- queueName = queueNames[i];
7922
- queues[queueName] = new Queue(this, queueName, options[queueName]);
7923
- }
7924
- }
7925
-
7926
- DeferredActionQueues.prototype = {
7927
- queueNames: null,
7928
- queues: null,
7929
-
7930
- schedule: function(queueName, target, method, args, onceFlag, stack) {
7931
- var queues = this.queues,
7932
- queue = queues[queueName];
7933
-
7934
- if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }
7935
-
7936
- if (onceFlag) {
7937
- return queue.pushUnique(target, method, args, stack);
7938
- } else {
7939
- return queue.push(target, method, args, stack);
7940
- }
7941
- },
7942
-
7943
- flush: function() {
7944
- var queues = this.queues,
7945
- queueNames = this.queueNames,
7946
- queueName, queue, queueItems, priorQueueNameIndex,
7947
- queueNameIndex = 0, numberOfQueues = queueNames.length;
7948
-
7949
- outerloop:
7950
- while (queueNameIndex < numberOfQueues) {
7951
- queueName = queueNames[queueNameIndex];
7952
- queue = queues[queueName];
7953
- queueItems = queue._queueBeingFlushed = queue._queue.slice();
7954
- queue._queue = [];
7955
-
7956
- var options = queue.options,
7957
- before = options && options.before,
7958
- after = options && options.after,
7959
- target, method, args, stack,
7960
- queueIndex = 0, numberOfQueueItems = queueItems.length;
7961
-
7962
- if (numberOfQueueItems && before) { before(); }
7963
- while (queueIndex < numberOfQueueItems) {
7964
- target = queueItems[queueIndex];
7965
- method = queueItems[queueIndex+1];
7966
- args = queueItems[queueIndex+2];
7967
- stack = queueItems[queueIndex+3]; // Debugging assistance
7968
-
7969
- if (typeof method === 'string') { method = target[method]; }
7970
-
7971
- // method could have been nullified / canceled during flush
7972
- if (method) {
7973
- // TODO: error handling
7974
- if (args && args.length > 0) {
7975
- method.apply(target, args);
7976
- } else {
7977
- method.call(target);
7978
- }
7979
- }
7980
-
7981
- queueIndex += 4;
7982
- }
7983
- queue._queueBeingFlushed = null;
7984
- if (numberOfQueueItems && after) { after(); }
7985
-
7986
- if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
7987
- queueNameIndex = priorQueueNameIndex;
7988
- continue outerloop;
7989
- }
7990
-
7991
- queueNameIndex++;
7992
- }
7993
- }
7994
- };
7995
-
7996
- function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
7997
- var queueName, queue;
7998
-
7999
- for (var i = 0, l = currentQueueIndex; i <= l; i++) {
8000
- queueName = daq.queueNames[i];
8001
- queue = daq.queues[queueName];
8002
- if (queue._queue.length) { return i; }
8003
- }
8004
-
8005
- return -1;
8006
- }
8007
-
8008
- __exports__.DeferredActionQueues = DeferredActionQueues;
8009
- });
8010
-
8011
- define("backburner",
7833
+ define("backburner",
8012
7834
  ["backburner/deferred_action_queues","exports"],
8013
7835
  function(__dependency1__, __exports__) {
8014
7836
  "use strict";
@@ -8023,6 +7845,15 @@ define("backburner",
8023
7845
  global = this,
8024
7846
  NUMBER = /\d+/;
8025
7847
 
7848
+ // In IE 6-8, try/finally doesn't work without a catch.
7849
+ // Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug.
7850
+ // This tests for another broken try/catch behavior that only exhibits in the same versions of IE.
7851
+ var needsIETryCatchFix = (function(e,x){
7852
+ try{ x(); }
7853
+ catch(e) { } // jshint ignore:line
7854
+ return !!e;
7855
+ })();
7856
+
8026
7857
  function isCoercableNumber(number) {
8027
7858
  return typeof number === 'number' || NUMBER.test(number);
8028
7859
  }
@@ -8043,42 +7874,53 @@ define("backburner",
8043
7874
  instanceStack: null,
8044
7875
 
8045
7876
  begin: function() {
8046
- var onBegin = this.options && this.options.onBegin,
7877
+ var options = this.options,
7878
+ onBegin = options && options.onBegin,
8047
7879
  previousInstance = this.currentInstance;
8048
7880
 
8049
7881
  if (previousInstance) {
8050
7882
  this.instanceStack.push(previousInstance);
8051
7883
  }
8052
7884
 
8053
- this.currentInstance = new DeferredActionQueues(this.queueNames, this.options);
7885
+ this.currentInstance = new DeferredActionQueues(this.queueNames, options);
8054
7886
  if (onBegin) {
8055
7887
  onBegin(this.currentInstance, previousInstance);
8056
7888
  }
8057
7889
  },
8058
7890
 
8059
7891
  end: function() {
8060
- var onEnd = this.options && this.options.onEnd,
7892
+ var options = this.options,
7893
+ onEnd = options && options.onEnd,
8061
7894
  currentInstance = this.currentInstance,
8062
7895
  nextInstance = null;
8063
7896
 
7897
+ // Prevent double-finally bug in Safari 6.0.2 and iOS 6
7898
+ // This bug appears to be resolved in Safari 6.0.5 and iOS 7
7899
+ var finallyAlreadyCalled = false;
8064
7900
  try {
8065
7901
  currentInstance.flush();
8066
7902
  } finally {
8067
- this.currentInstance = null;
7903
+ if (!finallyAlreadyCalled) {
7904
+ finallyAlreadyCalled = true;
8068
7905
 
8069
- if (this.instanceStack.length) {
8070
- nextInstance = this.instanceStack.pop();
8071
- this.currentInstance = nextInstance;
8072
- }
7906
+ this.currentInstance = null;
7907
+
7908
+ if (this.instanceStack.length) {
7909
+ nextInstance = this.instanceStack.pop();
7910
+ this.currentInstance = nextInstance;
7911
+ }
8073
7912
 
8074
- if (onEnd) {
8075
- onEnd(currentInstance, nextInstance);
7913
+ if (onEnd) {
7914
+ onEnd(currentInstance, nextInstance);
7915
+ }
8076
7916
  }
8077
7917
  }
8078
7918
  },
8079
7919
 
8080
7920
  run: function(target, method /*, args */) {
8081
- var ret;
7921
+ var options = this.options,
7922
+ ret, length = arguments.length;
7923
+
8082
7924
  this.begin();
8083
7925
 
8084
7926
  if (!method) {
@@ -8090,21 +7932,33 @@ define("backburner",
8090
7932
  method = target[method];
8091
7933
  }
8092
7934
 
8093
- // Prevent Safari double-finally.
8094
- var finallyAlreadyCalled = false;
8095
- try {
8096
- if (arguments.length > 2) {
8097
- ret = method.apply(target, slice.call(arguments, 2));
8098
- } else {
8099
- ret = method.call(target);
7935
+ var onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]);
7936
+ var args = slice.call(arguments, 2);
7937
+
7938
+ // guard against Safari 6's double-finally bug
7939
+ var didFinally = false;
7940
+
7941
+ if (onError) {
7942
+ try {
7943
+ return method.apply(target, args);
7944
+ } catch(error) {
7945
+ onError(error);
7946
+ } finally {
7947
+ if (!didFinally) {
7948
+ didFinally = true;
7949
+ this.end();
7950
+ }
8100
7951
  }
8101
- } finally {
8102
- if (!finallyAlreadyCalled) {
8103
- finallyAlreadyCalled = true;
8104
- this.end();
7952
+ } else {
7953
+ try {
7954
+ return method.apply(target, args);
7955
+ } finally {
7956
+ if (!didFinally) {
7957
+ didFinally = true;
7958
+ this.end();
7959
+ }
8105
7960
  }
8106
7961
  }
8107
- return ret;
8108
7962
  },
8109
7963
 
8110
7964
  defer: function(queueName, target, method /* , args */) {
@@ -8145,6 +7999,7 @@ define("backburner",
8145
7999
  var method, wait, target;
8146
8000
  var self = this;
8147
8001
  var methodOrTarget, methodOrWait, methodOrArgs;
8002
+ var options = this.options;
8148
8003
 
8149
8004
  if (length === 0) {
8150
8005
  return;
@@ -8171,6 +8026,8 @@ define("backburner",
8171
8026
 
8172
8027
  if (isCoercableNumber(last)) {
8173
8028
  wait = args.pop();
8029
+ } else {
8030
+ wait = 0;
8174
8031
  }
8175
8032
 
8176
8033
  methodOrTarget = args[0];
@@ -8192,15 +8049,22 @@ define("backburner",
8192
8049
  method = target[method];
8193
8050
  }
8194
8051
 
8052
+ var onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]);
8053
+
8195
8054
  function fn() {
8196
- method.apply(target, args);
8055
+ if (onError) {
8056
+ try {
8057
+ method.apply(target, args);
8058
+ } catch (e) {
8059
+ onError(e);
8060
+ }
8061
+ } else {
8062
+ method.apply(target, args);
8063
+ }
8197
8064
  }
8198
8065
 
8199
- // find position to insert - TODO: binary search
8200
- var i, l;
8201
- for (i = 0, l = timers.length; i < l; i += 2) {
8202
- if (executeAt < timers[i]) { break; }
8203
- }
8066
+ // find position to insert
8067
+ var i = searchTimer(executeAt, timers);
8204
8068
 
8205
8069
  timers.splice(i, 0, executeAt, fn);
8206
8070
 
@@ -8322,7 +8186,7 @@ define("backburner",
8322
8186
  },
8323
8187
 
8324
8188
  hasTimers: function() {
8325
- return !!timers.length || autorun;
8189
+ return !!timers.length || !!debouncees.length || !!throttlers.length || autorun;
8326
8190
  },
8327
8191
 
8328
8192
  cancel: function(timer) {
@@ -8366,12 +8230,32 @@ define("backburner",
8366
8230
 
8367
8231
  return false;
8368
8232
  }
8233
+ };
8234
+
8235
+ Backburner.prototype.schedule = Backburner.prototype.defer;
8236
+ Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
8237
+ Backburner.prototype.later = Backburner.prototype.setTimeout;
8238
+
8239
+ if (needsIETryCatchFix) {
8240
+ var originalRun = Backburner.prototype.run;
8241
+ Backburner.prototype.run = function() {
8242
+ try {
8243
+ originalRun.apply(this, arguments);
8244
+ } catch (e) {
8245
+ throw e;
8246
+ }
8247
+ };
8369
8248
 
8370
- };
8249
+ var originalEnd = Backburner.prototype.end;
8250
+ Backburner.prototype.end = function() {
8251
+ try {
8252
+ originalEnd.apply(this, arguments);
8253
+ } catch (e) {
8254
+ throw e;
8255
+ }
8256
+ };
8257
+ }
8371
8258
 
8372
- Backburner.prototype.schedule = Backburner.prototype.defer;
8373
- Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
8374
- Backburner.prototype.later = Backburner.prototype.setTimeout;
8375
8259
 
8376
8260
  function createAutorun(backburner) {
8377
8261
  backburner.begin();
@@ -8400,11 +8284,7 @@ define("backburner",
8400
8284
  time, fns, i, l;
8401
8285
 
8402
8286
  self.run(function() {
8403
- // TODO: binary search
8404
- for (i = 0, l = timers.length; i < l; i += 2) {
8405
- time = timers[i];
8406
- if (time > now) { break; }
8407
- }
8287
+ i = searchTimer(now, timers);
8408
8288
 
8409
8289
  fns = timers.splice(0, i);
8410
8290
 
@@ -8448,9 +8328,285 @@ define("backburner",
8448
8328
  return index;
8449
8329
  }
8450
8330
 
8331
+ function searchTimer(time, timers) {
8332
+ var start = 0,
8333
+ end = timers.length - 2,
8334
+ middle, l;
8335
+
8336
+ while (start < end) {
8337
+ // since timers is an array of pairs 'l' will always
8338
+ // be an integer
8339
+ l = (end - start) / 2;
8340
+
8341
+ // compensate for the index in case even number
8342
+ // of pairs inside timers
8343
+ middle = start + l - (l % 2);
8344
+
8345
+ if (time >= timers[middle]) {
8346
+ start = middle + 2;
8347
+ } else {
8348
+ end = middle;
8349
+ }
8350
+ }
8351
+
8352
+ return (time >= timers[start]) ? start + 2 : start;
8353
+ }
8354
+
8451
8355
  __exports__.Backburner = Backburner;
8452
8356
  });
8357
+ define("backburner/deferred_action_queues",
8358
+ ["backburner/queue","exports"],
8359
+ function(__dependency1__, __exports__) {
8360
+ "use strict";
8361
+ var Queue = __dependency1__.Queue;
8362
+
8363
+ function DeferredActionQueues(queueNames, options) {
8364
+ var queues = this.queues = {};
8365
+ this.queueNames = queueNames = queueNames || [];
8366
+
8367
+ this.options = options;
8368
+
8369
+ var queueName;
8370
+ for (var i = 0, l = queueNames.length; i < l; i++) {
8371
+ queueName = queueNames[i];
8372
+ queues[queueName] = new Queue(this, queueName, this.options);
8373
+ }
8374
+ }
8375
+
8376
+ DeferredActionQueues.prototype = {
8377
+ queueNames: null,
8378
+ queues: null,
8379
+ options: null,
8380
+
8381
+ schedule: function(queueName, target, method, args, onceFlag, stack) {
8382
+ var queues = this.queues,
8383
+ queue = queues[queueName];
8384
+
8385
+ if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }
8386
+
8387
+ if (onceFlag) {
8388
+ return queue.pushUnique(target, method, args, stack);
8389
+ } else {
8390
+ return queue.push(target, method, args, stack);
8391
+ }
8392
+ },
8393
+
8394
+ invoke: function(target, method, args, _) {
8395
+ if (args && args.length > 0) {
8396
+ method.apply(target, args);
8397
+ } else {
8398
+ method.call(target);
8399
+ }
8400
+ },
8401
+
8402
+ invokeWithOnError: function(target, method, args, onError) {
8403
+ try {
8404
+ if (args && args.length > 0) {
8405
+ method.apply(target, args);
8406
+ } else {
8407
+ method.call(target);
8408
+ }
8409
+ } catch(error) {
8410
+ onError(error);
8411
+ }
8412
+ },
8413
+
8414
+ flush: function() {
8415
+ var queues = this.queues,
8416
+ queueNames = this.queueNames,
8417
+ queueName, queue, queueItems, priorQueueNameIndex,
8418
+ queueNameIndex = 0, numberOfQueues = queueNames.length,
8419
+ options = this.options,
8420
+ onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]),
8421
+ invoke = onError ? this.invokeWithOnError : this.invoke;
8422
+
8423
+ outerloop:
8424
+ while (queueNameIndex < numberOfQueues) {
8425
+ queueName = queueNames[queueNameIndex];
8426
+ queue = queues[queueName];
8427
+ queueItems = queue._queueBeingFlushed = queue._queue.slice();
8428
+ queue._queue = [];
8429
+
8430
+ var queueOptions = queue.options, // TODO: write a test for this
8431
+ before = queueOptions && queueOptions.before,
8432
+ after = queueOptions && queueOptions.after,
8433
+ target, method, args, stack,
8434
+ queueIndex = 0, numberOfQueueItems = queueItems.length;
8435
+
8436
+ if (numberOfQueueItems && before) { before(); }
8437
+
8438
+ while (queueIndex < numberOfQueueItems) {
8439
+ target = queueItems[queueIndex];
8440
+ method = queueItems[queueIndex+1];
8441
+ args = queueItems[queueIndex+2];
8442
+ stack = queueItems[queueIndex+3]; // Debugging assistance
8443
+
8444
+ if (typeof method === 'string') { method = target[method]; }
8445
+
8446
+ // method could have been nullified / canceled during flush
8447
+ if (method) {
8448
+ invoke(target, method, args, onError);
8449
+ }
8450
+
8451
+ queueIndex += 4;
8452
+ }
8453
+
8454
+ queue._queueBeingFlushed = null;
8455
+ if (numberOfQueueItems && after) { after(); }
8456
+
8457
+ if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
8458
+ queueNameIndex = priorQueueNameIndex;
8459
+ continue outerloop;
8460
+ }
8461
+
8462
+ queueNameIndex++;
8463
+ }
8464
+ }
8465
+ };
8466
+
8467
+ function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
8468
+ var queueName, queue;
8469
+
8470
+ for (var i = 0, l = currentQueueIndex; i <= l; i++) {
8471
+ queueName = daq.queueNames[i];
8472
+ queue = daq.queues[queueName];
8473
+ if (queue._queue.length) { return i; }
8474
+ }
8475
+
8476
+ return -1;
8477
+ }
8478
+
8479
+ __exports__.DeferredActionQueues = DeferredActionQueues;
8480
+ });
8481
+ define("backburner/queue",
8482
+ ["exports"],
8483
+ function(__exports__) {
8484
+ "use strict";
8485
+ function Queue(daq, name, options) {
8486
+ this.daq = daq;
8487
+ this.name = name;
8488
+ this.globalOptions = options;
8489
+ this.options = options[name];
8490
+ this._queue = [];
8491
+ }
8492
+
8493
+ Queue.prototype = {
8494
+ daq: null,
8495
+ name: null,
8496
+ options: null,
8497
+ onError: null,
8498
+ _queue: null,
8499
+
8500
+ push: function(target, method, args, stack) {
8501
+ var queue = this._queue;
8502
+ queue.push(target, method, args, stack);
8503
+ return {queue: this, target: target, method: method};
8504
+ },
8505
+
8506
+ pushUnique: function(target, method, args, stack) {
8507
+ var queue = this._queue, currentTarget, currentMethod, i, l;
8508
+
8509
+ for (i = 0, l = queue.length; i < l; i += 4) {
8510
+ currentTarget = queue[i];
8511
+ currentMethod = queue[i+1];
8512
+
8513
+ if (currentTarget === target && currentMethod === method) {
8514
+ queue[i+2] = args; // replace args
8515
+ queue[i+3] = stack; // replace stack
8516
+ return {queue: this, target: target, method: method};
8517
+ }
8518
+ }
8519
+
8520
+ this._queue.push(target, method, args, stack);
8521
+ return {queue: this, target: target, method: method};
8522
+ },
8523
+
8524
+ // TODO: remove me, only being used for Ember.run.sync
8525
+ flush: function() {
8526
+ var queue = this._queue,
8527
+ globalOptions = this.globalOptions,
8528
+ options = this.options,
8529
+ before = options && options.before,
8530
+ after = options && options.after,
8531
+ onError = globalOptions.onError || (globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod]),
8532
+ target, method, args, stack, i, l = queue.length;
8533
+
8534
+ if (l && before) { before(); }
8535
+ for (i = 0; i < l; i += 4) {
8536
+ target = queue[i];
8537
+ method = queue[i+1];
8538
+ args = queue[i+2];
8539
+ stack = queue[i+3]; // Debugging assistance
8540
+
8541
+ // TODO: error handling
8542
+ if (args && args.length > 0) {
8543
+ if (onError) {
8544
+ try {
8545
+ method.apply(target, args);
8546
+ } catch (e) {
8547
+ onError(e);
8548
+ }
8549
+ } else {
8550
+ method.apply(target, args);
8551
+ }
8552
+ } else {
8553
+ if (onError) {
8554
+ try {
8555
+ method.call(target);
8556
+ } catch(e) {
8557
+ onError(e);
8558
+ }
8559
+ } else {
8560
+ method.call(target);
8561
+ }
8562
+ }
8563
+ }
8564
+ if (l && after) { after(); }
8565
+
8566
+ // check if new items have been added
8567
+ if (queue.length > l) {
8568
+ this._queue = queue.slice(l);
8569
+ this.flush();
8570
+ } else {
8571
+ this._queue.length = 0;
8572
+ }
8573
+ },
8574
+
8575
+ cancel: function(actionToCancel) {
8576
+ var queue = this._queue, currentTarget, currentMethod, i, l;
8577
+
8578
+ for (i = 0, l = queue.length; i < l; i += 4) {
8579
+ currentTarget = queue[i];
8580
+ currentMethod = queue[i+1];
8581
+
8582
+ if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
8583
+ queue.splice(i, 4);
8584
+ return true;
8585
+ }
8586
+ }
8587
+
8588
+ // if not found in current queue
8589
+ // could be in the queue that is being flushed
8590
+ queue = this._queueBeingFlushed;
8591
+ if (!queue) {
8592
+ return;
8593
+ }
8594
+ for (i = 0, l = queue.length; i < l; i += 4) {
8595
+ currentTarget = queue[i];
8596
+ currentMethod = queue[i+1];
8597
+
8598
+ if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
8599
+ // don't mess with array during flush
8600
+ // just nullify the method
8601
+ queue[i+1] = null;
8602
+ return true;
8603
+ }
8604
+ }
8605
+ }
8606
+ };
8453
8607
 
8608
+ __exports__.Queue = Queue;
8609
+ });
8454
8610
  define("ember-metal/watch_key",
8455
8611
  ["ember-metal/core","ember-metal/utils","ember-metal/platform","exports"],
8456
8612
  function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
@@ -11804,7 +11960,7 @@ define("container",
11804
11960
  ["container/container","exports"],
11805
11961
  function(__dependency1__, __exports__) {
11806
11962
  "use strict";
11807
- /**
11963
+ /*
11808
11964
  Public api for the container is still in flux.
11809
11965
  The public api, specified on the application namespace should be considered the stable api.
11810
11966
  // @module container
@@ -12388,11 +12544,11 @@ define("ember-runtime/computed/reduce_computed",
12388
12544
  var length = get(array, 'length');
12389
12545
  // OPTIMIZE: we could stop updating once we hit the object whose observer
12390
12546
  // fired; ie partially apply the transformations
12391
- trackedArray.apply(function (observerContexts, offset, operation) {
12547
+ trackedArray.apply(function (observerContexts, offset, operation, operationIndex) {
12392
12548
  // we don't even have observer contexts for removed items, even if we did,
12393
12549
  // they no longer have any index in the array
12394
12550
  if (operation === TrackedArray.DELETE) { return; }
12395
- if (operation === TrackedArray.RETAIN && observerContexts.length === length && offset === 0) {
12551
+ if (operationIndex === 0 && operation === TrackedArray.RETAIN && observerContexts.length === length && offset === 0) {
12396
12552
  // If we update many items we don't want to walk the array each time: we
12397
12553
  // only need to update the indexes at most once per run loop.
12398
12554
  return;
@@ -12643,10 +12799,11 @@ define("ember-runtime/computed/reduce_computed",
12643
12799
  this.cacheable();
12644
12800
 
12645
12801
  this.recomputeOnce = function(propertyName) {
12646
- // TODO: Coalesce recomputation by <this, propertyName, cp>.
12647
- recompute.call(this, propertyName);
12802
+ // What we really want to do is coalesce by <cp, propertyName>.
12803
+ // We need a form of `scheduleOnce` that accepts an arbitrary token to
12804
+ // coalesce by, in addition to the target and method.
12805
+ run.once(this, recompute, propertyName);
12648
12806
  };
12649
-
12650
12807
  var recompute = function(propertyName) {
12651
12808
  var dependentKeys = cp._dependentKeys,
12652
12809
  meta = cp._instanceMeta(this, propertyName),
@@ -13005,7 +13162,7 @@ define("ember-runtime/computed/reduce_computed",
13005
13162
  }
13006
13163
 
13007
13164
  return cp;
13008
- };
13165
+ }
13009
13166
 
13010
13167
  __exports__.reduceComputed = reduceComputed;
13011
13168
  __exports__.ReduceComputedProperty = ReduceComputedProperty;
@@ -13049,6 +13206,7 @@ define("ember-runtime/computed/reduce_computed_macros",
13049
13206
  @for Ember
13050
13207
  @param {String} dependentKey
13051
13208
  @return {Ember.ComputedProperty} computes the sum of all values in the dependentKey's array
13209
+ @since 1.4.0
13052
13210
  */
13053
13211
 
13054
13212
  function sum(dependentKey){
@@ -14000,6 +14158,7 @@ define("ember-runtime/controllers/array_controller",
14000
14158
  * from participating in the parentController hierarchy.
14001
14159
  *
14002
14160
  * @private
14161
+ * @property _isVirtual
14003
14162
  * @type Boolean
14004
14163
  */
14005
14164
  _isVirtual: false,
@@ -14085,8 +14244,14 @@ define("ember-runtime/controllers/controller",
14085
14244
  For example, when a Handlebars template uses the `{{action}}` helper,
14086
14245
  it will attempt to send the action to the view's controller's `target`.
14087
14246
 
14088
- By default, a controller's `target` is set to the router after it is
14089
- instantiated by `Ember.Application#initialize`.
14247
+ By default, the value of the target property is set to the router, and
14248
+ is injected when a controller is instantiated. This injection is defined
14249
+ in Ember.Application#buildContainer, and is applied as part of the
14250
+ applications initialization process. It can also be set after a controller
14251
+ has been instantiated, for instance when using the render helper in a
14252
+ template, or when a controller is used as an `itemController`. In most
14253
+ cases the `target` property will automatically be set to the logical
14254
+ consumer of actions for the controller.
14090
14255
 
14091
14256
  @property target
14092
14257
  @default null
@@ -14514,6 +14679,8 @@ define("ember-runtime/ext/rsvp",
14514
14679
  } else {
14515
14680
  throw error;
14516
14681
  }
14682
+ } else if (Ember.onerror) {
14683
+ Ember.onerror(error);
14517
14684
  } else {
14518
14685
  Logger.error(error.stack);
14519
14686
  Ember.assert(error, false);
@@ -14658,7 +14825,7 @@ define("ember-runtime/keys",
14658
14825
  @return {Array} Array containing keys of obj
14659
14826
  */
14660
14827
  var keys = Object.keys;
14661
- if (keys || create.isSimulated) {
14828
+ if (!keys || create.isSimulated) {
14662
14829
  var prototypeProperties = [
14663
14830
  'constructor',
14664
14831
  'hasOwnProperty',
@@ -16326,6 +16493,7 @@ define("ember-runtime/mixins/enumerable",
16326
16493
  @param {String} key the property to test
16327
16494
  @param {String} [value] optional value to test against.
16328
16495
  @return {Boolean}
16496
+ @since 1.3.0
16329
16497
  */
16330
16498
  isEvery: function(key, value) {
16331
16499
  return this.every(apply(this, iter, arguments));
@@ -16428,6 +16596,7 @@ define("ember-runtime/mixins/enumerable",
16428
16596
  @param {String} key the property to test
16429
16597
  @param {String} [value] optional value to test against.
16430
16598
  @return {Boolean} `true` if the passed function returns `true` for any item
16599
+ @since 1.3.0
16431
16600
  */
16432
16601
  isAny: function(key, value) {
16433
16602
  return this.any(apply(this, iter, arguments));
@@ -16746,6 +16915,7 @@ define("ember-runtime/mixins/enumerable",
16746
16915
  @method sortBy
16747
16916
  @param {String} property name(s) to sort on
16748
16917
  @return {Array} The sorted array.
16918
+ @since 1.2.0
16749
16919
  */
16750
16920
  sortBy: function() {
16751
16921
  var sortKeys = arguments;
@@ -17881,7 +18051,6 @@ define("ember-runtime/mixins/observable",
17881
18051
  @param {String} key The key to observer
17882
18052
  @param {Object} target The target object to invoke
17883
18053
  @param {String|Function} method The method to invoke.
17884
- @return {Ember.Object} self
17885
18054
  */
17886
18055
  addObserver: function(key, target, method) {
17887
18056
  addObserver(this, key, target, method);
@@ -17896,7 +18065,6 @@ define("ember-runtime/mixins/observable",
17896
18065
  @param {String} key The key to observer
17897
18066
  @param {Object} target The target object to invoke
17898
18067
  @param {String|Function} method The method to invoke.
17899
- @return {Ember.Observable} receiver
17900
18068
  */
17901
18069
  removeObserver: function(key, target, method) {
17902
18070
  removeObserver(this, key, target, method);
@@ -18194,6 +18362,7 @@ define("ember-runtime/mixins/promise_proxy",
18194
18362
  @method catch
18195
18363
  @param {Function} callback
18196
18364
  @return {RSVP.Promise}
18365
+ @since 1.3.0
18197
18366
  */
18198
18367
  'catch': promiseAlias('catch'),
18199
18368
 
@@ -18205,6 +18374,7 @@ define("ember-runtime/mixins/promise_proxy",
18205
18374
  @method finally
18206
18375
  @param {Function} callback
18207
18376
  @return {RSVP.Promise}
18377
+ @since 1.3.0
18208
18378
  */
18209
18379
  'finally': promiseAlias('finally')
18210
18380
 
@@ -18352,12 +18522,12 @@ define("ember-runtime/mixins/sortable",
18352
18522
 
18353
18523
  forEach(sortProperties, function(propertyName) {
18354
18524
  if (result === 0) {
18355
- result = sortFunction(get(item1, propertyName), get(item2, propertyName));
18525
+ result = sortFunction.call(this, get(item1, propertyName), get(item2, propertyName));
18356
18526
  if ((result !== 0) && !sortAscending) {
18357
18527
  result = (-1) * result;
18358
18528
  }
18359
18529
  }
18360
- });
18530
+ }, this);
18361
18531
 
18362
18532
  return result;
18363
18533
  },
@@ -18423,12 +18593,20 @@ define("ember-runtime/mixins/sortable",
18423
18593
  this._super();
18424
18594
  }),
18425
18595
 
18596
+ sortPropertiesWillChange: beforeObserver('sortProperties', function() {
18597
+ this._lastSortAscending = undefined;
18598
+ }),
18599
+
18600
+ sortPropertiesDidChange: observer('sortProperties', function() {
18601
+ this._lastSortAscending = undefined;
18602
+ }),
18603
+
18426
18604
  sortAscendingWillChange: beforeObserver('sortAscending', function() {
18427
18605
  this._lastSortAscending = get(this, 'sortAscending');
18428
18606
  }),
18429
18607
 
18430
18608
  sortAscendingDidChange: observer('sortAscending', function() {
18431
- if (get(this, 'sortAscending') !== this._lastSortAscending) {
18609
+ if (this._lastSortAscending !== undefined && get(this, 'sortAscending') !== this._lastSortAscending) {
18432
18610
  var arrangedContent = get(this, 'arrangedContent');
18433
18611
  arrangedContent.reverseObjects();
18434
18612
  }
@@ -18613,7 +18791,7 @@ define("ember-runtime/mixins/target_action_support",
18613
18791
  });
18614
18792
  ```
18615
18793
 
18616
- The `actionContext` defaults to the object you mixing `TargetActionSupport` into.
18794
+ The `actionContext` defaults to the object you are mixing `TargetActionSupport` into.
18617
18795
  But `target` and `action` must be specified either as properties or with the argument
18618
18796
  to `triggerAction`, or a combination:
18619
18797
 
@@ -20202,7 +20380,7 @@ define("ember-runtime/system/namespace",
20202
20380
  if (name) { return name; }
20203
20381
 
20204
20382
  findNamespaces();
20205
- return this[GUID_KEY+'_name'];
20383
+ return this[NAME_KEY];
20206
20384
  },
20207
20385
 
20208
20386
  nameClasses: function() {
@@ -20278,32 +20456,30 @@ define("ember-runtime/system/namespace",
20278
20456
  paths.length = idx; // cut out last item
20279
20457
  }
20280
20458
 
20459
+ var STARTS_WITH_UPPERCASE = /^[A-Z]/;
20460
+
20281
20461
  function findNamespaces() {
20282
20462
  var lookup = Ember.lookup, obj, isNamespace;
20283
20463
 
20284
20464
  if (Namespace.PROCESSED) { return; }
20285
20465
 
20286
20466
  for (var prop in lookup) {
20287
- // These don't raise exceptions but can cause warnings
20288
- if (prop === "parent" || prop === "top" || prop === "frameElement" || prop === "webkitStorageInfo") { continue; }
20467
+ // Only process entities that start with uppercase A-Z
20468
+ if (!STARTS_WITH_UPPERCASE.test(prop)) { continue; }
20289
20469
 
20290
- // get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
20291
- // globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
20292
- if (prop === "globalStorage" && lookup.StorageList && lookup.globalStorage instanceof lookup.StorageList) { continue; }
20293
20470
  // Unfortunately, some versions of IE don't support window.hasOwnProperty
20294
20471
  if (lookup.hasOwnProperty && !lookup.hasOwnProperty(prop)) { continue; }
20295
20472
 
20296
20473
  // At times we are not allowed to access certain properties for security reasons.
20297
20474
  // There are also times where even if we can access them, we are not allowed to access their properties.
20298
20475
  try {
20299
- obj = Ember.lookup[prop];
20476
+ obj = lookup[prop];
20300
20477
  isNamespace = obj && obj.isNamespace;
20301
20478
  } catch (e) {
20302
20479
  continue;
20303
20480
  }
20304
20481
 
20305
20482
  if (isNamespace) {
20306
- Ember.deprecate("Namespaces should not begin with lowercase.", /^[A-Z]/.test(prop));
20307
20483
  obj[NAME_KEY] = prop;
20308
20484
  }
20309
20485
  }
@@ -21740,7 +21916,7 @@ define("ember-runtime/system/tracked_array",
21740
21916
  } else {
21741
21917
  this._operations = [];
21742
21918
  }
21743
- };
21919
+ }
21744
21920
 
21745
21921
  TrackedArray.RETAIN = RETAIN;
21746
21922
  TrackedArray.INSERT = INSERT;
@@ -21838,8 +22014,8 @@ define("ember-runtime/system/tracked_array",
21838
22014
  var items = [],
21839
22015
  offset = 0;
21840
22016
 
21841
- forEach(this._operations, function (arrayOperation) {
21842
- callback(arrayOperation.items, offset, arrayOperation.type);
22017
+ forEach(this._operations, function (arrayOperation, operationIndex) {
22018
+ callback(arrayOperation.items, offset, arrayOperation.type, operationIndex);
21843
22019
 
21844
22020
  if (arrayOperation.type !== DELETE) {
21845
22021
  offset += arrayOperation.count;
@@ -22888,6 +23064,8 @@ define("container/container",
22888
23064
  } else {
22889
23065
  throw error;
22890
23066
  }
23067
+ } else if (Ember.onerror) {
23068
+ Ember.onerror(error);
22891
23069
  } else {
22892
23070
  Logger.error(error.stack);
22893
23071
  Ember.assert(error, false);