ember-source 1.0.0.rc3.5 → 1.0.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ember-source might be problematic. Click here for more details.
- data/VERSION +1 -0
- data/dist/ember-data-deps.js +1947 -1299
- data/dist/ember-data-deps.min.js +6 -5
- data/dist/ember-data-deps.prod.js +1945 -1297
- data/dist/ember-debug.js +2 -2
- data/dist/ember-old-router.js +2066 -1375
- data/dist/ember-old-router.min.js +9 -8
- data/dist/ember-old-router.prod.js +2069 -1379
- data/dist/ember-runtime.js +1947 -1299
- data/dist/ember-runtime.min.js +5 -5
- data/dist/ember-runtime.prod.js +1945 -1297
- data/dist/ember-spade.js +13 -6
- data/dist/ember-template-compiler.js +20 -4
- data/dist/ember-template-compiler.min.js +3 -3
- data/dist/ember-template-compiler.prod.js +18 -2
- data/dist/ember-tests.js +1 -1
- data/dist/ember.js +2980 -1618
- data/dist/ember.min.js +9 -9
- data/dist/ember.prod.js +2968 -1608
- data/lib/ember/source.rb +2 -0
- data/lib/ember/version.rb +3 -0
- metadata +6 -13
- data/dist/ember-1.0.0-rc.3.1.js +0 -28566
- data/dist/ember-1.0.0-rc.3.1.min.js +0 -21
- data/dist/ember-1.0.0-rc.3.1.prod.js +0 -28360
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0-rc4
|
data/dist/ember-data-deps.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
// Version: v1.0.0-
|
2
|
-
// Last commit:
|
1
|
+
// Version: v1.0.0-rc4
|
2
|
+
// Last commit: ae2e55f (2013-05-27 19:34:11 -0400)
|
3
3
|
|
4
4
|
|
5
5
|
(function() {
|
@@ -151,8 +151,8 @@ Ember.deprecateFunc = function(message, func) {
|
|
151
151
|
|
152
152
|
})();
|
153
153
|
|
154
|
-
// Version: v1.0.0-
|
155
|
-
// Last commit:
|
154
|
+
// Version: v1.0.0-rc4
|
155
|
+
// Last commit: ae2e55f (2013-05-27 19:34:11 -0400)
|
156
156
|
|
157
157
|
|
158
158
|
(function() {
|
@@ -169,11 +169,18 @@ var define, requireModule;
|
|
169
169
|
if (seen[name]) { return seen[name]; }
|
170
170
|
seen[name] = {};
|
171
171
|
|
172
|
-
var mod
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
172
|
+
var mod, deps, callback, reified, exports;
|
173
|
+
|
174
|
+
mod = registry[name];
|
175
|
+
|
176
|
+
if (!mod) {
|
177
|
+
throw new Error("Module '" + name + "' not found.");
|
178
|
+
}
|
179
|
+
|
180
|
+
deps = mod.deps;
|
181
|
+
callback = mod.callback;
|
182
|
+
reified = [];
|
183
|
+
exports;
|
177
184
|
|
178
185
|
for (var i=0, l=deps.length; i<l; i++) {
|
179
186
|
if (deps[i] === 'exports') {
|
@@ -212,7 +219,7 @@ var define, requireModule;
|
|
212
219
|
|
213
220
|
@class Ember
|
214
221
|
@static
|
215
|
-
@version 1.0.0-
|
222
|
+
@version 1.0.0-rc4
|
216
223
|
*/
|
217
224
|
|
218
225
|
if ('undefined' === typeof Ember) {
|
@@ -239,10 +246,10 @@ Ember.toString = function() { return "Ember"; };
|
|
239
246
|
/**
|
240
247
|
@property VERSION
|
241
248
|
@type String
|
242
|
-
@default '1.0.0-
|
249
|
+
@default '1.0.0-rc4'
|
243
250
|
@final
|
244
251
|
*/
|
245
|
-
Ember.VERSION = '1.0.0-
|
252
|
+
Ember.VERSION = '1.0.0-rc4';
|
246
253
|
|
247
254
|
/**
|
248
255
|
Standard environmental variables. You can define these in a global `ENV`
|
@@ -391,7 +398,7 @@ Ember.onerror = null;
|
|
391
398
|
/**
|
392
399
|
@private
|
393
400
|
|
394
|
-
Wrap code block in a try/catch if
|
401
|
+
Wrap code block in a try/catch if `Ember.onerror` is set.
|
395
402
|
|
396
403
|
@method handleErrors
|
397
404
|
@for Ember
|
@@ -467,7 +474,7 @@ Ember.none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isN
|
|
467
474
|
@return {Boolean}
|
468
475
|
*/
|
469
476
|
Ember.isEmpty = function(obj) {
|
470
|
-
return obj
|
477
|
+
return Ember.isNone(obj) || (obj.length === 0 && typeof obj !== 'function') || (typeof obj === 'object' && Ember.get(obj, 'length') === 0);
|
471
478
|
};
|
472
479
|
Ember.empty = Ember.deprecateFunc("Ember.empty is deprecated. Please use Ember.isEmpty instead.", Ember.isEmpty) ;
|
473
480
|
|
@@ -500,6 +507,13 @@ var platform = Ember.platform = {};
|
|
500
507
|
*/
|
501
508
|
Ember.create = Object.create;
|
502
509
|
|
510
|
+
// IE8 has Object.create but it couldn't treat property descripters.
|
511
|
+
if (Ember.create) {
|
512
|
+
if (Ember.create({a: 1}, {a: {value: 2}}).a !== 2) {
|
513
|
+
Ember.create = null;
|
514
|
+
}
|
515
|
+
}
|
516
|
+
|
503
517
|
// STUB_OBJECT_CREATE allows us to override other libraries that stub
|
504
518
|
// Object.create different than we would prefer
|
505
519
|
if (!Ember.create || Ember.ENV.STUB_OBJECT_CREATE) {
|
@@ -820,7 +834,7 @@ Ember.guidFor = function guidFor(obj) {
|
|
820
834
|
if (obj === undefined) return "(undefined)";
|
821
835
|
if (obj === null) return "(null)";
|
822
836
|
|
823
|
-
var
|
837
|
+
var ret;
|
824
838
|
var type = typeof obj;
|
825
839
|
|
826
840
|
// Don't allow prototype changes to String etc. to change the guidFor
|
@@ -969,6 +983,7 @@ Ember.setMeta = function setMeta(obj, property, value) {
|
|
969
983
|
};
|
970
984
|
|
971
985
|
/**
|
986
|
+
@deprecated
|
972
987
|
@private
|
973
988
|
|
974
989
|
In order to store defaults for a class, a prototype may need to create
|
@@ -1001,6 +1016,7 @@ Ember.setMeta = function setMeta(obj, property, value) {
|
|
1001
1016
|
shared with its constructor
|
1002
1017
|
*/
|
1003
1018
|
Ember.metaPath = function metaPath(obj, path, writable) {
|
1019
|
+
Ember.deprecate("Ember.metaPath is deprecated and will be removed from future releases.");
|
1004
1020
|
var meta = Ember.meta(obj, writable), keyName, value;
|
1005
1021
|
|
1006
1022
|
for (var i=0, l=path.length; i<l; i++) {
|
@@ -1221,7 +1237,7 @@ if (needsFinallyFix) {
|
|
1221
1237
|
*/
|
1222
1238
|
if (needsFinallyFix) {
|
1223
1239
|
Ember.tryCatchFinally = function(tryable, catchable, finalizer, binding) {
|
1224
|
-
var result, finalResult, finalError
|
1240
|
+
var result, finalResult, finalError;
|
1225
1241
|
|
1226
1242
|
binding = binding || this;
|
1227
1243
|
|
@@ -1331,6 +1347,7 @@ Ember.typeOf = function(item) {
|
|
1331
1347
|
|
1332
1348
|
return ret;
|
1333
1349
|
};
|
1350
|
+
|
1334
1351
|
})();
|
1335
1352
|
|
1336
1353
|
|
@@ -1577,816 +1594,454 @@ var utils = Ember.EnumerableUtils = {
|
|
1577
1594
|
@module ember-metal
|
1578
1595
|
*/
|
1579
1596
|
|
1580
|
-
|
1581
|
-
JavaScript (before ES6) does not have a Map implementation. Objects,
|
1582
|
-
which are often used as dictionaries, may only have Strings as keys.
|
1583
|
-
|
1584
|
-
Because Ember has a way to get a unique identifier for every object
|
1585
|
-
via `Ember.guidFor`, we can implement a performant Map with arbitrary
|
1586
|
-
keys. Because it is commonly used in low-level bookkeeping, Map is
|
1587
|
-
implemented as a pure JavaScript object for performance.
|
1588
|
-
|
1589
|
-
This implementation follows the current iteration of the ES6 proposal for
|
1590
|
-
maps (http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets),
|
1591
|
-
with two exceptions. First, because we need our implementation to be pleasant
|
1592
|
-
on older browsers, we do not use the `delete` name (using `remove` instead).
|
1593
|
-
Second, as we do not have the luxury of in-VM iteration, we implement a
|
1594
|
-
forEach method for iteration.
|
1595
|
-
|
1596
|
-
Map is mocked out to look like an Ember object, so you can do
|
1597
|
-
`Ember.Map.create()` for symmetry with other Ember classes.
|
1598
|
-
*/
|
1599
|
-
var guidFor = Ember.guidFor,
|
1600
|
-
indexOf = Ember.ArrayPolyfills.indexOf;
|
1597
|
+
var META_KEY = Ember.META_KEY, get;
|
1601
1598
|
|
1602
|
-
var
|
1603
|
-
var output = {};
|
1599
|
+
var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
|
1604
1600
|
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1601
|
+
var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
|
1602
|
+
var HAS_THIS = /^this[\.\*]/;
|
1603
|
+
var FIRST_KEY = /^([^\.\*]+)/;
|
1608
1604
|
|
1609
|
-
|
1610
|
-
|
1605
|
+
// ..........................................................
|
1606
|
+
// GET AND SET
|
1607
|
+
//
|
1608
|
+
// If we are on a platform that supports accessors we can use those.
|
1609
|
+
// Otherwise simulate accessors by looking up the property directly on the
|
1610
|
+
// object.
|
1611
1611
|
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1612
|
+
/**
|
1613
|
+
Gets the value of a property on an object. If the property is computed,
|
1614
|
+
the function will be invoked. If the property is not defined but the
|
1615
|
+
object implements the `unknownProperty` method then that will be invoked.
|
1615
1616
|
|
1616
|
-
|
1617
|
-
|
1617
|
+
If you plan to run on IE8 and older browsers then you should use this
|
1618
|
+
method anytime you want to retrieve a property on an object that you don't
|
1619
|
+
know for sure is private. (Properties beginning with an underscore '_'
|
1620
|
+
are considered private.)
|
1618
1621
|
|
1619
|
-
|
1620
|
-
|
1622
|
+
On all newer browsers, you only need to use this method to retrieve
|
1623
|
+
properties if the property might not be defined on the object and you want
|
1624
|
+
to respect the `unknownProperty` handler. Otherwise you can ignore this
|
1625
|
+
method.
|
1621
1626
|
|
1622
|
-
|
1623
|
-
|
1624
|
-
Please do not use it at this time. We plan to clean it up
|
1625
|
-
and add many tests soon.
|
1627
|
+
Note that if the object itself is `undefined`, this method will throw
|
1628
|
+
an error.
|
1626
1629
|
|
1627
|
-
@
|
1628
|
-
@
|
1629
|
-
@
|
1630
|
-
@
|
1630
|
+
@method get
|
1631
|
+
@for Ember
|
1632
|
+
@param {Object} obj The object to retrieve from.
|
1633
|
+
@param {String} keyName The property key to retrieve
|
1634
|
+
@return {Object} the property value or `null`.
|
1631
1635
|
*/
|
1632
|
-
|
1633
|
-
this
|
1634
|
-
|
1636
|
+
get = function get(obj, keyName) {
|
1637
|
+
// Helpers that operate with 'this' within an #each
|
1638
|
+
if (keyName === '') {
|
1639
|
+
return obj;
|
1640
|
+
}
|
1635
1641
|
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
*/
|
1641
|
-
OrderedSet.create = function() {
|
1642
|
-
return new OrderedSet();
|
1643
|
-
};
|
1642
|
+
if (!keyName && 'string'===typeof obj) {
|
1643
|
+
keyName = obj;
|
1644
|
+
obj = null;
|
1645
|
+
}
|
1644
1646
|
|
1647
|
+
Ember.assert("Cannot call get with '"+ keyName +"' on an undefined object.", obj !== undefined);
|
1645
1648
|
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
*/
|
1650
|
-
clear: function() {
|
1651
|
-
this.presenceSet = {};
|
1652
|
-
this.list = [];
|
1653
|
-
},
|
1649
|
+
if (obj === null || keyName.indexOf('.') !== -1) {
|
1650
|
+
return getPath(obj, keyName);
|
1651
|
+
}
|
1654
1652
|
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1653
|
+
var meta = obj[META_KEY], desc = meta && meta.descs[keyName], ret;
|
1654
|
+
if (desc) {
|
1655
|
+
return desc.get(obj, keyName);
|
1656
|
+
} else {
|
1657
|
+
if (MANDATORY_SETTER && meta && meta.watching[keyName] > 0) {
|
1658
|
+
ret = meta.values[keyName];
|
1659
|
+
} else {
|
1660
|
+
ret = obj[keyName];
|
1661
|
+
}
|
1663
1662
|
|
1664
|
-
if (
|
1663
|
+
if (ret === undefined &&
|
1664
|
+
'object' === typeof obj && !(keyName in obj) && 'function' === typeof obj.unknownProperty) {
|
1665
|
+
return obj.unknownProperty(keyName);
|
1666
|
+
}
|
1665
1667
|
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1668
|
+
return ret;
|
1669
|
+
}
|
1670
|
+
};
|
1669
1671
|
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
presenceSet = this.presenceSet,
|
1677
|
-
list = this.list;
|
1672
|
+
// Currently used only by Ember Data tests
|
1673
|
+
if (Ember.config.overrideAccessors) {
|
1674
|
+
Ember.get = get;
|
1675
|
+
Ember.config.overrideAccessors();
|
1676
|
+
get = Ember.get;
|
1677
|
+
}
|
1678
1678
|
|
1679
|
-
|
1679
|
+
function firstKey(path) {
|
1680
|
+
return path.match(FIRST_KEY)[0];
|
1681
|
+
}
|
1680
1682
|
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1683
|
+
// assumes path is already normalized
|
1684
|
+
function normalizeTuple(target, path) {
|
1685
|
+
var hasThis = HAS_THIS.test(path),
|
1686
|
+
isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
|
1687
|
+
key;
|
1686
1688
|
|
1687
|
-
|
1688
|
-
|
1689
|
-
@return {Boolean}
|
1690
|
-
*/
|
1691
|
-
isEmpty: function() {
|
1692
|
-
return this.list.length === 0;
|
1693
|
-
},
|
1689
|
+
if (!target || isGlobal) target = Ember.lookup;
|
1690
|
+
if (hasThis) path = path.slice(5);
|
1694
1691
|
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
has: function(obj) {
|
1701
|
-
var guid = guidFor(obj),
|
1702
|
-
presenceSet = this.presenceSet;
|
1692
|
+
if (target === Ember.lookup) {
|
1693
|
+
key = firstKey(path);
|
1694
|
+
target = get(target, key);
|
1695
|
+
path = path.slice(key.length+1);
|
1696
|
+
}
|
1703
1697
|
|
1704
|
-
|
1705
|
-
|
1698
|
+
// must return some kind of path to be valid else other things will break.
|
1699
|
+
if (!path || path.length===0) throw new Error('Invalid Path');
|
1706
1700
|
|
1707
|
-
|
1708
|
-
|
1709
|
-
@param {Function} fn
|
1710
|
-
@param self
|
1711
|
-
*/
|
1712
|
-
forEach: function(fn, self) {
|
1713
|
-
// allow mutation during iteration
|
1714
|
-
var list = this.toArray();
|
1701
|
+
return [ target, path ];
|
1702
|
+
}
|
1715
1703
|
|
1716
|
-
|
1717
|
-
|
1718
|
-
}
|
1719
|
-
},
|
1704
|
+
var getPath = Ember._getPath = function(root, path) {
|
1705
|
+
var hasThis, parts, tuple, idx, len;
|
1720
1706
|
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
toArray: function() {
|
1726
|
-
return this.list.slice();
|
1727
|
-
},
|
1707
|
+
// If there is no root and path is a key name, return that
|
1708
|
+
// property from the global object.
|
1709
|
+
// E.g. get('Ember') -> Ember
|
1710
|
+
if (root === null && path.indexOf('.') === -1) { return get(Ember.lookup, path); }
|
1728
1711
|
|
1729
|
-
|
1730
|
-
|
1731
|
-
@return {Ember.OrderedSet}
|
1732
|
-
*/
|
1733
|
-
copy: function() {
|
1734
|
-
var set = new OrderedSet();
|
1712
|
+
// detect complicated paths and normalize them
|
1713
|
+
hasThis = HAS_THIS.test(path);
|
1735
1714
|
|
1736
|
-
|
1737
|
-
|
1715
|
+
if (!root || hasThis) {
|
1716
|
+
tuple = normalizeTuple(root, path);
|
1717
|
+
root = tuple[0];
|
1718
|
+
path = tuple[1];
|
1719
|
+
tuple.length = 0;
|
1720
|
+
}
|
1738
1721
|
|
1739
|
-
|
1722
|
+
parts = path.split(".");
|
1723
|
+
len = parts.length;
|
1724
|
+
for (idx = 0; root != null && idx < len; idx++) {
|
1725
|
+
root = get(root, parts[idx], true);
|
1726
|
+
if (root && root.isDestroyed) { return undefined; }
|
1740
1727
|
}
|
1728
|
+
return root;
|
1741
1729
|
};
|
1742
1730
|
|
1743
1731
|
/**
|
1744
|
-
|
1745
|
-
default Objects, the keys of a Map can be any JavaScript
|
1746
|
-
object.
|
1747
|
-
|
1748
|
-
Internally, a Map has two data structures:
|
1732
|
+
@private
|
1749
1733
|
|
1750
|
-
|
1751
|
-
|
1734
|
+
Normalizes a target/path pair to reflect that actual target/path that should
|
1735
|
+
be observed, etc. This takes into account passing in global property
|
1736
|
+
paths (i.e. a path beginning with a captial letter not defined on the
|
1737
|
+
target) and * separators.
|
1752
1738
|
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
@class Map
|
1759
|
-
@namespace Ember
|
1760
|
-
@private
|
1761
|
-
@constructor
|
1739
|
+
@method normalizeTuple
|
1740
|
+
@for Ember
|
1741
|
+
@param {Object} target The current target. May be `null`.
|
1742
|
+
@param {String} path A path on the target or a global property path.
|
1743
|
+
@return {Array} a temporary array with the normalized target/path pair.
|
1762
1744
|
*/
|
1763
|
-
|
1764
|
-
|
1765
|
-
this.values = {};
|
1745
|
+
Ember.normalizeTuple = function(target, path) {
|
1746
|
+
return normalizeTuple(target, path);
|
1766
1747
|
};
|
1767
1748
|
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
|
1773
|
-
return new Map();
|
1749
|
+
Ember.getWithDefault = function(root, key, defaultValue) {
|
1750
|
+
var value = get(root, key);
|
1751
|
+
|
1752
|
+
if (value === undefined) { return defaultValue; }
|
1753
|
+
return value;
|
1774
1754
|
};
|
1775
1755
|
|
1776
|
-
Map.prototype = {
|
1777
|
-
/**
|
1778
|
-
Retrieve the value associated with a given key.
|
1779
1756
|
|
1780
|
-
|
1781
|
-
|
1782
|
-
@return {*} the value associated with the key, or `undefined`
|
1783
|
-
*/
|
1784
|
-
get: function(key) {
|
1785
|
-
var values = this.values,
|
1786
|
-
guid = guidFor(key);
|
1757
|
+
Ember.get = get;
|
1758
|
+
Ember.getPath = Ember.deprecateFunc('getPath is deprecated since get now supports paths', Ember.get);
|
1787
1759
|
|
1788
|
-
|
1789
|
-
},
|
1760
|
+
})();
|
1790
1761
|
|
1791
|
-
/**
|
1792
|
-
Adds a value to the map. If a value for the given key has already been
|
1793
|
-
provided, the new value will replace the old value.
|
1794
1762
|
|
1795
|
-
@method set
|
1796
|
-
@param {*} key
|
1797
|
-
@param {*} value
|
1798
|
-
*/
|
1799
|
-
set: function(key, value) {
|
1800
|
-
var keys = this.keys,
|
1801
|
-
values = this.values,
|
1802
|
-
guid = guidFor(key);
|
1803
1763
|
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1764
|
+
(function() {
|
1765
|
+
/**
|
1766
|
+
@module ember-metal
|
1767
|
+
*/
|
1807
1768
|
|
1808
|
-
|
1809
|
-
|
1769
|
+
var o_create = Ember.create,
|
1770
|
+
metaFor = Ember.meta,
|
1771
|
+
META_KEY = Ember.META_KEY,
|
1772
|
+
/* listener flags */
|
1773
|
+
ONCE = 1, SUSPENDED = 2;
|
1810
1774
|
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
remove: function(key) {
|
1816
|
-
// don't use ES6 "delete" because it will be annoying
|
1817
|
-
// to use in browsers that are not ES6 friendly;
|
1818
|
-
var keys = this.keys,
|
1819
|
-
values = this.values,
|
1820
|
-
guid = guidFor(key);
|
1775
|
+
/*
|
1776
|
+
The event system uses a series of nested hashes to store listeners on an
|
1777
|
+
object. When a listener is registered, or when an event arrives, these
|
1778
|
+
hashes are consulted to determine which target and action pair to invoke.
|
1821
1779
|
|
1822
|
-
|
1823
|
-
keys.remove(key);
|
1824
|
-
delete values[guid];
|
1825
|
-
return true;
|
1826
|
-
} else {
|
1827
|
-
return false;
|
1828
|
-
}
|
1829
|
-
},
|
1780
|
+
The hashes are stored in the object's meta hash, and look like this:
|
1830
1781
|
|
1831
|
-
|
1832
|
-
|
1782
|
+
// Object's meta hash
|
1783
|
+
{
|
1784
|
+
listeners: { // variable name: `listenerSet`
|
1785
|
+
"foo:changed": [ // variable name: `actions`
|
1786
|
+
[target, method, flags]
|
1787
|
+
]
|
1788
|
+
}
|
1789
|
+
}
|
1833
1790
|
|
1834
|
-
|
1835
|
-
@param {*} key
|
1836
|
-
@return {Boolean} true if the item was present, false otherwise
|
1837
|
-
*/
|
1838
|
-
has: function(key) {
|
1839
|
-
var values = this.values,
|
1840
|
-
guid = guidFor(key);
|
1791
|
+
*/
|
1841
1792
|
|
1842
|
-
|
1843
|
-
|
1793
|
+
function indexOf(array, target, method) {
|
1794
|
+
var index = -1;
|
1795
|
+
for (var i = 0, l = array.length; i < l; i++) {
|
1796
|
+
if (target === array[i][0] && method === array[i][1]) { index = i; break; }
|
1797
|
+
}
|
1798
|
+
return index;
|
1799
|
+
}
|
1844
1800
|
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1801
|
+
function actionsFor(obj, eventName) {
|
1802
|
+
var meta = metaFor(obj, true),
|
1803
|
+
actions;
|
1848
1804
|
|
1849
|
-
|
1805
|
+
if (!meta.listeners) { meta.listeners = {}; }
|
1850
1806
|
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
*/
|
1856
|
-
forEach: function(callback, self) {
|
1857
|
-
var keys = this.keys,
|
1858
|
-
values = this.values;
|
1807
|
+
if (!meta.hasOwnProperty('listeners')) {
|
1808
|
+
// setup inherited copy of the listeners object
|
1809
|
+
meta.listeners = o_create(meta.listeners);
|
1810
|
+
}
|
1859
1811
|
|
1860
|
-
|
1861
|
-
var guid = guidFor(key);
|
1862
|
-
callback.call(self, key, values[guid]);
|
1863
|
-
});
|
1864
|
-
},
|
1812
|
+
actions = meta.listeners[eventName];
|
1865
1813
|
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
return copyMap(this, new Map());
|
1814
|
+
// if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
|
1815
|
+
if (actions && !meta.listeners.hasOwnProperty(eventName)) {
|
1816
|
+
actions = meta.listeners[eventName] = meta.listeners[eventName].slice();
|
1817
|
+
} else if (!actions) {
|
1818
|
+
actions = meta.listeners[eventName] = [];
|
1872
1819
|
}
|
1873
|
-
};
|
1874
1820
|
|
1875
|
-
|
1876
|
-
|
1877
|
-
@namespace Ember
|
1878
|
-
@extends Ember.Map
|
1879
|
-
@private
|
1880
|
-
@constructor
|
1881
|
-
@param [options]
|
1882
|
-
@param {*} [options.defaultValue]
|
1883
|
-
*/
|
1884
|
-
var MapWithDefault = Ember.MapWithDefault = function(options) {
|
1885
|
-
Map.call(this);
|
1886
|
-
this.defaultValue = options.defaultValue;
|
1887
|
-
};
|
1821
|
+
return actions;
|
1822
|
+
}
|
1888
1823
|
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1824
|
+
function actionsUnion(obj, eventName, otherActions) {
|
1825
|
+
var meta = obj[META_KEY],
|
1826
|
+
actions = meta && meta.listeners && meta.listeners[eventName];
|
1827
|
+
|
1828
|
+
if (!actions) { return; }
|
1829
|
+
for (var i = actions.length - 1; i >= 0; i--) {
|
1830
|
+
var target = actions[i][0],
|
1831
|
+
method = actions[i][1],
|
1832
|
+
flags = actions[i][2],
|
1833
|
+
actionIndex = indexOf(otherActions, target, method);
|
1834
|
+
|
1835
|
+
if (actionIndex === -1) {
|
1836
|
+
otherActions.push([target, method, flags]);
|
1837
|
+
}
|
1902
1838
|
}
|
1903
|
-
}
|
1839
|
+
}
|
1904
1840
|
|
1905
|
-
|
1841
|
+
function actionsDiff(obj, eventName, otherActions) {
|
1842
|
+
var meta = obj[META_KEY],
|
1843
|
+
actions = meta && meta.listeners && meta.listeners[eventName],
|
1844
|
+
diffActions = [];
|
1906
1845
|
|
1907
|
-
|
1908
|
-
|
1846
|
+
if (!actions) { return; }
|
1847
|
+
for (var i = actions.length - 1; i >= 0; i--) {
|
1848
|
+
var target = actions[i][0],
|
1849
|
+
method = actions[i][1],
|
1850
|
+
flags = actions[i][2],
|
1851
|
+
actionIndex = indexOf(otherActions, target, method);
|
1909
1852
|
|
1910
|
-
|
1911
|
-
@param {*} key
|
1912
|
-
@return {*} the value associated with the key, or the default value
|
1913
|
-
*/
|
1914
|
-
MapWithDefault.prototype.get = function(key) {
|
1915
|
-
var hasValue = this.has(key);
|
1853
|
+
if (actionIndex !== -1) { continue; }
|
1916
1854
|
|
1917
|
-
|
1918
|
-
|
1919
|
-
} else {
|
1920
|
-
var defaultValue = this.defaultValue(key);
|
1921
|
-
this.set(key, defaultValue);
|
1922
|
-
return defaultValue;
|
1855
|
+
otherActions.push([target, method, flags]);
|
1856
|
+
diffActions.push([target, method, flags]);
|
1923
1857
|
}
|
1924
|
-
|
1858
|
+
|
1859
|
+
return diffActions;
|
1860
|
+
}
|
1925
1861
|
|
1926
1862
|
/**
|
1927
|
-
|
1928
|
-
|
1863
|
+
Add an event listener
|
1864
|
+
|
1865
|
+
@method addListener
|
1866
|
+
@for Ember
|
1867
|
+
@param obj
|
1868
|
+
@param {String} eventName
|
1869
|
+
@param {Object|Function} targetOrMethod A target object or a function
|
1870
|
+
@param {Function|String} method A function or the name of a function to be called on `target`
|
1871
|
+
@param {Boolean} once A flag whether a function should only be called once
|
1929
1872
|
*/
|
1930
|
-
|
1931
|
-
|
1932
|
-
defaultValue: this.defaultValue
|
1933
|
-
}));
|
1934
|
-
};
|
1873
|
+
function addListener(obj, eventName, target, method, once) {
|
1874
|
+
Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName);
|
1935
1875
|
|
1936
|
-
|
1876
|
+
if (!method && 'function' === typeof target) {
|
1877
|
+
method = target;
|
1878
|
+
target = null;
|
1879
|
+
}
|
1937
1880
|
|
1881
|
+
var actions = actionsFor(obj, eventName),
|
1882
|
+
actionIndex = indexOf(actions, target, method),
|
1883
|
+
flags = 0;
|
1938
1884
|
|
1885
|
+
if (once) flags |= ONCE;
|
1939
1886
|
|
1940
|
-
(
|
1941
|
-
/**
|
1942
|
-
@module ember-metal
|
1943
|
-
*/
|
1887
|
+
if (actionIndex !== -1) { return; }
|
1944
1888
|
|
1945
|
-
|
1946
|
-
|
1947
|
-
var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
|
1948
|
-
|
1949
|
-
var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
|
1950
|
-
var HAS_THIS = /^this[\.\*]/;
|
1951
|
-
var FIRST_KEY = /^([^\.\*]+)/;
|
1889
|
+
actions.push([target, method, flags]);
|
1952
1890
|
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
// Otherwise simulate accessors by looking up the property directly on the
|
1958
|
-
// object.
|
1891
|
+
if ('function' === typeof obj.didAddListener) {
|
1892
|
+
obj.didAddListener(eventName, target, method);
|
1893
|
+
}
|
1894
|
+
}
|
1959
1895
|
|
1960
1896
|
/**
|
1961
|
-
|
1962
|
-
the function will be invoked. If the property is not defined but the
|
1963
|
-
object implements the `unknownProperty` method then that will be invoked.
|
1964
|
-
|
1965
|
-
If you plan to run on IE8 and older browsers then you should use this
|
1966
|
-
method anytime you want to retrieve a property on an object that you don't
|
1967
|
-
know for sure is private. (Properties beginning with an underscore '_'
|
1968
|
-
are considered private.)
|
1969
|
-
|
1970
|
-
On all newer browsers, you only need to use this method to retrieve
|
1971
|
-
properties if the property might not be defined on the object and you want
|
1972
|
-
to respect the `unknownProperty` handler. Otherwise you can ignore this
|
1973
|
-
method.
|
1897
|
+
Remove an event listener
|
1974
1898
|
|
1975
|
-
|
1976
|
-
an error.
|
1899
|
+
Arguments should match those passed to `Ember.addListener`.
|
1977
1900
|
|
1978
|
-
@method
|
1901
|
+
@method removeListener
|
1979
1902
|
@for Ember
|
1980
|
-
@param
|
1981
|
-
@param {String}
|
1982
|
-
@
|
1903
|
+
@param obj
|
1904
|
+
@param {String} eventName
|
1905
|
+
@param {Object|Function} targetOrMethod A target object or a function
|
1906
|
+
@param {Function|String} method A function or the name of a function to be called on `target`
|
1983
1907
|
*/
|
1984
|
-
|
1985
|
-
|
1986
|
-
if (keyName === '') {
|
1987
|
-
return obj;
|
1988
|
-
}
|
1908
|
+
function removeListener(obj, eventName, target, method) {
|
1909
|
+
Ember.assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName);
|
1989
1910
|
|
1990
|
-
if (!
|
1991
|
-
|
1992
|
-
|
1911
|
+
if (!method && 'function' === typeof target) {
|
1912
|
+
method = target;
|
1913
|
+
target = null;
|
1993
1914
|
}
|
1994
1915
|
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
}
|
1916
|
+
function _removeListener(target, method) {
|
1917
|
+
var actions = actionsFor(obj, eventName),
|
1918
|
+
actionIndex = indexOf(actions, target, method);
|
1999
1919
|
|
2000
|
-
|
1920
|
+
// action doesn't exist, give up silently
|
1921
|
+
if (actionIndex === -1) { return; }
|
2001
1922
|
|
2002
|
-
|
2003
|
-
if (desc) {
|
2004
|
-
return desc.get(obj, keyName);
|
2005
|
-
} else {
|
2006
|
-
if (MANDATORY_SETTER && meta && meta.watching[keyName] > 0) {
|
2007
|
-
ret = meta.values[keyName];
|
2008
|
-
} else {
|
2009
|
-
ret = obj[keyName];
|
2010
|
-
}
|
1923
|
+
actions.splice(actionIndex, 1);
|
2011
1924
|
|
2012
|
-
if (
|
2013
|
-
|
2014
|
-
return obj.unknownProperty(keyName);
|
1925
|
+
if ('function' === typeof obj.didRemoveListener) {
|
1926
|
+
obj.didRemoveListener(eventName, target, method);
|
2015
1927
|
}
|
2016
|
-
|
2017
|
-
return ret;
|
2018
1928
|
}
|
2019
|
-
};
|
2020
|
-
|
2021
|
-
// Currently used only by Ember Data tests
|
2022
|
-
if (Ember.config.overrideAccessors) {
|
2023
|
-
Ember.get = get;
|
2024
|
-
Ember.config.overrideAccessors();
|
2025
|
-
get = Ember.get;
|
2026
|
-
}
|
2027
|
-
|
2028
|
-
function firstKey(path) {
|
2029
|
-
return path.match(FIRST_KEY)[0];
|
2030
|
-
}
|
2031
|
-
|
2032
|
-
// assumes path is already normalized
|
2033
|
-
function normalizeTuple(target, path) {
|
2034
|
-
var hasThis = HAS_THIS.test(path),
|
2035
|
-
isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
|
2036
|
-
key;
|
2037
1929
|
|
2038
|
-
if (
|
2039
|
-
|
1930
|
+
if (method) {
|
1931
|
+
_removeListener(target, method);
|
1932
|
+
} else {
|
1933
|
+
var meta = obj[META_KEY],
|
1934
|
+
actions = meta && meta.listeners && meta.listeners[eventName];
|
2040
1935
|
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
1936
|
+
if (!actions) { return; }
|
1937
|
+
for (var i = actions.length - 1; i >= 0; i--) {
|
1938
|
+
_removeListener(actions[i][0], actions[i][1]);
|
1939
|
+
}
|
2045
1940
|
}
|
2046
|
-
|
2047
|
-
// must return some kind of path to be valid else other things will break.
|
2048
|
-
if (!path || path.length===0) throw new Error('Invalid Path');
|
2049
|
-
|
2050
|
-
return [ target, path ];
|
2051
1941
|
}
|
2052
1942
|
|
2053
|
-
|
2054
|
-
|
1943
|
+
/**
|
1944
|
+
@private
|
2055
1945
|
|
2056
|
-
|
2057
|
-
// property from the global object.
|
2058
|
-
// E.g. get('Ember') -> Ember
|
2059
|
-
if (root === null && path.indexOf('.') === -1) { return get(Ember.lookup, path); }
|
1946
|
+
Suspend listener during callback.
|
2060
1947
|
|
2061
|
-
|
2062
|
-
|
1948
|
+
This should only be used by the target of the event listener
|
1949
|
+
when it is taking an action that would cause the event, e.g.
|
1950
|
+
an object might suspend its property change listener while it is
|
1951
|
+
setting that property.
|
2063
1952
|
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
1953
|
+
@method suspendListener
|
1954
|
+
@for Ember
|
1955
|
+
@param obj
|
1956
|
+
@param {String} eventName
|
1957
|
+
@param {Object|Function} targetOrMethod A target object or a function
|
1958
|
+
@param {Function|String} method A function or the name of a function to be called on `target`
|
1959
|
+
@param {Function} callback
|
1960
|
+
*/
|
1961
|
+
function suspendListener(obj, eventName, target, method, callback) {
|
1962
|
+
if (!method && 'function' === typeof target) {
|
1963
|
+
method = target;
|
1964
|
+
target = null;
|
2069
1965
|
}
|
2070
1966
|
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
1967
|
+
var actions = actionsFor(obj, eventName),
|
1968
|
+
actionIndex = indexOf(actions, target, method),
|
1969
|
+
action;
|
1970
|
+
|
1971
|
+
if (actionIndex !== -1) {
|
1972
|
+
action = actions[actionIndex].slice(); // copy it, otherwise we're modifying a shared object
|
1973
|
+
action[2] |= SUSPENDED; // mark the action as suspended
|
1974
|
+
actions[actionIndex] = action; // replace the shared object with our copy
|
2076
1975
|
}
|
2077
|
-
|
2078
|
-
}
|
1976
|
+
|
1977
|
+
function tryable() { return callback.call(target); }
|
1978
|
+
function finalizer() { if (action) { action[2] &= ~SUSPENDED; } }
|
1979
|
+
|
1980
|
+
return Ember.tryFinally(tryable, finalizer);
|
1981
|
+
}
|
2079
1982
|
|
2080
1983
|
/**
|
2081
1984
|
@private
|
2082
1985
|
|
2083
|
-
|
2084
|
-
be observed, etc. This takes into account passing in global property
|
2085
|
-
paths (i.e. a path beginning with a captial letter not defined on the
|
2086
|
-
target) and * separators.
|
1986
|
+
Suspend listener during callback.
|
2087
1987
|
|
2088
|
-
|
1988
|
+
This should only be used by the target of the event listener
|
1989
|
+
when it is taking an action that would cause the event, e.g.
|
1990
|
+
an object might suspend its property change listener while it is
|
1991
|
+
setting that property.
|
1992
|
+
|
1993
|
+
@method suspendListener
|
2089
1994
|
@for Ember
|
2090
|
-
@param
|
2091
|
-
@param {
|
2092
|
-
@
|
1995
|
+
@param obj
|
1996
|
+
@param {Array} eventName Array of event names
|
1997
|
+
@param {Object|Function} targetOrMethod A target object or a function
|
1998
|
+
@param {Function|String} method A function or the name of a function to be called on `target`
|
1999
|
+
@param {Function} callback
|
2093
2000
|
*/
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2001
|
+
function suspendListeners(obj, eventNames, target, method, callback) {
|
2002
|
+
if (!method && 'function' === typeof target) {
|
2003
|
+
method = target;
|
2004
|
+
target = null;
|
2005
|
+
}
|
2097
2006
|
|
2098
|
-
|
2099
|
-
|
2007
|
+
var suspendedActions = [],
|
2008
|
+
eventName, actions, action, i, l;
|
2100
2009
|
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2010
|
+
for (i=0, l=eventNames.length; i<l; i++) {
|
2011
|
+
eventName = eventNames[i];
|
2012
|
+
actions = actionsFor(obj, eventName);
|
2013
|
+
var actionIndex = indexOf(actions, target, method);
|
2104
2014
|
|
2015
|
+
if (actionIndex !== -1) {
|
2016
|
+
action = actions[actionIndex].slice();
|
2017
|
+
action[2] |= SUSPENDED;
|
2018
|
+
actions[actionIndex] = action;
|
2019
|
+
suspendedActions.push(action);
|
2020
|
+
}
|
2021
|
+
}
|
2105
2022
|
|
2106
|
-
|
2107
|
-
Ember.getPath = Ember.deprecateFunc('getPath is deprecated since get now supports paths', Ember.get);
|
2108
|
-
})();
|
2023
|
+
function tryable() { return callback.call(target); }
|
2109
2024
|
|
2025
|
+
function finalizer() {
|
2026
|
+
for (i = 0, l = suspendedActions.length; i < l; i++) {
|
2027
|
+
suspendedActions[i][2] &= ~SUSPENDED;
|
2028
|
+
}
|
2029
|
+
}
|
2110
2030
|
|
2031
|
+
return Ember.tryFinally(tryable, finalizer);
|
2032
|
+
}
|
2111
2033
|
|
2112
|
-
(function() {
|
2113
2034
|
/**
|
2114
|
-
@
|
2115
|
-
*/
|
2116
|
-
|
2117
|
-
var o_create = Ember.create,
|
2118
|
-
metaFor = Ember.meta,
|
2119
|
-
META_KEY = Ember.META_KEY;
|
2120
|
-
|
2121
|
-
/*
|
2122
|
-
The event system uses a series of nested hashes to store listeners on an
|
2123
|
-
object. When a listener is registered, or when an event arrives, these
|
2124
|
-
hashes are consulted to determine which target and action pair to invoke.
|
2125
|
-
|
2126
|
-
The hashes are stored in the object's meta hash, and look like this:
|
2035
|
+
@private
|
2127
2036
|
|
2128
|
-
|
2129
|
-
{
|
2130
|
-
listeners: { // variable name: `listenerSet`
|
2131
|
-
"foo:changed": [ // variable name: `actions`
|
2132
|
-
[target, method, onceFlag, suspendedFlag]
|
2133
|
-
]
|
2134
|
-
}
|
2135
|
-
}
|
2037
|
+
Return a list of currently watched events
|
2136
2038
|
|
2039
|
+
@method watchedEvents
|
2040
|
+
@for Ember
|
2041
|
+
@param obj
|
2137
2042
|
*/
|
2138
|
-
|
2139
|
-
|
2140
|
-
var index = -1;
|
2141
|
-
for (var i = 0, l = array.length; i < l; i++) {
|
2142
|
-
if (target === array[i][0] && method === array[i][1]) { index = i; break; }
|
2143
|
-
}
|
2144
|
-
return index;
|
2145
|
-
}
|
2146
|
-
|
2147
|
-
function actionsFor(obj, eventName) {
|
2148
|
-
var meta = metaFor(obj, true),
|
2149
|
-
actions;
|
2150
|
-
|
2151
|
-
if (!meta.listeners) { meta.listeners = {}; }
|
2152
|
-
|
2153
|
-
if (!meta.hasOwnProperty('listeners')) {
|
2154
|
-
// setup inherited copy of the listeners object
|
2155
|
-
meta.listeners = o_create(meta.listeners);
|
2156
|
-
}
|
2157
|
-
|
2158
|
-
actions = meta.listeners[eventName];
|
2159
|
-
|
2160
|
-
// if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
|
2161
|
-
if (actions && !meta.listeners.hasOwnProperty(eventName)) {
|
2162
|
-
actions = meta.listeners[eventName] = meta.listeners[eventName].slice();
|
2163
|
-
} else if (!actions) {
|
2164
|
-
actions = meta.listeners[eventName] = [];
|
2165
|
-
}
|
2166
|
-
|
2167
|
-
return actions;
|
2168
|
-
}
|
2169
|
-
|
2170
|
-
function actionsUnion(obj, eventName, otherActions) {
|
2171
|
-
var meta = obj[META_KEY],
|
2172
|
-
actions = meta && meta.listeners && meta.listeners[eventName];
|
2173
|
-
|
2174
|
-
if (!actions) { return; }
|
2175
|
-
for (var i = actions.length - 1; i >= 0; i--) {
|
2176
|
-
var target = actions[i][0],
|
2177
|
-
method = actions[i][1],
|
2178
|
-
once = actions[i][2],
|
2179
|
-
suspended = actions[i][3],
|
2180
|
-
actionIndex = indexOf(otherActions, target, method);
|
2181
|
-
|
2182
|
-
if (actionIndex === -1) {
|
2183
|
-
otherActions.push([target, method, once, suspended]);
|
2184
|
-
}
|
2185
|
-
}
|
2186
|
-
}
|
2187
|
-
|
2188
|
-
function actionsDiff(obj, eventName, otherActions) {
|
2189
|
-
var meta = obj[META_KEY],
|
2190
|
-
actions = meta && meta.listeners && meta.listeners[eventName],
|
2191
|
-
diffActions = [];
|
2192
|
-
|
2193
|
-
if (!actions) { return; }
|
2194
|
-
for (var i = actions.length - 1; i >= 0; i--) {
|
2195
|
-
var target = actions[i][0],
|
2196
|
-
method = actions[i][1],
|
2197
|
-
once = actions[i][2],
|
2198
|
-
suspended = actions[i][3],
|
2199
|
-
actionIndex = indexOf(otherActions, target, method);
|
2200
|
-
|
2201
|
-
if (actionIndex !== -1) { continue; }
|
2202
|
-
|
2203
|
-
otherActions.push([target, method, once, suspended]);
|
2204
|
-
diffActions.push([target, method, once, suspended]);
|
2205
|
-
}
|
2206
|
-
|
2207
|
-
return diffActions;
|
2208
|
-
}
|
2209
|
-
|
2210
|
-
/**
|
2211
|
-
Add an event listener
|
2212
|
-
|
2213
|
-
@method addListener
|
2214
|
-
@for Ember
|
2215
|
-
@param obj
|
2216
|
-
@param {String} eventName
|
2217
|
-
@param {Object|Function} targetOrMethod A target object or a function
|
2218
|
-
@param {Function|String} method A function or the name of a function to be called on `target`
|
2219
|
-
@param {Boolean} once A flag whether a function should only be called once
|
2220
|
-
*/
|
2221
|
-
function addListener(obj, eventName, target, method, once) {
|
2222
|
-
Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName);
|
2223
|
-
|
2224
|
-
if (!method && 'function' === typeof target) {
|
2225
|
-
method = target;
|
2226
|
-
target = null;
|
2227
|
-
}
|
2228
|
-
|
2229
|
-
var actions = actionsFor(obj, eventName),
|
2230
|
-
actionIndex = indexOf(actions, target, method);
|
2231
|
-
|
2232
|
-
if (actionIndex !== -1) { return; }
|
2233
|
-
|
2234
|
-
actions.push([target, method, once, undefined]);
|
2235
|
-
|
2236
|
-
if ('function' === typeof obj.didAddListener) {
|
2237
|
-
obj.didAddListener(eventName, target, method);
|
2238
|
-
}
|
2239
|
-
}
|
2240
|
-
|
2241
|
-
/**
|
2242
|
-
Remove an event listener
|
2243
|
-
|
2244
|
-
Arguments should match those passed to {{#crossLink "Ember/addListener"}}{{/crossLink}}
|
2245
|
-
|
2246
|
-
@method removeListener
|
2247
|
-
@for Ember
|
2248
|
-
@param obj
|
2249
|
-
@param {String} eventName
|
2250
|
-
@param {Object|Function} targetOrMethod A target object or a function
|
2251
|
-
@param {Function|String} method A function or the name of a function to be called on `target`
|
2252
|
-
*/
|
2253
|
-
function removeListener(obj, eventName, target, method) {
|
2254
|
-
Ember.assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName);
|
2255
|
-
|
2256
|
-
if (!method && 'function' === typeof target) {
|
2257
|
-
method = target;
|
2258
|
-
target = null;
|
2259
|
-
}
|
2260
|
-
|
2261
|
-
function _removeListener(target, method, once) {
|
2262
|
-
var actions = actionsFor(obj, eventName),
|
2263
|
-
actionIndex = indexOf(actions, target, method);
|
2264
|
-
|
2265
|
-
// action doesn't exist, give up silently
|
2266
|
-
if (actionIndex === -1) { return; }
|
2267
|
-
|
2268
|
-
actions.splice(actionIndex, 1);
|
2269
|
-
|
2270
|
-
if ('function' === typeof obj.didRemoveListener) {
|
2271
|
-
obj.didRemoveListener(eventName, target, method);
|
2272
|
-
}
|
2273
|
-
}
|
2274
|
-
|
2275
|
-
if (method) {
|
2276
|
-
_removeListener(target, method);
|
2277
|
-
} else {
|
2278
|
-
var meta = obj[META_KEY],
|
2279
|
-
actions = meta && meta.listeners && meta.listeners[eventName];
|
2280
|
-
|
2281
|
-
if (!actions) { return; }
|
2282
|
-
for (var i = actions.length - 1; i >= 0; i--) {
|
2283
|
-
_removeListener(actions[i][0], actions[i][1]);
|
2284
|
-
}
|
2285
|
-
}
|
2286
|
-
}
|
2287
|
-
|
2288
|
-
/**
|
2289
|
-
@private
|
2290
|
-
|
2291
|
-
Suspend listener during callback.
|
2292
|
-
|
2293
|
-
This should only be used by the target of the event listener
|
2294
|
-
when it is taking an action that would cause the event, e.g.
|
2295
|
-
an object might suspend its property change listener while it is
|
2296
|
-
setting that property.
|
2297
|
-
|
2298
|
-
@method suspendListener
|
2299
|
-
@for Ember
|
2300
|
-
@param obj
|
2301
|
-
@param {String} eventName
|
2302
|
-
@param {Object|Function} targetOrMethod A target object or a function
|
2303
|
-
@param {Function|String} method A function or the name of a function to be called on `target`
|
2304
|
-
@param {Function} callback
|
2305
|
-
*/
|
2306
|
-
function suspendListener(obj, eventName, target, method, callback) {
|
2307
|
-
if (!method && 'function' === typeof target) {
|
2308
|
-
method = target;
|
2309
|
-
target = null;
|
2310
|
-
}
|
2311
|
-
|
2312
|
-
var actions = actionsFor(obj, eventName),
|
2313
|
-
actionIndex = indexOf(actions, target, method),
|
2314
|
-
action;
|
2315
|
-
|
2316
|
-
if (actionIndex !== -1) {
|
2317
|
-
action = actions[actionIndex].slice(); // copy it, otherwise we're modifying a shared object
|
2318
|
-
action[3] = true; // mark the action as suspended
|
2319
|
-
actions[actionIndex] = action; // replace the shared object with our copy
|
2320
|
-
}
|
2321
|
-
|
2322
|
-
function tryable() { return callback.call(target); }
|
2323
|
-
function finalizer() { if (action) { action[3] = undefined; } }
|
2324
|
-
|
2325
|
-
return Ember.tryFinally(tryable, finalizer);
|
2326
|
-
}
|
2327
|
-
|
2328
|
-
/**
|
2329
|
-
@private
|
2330
|
-
|
2331
|
-
Suspend listener during callback.
|
2332
|
-
|
2333
|
-
This should only be used by the target of the event listener
|
2334
|
-
when it is taking an action that would cause the event, e.g.
|
2335
|
-
an object might suspend its property change listener while it is
|
2336
|
-
setting that property.
|
2337
|
-
|
2338
|
-
@method suspendListener
|
2339
|
-
@for Ember
|
2340
|
-
@param obj
|
2341
|
-
@param {Array} eventName Array of event names
|
2342
|
-
@param {Object|Function} targetOrMethod A target object or a function
|
2343
|
-
@param {Function|String} method A function or the name of a function to be called on `target`
|
2344
|
-
@param {Function} callback
|
2345
|
-
*/
|
2346
|
-
function suspendListeners(obj, eventNames, target, method, callback) {
|
2347
|
-
if (!method && 'function' === typeof target) {
|
2348
|
-
method = target;
|
2349
|
-
target = null;
|
2350
|
-
}
|
2351
|
-
|
2352
|
-
var suspendedActions = [],
|
2353
|
-
eventName, actions, action, i, l;
|
2354
|
-
|
2355
|
-
for (i=0, l=eventNames.length; i<l; i++) {
|
2356
|
-
eventName = eventNames[i];
|
2357
|
-
actions = actionsFor(obj, eventName);
|
2358
|
-
var actionIndex = indexOf(actions, target, method);
|
2359
|
-
|
2360
|
-
if (actionIndex !== -1) {
|
2361
|
-
action = actions[actionIndex].slice();
|
2362
|
-
action[3] = true;
|
2363
|
-
actions[actionIndex] = action;
|
2364
|
-
suspendedActions.push(action);
|
2365
|
-
}
|
2366
|
-
}
|
2367
|
-
|
2368
|
-
function tryable() { return callback.call(target); }
|
2369
|
-
|
2370
|
-
function finalizer() {
|
2371
|
-
for (i = 0, l = suspendedActions.length; i < l; i++) {
|
2372
|
-
suspendedActions[i][3] = undefined;
|
2373
|
-
}
|
2374
|
-
}
|
2375
|
-
|
2376
|
-
return Ember.tryFinally(tryable, finalizer);
|
2377
|
-
}
|
2378
|
-
|
2379
|
-
/**
|
2380
|
-
@private
|
2381
|
-
|
2382
|
-
Return a list of currently watched events
|
2383
|
-
|
2384
|
-
@method watchedEvents
|
2385
|
-
@for Ember
|
2386
|
-
@param obj
|
2387
|
-
*/
|
2388
|
-
function watchedEvents(obj) {
|
2389
|
-
var listeners = obj[META_KEY].listeners, ret = [];
|
2043
|
+
function watchedEvents(obj) {
|
2044
|
+
var listeners = obj[META_KEY].listeners, ret = [];
|
2390
2045
|
|
2391
2046
|
if (listeners) {
|
2392
2047
|
for(var eventName in listeners) {
|
@@ -2419,13 +2074,11 @@ function sendEvent(obj, eventName, params, actions) {
|
|
2419
2074
|
if (!actions) { return; }
|
2420
2075
|
|
2421
2076
|
for (var i = actions.length - 1; i >= 0; i--) { // looping in reverse for once listeners
|
2422
|
-
|
2423
|
-
|
2424
|
-
var target =
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
if (once) { removeListener(obj, eventName, target, method); }
|
2077
|
+
var action = actions[i];
|
2078
|
+
if (!action) { continue; }
|
2079
|
+
var target = action[0], method = action[1], flags = action[2];
|
2080
|
+
if (flags & SUSPENDED) { continue; }
|
2081
|
+
if (flags & ONCE) { removeListener(obj, eventName, target, method); }
|
2429
2082
|
if (!target) { target = obj; }
|
2430
2083
|
if ('string' === typeof method) { method = target[method]; }
|
2431
2084
|
if (params) {
|
@@ -2505,7 +2158,7 @@ var guidFor = Ember.guidFor,
|
|
2505
2158
|
keyName: keyName,
|
2506
2159
|
eventName: eventName,
|
2507
2160
|
listeners: [
|
2508
|
-
[target, method,
|
2161
|
+
[target, method, flags]
|
2509
2162
|
]
|
2510
2163
|
},
|
2511
2164
|
...
|
@@ -2734,11 +2387,11 @@ var endPropertyChanges = Ember.endPropertyChanges = function() {
|
|
2734
2387
|
});
|
2735
2388
|
```
|
2736
2389
|
|
2737
|
-
@method
|
2390
|
+
@method changeProperties
|
2738
2391
|
@param {Function} callback
|
2739
2392
|
@param [binding]
|
2740
2393
|
*/
|
2741
|
-
|
2394
|
+
Ember.changeProperties = function(cb, binding){
|
2742
2395
|
beginPropertyChanges();
|
2743
2396
|
tryFinally(cb, endPropertyChanges, binding);
|
2744
2397
|
};
|
@@ -2852,66 +2505,446 @@ var set = function set(obj, keyName, value, tolerant) {
|
|
2852
2505
|
Ember.propertyDidChange(obj, keyName);
|
2853
2506
|
}
|
2854
2507
|
} else {
|
2855
|
-
obj[keyName] = value;
|
2508
|
+
obj[keyName] = value;
|
2509
|
+
}
|
2510
|
+
}
|
2511
|
+
return value;
|
2512
|
+
};
|
2513
|
+
|
2514
|
+
// Currently used only by Ember Data tests
|
2515
|
+
if (Ember.config.overrideAccessors) {
|
2516
|
+
Ember.set = set;
|
2517
|
+
Ember.config.overrideAccessors();
|
2518
|
+
set = Ember.set;
|
2519
|
+
}
|
2520
|
+
|
2521
|
+
function setPath(root, path, value, tolerant) {
|
2522
|
+
var keyName;
|
2523
|
+
|
2524
|
+
// get the last part of the path
|
2525
|
+
keyName = path.slice(path.lastIndexOf('.') + 1);
|
2526
|
+
|
2527
|
+
// get the first part of the part
|
2528
|
+
path = path.slice(0, path.length-(keyName.length+1));
|
2529
|
+
|
2530
|
+
// unless the path is this, look up the first part to
|
2531
|
+
// get the root
|
2532
|
+
if (path !== 'this') {
|
2533
|
+
root = getPath(root, path);
|
2534
|
+
}
|
2535
|
+
|
2536
|
+
if (!keyName || keyName.length === 0) {
|
2537
|
+
throw new Error('You passed an empty path');
|
2538
|
+
}
|
2539
|
+
|
2540
|
+
if (!root) {
|
2541
|
+
if (tolerant) { return; }
|
2542
|
+
else { throw new Error('Object in path '+path+' could not be found or was destroyed.'); }
|
2543
|
+
}
|
2544
|
+
|
2545
|
+
return set(root, keyName, value);
|
2546
|
+
}
|
2547
|
+
|
2548
|
+
Ember.set = set;
|
2549
|
+
Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now supports paths', Ember.set);
|
2550
|
+
|
2551
|
+
/**
|
2552
|
+
Error-tolerant form of `Ember.set`. Will not blow up if any part of the
|
2553
|
+
chain is `undefined`, `null`, or destroyed.
|
2554
|
+
|
2555
|
+
This is primarily used when syncing bindings, which may try to update after
|
2556
|
+
an object has been destroyed.
|
2557
|
+
|
2558
|
+
@method trySet
|
2559
|
+
@for Ember
|
2560
|
+
@param {Object} obj The object to modify.
|
2561
|
+
@param {String} path The property path to set
|
2562
|
+
@param {Object} value The value to set
|
2563
|
+
*/
|
2564
|
+
Ember.trySet = function(root, path, value) {
|
2565
|
+
return set(root, path, value, true);
|
2566
|
+
};
|
2567
|
+
Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet', Ember.trySet);
|
2568
|
+
|
2569
|
+
})();
|
2570
|
+
|
2571
|
+
|
2572
|
+
|
2573
|
+
(function() {
|
2574
|
+
/**
|
2575
|
+
@module ember-metal
|
2576
|
+
*/
|
2577
|
+
|
2578
|
+
/*
|
2579
|
+
JavaScript (before ES6) does not have a Map implementation. Objects,
|
2580
|
+
which are often used as dictionaries, may only have Strings as keys.
|
2581
|
+
|
2582
|
+
Because Ember has a way to get a unique identifier for every object
|
2583
|
+
via `Ember.guidFor`, we can implement a performant Map with arbitrary
|
2584
|
+
keys. Because it is commonly used in low-level bookkeeping, Map is
|
2585
|
+
implemented as a pure JavaScript object for performance.
|
2586
|
+
|
2587
|
+
This implementation follows the current iteration of the ES6 proposal for
|
2588
|
+
maps (http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets),
|
2589
|
+
with two exceptions. First, because we need our implementation to be pleasant
|
2590
|
+
on older browsers, we do not use the `delete` name (using `remove` instead).
|
2591
|
+
Second, as we do not have the luxury of in-VM iteration, we implement a
|
2592
|
+
forEach method for iteration.
|
2593
|
+
|
2594
|
+
Map is mocked out to look like an Ember object, so you can do
|
2595
|
+
`Ember.Map.create()` for symmetry with other Ember classes.
|
2596
|
+
*/
|
2597
|
+
var get = Ember.get,
|
2598
|
+
set = Ember.set,
|
2599
|
+
guidFor = Ember.guidFor,
|
2600
|
+
indexOf = Ember.ArrayPolyfills.indexOf;
|
2601
|
+
|
2602
|
+
var copy = function(obj) {
|
2603
|
+
var output = {};
|
2604
|
+
|
2605
|
+
for (var prop in obj) {
|
2606
|
+
if (obj.hasOwnProperty(prop)) { output[prop] = obj[prop]; }
|
2607
|
+
}
|
2608
|
+
|
2609
|
+
return output;
|
2610
|
+
};
|
2611
|
+
|
2612
|
+
var copyMap = function(original, newObject) {
|
2613
|
+
var keys = original.keys.copy(),
|
2614
|
+
values = copy(original.values);
|
2615
|
+
|
2616
|
+
newObject.keys = keys;
|
2617
|
+
newObject.values = values;
|
2618
|
+
newObject.length = original.length;
|
2619
|
+
|
2620
|
+
return newObject;
|
2621
|
+
};
|
2622
|
+
|
2623
|
+
/**
|
2624
|
+
This class is used internally by Ember and Ember Data.
|
2625
|
+
Please do not use it at this time. We plan to clean it up
|
2626
|
+
and add many tests soon.
|
2627
|
+
|
2628
|
+
@class OrderedSet
|
2629
|
+
@namespace Ember
|
2630
|
+
@constructor
|
2631
|
+
@private
|
2632
|
+
*/
|
2633
|
+
var OrderedSet = Ember.OrderedSet = function() {
|
2634
|
+
this.clear();
|
2635
|
+
};
|
2636
|
+
|
2637
|
+
/**
|
2638
|
+
@method create
|
2639
|
+
@static
|
2640
|
+
@return {Ember.OrderedSet}
|
2641
|
+
*/
|
2642
|
+
OrderedSet.create = function() {
|
2643
|
+
return new OrderedSet();
|
2644
|
+
};
|
2645
|
+
|
2646
|
+
|
2647
|
+
OrderedSet.prototype = {
|
2648
|
+
/**
|
2649
|
+
@method clear
|
2650
|
+
*/
|
2651
|
+
clear: function() {
|
2652
|
+
this.presenceSet = {};
|
2653
|
+
this.list = [];
|
2654
|
+
},
|
2655
|
+
|
2656
|
+
/**
|
2657
|
+
@method add
|
2658
|
+
@param obj
|
2659
|
+
*/
|
2660
|
+
add: function(obj) {
|
2661
|
+
var guid = guidFor(obj),
|
2662
|
+
presenceSet = this.presenceSet,
|
2663
|
+
list = this.list;
|
2664
|
+
|
2665
|
+
if (guid in presenceSet) { return; }
|
2666
|
+
|
2667
|
+
presenceSet[guid] = true;
|
2668
|
+
list.push(obj);
|
2669
|
+
},
|
2670
|
+
|
2671
|
+
/**
|
2672
|
+
@method remove
|
2673
|
+
@param obj
|
2674
|
+
*/
|
2675
|
+
remove: function(obj) {
|
2676
|
+
var guid = guidFor(obj),
|
2677
|
+
presenceSet = this.presenceSet,
|
2678
|
+
list = this.list;
|
2679
|
+
|
2680
|
+
delete presenceSet[guid];
|
2681
|
+
|
2682
|
+
var index = indexOf.call(list, obj);
|
2683
|
+
if (index > -1) {
|
2684
|
+
list.splice(index, 1);
|
2685
|
+
}
|
2686
|
+
},
|
2687
|
+
|
2688
|
+
/**
|
2689
|
+
@method isEmpty
|
2690
|
+
@return {Boolean}
|
2691
|
+
*/
|
2692
|
+
isEmpty: function() {
|
2693
|
+
return this.list.length === 0;
|
2694
|
+
},
|
2695
|
+
|
2696
|
+
/**
|
2697
|
+
@method has
|
2698
|
+
@param obj
|
2699
|
+
@return {Boolean}
|
2700
|
+
*/
|
2701
|
+
has: function(obj) {
|
2702
|
+
var guid = guidFor(obj),
|
2703
|
+
presenceSet = this.presenceSet;
|
2704
|
+
|
2705
|
+
return guid in presenceSet;
|
2706
|
+
},
|
2707
|
+
|
2708
|
+
/**
|
2709
|
+
@method forEach
|
2710
|
+
@param {Function} fn
|
2711
|
+
@param self
|
2712
|
+
*/
|
2713
|
+
forEach: function(fn, self) {
|
2714
|
+
// allow mutation during iteration
|
2715
|
+
var list = this.toArray();
|
2716
|
+
|
2717
|
+
for (var i = 0, j = list.length; i < j; i++) {
|
2718
|
+
fn.call(self, list[i]);
|
2719
|
+
}
|
2720
|
+
},
|
2721
|
+
|
2722
|
+
/**
|
2723
|
+
@method toArray
|
2724
|
+
@return {Array}
|
2725
|
+
*/
|
2726
|
+
toArray: function() {
|
2727
|
+
return this.list.slice();
|
2728
|
+
},
|
2729
|
+
|
2730
|
+
/**
|
2731
|
+
@method copy
|
2732
|
+
@return {Ember.OrderedSet}
|
2733
|
+
*/
|
2734
|
+
copy: function() {
|
2735
|
+
var set = new OrderedSet();
|
2736
|
+
|
2737
|
+
set.presenceSet = copy(this.presenceSet);
|
2738
|
+
set.list = this.toArray();
|
2739
|
+
|
2740
|
+
return set;
|
2741
|
+
}
|
2742
|
+
};
|
2743
|
+
|
2744
|
+
/**
|
2745
|
+
A Map stores values indexed by keys. Unlike JavaScript's
|
2746
|
+
default Objects, the keys of a Map can be any JavaScript
|
2747
|
+
object.
|
2748
|
+
|
2749
|
+
Internally, a Map has two data structures:
|
2750
|
+
|
2751
|
+
1. `keys`: an OrderedSet of all of the existing keys
|
2752
|
+
2. `values`: a JavaScript Object indexed by the `Ember.guidFor(key)`
|
2753
|
+
|
2754
|
+
When a key/value pair is added for the first time, we
|
2755
|
+
add the key to the `keys` OrderedSet, and create or
|
2756
|
+
replace an entry in `values`. When an entry is deleted,
|
2757
|
+
we delete its entry in `keys` and `values`.
|
2758
|
+
|
2759
|
+
@class Map
|
2760
|
+
@namespace Ember
|
2761
|
+
@private
|
2762
|
+
@constructor
|
2763
|
+
*/
|
2764
|
+
var Map = Ember.Map = function() {
|
2765
|
+
this.keys = Ember.OrderedSet.create();
|
2766
|
+
this.values = {};
|
2767
|
+
};
|
2768
|
+
|
2769
|
+
/**
|
2770
|
+
@method create
|
2771
|
+
@static
|
2772
|
+
*/
|
2773
|
+
Map.create = function() {
|
2774
|
+
return new Map();
|
2775
|
+
};
|
2776
|
+
|
2777
|
+
Map.prototype = {
|
2778
|
+
/**
|
2779
|
+
This property will change as the number of objects in the map changes.
|
2780
|
+
|
2781
|
+
@property length
|
2782
|
+
@type number
|
2783
|
+
@default 0
|
2784
|
+
*/
|
2785
|
+
length: 0,
|
2786
|
+
|
2787
|
+
|
2788
|
+
/**
|
2789
|
+
Retrieve the value associated with a given key.
|
2790
|
+
|
2791
|
+
@method get
|
2792
|
+
@param {*} key
|
2793
|
+
@return {*} the value associated with the key, or `undefined`
|
2794
|
+
*/
|
2795
|
+
get: function(key) {
|
2796
|
+
var values = this.values,
|
2797
|
+
guid = guidFor(key);
|
2798
|
+
|
2799
|
+
return values[guid];
|
2800
|
+
},
|
2801
|
+
|
2802
|
+
/**
|
2803
|
+
Adds a value to the map. If a value for the given key has already been
|
2804
|
+
provided, the new value will replace the old value.
|
2805
|
+
|
2806
|
+
@method set
|
2807
|
+
@param {*} key
|
2808
|
+
@param {*} value
|
2809
|
+
*/
|
2810
|
+
set: function(key, value) {
|
2811
|
+
var keys = this.keys,
|
2812
|
+
values = this.values,
|
2813
|
+
guid = guidFor(key);
|
2814
|
+
|
2815
|
+
keys.add(key);
|
2816
|
+
values[guid] = value;
|
2817
|
+
set(this, 'length', keys.list.length);
|
2818
|
+
},
|
2819
|
+
|
2820
|
+
/**
|
2821
|
+
Removes a value from the map for an associated key.
|
2822
|
+
|
2823
|
+
@method remove
|
2824
|
+
@param {*} key
|
2825
|
+
@return {Boolean} true if an item was removed, false otherwise
|
2826
|
+
*/
|
2827
|
+
remove: function(key) {
|
2828
|
+
// don't use ES6 "delete" because it will be annoying
|
2829
|
+
// to use in browsers that are not ES6 friendly;
|
2830
|
+
var keys = this.keys,
|
2831
|
+
values = this.values,
|
2832
|
+
guid = guidFor(key);
|
2833
|
+
|
2834
|
+
if (values.hasOwnProperty(guid)) {
|
2835
|
+
keys.remove(key);
|
2836
|
+
delete values[guid];
|
2837
|
+
set(this, 'length', keys.list.length);
|
2838
|
+
return true;
|
2839
|
+
} else {
|
2840
|
+
return false;
|
2856
2841
|
}
|
2857
|
-
}
|
2858
|
-
return value;
|
2859
|
-
};
|
2842
|
+
},
|
2860
2843
|
|
2861
|
-
|
2862
|
-
|
2863
|
-
Ember.set = set;
|
2864
|
-
Ember.config.overrideAccessors();
|
2865
|
-
set = Ember.set;
|
2866
|
-
}
|
2844
|
+
/**
|
2845
|
+
Check whether a key is present.
|
2867
2846
|
|
2868
|
-
|
2869
|
-
|
2847
|
+
@method has
|
2848
|
+
@param {*} key
|
2849
|
+
@return {Boolean} true if the item was present, false otherwise
|
2850
|
+
*/
|
2851
|
+
has: function(key) {
|
2852
|
+
var values = this.values,
|
2853
|
+
guid = guidFor(key);
|
2870
2854
|
|
2871
|
-
|
2872
|
-
|
2855
|
+
return values.hasOwnProperty(guid);
|
2856
|
+
},
|
2873
2857
|
|
2874
|
-
|
2875
|
-
|
2858
|
+
/**
|
2859
|
+
Iterate over all the keys and values. Calls the function once
|
2860
|
+
for each key, passing in the key and value, in that order.
|
2876
2861
|
|
2877
|
-
|
2878
|
-
// get the root
|
2879
|
-
if (path !== 'this') {
|
2880
|
-
root = getPath(root, path);
|
2881
|
-
}
|
2862
|
+
The keys are guaranteed to be iterated over in insertion order.
|
2882
2863
|
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2864
|
+
@method forEach
|
2865
|
+
@param {Function} callback
|
2866
|
+
@param {*} self if passed, the `this` value inside the
|
2867
|
+
callback. By default, `this` is the map.
|
2868
|
+
*/
|
2869
|
+
forEach: function(callback, self) {
|
2870
|
+
var keys = this.keys,
|
2871
|
+
values = this.values;
|
2886
2872
|
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2873
|
+
keys.forEach(function(key) {
|
2874
|
+
var guid = guidFor(key);
|
2875
|
+
callback.call(self, key, values[guid]);
|
2876
|
+
});
|
2877
|
+
},
|
2878
|
+
|
2879
|
+
/**
|
2880
|
+
@method copy
|
2881
|
+
@return {Ember.Map}
|
2882
|
+
*/
|
2883
|
+
copy: function() {
|
2884
|
+
return copyMap(this, new Map());
|
2890
2885
|
}
|
2886
|
+
};
|
2891
2887
|
|
2892
|
-
|
2893
|
-
|
2888
|
+
/**
|
2889
|
+
@class MapWithDefault
|
2890
|
+
@namespace Ember
|
2891
|
+
@extends Ember.Map
|
2892
|
+
@private
|
2893
|
+
@constructor
|
2894
|
+
@param [options]
|
2895
|
+
@param {*} [options.defaultValue]
|
2896
|
+
*/
|
2897
|
+
var MapWithDefault = Ember.MapWithDefault = function(options) {
|
2898
|
+
Map.call(this);
|
2899
|
+
this.defaultValue = options.defaultValue;
|
2900
|
+
};
|
2894
2901
|
|
2895
|
-
|
2896
|
-
|
2902
|
+
/**
|
2903
|
+
@method create
|
2904
|
+
@static
|
2905
|
+
@param [options]
|
2906
|
+
@param {*} [options.defaultValue]
|
2907
|
+
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
2908
|
+
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
2909
|
+
*/
|
2910
|
+
MapWithDefault.create = function(options) {
|
2911
|
+
if (options) {
|
2912
|
+
return new MapWithDefault(options);
|
2913
|
+
} else {
|
2914
|
+
return new Map();
|
2915
|
+
}
|
2916
|
+
};
|
2917
|
+
|
2918
|
+
MapWithDefault.prototype = Ember.create(Map.prototype);
|
2897
2919
|
|
2898
2920
|
/**
|
2899
|
-
|
2900
|
-
chain is `undefined`, `null`, or destroyed.
|
2921
|
+
Retrieve the value associated with a given key.
|
2901
2922
|
|
2902
|
-
|
2903
|
-
|
2923
|
+
@method get
|
2924
|
+
@param {*} key
|
2925
|
+
@return {*} the value associated with the key, or the default value
|
2926
|
+
*/
|
2927
|
+
MapWithDefault.prototype.get = function(key) {
|
2928
|
+
var hasValue = this.has(key);
|
2904
2929
|
|
2905
|
-
|
2906
|
-
|
2907
|
-
|
2908
|
-
|
2909
|
-
|
2930
|
+
if (hasValue) {
|
2931
|
+
return Map.prototype.get.call(this, key);
|
2932
|
+
} else {
|
2933
|
+
var defaultValue = this.defaultValue(key);
|
2934
|
+
this.set(key, defaultValue);
|
2935
|
+
return defaultValue;
|
2936
|
+
}
|
2937
|
+
};
|
2938
|
+
|
2939
|
+
/**
|
2940
|
+
@method copy
|
2941
|
+
@return {Ember.MapWithDefault}
|
2910
2942
|
*/
|
2911
|
-
|
2912
|
-
return
|
2943
|
+
MapWithDefault.prototype.copy = function() {
|
2944
|
+
return copyMap(this, new MapWithDefault({
|
2945
|
+
defaultValue: this.defaultValue
|
2946
|
+
}));
|
2913
2947
|
};
|
2914
|
-
Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet', Ember.trySet);
|
2915
2948
|
|
2916
2949
|
})();
|
2917
2950
|
|
@@ -2943,7 +2976,7 @@ var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
|
|
2943
2976
|
@private
|
2944
2977
|
@constructor
|
2945
2978
|
*/
|
2946
|
-
|
2979
|
+
Ember.Descriptor = function() {};
|
2947
2980
|
|
2948
2981
|
// ..........................................................
|
2949
2982
|
// DEFINING PROPERTIES API
|
@@ -3504,7 +3537,7 @@ Ember.watchPath = function(obj, keyPath) {
|
|
3504
3537
|
};
|
3505
3538
|
|
3506
3539
|
Ember.unwatchPath = function(obj, keyPath) {
|
3507
|
-
var m = metaFor(obj), watching = m.watching
|
3540
|
+
var m = metaFor(obj), watching = m.watching;
|
3508
3541
|
|
3509
3542
|
if (watching[keyPath] === 1) {
|
3510
3543
|
watching[keyPath] = 0;
|
@@ -3766,27 +3799,14 @@ ComputedProperty.prototype = new Ember.Descriptor();
|
|
3766
3799
|
var ComputedPropertyPrototype = ComputedProperty.prototype;
|
3767
3800
|
|
3768
3801
|
/*
|
3769
|
-
|
3770
|
-
|
3771
|
-
Please use `.volatile` over this method.
|
3772
|
-
|
3773
|
-
```javascript
|
3774
|
-
MyApp.president = Ember.Object.create({
|
3775
|
-
fullName: function() {
|
3776
|
-
return this.get('firstName') + ' ' + this.get('lastName');
|
3777
|
-
|
3778
|
-
// By default, Ember will return the value of this property
|
3779
|
-
// without re-executing this function.
|
3780
|
-
}.property('firstName', 'lastName')
|
3802
|
+
Properties are cacheable by default. Computed property will automatically
|
3803
|
+
cache the return value of your function until one of the dependent keys changes.
|
3781
3804
|
|
3782
|
-
|
3783
|
-
|
3805
|
+
Call `volatile()` to set it into non-cached mode. When in this mode
|
3806
|
+
the computed property will not automatically cache the return value.
|
3784
3807
|
|
3785
|
-
|
3786
|
-
|
3787
|
-
}.property('firstName', 'lastName').cacheable(false)
|
3788
|
-
});
|
3789
|
-
```
|
3808
|
+
However, if a property is properly observable, there is no reason to disable
|
3809
|
+
caching.
|
3790
3810
|
|
3791
3811
|
@method cacheable
|
3792
3812
|
@param {Boolean} aFlag optional set to `false` to disable caching
|
@@ -4050,7 +4070,6 @@ ComputedPropertyPrototype.teardown = function(obj, keyName) {
|
|
4050
4070
|
The function should accept two parameters, key and value. If value is not
|
4051
4071
|
undefined you should set the value first. In either case return the
|
4052
4072
|
current value of the property.
|
4053
|
-
|
4054
4073
|
@method computed
|
4055
4074
|
@for Ember
|
4056
4075
|
@param {Function} func The computed property function.
|
@@ -4292,7 +4311,7 @@ registerComputedWithProperties('or', function(properties) {
|
|
4292
4311
|
@for Ember
|
4293
4312
|
@param {String} dependentKey, [dependentKey...]
|
4294
4313
|
@return {Ember.ComputedProperty} computed property which returns
|
4295
|
-
the first
|
4314
|
+
the first truthy value of given list of properties.
|
4296
4315
|
*/
|
4297
4316
|
registerComputedWithProperties('any', function(properties) {
|
4298
4317
|
for (var key in properties) {
|
@@ -4342,6 +4361,48 @@ Ember.computed.alias = function(dependentKey) {
|
|
4342
4361
|
});
|
4343
4362
|
};
|
4344
4363
|
|
4364
|
+
/**
|
4365
|
+
@method computed.oneWay
|
4366
|
+
@for Ember
|
4367
|
+
@param {String} dependentKey
|
4368
|
+
@return {Ember.ComputedProperty} computed property which creates an
|
4369
|
+
one way computed property to the original value for property.
|
4370
|
+
|
4371
|
+
Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
|
4372
|
+
data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
|
4373
|
+
not mutate the upstream property, rather causes the current property to
|
4374
|
+
become the value set. This causes the downstream property to permentantly
|
4375
|
+
diverge from the upstream property.
|
4376
|
+
|
4377
|
+
```javascript
|
4378
|
+
User = Ember.Object.extend({
|
4379
|
+
firstName: null,
|
4380
|
+
lastName: null,
|
4381
|
+
nickName: Ember.computed.oneWay('firstName')
|
4382
|
+
});
|
4383
|
+
|
4384
|
+
user = User.create({
|
4385
|
+
firstName: 'Teddy',
|
4386
|
+
lastName: 'Zeenny'
|
4387
|
+
});
|
4388
|
+
|
4389
|
+
user.get('nickName');
|
4390
|
+
# 'Teddy'
|
4391
|
+
|
4392
|
+
user.set('nickName', 'TeddyBear');
|
4393
|
+
# 'TeddyBear'
|
4394
|
+
|
4395
|
+
user.get('firstName');
|
4396
|
+
# 'Teddy'
|
4397
|
+
```
|
4398
|
+
*/
|
4399
|
+
Ember.computed.oneWay = function(dependentKey) {
|
4400
|
+
return Ember.computed(dependentKey, function() {
|
4401
|
+
return get(this, dependentKey);
|
4402
|
+
});
|
4403
|
+
};
|
4404
|
+
|
4405
|
+
|
4345
4406
|
/**
|
4346
4407
|
@method computed.defaultTo
|
4347
4408
|
@for Ember
|
@@ -4371,8 +4432,6 @@ Ember.computed.defaultTo = function(defaultPath) {
|
|
4371
4432
|
var AFTER_OBSERVERS = ':change';
|
4372
4433
|
var BEFORE_OBSERVERS = ':before';
|
4373
4434
|
|
4374
|
-
var guidFor = Ember.guidFor;
|
4375
|
-
|
4376
4435
|
function changeEvent(keyName) {
|
4377
4436
|
return keyName+AFTER_OBSERVERS;
|
4378
4437
|
}
|
@@ -4432,220 +4491,544 @@ Ember._suspendBeforeObserver = function(obj, path, target, method, callback) {
|
|
4432
4491
|
return Ember._suspendListener(obj, beforeEvent(path), target, method, callback);
|
4433
4492
|
};
|
4434
4493
|
|
4435
|
-
Ember._suspendObserver = function(obj, path, target, method, callback) {
|
4436
|
-
return Ember._suspendListener(obj, changeEvent(path), target, method, callback);
|
4437
|
-
};
|
4494
|
+
Ember._suspendObserver = function(obj, path, target, method, callback) {
|
4495
|
+
return Ember._suspendListener(obj, changeEvent(path), target, method, callback);
|
4496
|
+
};
|
4497
|
+
|
4498
|
+
var map = Ember.ArrayPolyfills.map;
|
4499
|
+
|
4500
|
+
Ember._suspendBeforeObservers = function(obj, paths, target, method, callback) {
|
4501
|
+
var events = map.call(paths, beforeEvent);
|
4502
|
+
return Ember._suspendListeners(obj, events, target, method, callback);
|
4503
|
+
};
|
4504
|
+
|
4505
|
+
Ember._suspendObservers = function(obj, paths, target, method, callback) {
|
4506
|
+
var events = map.call(paths, changeEvent);
|
4507
|
+
return Ember._suspendListeners(obj, events, target, method, callback);
|
4508
|
+
};
|
4509
|
+
|
4510
|
+
Ember.beforeObserversFor = function(obj, path) {
|
4511
|
+
return Ember.listenersFor(obj, beforeEvent(path));
|
4512
|
+
};
|
4513
|
+
|
4514
|
+
/**
|
4515
|
+
@method removeBeforeObserver
|
4516
|
+
@param obj
|
4517
|
+
@param {String} path
|
4518
|
+
@param {Object|Function} targetOrMethod
|
4519
|
+
@param {Function|String} [method]
|
4520
|
+
*/
|
4521
|
+
Ember.removeBeforeObserver = function(obj, path, target, method) {
|
4522
|
+
Ember.unwatch(obj, path);
|
4523
|
+
Ember.removeListener(obj, beforeEvent(path), target, method);
|
4524
|
+
return this;
|
4525
|
+
};
|
4526
|
+
})();
|
4527
|
+
|
4528
|
+
|
4529
|
+
|
4530
|
+
(function() {
|
4531
|
+
define("backburner",
|
4532
|
+
["backburner/deferred_action_queues","exports"],
|
4533
|
+
function(__dependency1__, __exports__) {
|
4534
|
+
"use strict";
|
4535
|
+
var DeferredActionQueues = __dependency1__.DeferredActionQueues;
|
4536
|
+
|
4537
|
+
var slice = [].slice,
|
4538
|
+
pop = [].pop,
|
4539
|
+
debouncees = [],
|
4540
|
+
timers = [],
|
4541
|
+
autorun, laterTimer, laterTimerExpiresAt;
|
4542
|
+
|
4543
|
+
function Backburner(queueNames, options) {
|
4544
|
+
this.queueNames = queueNames;
|
4545
|
+
this.options = options || {};
|
4546
|
+
if (!this.options.defaultQueue) {
|
4547
|
+
this.options.defaultQueue = queueNames[0];
|
4548
|
+
}
|
4549
|
+
this.instanceStack = [];
|
4550
|
+
}
|
4551
|
+
|
4552
|
+
Backburner.prototype = {
|
4553
|
+
queueNames: null,
|
4554
|
+
options: null,
|
4555
|
+
currentInstance: null,
|
4556
|
+
instanceStack: null,
|
4557
|
+
|
4558
|
+
begin: function() {
|
4559
|
+
var onBegin = this.options && this.options.onBegin,
|
4560
|
+
previousInstance = this.currentInstance;
|
4561
|
+
|
4562
|
+
if (previousInstance) {
|
4563
|
+
this.instanceStack.push(previousInstance);
|
4564
|
+
}
|
4565
|
+
|
4566
|
+
this.currentInstance = new DeferredActionQueues(this.queueNames, this.options);
|
4567
|
+
if (onBegin) {
|
4568
|
+
onBegin(this.currentInstance, previousInstance);
|
4569
|
+
}
|
4570
|
+
},
|
4571
|
+
|
4572
|
+
end: function() {
|
4573
|
+
var onEnd = this.options && this.options.onEnd,
|
4574
|
+
currentInstance = this.currentInstance,
|
4575
|
+
nextInstance = null;
|
4576
|
+
|
4577
|
+
try {
|
4578
|
+
currentInstance.flush();
|
4579
|
+
} finally {
|
4580
|
+
this.currentInstance = null;
|
4581
|
+
|
4582
|
+
if (this.instanceStack.length) {
|
4583
|
+
nextInstance = this.instanceStack.pop();
|
4584
|
+
this.currentInstance = nextInstance;
|
4585
|
+
}
|
4586
|
+
|
4587
|
+
if (onEnd) {
|
4588
|
+
onEnd(currentInstance, nextInstance);
|
4589
|
+
}
|
4590
|
+
}
|
4591
|
+
},
|
4592
|
+
|
4593
|
+
run: function(target, method /*, args */) {
|
4594
|
+
var ret;
|
4595
|
+
this.begin();
|
4596
|
+
|
4597
|
+
if (!method) {
|
4598
|
+
method = target;
|
4599
|
+
target = null;
|
4600
|
+
}
|
4601
|
+
|
4602
|
+
if (typeof method === 'string') {
|
4603
|
+
method = target[method];
|
4604
|
+
}
|
4605
|
+
|
4606
|
+
// Prevent Safari double-finally.
|
4607
|
+
var finallyAlreadyCalled = false;
|
4608
|
+
try {
|
4609
|
+
if (arguments.length > 2) {
|
4610
|
+
ret = method.apply(target, slice.call(arguments, 2));
|
4611
|
+
} else {
|
4612
|
+
ret = method.call(target);
|
4613
|
+
}
|
4614
|
+
} finally {
|
4615
|
+
if (!finallyAlreadyCalled) {
|
4616
|
+
finallyAlreadyCalled = true;
|
4617
|
+
this.end();
|
4618
|
+
}
|
4619
|
+
}
|
4620
|
+
return ret;
|
4621
|
+
},
|
4438
4622
|
|
4439
|
-
|
4623
|
+
defer: function(queueName, target, method /* , args */) {
|
4624
|
+
if (!method) {
|
4625
|
+
method = target;
|
4626
|
+
target = null;
|
4627
|
+
}
|
4440
4628
|
|
4441
|
-
|
4442
|
-
|
4443
|
-
|
4444
|
-
};
|
4629
|
+
if (typeof method === 'string') {
|
4630
|
+
method = target[method];
|
4631
|
+
}
|
4445
4632
|
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
4449
|
-
|
4633
|
+
var stack = new Error().stack,
|
4634
|
+
args = arguments.length > 3 ? slice.call(arguments, 3) : undefined;
|
4635
|
+
if (!this.currentInstance) { createAutorun(this); }
|
4636
|
+
return this.currentInstance.schedule(queueName, target, method, args, false, stack);
|
4637
|
+
},
|
4450
4638
|
|
4451
|
-
|
4452
|
-
|
4453
|
-
|
4639
|
+
deferOnce: function(queueName, target, method /* , args */) {
|
4640
|
+
if (!method) {
|
4641
|
+
method = target;
|
4642
|
+
target = null;
|
4643
|
+
}
|
4454
4644
|
|
4455
|
-
|
4456
|
-
|
4457
|
-
|
4458
|
-
@param {String} path
|
4459
|
-
@param {Object|Function} targetOrMethod
|
4460
|
-
@param {Function|String} [method]
|
4461
|
-
*/
|
4462
|
-
Ember.removeBeforeObserver = function(obj, path, target, method) {
|
4463
|
-
Ember.unwatch(obj, path);
|
4464
|
-
Ember.removeListener(obj, beforeEvent(path), target, method);
|
4465
|
-
return this;
|
4466
|
-
};
|
4467
|
-
})();
|
4645
|
+
if (typeof method === 'string') {
|
4646
|
+
method = target[method];
|
4647
|
+
}
|
4468
4648
|
|
4649
|
+
var stack = new Error().stack,
|
4650
|
+
args = arguments.length > 3 ? slice.call(arguments, 3) : undefined;
|
4651
|
+
if (!this.currentInstance) { createAutorun(this); }
|
4652
|
+
return this.currentInstance.schedule(queueName, target, method, args, true, stack);
|
4653
|
+
},
|
4469
4654
|
|
4655
|
+
setTimeout: function() {
|
4656
|
+
var self = this,
|
4657
|
+
wait = pop.call(arguments),
|
4658
|
+
target = arguments[0],
|
4659
|
+
method = arguments[1],
|
4660
|
+
executeAt = (+new Date()) + wait;
|
4470
4661
|
|
4471
|
-
(
|
4472
|
-
|
4473
|
-
|
4474
|
-
|
4475
|
-
// Ember.guidFor, Ember.tryFinally
|
4662
|
+
if (!method) {
|
4663
|
+
method = target;
|
4664
|
+
target = null;
|
4665
|
+
}
|
4476
4666
|
|
4477
|
-
|
4478
|
-
|
4479
|
-
|
4667
|
+
if (typeof method === 'string') {
|
4668
|
+
method = target[method];
|
4669
|
+
}
|
4480
4670
|
|
4481
|
-
|
4482
|
-
|
4483
|
-
|
4671
|
+
var fn, args;
|
4672
|
+
if (arguments.length > 2) {
|
4673
|
+
args = slice.call(arguments, 2);
|
4484
4674
|
|
4485
|
-
|
4486
|
-
|
4675
|
+
fn = function() {
|
4676
|
+
method.apply(target, args);
|
4677
|
+
};
|
4678
|
+
} else {
|
4679
|
+
fn = function() {
|
4680
|
+
method.call(target);
|
4681
|
+
};
|
4682
|
+
}
|
4487
4683
|
|
4488
|
-
//
|
4489
|
-
|
4490
|
-
|
4684
|
+
// find position to insert - TODO: binary search
|
4685
|
+
var i, l;
|
4686
|
+
for (i = 0, l = timers.length; i < l; i += 2) {
|
4687
|
+
if (executeAt < timers[i]) { break; }
|
4688
|
+
}
|
4491
4689
|
|
4492
|
-
|
4493
|
-
method = target;
|
4494
|
-
target = undefined;
|
4495
|
-
}
|
4690
|
+
timers.splice(i, 0, executeAt, fn);
|
4496
4691
|
|
4497
|
-
|
4498
|
-
if (args && ignore > 0) {
|
4499
|
-
args = args.length > ignore ? slice.call(args, ignore) : null;
|
4500
|
-
}
|
4692
|
+
if (laterTimer && laterTimerExpiresAt < executeAt) { return fn; }
|
4501
4693
|
|
4502
|
-
|
4503
|
-
|
4504
|
-
|
4505
|
-
|
4506
|
-
|
4694
|
+
if (laterTimer) {
|
4695
|
+
clearTimeout(laterTimer);
|
4696
|
+
laterTimer = null;
|
4697
|
+
}
|
4698
|
+
laterTimer = setTimeout(function() {
|
4699
|
+
executeTimers(self);
|
4700
|
+
laterTimer = null;
|
4701
|
+
laterTimerExpiresAt = null;
|
4702
|
+
}, wait);
|
4703
|
+
laterTimerExpiresAt = executeAt;
|
4704
|
+
|
4705
|
+
return fn;
|
4706
|
+
},
|
4507
4707
|
|
4708
|
+
debounce: function(target, method /* , args, wait */) {
|
4709
|
+
var self = this,
|
4710
|
+
args = arguments,
|
4711
|
+
wait = pop.call(args),
|
4712
|
+
debouncee;
|
4508
4713
|
|
4509
|
-
|
4510
|
-
|
4511
|
-
//
|
4714
|
+
for (var i = 0, l = debouncees.length; i < l; i++) {
|
4715
|
+
debouncee = debouncees[i];
|
4716
|
+
if (debouncee[0] === target && debouncee[1] === method) { return; } // do nothing
|
4717
|
+
}
|
4512
4718
|
|
4513
|
-
|
4514
|
-
|
4719
|
+
var timer = setTimeout(function() {
|
4720
|
+
self.run.apply(self, args);
|
4515
4721
|
|
4516
|
-
|
4517
|
-
|
4518
|
-
|
4519
|
-
|
4520
|
-
|
4521
|
-
|
4522
|
-
|
4523
|
-
|
4524
|
-
}
|
4722
|
+
// remove debouncee
|
4723
|
+
var index = -1;
|
4724
|
+
for (var i = 0, l = debouncees.length; i < l; i++) {
|
4725
|
+
debouncee = debouncees[i];
|
4726
|
+
if (debouncee[0] === target && debouncee[1] === method) {
|
4727
|
+
index = i;
|
4728
|
+
break;
|
4729
|
+
}
|
4730
|
+
}
|
4525
4731
|
|
4526
|
-
|
4527
|
-
|
4528
|
-
@method end
|
4529
|
-
*/
|
4530
|
-
end: function() {
|
4531
|
-
this.flush();
|
4532
|
-
},
|
4732
|
+
if (index > -1) { debouncees.splice(index, 1); }
|
4733
|
+
}, wait);
|
4533
4734
|
|
4534
|
-
|
4535
|
-
|
4536
|
-
*/
|
4537
|
-
prev: function() {
|
4538
|
-
return this._prev;
|
4539
|
-
},
|
4735
|
+
debouncees.push([target, method, timer]);
|
4736
|
+
},
|
4540
4737
|
|
4541
|
-
|
4542
|
-
|
4543
|
-
|
4738
|
+
cancelTimers: function() {
|
4739
|
+
for (var i = 0, l = debouncees.length; i < l; i++) {
|
4740
|
+
clearTimeout(debouncees[i][2]);
|
4741
|
+
}
|
4742
|
+
debouncees = [];
|
4544
4743
|
|
4545
|
-
|
4546
|
-
|
4547
|
-
|
4548
|
-
|
4549
|
-
|
4550
|
-
*/
|
4551
|
-
schedule: function(queueName, target, method) {
|
4552
|
-
var queues = this._queues, queue;
|
4553
|
-
if (!queues) { queues = this._queues = {}; }
|
4554
|
-
queue = queues[queueName];
|
4555
|
-
if (!queue) { queue = queues[queueName] = []; }
|
4744
|
+
if (laterTimer) {
|
4745
|
+
clearTimeout(laterTimer);
|
4746
|
+
laterTimer = null;
|
4747
|
+
}
|
4748
|
+
timers = [];
|
4556
4749
|
|
4557
|
-
|
4558
|
-
|
4559
|
-
|
4560
|
-
|
4750
|
+
if (autorun) {
|
4751
|
+
clearTimeout(autorun);
|
4752
|
+
autorun = null;
|
4753
|
+
}
|
4754
|
+
},
|
4561
4755
|
|
4562
|
-
|
4563
|
-
|
4564
|
-
|
4565
|
-
*/
|
4566
|
-
flush: function(queueName) {
|
4567
|
-
var queueNames, idx, len, queue, log;
|
4756
|
+
hasTimers: function() {
|
4757
|
+
return !!timers.length || autorun;
|
4758
|
+
},
|
4568
4759
|
|
4569
|
-
|
4760
|
+
cancel: function(timer) {
|
4761
|
+
if (typeof timer === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
|
4762
|
+
return timer.queue.cancel(timer);
|
4763
|
+
} else if (typeof timer === 'function') { // we're cancelling a setTimeout
|
4764
|
+
for (var i = 0, l = timers.length; i < l; i += 2) {
|
4765
|
+
if (timers[i + 1] === timer) {
|
4766
|
+
timers.splice(i, 2); // remove the two elements
|
4767
|
+
return true;
|
4768
|
+
}
|
4769
|
+
}
|
4770
|
+
}
|
4771
|
+
}
|
4772
|
+
};
|
4773
|
+
|
4774
|
+
Backburner.prototype.schedule = Backburner.prototype.defer;
|
4775
|
+
Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
|
4776
|
+
Backburner.prototype.later = Backburner.prototype.setTimeout;
|
4570
4777
|
|
4571
|
-
function
|
4572
|
-
|
4778
|
+
function createAutorun(backburner) {
|
4779
|
+
backburner.begin();
|
4780
|
+
autorun = setTimeout(function() {
|
4781
|
+
backburner.end();
|
4782
|
+
autorun = null;
|
4783
|
+
});
|
4573
4784
|
}
|
4574
4785
|
|
4575
|
-
function
|
4576
|
-
|
4786
|
+
function executeTimers(self) {
|
4787
|
+
var now = +new Date(),
|
4788
|
+
time, fns, i, l;
|
4789
|
+
|
4790
|
+
self.run(function() {
|
4791
|
+
// TODO: binary search
|
4792
|
+
for (i = 0, l = timers.length; i < l; i += 2) {
|
4793
|
+
time = timers[i];
|
4794
|
+
if (time > now) { break; }
|
4795
|
+
}
|
4796
|
+
|
4797
|
+
fns = timers.splice(0, i);
|
4798
|
+
|
4799
|
+
for (i = 1, l = fns.length; i < l; i += 2) {
|
4800
|
+
self.schedule(self.options.defaultQueue, null, fns[i]);
|
4801
|
+
}
|
4802
|
+
});
|
4803
|
+
|
4804
|
+
if (timers.length) {
|
4805
|
+
laterTimer = setTimeout(function() {
|
4806
|
+
executeTimers(self);
|
4807
|
+
laterTimer = null;
|
4808
|
+
laterTimerExpiresAt = null;
|
4809
|
+
}, timers[0] - now);
|
4810
|
+
laterTimerExpiresAt = timers[0];
|
4811
|
+
}
|
4577
4812
|
}
|
4578
4813
|
|
4579
|
-
Ember.watch.flushPending(); // make sure all chained watchers are setup
|
4580
4814
|
|
4581
|
-
|
4582
|
-
|
4583
|
-
|
4815
|
+
__exports__.Backburner = Backburner;
|
4816
|
+
});
|
4817
|
+
|
4818
|
+
define("backburner/deferred_action_queues",
|
4819
|
+
["backburner/queue","exports"],
|
4820
|
+
function(__dependency1__, __exports__) {
|
4821
|
+
"use strict";
|
4822
|
+
var Queue = __dependency1__.Queue;
|
4823
|
+
|
4824
|
+
function DeferredActionQueues(queueNames, options) {
|
4825
|
+
var queues = this.queues = {};
|
4826
|
+
this.queueNames = queueNames = queueNames || [];
|
4584
4827
|
|
4585
|
-
|
4586
|
-
|
4587
|
-
|
4588
|
-
|
4589
|
-
|
4828
|
+
var queueName;
|
4829
|
+
for (var i = 0, l = queueNames.length; i < l; i++) {
|
4830
|
+
queueName = queueNames[i];
|
4831
|
+
queues[queueName] = new Queue(this, queueName, options[queueName]);
|
4832
|
+
}
|
4833
|
+
}
|
4590
4834
|
|
4591
|
-
|
4835
|
+
DeferredActionQueues.prototype = {
|
4836
|
+
queueNames: null,
|
4837
|
+
queues: null,
|
4592
4838
|
|
4593
|
-
|
4839
|
+
schedule: function(queueName, target, method, args, onceFlag, stack) {
|
4840
|
+
var queues = this.queues,
|
4841
|
+
queue = queues[queueName];
|
4594
4842
|
|
4595
|
-
|
4843
|
+
if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }
|
4596
4844
|
|
4845
|
+
if (onceFlag) {
|
4846
|
+
return queue.pushUnique(target, method, args, stack);
|
4597
4847
|
} else {
|
4598
|
-
|
4848
|
+
return queue.push(target, method, args, stack);
|
4849
|
+
}
|
4850
|
+
},
|
4851
|
+
|
4852
|
+
flush: function() {
|
4853
|
+
var queues = this.queues,
|
4854
|
+
queueNames = this.queueNames,
|
4855
|
+
queueName, queue, queueItems, priorQueueNameIndex,
|
4856
|
+
queueNameIndex = 0, numberOfQueues = queueNames.length;
|
4857
|
+
|
4858
|
+
outerloop:
|
4859
|
+
while (queueNameIndex < numberOfQueues) {
|
4860
|
+
queueName = queueNames[queueNameIndex];
|
4861
|
+
queue = queues[queueName];
|
4862
|
+
queueItems = queue._queue.slice();
|
4863
|
+
queue._queue = [];
|
4864
|
+
|
4865
|
+
var options = queue.options,
|
4866
|
+
before = options && options.before,
|
4867
|
+
after = options && options.after,
|
4868
|
+
target, method, args, stack,
|
4869
|
+
queueIndex = 0, numberOfQueueItems = queueItems.length;
|
4870
|
+
|
4871
|
+
if (numberOfQueueItems && before) { before(); }
|
4872
|
+
while (queueIndex < numberOfQueueItems) {
|
4873
|
+
target = queueItems[queueIndex];
|
4874
|
+
method = queueItems[queueIndex+1];
|
4875
|
+
args = queueItems[queueIndex+2];
|
4876
|
+
stack = queueItems[queueIndex+3]; // Debugging assistance
|
4877
|
+
|
4878
|
+
if (typeof method === 'string') { method = target[method]; }
|
4879
|
+
|
4880
|
+
// TODO: error handling
|
4881
|
+
if (args && args.length > 0) {
|
4882
|
+
method.apply(target, args);
|
4883
|
+
} else {
|
4884
|
+
method.call(target);
|
4885
|
+
}
|
4886
|
+
|
4887
|
+
queueIndex += 4;
|
4888
|
+
}
|
4889
|
+
if (numberOfQueueItems && after) { after(); }
|
4890
|
+
|
4891
|
+
if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
|
4892
|
+
queueNameIndex = priorQueueNameIndex;
|
4893
|
+
continue outerloop;
|
4894
|
+
}
|
4895
|
+
|
4896
|
+
queueNameIndex++;
|
4599
4897
|
}
|
4600
4898
|
}
|
4899
|
+
};
|
4601
4900
|
|
4602
|
-
|
4603
|
-
|
4604
|
-
|
4605
|
-
|
4901
|
+
function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
|
4902
|
+
var queueName, queue;
|
4903
|
+
|
4904
|
+
for (var i = 0, l = currentQueueIndex; i <= l; i++) {
|
4905
|
+
queueName = daq.queueNames[i];
|
4906
|
+
queue = daq.queues[queueName];
|
4907
|
+
if (queue._queue.length) { return i; }
|
4908
|
+
}
|
4909
|
+
|
4910
|
+
return -1;
|
4911
|
+
}
|
4912
|
+
|
4913
|
+
__exports__.DeferredActionQueues = DeferredActionQueues;
|
4914
|
+
});
|
4915
|
+
|
4916
|
+
define("backburner/queue",
|
4917
|
+
["exports"],
|
4918
|
+
function(__exports__) {
|
4919
|
+
"use strict";
|
4920
|
+
function Queue(daq, name, options) {
|
4921
|
+
this.daq = daq;
|
4922
|
+
this.name = name;
|
4923
|
+
this.options = options;
|
4924
|
+
this._queue = [];
|
4925
|
+
}
|
4926
|
+
|
4927
|
+
Queue.prototype = {
|
4928
|
+
daq: null,
|
4929
|
+
name: null,
|
4930
|
+
options: null,
|
4931
|
+
_queue: null,
|
4932
|
+
|
4933
|
+
push: function(target, method, args, stack) {
|
4934
|
+
var queue = this._queue;
|
4935
|
+
queue.push(target, method, args, stack);
|
4936
|
+
return {queue: this, target: target, method: method};
|
4937
|
+
},
|
4606
4938
|
|
4607
|
-
|
4608
|
-
|
4609
|
-
queueName = queueNames[idx];
|
4610
|
-
queue = this._queues && this._queues[queueName];
|
4611
|
-
delete this._queues[queueName];
|
4939
|
+
pushUnique: function(target, method, args, stack) {
|
4940
|
+
var queue = this._queue, currentTarget, currentMethod, i, l;
|
4612
4941
|
|
4613
|
-
|
4614
|
-
|
4615
|
-
|
4616
|
-
if (queueName === 'sync') {
|
4617
|
-
log = Ember.LOG_BINDINGS;
|
4618
|
-
if (log) { Ember.Logger.log('Begin: Flush Sync Queue'); }
|
4942
|
+
for (i = 0, l = queue.length; i < l; i += 4) {
|
4943
|
+
currentTarget = queue[i];
|
4944
|
+
currentMethod = queue[i+1];
|
4619
4945
|
|
4620
|
-
|
4946
|
+
if (currentTarget === target && currentMethod === method) {
|
4947
|
+
queue[i+2] = args; // replace args
|
4948
|
+
queue[i+3] = stack; // replace stack
|
4949
|
+
return {queue: this, target: target, method: method}; // TODO: test this code path
|
4950
|
+
}
|
4951
|
+
}
|
4621
4952
|
|
4622
|
-
|
4953
|
+
this._queue.push(target, method, args, stack);
|
4954
|
+
return {queue: this, target: target, method: method};
|
4955
|
+
},
|
4623
4956
|
|
4624
|
-
|
4957
|
+
// TODO: remove me, only being used for Ember.run.sync
|
4958
|
+
flush: function() {
|
4959
|
+
var queue = this._queue,
|
4960
|
+
options = this.options,
|
4961
|
+
before = options && options.before,
|
4962
|
+
after = options && options.after,
|
4963
|
+
target, method, args, stack, i, l = queue.length;
|
4964
|
+
|
4965
|
+
if (l && before) { before(); }
|
4966
|
+
for (i = 0; i < l; i += 4) {
|
4967
|
+
target = queue[i];
|
4968
|
+
method = queue[i+1];
|
4969
|
+
args = queue[i+2];
|
4970
|
+
stack = queue[i+3]; // Debugging assistance
|
4971
|
+
|
4972
|
+
// TODO: error handling
|
4973
|
+
if (args && args.length > 0) {
|
4974
|
+
method.apply(target, args);
|
4625
4975
|
} else {
|
4626
|
-
|
4976
|
+
method.call(target);
|
4627
4977
|
}
|
4628
4978
|
}
|
4979
|
+
if (l && after) { after(); }
|
4629
4980
|
|
4630
|
-
//
|
4631
|
-
|
4632
|
-
|
4633
|
-
|
4634
|
-
|
4635
|
-
|
4636
|
-
}
|
4981
|
+
// check if new items have been added
|
4982
|
+
if (queue.length > l) {
|
4983
|
+
this._queue = queue.slice(l);
|
4984
|
+
this.flush();
|
4985
|
+
} else {
|
4986
|
+
this._queue.length = 0;
|
4637
4987
|
}
|
4988
|
+
},
|
4989
|
+
|
4990
|
+
cancel: function(actionToCancel) {
|
4991
|
+
var queue = this._queue, currentTarget, currentMethod, i, l;
|
4638
4992
|
|
4639
|
-
|
4993
|
+
for (i = 0, l = queue.length; i < l; i += 4) {
|
4994
|
+
currentTarget = queue[i];
|
4995
|
+
currentMethod = queue[i+1];
|
4996
|
+
|
4997
|
+
if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
|
4998
|
+
queue.splice(i, 4);
|
4999
|
+
return true;
|
5000
|
+
}
|
5001
|
+
}
|
4640
5002
|
}
|
4641
|
-
}
|
5003
|
+
};
|
5004
|
+
|
5005
|
+
__exports__.Queue = Queue;
|
5006
|
+
});
|
5007
|
+
|
5008
|
+
})();
|
5009
|
+
|
4642
5010
|
|
4643
|
-
return this;
|
4644
|
-
}
|
4645
5011
|
|
5012
|
+
(function() {
|
5013
|
+
var onBegin = function(current) {
|
5014
|
+
Ember.run.currentRunLoop = current;
|
5015
|
+
};
|
5016
|
+
|
5017
|
+
var onEnd = function(current, next) {
|
5018
|
+
Ember.run.currentRunLoop = next;
|
4646
5019
|
};
|
4647
5020
|
|
4648
|
-
|
5021
|
+
var Backburner = requireModule('backburner').Backburner,
|
5022
|
+
backburner = new Backburner(['sync', 'actions', 'destroy'], {
|
5023
|
+
sync: {
|
5024
|
+
before: Ember.beginPropertyChanges,
|
5025
|
+
after: Ember.endPropertyChanges
|
5026
|
+
},
|
5027
|
+
defaultQueue: 'actions',
|
5028
|
+
onBegin: onBegin,
|
5029
|
+
onEnd: onEnd
|
5030
|
+
}),
|
5031
|
+
slice = [].slice;
|
4649
5032
|
|
4650
5033
|
// ..........................................................
|
4651
5034
|
// Ember.run - this is ideally the only public API the dev sees
|
@@ -4679,20 +5062,76 @@ Ember.RunLoop = RunLoop;
|
|
4679
5062
|
@return {Object} return value from invoking the passed function.
|
4680
5063
|
*/
|
4681
5064
|
Ember.run = function(target, method) {
|
4682
|
-
var
|
4683
|
-
run.begin();
|
5065
|
+
var ret;
|
4684
5066
|
|
4685
|
-
|
4686
|
-
|
4687
|
-
|
5067
|
+
if (Ember.onerror) {
|
5068
|
+
try {
|
5069
|
+
ret = backburner.run.apply(backburner, arguments);
|
5070
|
+
} catch (e) {
|
5071
|
+
Ember.onerror(e);
|
4688
5072
|
}
|
5073
|
+
} else {
|
5074
|
+
ret = backburner.run.apply(backburner, arguments);
|
5075
|
+
}
|
5076
|
+
|
5077
|
+
return ret;
|
5078
|
+
};
|
5079
|
+
|
5080
|
+
/**
|
5081
|
+
|
5082
|
+
If no run-loop is present, it creates a new one. If a run loop is
|
5083
|
+
present it will queue itself to run on the existing run-loops action
|
5084
|
+
queue.
|
5085
|
+
|
5086
|
+
Please note: This is not for normal usage, and should be used sparingly.
|
5087
|
+
|
5088
|
+
If invoked when not within a run loop:
|
5089
|
+
|
5090
|
+
```javascript
|
5091
|
+
Ember.run.join(function(){
|
5092
|
+
// creates a new run-loop
|
5093
|
+
});
|
5094
|
+
```
|
5095
|
+
|
5096
|
+
Alternatively, if called within an existing run loop:
|
5097
|
+
|
5098
|
+
```javascript
|
5099
|
+
Ember.run(function(){
|
5100
|
+
// creates a new run-loop
|
5101
|
+
Ember.run.join(function(){
|
5102
|
+
// joins with the existing run-loop, and queues for invocation on
|
5103
|
+
// the existing run-loops action queue.
|
5104
|
+
});
|
5105
|
+
});
|
5106
|
+
```
|
5107
|
+
|
5108
|
+
@method join
|
5109
|
+
@namespace Ember
|
5110
|
+
@param {Object} [target] target of method to call
|
5111
|
+
@param {Function|String} method Method to invoke.
|
5112
|
+
May be a function or a string. If you pass a string
|
5113
|
+
then it will be looked up on the passed target.
|
5114
|
+
@param {Object} [args*] Any additional arguments you wish to pass to the method.
|
5115
|
+
@return {Object} return value from invoking the passed function. Please note,
|
5116
|
+
when called within an existing loop, no return value is possible.
|
5117
|
+
*/
|
5118
|
+
Ember.run.join = function(target, method) {
|
5119
|
+
if (!Ember.run.currentRunLoop) {
|
5120
|
+
return Ember.run.apply(Ember.run, arguments);
|
4689
5121
|
}
|
4690
5122
|
|
4691
|
-
|
5123
|
+
var args = slice.call(arguments);
|
5124
|
+
args.unshift('actions');
|
5125
|
+
Ember.run.schedule.apply(Ember.run, args);
|
4692
5126
|
};
|
4693
5127
|
|
5128
|
+
Ember.run.backburner = backburner;
|
5129
|
+
|
4694
5130
|
var run = Ember.run;
|
4695
5131
|
|
5132
|
+
Ember.run.currentRunLoop = null;
|
5133
|
+
|
5134
|
+
Ember.run.queues = backburner.queueNames;
|
4696
5135
|
|
4697
5136
|
/**
|
4698
5137
|
Begins a new RunLoop. Any deferred actions invoked after the begin will
|
@@ -4709,7 +5148,7 @@ var run = Ember.run;
|
|
4709
5148
|
@return {void}
|
4710
5149
|
*/
|
4711
5150
|
Ember.run.begin = function() {
|
4712
|
-
|
5151
|
+
backburner.begin();
|
4713
5152
|
};
|
4714
5153
|
|
4715
5154
|
/**
|
@@ -4727,12 +5166,7 @@ Ember.run.begin = function() {
|
|
4727
5166
|
@return {void}
|
4728
5167
|
*/
|
4729
5168
|
Ember.run.end = function() {
|
4730
|
-
|
4731
|
-
|
4732
|
-
function tryable() { run.currentRunLoop.end(); }
|
4733
|
-
function finalizer() { run.currentRunLoop = run.currentRunLoop.prev(); }
|
4734
|
-
|
4735
|
-
Ember.tryFinally(tryable, finalizer);
|
5169
|
+
backburner.end();
|
4736
5170
|
};
|
4737
5171
|
|
4738
5172
|
/**
|
@@ -4745,7 +5179,6 @@ Ember.run.end = function() {
|
|
4745
5179
|
@type Array
|
4746
5180
|
@default ['sync', 'actions', 'destroy']
|
4747
5181
|
*/
|
4748
|
-
Ember.run.queues = ['sync', 'actions', 'destroy'];
|
4749
5182
|
|
4750
5183
|
/**
|
4751
5184
|
Adds the passed target/method and any optional arguments to the named
|
@@ -4784,57 +5217,18 @@ Ember.run.queues = ['sync', 'actions', 'destroy'];
|
|
4784
5217
|
@return {void}
|
4785
5218
|
*/
|
4786
5219
|
Ember.run.schedule = function(queue, target, method) {
|
4787
|
-
|
4788
|
-
|
5220
|
+
checkAutoRun();
|
5221
|
+
backburner.schedule.apply(backburner, arguments);
|
4789
5222
|
};
|
4790
5223
|
|
4791
|
-
var scheduledAutorun;
|
4792
|
-
function autorun() {
|
4793
|
-
scheduledAutorun = null;
|
4794
|
-
if (run.currentRunLoop) { run.end(); }
|
4795
|
-
}
|
4796
|
-
|
4797
5224
|
// Used by global test teardown
|
4798
5225
|
Ember.run.hasScheduledTimers = function() {
|
4799
|
-
return
|
5226
|
+
return backburner.hasTimers();
|
4800
5227
|
};
|
4801
5228
|
|
4802
5229
|
// Used by global test teardown
|
4803
5230
|
Ember.run.cancelTimers = function () {
|
4804
|
-
|
4805
|
-
clearTimeout(scheduledAutorun);
|
4806
|
-
scheduledAutorun = null;
|
4807
|
-
}
|
4808
|
-
if (scheduledLater) {
|
4809
|
-
clearTimeout(scheduledLater);
|
4810
|
-
scheduledLater = null;
|
4811
|
-
}
|
4812
|
-
timers = {};
|
4813
|
-
};
|
4814
|
-
|
4815
|
-
/**
|
4816
|
-
Begins a new RunLoop if necessary and schedules a timer to flush the
|
4817
|
-
RunLoop at a later time. This method is used by parts of Ember to
|
4818
|
-
ensure the RunLoop always finishes. You normally do not need to call this
|
4819
|
-
method directly. Instead use `Ember.run()`
|
4820
|
-
|
4821
|
-
@method autorun
|
4822
|
-
@example
|
4823
|
-
Ember.run.autorun();
|
4824
|
-
@return {Ember.RunLoop} the new current RunLoop
|
4825
|
-
*/
|
4826
|
-
Ember.run.autorun = function() {
|
4827
|
-
if (!run.currentRunLoop) {
|
4828
|
-
Ember.assert("You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run", !Ember.testing);
|
4829
|
-
|
4830
|
-
run.begin();
|
4831
|
-
|
4832
|
-
if (!scheduledAutorun) {
|
4833
|
-
scheduledAutorun = setTimeout(autorun, 1);
|
4834
|
-
}
|
4835
|
-
}
|
4836
|
-
|
4837
|
-
return run.currentRunLoop;
|
5231
|
+
backburner.cancelTimers();
|
4838
5232
|
};
|
4839
5233
|
|
4840
5234
|
/**
|
@@ -4854,42 +5248,9 @@ Ember.run.autorun = function() {
|
|
4854
5248
|
@return {void}
|
4855
5249
|
*/
|
4856
5250
|
Ember.run.sync = function() {
|
4857
|
-
|
4858
|
-
run.currentRunLoop.flush('sync');
|
5251
|
+
backburner.currentInstance.queues.sync.flush();
|
4859
5252
|
};
|
4860
5253
|
|
4861
|
-
// ..........................................................
|
4862
|
-
// TIMERS
|
4863
|
-
//
|
4864
|
-
|
4865
|
-
var timers = {}; // active timers...
|
4866
|
-
|
4867
|
-
var scheduledLater, scheduledLaterExpires;
|
4868
|
-
function invokeLaterTimers() {
|
4869
|
-
scheduledLater = null;
|
4870
|
-
run(function() {
|
4871
|
-
var now = (+ new Date()), earliest = -1;
|
4872
|
-
for (var key in timers) {
|
4873
|
-
if (!timers.hasOwnProperty(key)) { continue; }
|
4874
|
-
var timer = timers[key];
|
4875
|
-
if (timer && timer.expires) {
|
4876
|
-
if (now >= timer.expires) {
|
4877
|
-
delete timers[key];
|
4878
|
-
invoke(timer.target, timer.method, timer.args, 2);
|
4879
|
-
} else {
|
4880
|
-
if (earliest < 0 || (timer.expires < earliest)) { earliest = timer.expires; }
|
4881
|
-
}
|
4882
|
-
}
|
4883
|
-
}
|
4884
|
-
|
4885
|
-
// schedule next timeout to fire when the earliest timer expires
|
4886
|
-
if (earliest > 0) {
|
4887
|
-
scheduledLater = setTimeout(invokeLaterTimers, earliest - now);
|
4888
|
-
scheduledLaterExpires = earliest;
|
4889
|
-
}
|
4890
|
-
});
|
4891
|
-
}
|
4892
|
-
|
4893
5254
|
/**
|
4894
5255
|
Invokes the passed target/method and optional arguments after a specified
|
4895
5256
|
period if time. The last parameter of this method must always be a number
|
@@ -4901,89 +5262,24 @@ function invokeLaterTimers() {
|
|
4901
5262
|
together, which is often more efficient than using a real setTimeout.
|
4902
5263
|
|
4903
5264
|
```javascript
|
4904
|
-
Ember.run.later(myContext, function(){
|
4905
|
-
// code here will execute within a RunLoop in about 500ms with this == myContext
|
4906
|
-
}, 500);
|
4907
|
-
```
|
4908
|
-
|
4909
|
-
@method later
|
4910
|
-
@param {Object} [target] target of method to invoke
|
4911
|
-
@param {Function|String} method The method to invoke.
|
4912
|
-
If you pass a string it will be resolved on the
|
4913
|
-
target at the time the method is invoked.
|
4914
|
-
@param {Object} [args*] Optional arguments to pass to the timeout.
|
4915
|
-
@param {Number} wait Number of milliseconds to wait.
|
4916
|
-
@return {String} a string you can use to cancel the timer in
|
4917
|
-
{{#crossLink "Ember/run.cancel"}}{{/crossLink}} later.
|
4918
|
-
*/
|
4919
|
-
Ember.run.later = function(target, method) {
|
4920
|
-
var args, expires, timer, guid, wait;
|
4921
|
-
|
4922
|
-
// setTimeout compatibility...
|
4923
|
-
if (arguments.length===2 && 'function' === typeof target) {
|
4924
|
-
wait = method;
|
4925
|
-
method = target;
|
4926
|
-
target = undefined;
|
4927
|
-
args = [target, method];
|
4928
|
-
} else {
|
4929
|
-
args = slice.call(arguments);
|
4930
|
-
wait = args.pop();
|
4931
|
-
}
|
4932
|
-
|
4933
|
-
expires = (+ new Date()) + wait;
|
4934
|
-
timer = { target: target, method: method, expires: expires, args: args };
|
4935
|
-
guid = Ember.guidFor(timer);
|
4936
|
-
timers[guid] = timer;
|
4937
|
-
|
4938
|
-
if(scheduledLater && expires < scheduledLaterExpires) {
|
4939
|
-
// Cancel later timer (then reschedule earlier timer below)
|
4940
|
-
clearTimeout(scheduledLater);
|
4941
|
-
scheduledLater = null;
|
4942
|
-
}
|
4943
|
-
|
4944
|
-
if (!scheduledLater) {
|
4945
|
-
// Schedule later timers to be run.
|
4946
|
-
scheduledLater = setTimeout(invokeLaterTimers, wait);
|
4947
|
-
scheduledLaterExpires = expires;
|
4948
|
-
}
|
4949
|
-
|
4950
|
-
return guid;
|
4951
|
-
};
|
4952
|
-
|
4953
|
-
function invokeOnceTimer(guid, onceTimers) {
|
4954
|
-
if (onceTimers[this.tguid]) { delete onceTimers[this.tguid][this.mguid]; }
|
4955
|
-
if (timers[guid]) { invoke(this.target, this.method, this.args); }
|
4956
|
-
delete timers[guid];
|
4957
|
-
}
|
4958
|
-
|
4959
|
-
function scheduleOnce(queue, target, method, args) {
|
4960
|
-
var tguid = Ember.guidFor(target),
|
4961
|
-
mguid = Ember.guidFor(method),
|
4962
|
-
onceTimers = run.autorun().onceTimers,
|
4963
|
-
guid = onceTimers[tguid] && onceTimers[tguid][mguid],
|
4964
|
-
timer;
|
4965
|
-
|
4966
|
-
if (guid && timers[guid]) {
|
4967
|
-
timers[guid].args = args; // replace args
|
4968
|
-
} else {
|
4969
|
-
timer = {
|
4970
|
-
target: target,
|
4971
|
-
method: method,
|
4972
|
-
args: args,
|
4973
|
-
tguid: tguid,
|
4974
|
-
mguid: mguid
|
4975
|
-
};
|
4976
|
-
|
4977
|
-
guid = Ember.guidFor(timer);
|
4978
|
-
timers[guid] = timer;
|
4979
|
-
if (!onceTimers[tguid]) { onceTimers[tguid] = {}; }
|
4980
|
-
onceTimers[tguid][mguid] = guid; // so it isn't scheduled more than once
|
4981
|
-
|
4982
|
-
run.schedule(queue, timer, invokeOnceTimer, guid, onceTimers);
|
4983
|
-
}
|
5265
|
+
Ember.run.later(myContext, function(){
|
5266
|
+
// code here will execute within a RunLoop in about 500ms with this == myContext
|
5267
|
+
}, 500);
|
5268
|
+
```
|
4984
5269
|
|
4985
|
-
|
4986
|
-
}
|
5270
|
+
@method later
|
5271
|
+
@param {Object} [target] target of method to invoke
|
5272
|
+
@param {Function|String} method The method to invoke.
|
5273
|
+
If you pass a string it will be resolved on the
|
5274
|
+
target at the time the method is invoked.
|
5275
|
+
@param {Object} [args*] Optional arguments to pass to the timeout.
|
5276
|
+
@param {Number} wait Number of milliseconds to wait.
|
5277
|
+
@return {String} a string you can use to cancel the timer in
|
5278
|
+
`Ember.run.cancel` later.
|
5279
|
+
*/
|
5280
|
+
Ember.run.later = function(target, method) {
|
5281
|
+
return backburner.later.apply(backburner, arguments);
|
5282
|
+
};
|
4987
5283
|
|
4988
5284
|
/**
|
4989
5285
|
Schedule a function to run one time during the current RunLoop. This is equivalent
|
@@ -4998,7 +5294,10 @@ function scheduleOnce(queue, target, method, args) {
|
|
4998
5294
|
@return {Object} timer
|
4999
5295
|
*/
|
5000
5296
|
Ember.run.once = function(target, method) {
|
5001
|
-
|
5297
|
+
checkAutoRun();
|
5298
|
+
var args = slice.call(arguments);
|
5299
|
+
args.unshift('actions');
|
5300
|
+
return backburner.scheduleOnce.apply(backburner, args);
|
5002
5301
|
};
|
5003
5302
|
|
5004
5303
|
/**
|
@@ -5046,12 +5345,13 @@ Ember.run.once = function(target, method) {
|
|
5046
5345
|
@return {Object} timer
|
5047
5346
|
*/
|
5048
5347
|
Ember.run.scheduleOnce = function(queue, target, method) {
|
5049
|
-
|
5348
|
+
checkAutoRun();
|
5349
|
+
return backburner.scheduleOnce.apply(backburner, arguments);
|
5050
5350
|
};
|
5051
5351
|
|
5052
5352
|
/**
|
5053
|
-
Schedules an item to run from within a separate run loop, after
|
5054
|
-
control has been returned to the system. This is equivalent to calling
|
5353
|
+
Schedules an item to run from within a separate run loop, after
|
5354
|
+
control has been returned to the system. This is equivalent to calling
|
5055
5355
|
`Ember.run.later` with a wait time of 1ms.
|
5056
5356
|
|
5057
5357
|
```javascript
|
@@ -5063,7 +5363,7 @@ Ember.run.scheduleOnce = function(queue, target, method) {
|
|
5063
5363
|
Multiple operations scheduled with `Ember.run.next` will coalesce
|
5064
5364
|
into the same later run loop, along with any other operations
|
5065
5365
|
scheduled by `Ember.run.later` that expire right around the same
|
5066
|
-
time that `Ember.run.next` operations will fire.
|
5366
|
+
time that `Ember.run.next` operations will fire.
|
5067
5367
|
|
5068
5368
|
Note that there are often alternatives to using `Ember.run.next`.
|
5069
5369
|
For instance, if you'd like to schedule an operation to happen
|
@@ -5089,13 +5389,13 @@ Ember.run.scheduleOnce = function(queue, target, method) {
|
|
5089
5389
|
|
5090
5390
|
One benefit of the above approach compared to using `Ember.run.next` is
|
5091
5391
|
that you will be able to perform DOM/CSS operations before unprocessed
|
5092
|
-
elements are rendered to the screen, which may prevent flickering or
|
5392
|
+
elements are rendered to the screen, which may prevent flickering or
|
5093
5393
|
other artifacts caused by delaying processing until after rendering.
|
5094
5394
|
|
5095
|
-
The other major benefit to the above approach is that `Ember.run.next`
|
5096
|
-
introduces an element of non-determinism, which can make things much
|
5097
|
-
harder to test, due to its reliance on `setTimeout`; it's much harder
|
5098
|
-
to guarantee the order of scheduled operations when they are scheduled
|
5395
|
+
The other major benefit to the above approach is that `Ember.run.next`
|
5396
|
+
introduces an element of non-determinism, which can make things much
|
5397
|
+
harder to test, due to its reliance on `setTimeout`; it's much harder
|
5398
|
+
to guarantee the order of scheduled operations when they are scheduled
|
5099
5399
|
outside of the current run loop, i.e. with `Ember.run.next`.
|
5100
5400
|
|
5101
5401
|
@method next
|
@@ -5108,8 +5408,8 @@ Ember.run.scheduleOnce = function(queue, target, method) {
|
|
5108
5408
|
*/
|
5109
5409
|
Ember.run.next = function() {
|
5110
5410
|
var args = slice.call(arguments);
|
5111
|
-
args.push(1);
|
5112
|
-
return
|
5411
|
+
args.push(1);
|
5412
|
+
return backburner.later.apply(backburner, args);
|
5113
5413
|
};
|
5114
5414
|
|
5115
5415
|
/**
|
@@ -5138,9 +5438,16 @@ Ember.run.next = function() {
|
|
5138
5438
|
@return {void}
|
5139
5439
|
*/
|
5140
5440
|
Ember.run.cancel = function(timer) {
|
5141
|
-
|
5441
|
+
return backburner.cancel(timer);
|
5142
5442
|
};
|
5143
5443
|
|
5444
|
+
// Make sure it's not an autorun during testing
|
5445
|
+
function checkAutoRun() {
|
5446
|
+
if (!Ember.run.currentRunLoop) {
|
5447
|
+
Ember.assert("You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run", !Ember.testing);
|
5448
|
+
}
|
5449
|
+
}
|
5450
|
+
|
5144
5451
|
})();
|
5145
5452
|
|
5146
5453
|
|
@@ -5425,7 +5732,7 @@ function mixinProperties(to, from) {
|
|
5425
5732
|
mixinProperties(Binding, {
|
5426
5733
|
|
5427
5734
|
/**
|
5428
|
-
See
|
5735
|
+
See `Ember.Binding.from`.
|
5429
5736
|
|
5430
5737
|
@method from
|
5431
5738
|
@static
|
@@ -5436,7 +5743,7 @@ mixinProperties(Binding, {
|
|
5436
5743
|
},
|
5437
5744
|
|
5438
5745
|
/**
|
5439
|
-
See
|
5746
|
+
See `Ember.Binding.to`.
|
5440
5747
|
|
5441
5748
|
@method to
|
5442
5749
|
@static
|
@@ -5453,7 +5760,7 @@ mixinProperties(Binding, {
|
|
5453
5760
|
This means that if you change the "to" side directly, the "from" side may have
|
5454
5761
|
a different value.
|
5455
5762
|
|
5456
|
-
See
|
5763
|
+
See `Binding.oneWay`.
|
5457
5764
|
|
5458
5765
|
@method oneWay
|
5459
5766
|
@param {String} from from path.
|
@@ -5514,7 +5821,7 @@ mixinProperties(Binding, {
|
|
5514
5821
|
|
5515
5822
|
You should consider using one way bindings anytime you have an object that
|
5516
5823
|
may be created frequently and you do not intend to change a property; only
|
5517
|
-
to monitor it for changes
|
5824
|
+
to monitor it for changes (such as in the example above).
|
5518
5825
|
|
5519
5826
|
## Adding Bindings Manually
|
5520
5827
|
|
@@ -5815,14 +6122,6 @@ function mergeMixins(mixins, m, descs, values, base, keys) {
|
|
5815
6122
|
}
|
5816
6123
|
}
|
5817
6124
|
|
5818
|
-
function writableReq(obj) {
|
5819
|
-
var m = Ember.meta(obj), req = m.required;
|
5820
|
-
if (!req || !m.hasOwnProperty('required')) {
|
5821
|
-
req = m.required = req ? o_create(req) : {};
|
5822
|
-
}
|
5823
|
-
return req;
|
5824
|
-
}
|
5825
|
-
|
5826
6125
|
var IS_BINDING = Ember.IS_BINDING = /^.+Binding$/;
|
5827
6126
|
|
5828
6127
|
function detectBinding(obj, key, value, m) {
|
@@ -6308,14 +6607,57 @@ Ember Metal
|
|
6308
6607
|
})();
|
6309
6608
|
|
6310
6609
|
(function() {
|
6311
|
-
define("rsvp",
|
6312
|
-
[],
|
6313
|
-
function() {
|
6610
|
+
define("rsvp/all",
|
6611
|
+
["rsvp/defer","exports"],
|
6612
|
+
function(__dependency1__, __exports__) {
|
6613
|
+
"use strict";
|
6614
|
+
var defer = __dependency1__.defer;
|
6615
|
+
|
6616
|
+
function all(promises) {
|
6617
|
+
var results = [], deferred = defer(), remaining = promises.length;
|
6618
|
+
|
6619
|
+
if (remaining === 0) {
|
6620
|
+
deferred.resolve([]);
|
6621
|
+
}
|
6622
|
+
|
6623
|
+
var resolver = function(index) {
|
6624
|
+
return function(value) {
|
6625
|
+
resolveAll(index, value);
|
6626
|
+
};
|
6627
|
+
};
|
6628
|
+
|
6629
|
+
var resolveAll = function(index, value) {
|
6630
|
+
results[index] = value;
|
6631
|
+
if (--remaining === 0) {
|
6632
|
+
deferred.resolve(results);
|
6633
|
+
}
|
6634
|
+
};
|
6635
|
+
|
6636
|
+
var rejectAll = function(error) {
|
6637
|
+
deferred.reject(error);
|
6638
|
+
};
|
6639
|
+
|
6640
|
+
for (var i = 0; i < promises.length; i++) {
|
6641
|
+
if (promises[i] && typeof promises[i].then === 'function') {
|
6642
|
+
promises[i].then(resolver(i), rejectAll);
|
6643
|
+
} else {
|
6644
|
+
resolveAll(i, promises[i]);
|
6645
|
+
}
|
6646
|
+
}
|
6647
|
+
return deferred.promise;
|
6648
|
+
}
|
6649
|
+
|
6650
|
+
__exports__.all = all;
|
6651
|
+
});
|
6652
|
+
|
6653
|
+
define("rsvp/async",
|
6654
|
+
["exports"],
|
6655
|
+
function(__exports__) {
|
6314
6656
|
"use strict";
|
6315
6657
|
var browserGlobal = (typeof window !== 'undefined') ? window : {};
|
6316
6658
|
|
6317
|
-
var
|
6318
|
-
var
|
6659
|
+
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
6660
|
+
var async;
|
6319
6661
|
|
6320
6662
|
if (typeof process !== 'undefined' &&
|
6321
6663
|
{}.toString.call(process) === '[object process]') {
|
@@ -6324,10 +6666,10 @@ define("rsvp",
|
|
6324
6666
|
callback.call(binding);
|
6325
6667
|
});
|
6326
6668
|
};
|
6327
|
-
} else if (
|
6669
|
+
} else if (BrowserMutationObserver) {
|
6328
6670
|
var queue = [];
|
6329
6671
|
|
6330
|
-
var observer = new
|
6672
|
+
var observer = new BrowserMutationObserver(function() {
|
6331
6673
|
var toProcess = queue.slice();
|
6332
6674
|
queue = [];
|
6333
6675
|
|
@@ -6358,6 +6700,47 @@ define("rsvp",
|
|
6358
6700
|
};
|
6359
6701
|
}
|
6360
6702
|
|
6703
|
+
|
6704
|
+
__exports__.async = async;
|
6705
|
+
});
|
6706
|
+
|
6707
|
+
define("rsvp/config",
|
6708
|
+
["rsvp/async","exports"],
|
6709
|
+
function(__dependency1__, __exports__) {
|
6710
|
+
"use strict";
|
6711
|
+
var async = __dependency1__.async;
|
6712
|
+
|
6713
|
+
var config = {};
|
6714
|
+
config.async = async;
|
6715
|
+
|
6716
|
+
__exports__.config = config;
|
6717
|
+
});
|
6718
|
+
|
6719
|
+
define("rsvp/defer",
|
6720
|
+
["rsvp/promise","exports"],
|
6721
|
+
function(__dependency1__, __exports__) {
|
6722
|
+
"use strict";
|
6723
|
+
var Promise = __dependency1__.Promise;
|
6724
|
+
|
6725
|
+
function defer() {
|
6726
|
+
var deferred = {};
|
6727
|
+
|
6728
|
+
var promise = new Promise(function(resolve, reject) {
|
6729
|
+
deferred.resolve = resolve;
|
6730
|
+
deferred.reject = reject;
|
6731
|
+
});
|
6732
|
+
|
6733
|
+
deferred.promise = promise;
|
6734
|
+
return deferred;
|
6735
|
+
}
|
6736
|
+
|
6737
|
+
__exports__.defer = defer;
|
6738
|
+
});
|
6739
|
+
|
6740
|
+
define("rsvp/events",
|
6741
|
+
["exports"],
|
6742
|
+
function(__exports__) {
|
6743
|
+
"use strict";
|
6361
6744
|
var Event = function(type, options) {
|
6362
6745
|
this.type = type;
|
6363
6746
|
|
@@ -6452,7 +6835,148 @@ define("rsvp",
|
|
6452
6835
|
}
|
6453
6836
|
};
|
6454
6837
|
|
6455
|
-
|
6838
|
+
|
6839
|
+
__exports__.EventTarget = EventTarget;
|
6840
|
+
});
|
6841
|
+
|
6842
|
+
define("rsvp/hash",
|
6843
|
+
["rsvp/defer","exports"],
|
6844
|
+
function(__dependency1__, __exports__) {
|
6845
|
+
"use strict";
|
6846
|
+
var defer = __dependency1__.defer;
|
6847
|
+
|
6848
|
+
function size(object) {
|
6849
|
+
var size = 0;
|
6850
|
+
|
6851
|
+
for (var prop in object) {
|
6852
|
+
size++;
|
6853
|
+
}
|
6854
|
+
|
6855
|
+
return size;
|
6856
|
+
}
|
6857
|
+
|
6858
|
+
function hash(promises) {
|
6859
|
+
var results = {}, deferred = defer(), remaining = size(promises);
|
6860
|
+
|
6861
|
+
if (remaining === 0) {
|
6862
|
+
deferred.resolve({});
|
6863
|
+
}
|
6864
|
+
|
6865
|
+
var resolver = function(prop) {
|
6866
|
+
return function(value) {
|
6867
|
+
resolveAll(prop, value);
|
6868
|
+
};
|
6869
|
+
};
|
6870
|
+
|
6871
|
+
var resolveAll = function(prop, value) {
|
6872
|
+
results[prop] = value;
|
6873
|
+
if (--remaining === 0) {
|
6874
|
+
deferred.resolve(results);
|
6875
|
+
}
|
6876
|
+
};
|
6877
|
+
|
6878
|
+
var rejectAll = function(error) {
|
6879
|
+
deferred.reject(error);
|
6880
|
+
};
|
6881
|
+
|
6882
|
+
for (var prop in promises) {
|
6883
|
+
if (promises[prop] && typeof promises[prop].then === 'function') {
|
6884
|
+
promises[prop].then(resolver(prop), rejectAll);
|
6885
|
+
} else {
|
6886
|
+
resolveAll(prop, promises[prop]);
|
6887
|
+
}
|
6888
|
+
}
|
6889
|
+
|
6890
|
+
return deferred.promise;
|
6891
|
+
}
|
6892
|
+
|
6893
|
+
__exports__.hash = hash;
|
6894
|
+
});
|
6895
|
+
|
6896
|
+
define("rsvp/node",
|
6897
|
+
["rsvp/promise","rsvp/all","exports"],
|
6898
|
+
function(__dependency1__, __dependency2__, __exports__) {
|
6899
|
+
"use strict";
|
6900
|
+
var Promise = __dependency1__.Promise;
|
6901
|
+
var all = __dependency2__.all;
|
6902
|
+
|
6903
|
+
function makeNodeCallbackFor(resolve, reject) {
|
6904
|
+
return function (error, value) {
|
6905
|
+
if (error) {
|
6906
|
+
reject(error);
|
6907
|
+
} else if (arguments.length > 2) {
|
6908
|
+
resolve(Array.prototype.slice.call(arguments, 1));
|
6909
|
+
} else {
|
6910
|
+
resolve(value);
|
6911
|
+
}
|
6912
|
+
};
|
6913
|
+
}
|
6914
|
+
|
6915
|
+
function denodeify(nodeFunc) {
|
6916
|
+
return function() {
|
6917
|
+
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
|
6918
|
+
|
6919
|
+
var promise = new Promise(function(nodeResolve, nodeReject) {
|
6920
|
+
resolve = nodeResolve;
|
6921
|
+
reject = nodeReject;
|
6922
|
+
});
|
6923
|
+
|
6924
|
+
all(nodeArgs).then(function(nodeArgs) {
|
6925
|
+
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
|
6926
|
+
|
6927
|
+
try {
|
6928
|
+
nodeFunc.apply(this, nodeArgs);
|
6929
|
+
} catch(e) {
|
6930
|
+
reject(e);
|
6931
|
+
}
|
6932
|
+
});
|
6933
|
+
|
6934
|
+
return promise;
|
6935
|
+
};
|
6936
|
+
}
|
6937
|
+
|
6938
|
+
__exports__.denodeify = denodeify;
|
6939
|
+
});
|
6940
|
+
|
6941
|
+
define("rsvp/promise",
|
6942
|
+
["rsvp/config","rsvp/events","exports"],
|
6943
|
+
function(__dependency1__, __dependency2__, __exports__) {
|
6944
|
+
"use strict";
|
6945
|
+
var config = __dependency1__.config;
|
6946
|
+
var EventTarget = __dependency2__.EventTarget;
|
6947
|
+
|
6948
|
+
function objectOrFunction(x) {
|
6949
|
+
return isFunction(x) || (typeof x === "object" && x !== null);
|
6950
|
+
}
|
6951
|
+
|
6952
|
+
function isFunction(x){
|
6953
|
+
return typeof x === "function";
|
6954
|
+
}
|
6955
|
+
|
6956
|
+
var Promise = function(resolver) {
|
6957
|
+
var promise = this,
|
6958
|
+
resolved = false;
|
6959
|
+
|
6960
|
+
if (typeof resolver !== 'function') {
|
6961
|
+
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
|
6962
|
+
}
|
6963
|
+
|
6964
|
+
if (!(promise instanceof Promise)) {
|
6965
|
+
return new Promise(resolver);
|
6966
|
+
}
|
6967
|
+
|
6968
|
+
var resolvePromise = function(value) {
|
6969
|
+
if (resolved) { return; }
|
6970
|
+
resolved = true;
|
6971
|
+
resolve(promise, value);
|
6972
|
+
};
|
6973
|
+
|
6974
|
+
var rejectPromise = function(value) {
|
6975
|
+
if (resolved) { return; }
|
6976
|
+
resolved = true;
|
6977
|
+
reject(promise, value);
|
6978
|
+
};
|
6979
|
+
|
6456
6980
|
this.on('promise:resolved', function(event) {
|
6457
6981
|
this.trigger('success', { detail: event.detail });
|
6458
6982
|
}, this);
|
@@ -6460,12 +6984,16 @@ define("rsvp",
|
|
6460
6984
|
this.on('promise:failed', function(event) {
|
6461
6985
|
this.trigger('error', { detail: event.detail });
|
6462
6986
|
}, this);
|
6463
|
-
};
|
6464
6987
|
|
6465
|
-
|
6988
|
+
try {
|
6989
|
+
resolver(resolvePromise, rejectPromise);
|
6990
|
+
} catch(e) {
|
6991
|
+
rejectPromise(e);
|
6992
|
+
}
|
6993
|
+
};
|
6466
6994
|
|
6467
6995
|
var invokeCallback = function(type, promise, callback, event) {
|
6468
|
-
var hasCallback =
|
6996
|
+
var hasCallback = isFunction(callback),
|
6469
6997
|
value, error, succeeded, failed;
|
6470
6998
|
|
6471
6999
|
if (hasCallback) {
|
@@ -6481,34 +7009,34 @@ define("rsvp",
|
|
6481
7009
|
succeeded = true;
|
6482
7010
|
}
|
6483
7011
|
|
6484
|
-
if (
|
6485
|
-
|
6486
|
-
promise.resolve(value);
|
6487
|
-
}, function(error) {
|
6488
|
-
promise.reject(error);
|
6489
|
-
});
|
7012
|
+
if (handleThenable(promise, value)) {
|
7013
|
+
return;
|
6490
7014
|
} else if (hasCallback && succeeded) {
|
6491
|
-
|
7015
|
+
resolve(promise, value);
|
6492
7016
|
} else if (failed) {
|
6493
|
-
|
6494
|
-
} else {
|
6495
|
-
promise
|
7017
|
+
reject(promise, error);
|
7018
|
+
} else if (type === 'resolve') {
|
7019
|
+
resolve(promise, value);
|
7020
|
+
} else if (type === 'reject') {
|
7021
|
+
reject(promise, value);
|
6496
7022
|
}
|
6497
7023
|
};
|
6498
7024
|
|
6499
7025
|
Promise.prototype = {
|
7026
|
+
constructor: Promise,
|
7027
|
+
|
6500
7028
|
then: function(done, fail) {
|
6501
|
-
var thenPromise = new Promise();
|
7029
|
+
var thenPromise = new Promise(function() {});
|
6502
7030
|
|
6503
|
-
if (this.
|
6504
|
-
|
6505
|
-
invokeCallback('resolve', thenPromise, done, { detail: this.
|
7031
|
+
if (this.isFulfilled) {
|
7032
|
+
config.async(function() {
|
7033
|
+
invokeCallback('resolve', thenPromise, done, { detail: this.fulfillmentValue });
|
6506
7034
|
}, this);
|
6507
7035
|
}
|
6508
7036
|
|
6509
7037
|
if (this.isRejected) {
|
6510
|
-
|
6511
|
-
invokeCallback('reject', thenPromise, fail, { detail: this.
|
7038
|
+
config.async(function() {
|
7039
|
+
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedReason });
|
6512
7040
|
}, this);
|
6513
7041
|
}
|
6514
7042
|
|
@@ -6521,75 +7049,162 @@ define("rsvp",
|
|
6521
7049
|
});
|
6522
7050
|
|
6523
7051
|
return thenPromise;
|
6524
|
-
}
|
7052
|
+
}
|
7053
|
+
};
|
6525
7054
|
|
6526
|
-
|
6527
|
-
resolve(this, value);
|
7055
|
+
EventTarget.mixin(Promise.prototype);
|
6528
7056
|
|
6529
|
-
|
6530
|
-
|
6531
|
-
|
7057
|
+
function resolve(promise, value) {
|
7058
|
+
if (promise === value) {
|
7059
|
+
fulfill(promise, value);
|
7060
|
+
} else if (!handleThenable(promise, value)) {
|
7061
|
+
fulfill(promise, value);
|
7062
|
+
}
|
7063
|
+
}
|
7064
|
+
|
7065
|
+
function handleThenable(promise, value) {
|
7066
|
+
var then = null;
|
6532
7067
|
|
6533
|
-
|
6534
|
-
|
7068
|
+
if (objectOrFunction(value)) {
|
7069
|
+
try {
|
7070
|
+
then = value.then;
|
7071
|
+
} catch(e) {
|
7072
|
+
reject(promise, e);
|
7073
|
+
return true;
|
7074
|
+
}
|
6535
7075
|
|
6536
|
-
|
6537
|
-
|
7076
|
+
if (isFunction(then)) {
|
7077
|
+
try {
|
7078
|
+
then.call(value, function(val) {
|
7079
|
+
if (value !== val) {
|
7080
|
+
resolve(promise, val);
|
7081
|
+
} else {
|
7082
|
+
fulfill(promise, val);
|
7083
|
+
}
|
7084
|
+
}, function(val) {
|
7085
|
+
reject(promise, val);
|
7086
|
+
});
|
7087
|
+
} catch (e) {
|
7088
|
+
reject(promise, e);
|
7089
|
+
}
|
7090
|
+
return true;
|
7091
|
+
}
|
6538
7092
|
}
|
6539
|
-
};
|
6540
7093
|
|
6541
|
-
|
6542
|
-
|
7094
|
+
return false;
|
7095
|
+
}
|
7096
|
+
|
7097
|
+
function fulfill(promise, value) {
|
7098
|
+
config.async(function() {
|
6543
7099
|
promise.trigger('promise:resolved', { detail: value });
|
6544
|
-
promise.
|
6545
|
-
promise.
|
7100
|
+
promise.isFulfilled = true;
|
7101
|
+
promise.fulfillmentValue = value;
|
6546
7102
|
});
|
6547
7103
|
}
|
6548
7104
|
|
6549
7105
|
function reject(promise, value) {
|
6550
|
-
|
7106
|
+
config.async(function() {
|
6551
7107
|
promise.trigger('promise:failed', { detail: value });
|
6552
7108
|
promise.isRejected = true;
|
6553
|
-
promise.
|
7109
|
+
promise.rejectedReason = value;
|
6554
7110
|
});
|
6555
7111
|
}
|
6556
7112
|
|
6557
|
-
function all(promises) {
|
6558
|
-
var i, results = [];
|
6559
|
-
var allPromise = new Promise();
|
6560
|
-
var remaining = promises.length;
|
6561
7113
|
|
6562
|
-
|
6563
|
-
|
6564
|
-
}
|
7114
|
+
__exports__.Promise = Promise;
|
7115
|
+
});
|
6565
7116
|
|
6566
|
-
|
6567
|
-
|
6568
|
-
|
6569
|
-
|
6570
|
-
|
7117
|
+
define("rsvp/reject",
|
7118
|
+
["rsvp/promise","exports"],
|
7119
|
+
function(__dependency1__, __exports__) {
|
7120
|
+
"use strict";
|
7121
|
+
var Promise = __dependency1__.Promise;
|
6571
7122
|
|
6572
|
-
var resolve = function(index, value) {
|
6573
|
-
results[index] = value;
|
6574
|
-
if (--remaining === 0) {
|
6575
|
-
allPromise.resolve(results);
|
6576
|
-
}
|
6577
|
-
};
|
6578
7123
|
|
6579
|
-
|
6580
|
-
|
6581
|
-
|
7124
|
+
function objectOrFunction(x) {
|
7125
|
+
return typeof x === "function" || (typeof x === "object" && x !== null);
|
7126
|
+
}
|
6582
7127
|
|
6583
|
-
|
6584
|
-
|
6585
|
-
|
6586
|
-
|
7128
|
+
|
7129
|
+
function reject(reason) {
|
7130
|
+
return new Promise(function (resolve, reject) {
|
7131
|
+
reject(reason);
|
7132
|
+
});
|
6587
7133
|
}
|
6588
7134
|
|
6589
|
-
EventTarget.mixin(Promise.prototype);
|
6590
7135
|
|
6591
|
-
|
6592
|
-
|
7136
|
+
__exports__.reject = reject;
|
7137
|
+
});
|
7138
|
+
|
7139
|
+
define("rsvp/resolve",
|
7140
|
+
["rsvp/promise","exports"],
|
7141
|
+
function(__dependency1__, __exports__) {
|
7142
|
+
"use strict";
|
7143
|
+
var Promise = __dependency1__.Promise;
|
7144
|
+
|
7145
|
+
|
7146
|
+
function objectOrFunction(x) {
|
7147
|
+
return typeof x === "function" || (typeof x === "object" && x !== null);
|
7148
|
+
}
|
7149
|
+
|
7150
|
+
function resolve(thenable){
|
7151
|
+
var promise = new Promise(function(resolve, reject){
|
7152
|
+
var then;
|
7153
|
+
|
7154
|
+
try {
|
7155
|
+
if ( objectOrFunction(thenable) ) {
|
7156
|
+
then = thenable.then;
|
7157
|
+
|
7158
|
+
if (typeof then === "function") {
|
7159
|
+
then.call(thenable, resolve, reject);
|
7160
|
+
} else {
|
7161
|
+
resolve(thenable);
|
7162
|
+
}
|
7163
|
+
|
7164
|
+
} else {
|
7165
|
+
resolve(thenable);
|
7166
|
+
}
|
7167
|
+
|
7168
|
+
} catch(error) {
|
7169
|
+
reject(error);
|
7170
|
+
}
|
7171
|
+
});
|
7172
|
+
|
7173
|
+
return promise;
|
7174
|
+
}
|
7175
|
+
|
7176
|
+
|
7177
|
+
__exports__.resolve = resolve;
|
7178
|
+
});
|
7179
|
+
|
7180
|
+
define("rsvp",
|
7181
|
+
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
|
7182
|
+
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
|
7183
|
+
"use strict";
|
7184
|
+
var EventTarget = __dependency1__.EventTarget;
|
7185
|
+
var Promise = __dependency2__.Promise;
|
7186
|
+
var denodeify = __dependency3__.denodeify;
|
7187
|
+
var all = __dependency4__.all;
|
7188
|
+
var hash = __dependency5__.hash;
|
7189
|
+
var defer = __dependency6__.defer;
|
7190
|
+
var config = __dependency7__.config;
|
7191
|
+
var resolve = __dependency8__.resolve;
|
7192
|
+
var reject = __dependency9__.reject;
|
7193
|
+
|
7194
|
+
function configure(name, value) {
|
7195
|
+
config[name] = value;
|
7196
|
+
}
|
7197
|
+
|
7198
|
+
|
7199
|
+
__exports__.Promise = Promise;
|
7200
|
+
__exports__.EventTarget = EventTarget;
|
7201
|
+
__exports__.all = all;
|
7202
|
+
__exports__.hash = hash;
|
7203
|
+
__exports__.defer = defer;
|
7204
|
+
__exports__.denodeify = denodeify;
|
7205
|
+
__exports__.configure = configure;
|
7206
|
+
__exports__.resolve = resolve;
|
7207
|
+
__exports__.reject = reject;
|
6593
7208
|
});
|
6594
7209
|
|
6595
7210
|
})();
|
@@ -6765,10 +7380,6 @@ define("container",
|
|
6765
7380
|
|
6766
7381
|
this.children = [];
|
6767
7382
|
|
6768
|
-
eachDestroyable(this, function(item) {
|
6769
|
-
item.isDestroying = true;
|
6770
|
-
});
|
6771
|
-
|
6772
7383
|
eachDestroyable(this, function(item) {
|
6773
7384
|
item.destroy();
|
6774
7385
|
});
|
@@ -7140,10 +7751,15 @@ Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
|
|
7140
7751
|
*/
|
7141
7752
|
Ember.keys = Object.keys;
|
7142
7753
|
|
7143
|
-
if (!Ember.keys) {
|
7754
|
+
if (!Ember.keys || Ember.create.isSimulated) {
|
7144
7755
|
Ember.keys = function(obj) {
|
7145
7756
|
var ret = [];
|
7146
7757
|
for(var key in obj) {
|
7758
|
+
// Prevents browsers that don't respect non-enumerability from
|
7759
|
+
// copying internal Ember properties
|
7760
|
+
if (key.substring(0,2) === '__') continue;
|
7761
|
+
if (key === '_super') continue;
|
7762
|
+
|
7147
7763
|
if (obj.hasOwnProperty(key)) { ret.push(key); }
|
7148
7764
|
}
|
7149
7765
|
return ret;
|
@@ -7165,7 +7781,7 @@ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'n
|
|
7165
7781
|
@constructor
|
7166
7782
|
*/
|
7167
7783
|
Ember.Error = function() {
|
7168
|
-
var tmp = Error.
|
7784
|
+
var tmp = Error.apply(this, arguments);
|
7169
7785
|
|
7170
7786
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
7171
7787
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
@@ -7427,10 +8043,12 @@ Ember.String = {
|
|
7427
8043
|
/**
|
7428
8044
|
Returns the Capitalized form of a string
|
7429
8045
|
|
7430
|
-
|
7431
|
-
|
7432
|
-
|
7433
|
-
|
8046
|
+
```javascript
|
8047
|
+
'innerHTML'.capitalize() // 'InnerHTML'
|
8048
|
+
'action_name'.capitalize() // 'Action_name'
|
8049
|
+
'css-class-name'.capitalize() // 'Css-class-name'
|
8050
|
+
'my favorite items'.capitalize() // 'My favorite items'
|
8051
|
+
```
|
7434
8052
|
|
7435
8053
|
@method capitalize
|
7436
8054
|
@param {String} str
|
@@ -7467,7 +8085,7 @@ var fmt = Ember.String.fmt,
|
|
7467
8085
|
if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
7468
8086
|
|
7469
8087
|
/**
|
7470
|
-
See
|
8088
|
+
See `Ember.String.fmt`.
|
7471
8089
|
|
7472
8090
|
@method fmt
|
7473
8091
|
@for String
|
@@ -7477,7 +8095,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7477
8095
|
};
|
7478
8096
|
|
7479
8097
|
/**
|
7480
|
-
See
|
8098
|
+
See `Ember.String.w`.
|
7481
8099
|
|
7482
8100
|
@method w
|
7483
8101
|
@for String
|
@@ -7487,7 +8105,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7487
8105
|
};
|
7488
8106
|
|
7489
8107
|
/**
|
7490
|
-
See
|
8108
|
+
See `Ember.String.loc`.
|
7491
8109
|
|
7492
8110
|
@method loc
|
7493
8111
|
@for String
|
@@ -7497,7 +8115,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7497
8115
|
};
|
7498
8116
|
|
7499
8117
|
/**
|
7500
|
-
See
|
8118
|
+
See `Ember.String.camelize`.
|
7501
8119
|
|
7502
8120
|
@method camelize
|
7503
8121
|
@for String
|
@@ -7507,7 +8125,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7507
8125
|
};
|
7508
8126
|
|
7509
8127
|
/**
|
7510
|
-
See
|
8128
|
+
See `Ember.String.decamelize`.
|
7511
8129
|
|
7512
8130
|
@method decamelize
|
7513
8131
|
@for String
|
@@ -7517,7 +8135,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7517
8135
|
};
|
7518
8136
|
|
7519
8137
|
/**
|
7520
|
-
See
|
8138
|
+
See `Ember.String.dasherize`.
|
7521
8139
|
|
7522
8140
|
@method dasherize
|
7523
8141
|
@for String
|
@@ -7527,7 +8145,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7527
8145
|
};
|
7528
8146
|
|
7529
8147
|
/**
|
7530
|
-
See
|
8148
|
+
See `Ember.String.underscore`.
|
7531
8149
|
|
7532
8150
|
@method underscore
|
7533
8151
|
@for String
|
@@ -7537,7 +8155,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7537
8155
|
};
|
7538
8156
|
|
7539
8157
|
/**
|
7540
|
-
See
|
8158
|
+
See `Ember.String.classify`.
|
7541
8159
|
|
7542
8160
|
@method classify
|
7543
8161
|
@for String
|
@@ -7547,7 +8165,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
|
|
7547
8165
|
};
|
7548
8166
|
|
7549
8167
|
/**
|
7550
|
-
See
|
8168
|
+
See `Ember.String.capitalize`.
|
7551
8169
|
|
7552
8170
|
@method capitalize
|
7553
8171
|
@for String
|
@@ -7623,8 +8241,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {
|
|
7623
8241
|
will instead clear the cache so that it is updated when the next `get`
|
7624
8242
|
is called on the property.
|
7625
8243
|
|
7626
|
-
See
|
7627
|
-
{{#crossLink "Ember/computed"}}{{/crossLink}}
|
8244
|
+
See `Ember.ComputedProperty`, `Ember.computed`.
|
7628
8245
|
|
7629
8246
|
@method property
|
7630
8247
|
@for Function
|
@@ -7651,7 +8268,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {
|
|
7651
8268
|
});
|
7652
8269
|
```
|
7653
8270
|
|
7654
|
-
See
|
8271
|
+
See `Ember.Observable.observes`.
|
7655
8272
|
|
7656
8273
|
@method observes
|
7657
8274
|
@for Function
|
@@ -7678,7 +8295,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {
|
|
7678
8295
|
});
|
7679
8296
|
```
|
7680
8297
|
|
7681
|
-
See
|
8298
|
+
See `Ember.Observable.observesBefore`.
|
7682
8299
|
|
7683
8300
|
@method observesBefore
|
7684
8301
|
@for Function
|
@@ -8575,9 +9192,7 @@ Ember.Enumerable = Ember.Mixin.create({
|
|
8575
9192
|
// HELPERS
|
8576
9193
|
//
|
8577
9194
|
|
8578
|
-
var get = Ember.get, set = Ember.set, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
|
8579
|
-
|
8580
|
-
function none(obj) { return obj===null || obj===undefined; }
|
9195
|
+
var get = Ember.get, set = Ember.set, isNone = Ember.isNone, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
|
8581
9196
|
|
8582
9197
|
// ..........................................................
|
8583
9198
|
// ARRAY
|
@@ -8600,7 +9215,7 @@ function none(obj) { return obj===null || obj===undefined; }
|
|
8600
9215
|
|
8601
9216
|
You can use the methods defined in this module to access and modify array
|
8602
9217
|
contents in a KVO-friendly way. You can also be notified whenever the
|
8603
|
-
membership
|
9218
|
+
membership of an array changes by changing the syntax of the property to
|
8604
9219
|
`.observes('*myProperty.[]')`.
|
8605
9220
|
|
8606
9221
|
To support `Ember.Array` in your own class, you must override two
|
@@ -8617,9 +9232,6 @@ function none(obj) { return obj===null || obj===undefined; }
|
|
8617
9232
|
*/
|
8618
9233
|
Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.prototype */ {
|
8619
9234
|
|
8620
|
-
// compatibility
|
8621
|
-
isSCArray: true,
|
8622
|
-
|
8623
9235
|
/**
|
8624
9236
|
Your array must support the `length` property. Your replace methods should
|
8625
9237
|
set this property whenever it changes.
|
@@ -8727,8 +9339,8 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8727
9339
|
slice: function(beginIndex, endIndex) {
|
8728
9340
|
var ret = Ember.A([]);
|
8729
9341
|
var length = get(this, 'length') ;
|
8730
|
-
if (
|
8731
|
-
if (
|
9342
|
+
if (isNone(beginIndex)) beginIndex = 0 ;
|
9343
|
+
if (isNone(endIndex) || (endIndex > length)) endIndex = length ;
|
8732
9344
|
|
8733
9345
|
if (beginIndex < 0) beginIndex = length + beginIndex;
|
8734
9346
|
if (endIndex < 0) endIndex = length + endIndex;
|
@@ -8888,7 +9500,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8888
9500
|
@param {Number} startIdx The starting index in the array that will change.
|
8889
9501
|
@param {Number} removeAmt The number of items that will be removed. If you
|
8890
9502
|
pass `null` assumes 0
|
8891
|
-
@param {Number} addAmt The number of items that will be added
|
9503
|
+
@param {Number} addAmt The number of items that will be added. If you
|
8892
9504
|
pass `null` assumes 0.
|
8893
9505
|
@return {Ember.Array} receiver
|
8894
9506
|
*/
|
@@ -8922,6 +9534,20 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8922
9534
|
return this;
|
8923
9535
|
},
|
8924
9536
|
|
9537
|
+
/**
|
9538
|
+
If you are implementing an object that supports `Ember.Array`, call this
|
9539
|
+
method just after the array content changes to notify any observers and
|
9540
|
+
invalidate any related properties. Pass the starting index of the change
|
9541
|
+
as well as a delta of the amounts to change.
|
9542
|
+
|
9543
|
+
@method arrayContentDidChange
|
9544
|
+
@param {Number} startIdx The starting index in the array that did change.
|
9545
|
+
@param {Number} removeAmt The number of items that were removed. If you
|
9546
|
+
pass `null` assumes 0
|
9547
|
+
@param {Number} addAmt The number of items that were added. If you
|
9548
|
+
pass `null` assumes 0.
|
9549
|
+
@return {Ember.Array} receiver
|
9550
|
+
*/
|
8925
9551
|
arrayContentDidChange: function(startIdx, removeAmt, addAmt) {
|
8926
9552
|
|
8927
9553
|
// if no args are passed assume everything changes
|
@@ -9062,8 +9688,7 @@ var get = Ember.get, set = Ember.set;
|
|
9062
9688
|
@extends Ember.Mixin
|
9063
9689
|
@since Ember 0.9
|
9064
9690
|
*/
|
9065
|
-
Ember.Copyable = Ember.Mixin.create(
|
9066
|
-
/** @scope Ember.Copyable.prototype */ {
|
9691
|
+
Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
|
9067
9692
|
|
9068
9693
|
/**
|
9069
9694
|
Override to return a copy of the receiver. Default implementation raises
|
@@ -9168,8 +9793,7 @@ var get = Ember.get, set = Ember.set;
|
|
9168
9793
|
@extends Ember.Mixin
|
9169
9794
|
@since Ember 0.9
|
9170
9795
|
*/
|
9171
|
-
Ember.Freezable = Ember.Mixin.create(
|
9172
|
-
/** @scope Ember.Freezable.prototype */ {
|
9796
|
+
Ember.Freezable = Ember.Mixin.create(/** @scope Ember.Freezable.prototype */ {
|
9173
9797
|
|
9174
9798
|
/**
|
9175
9799
|
Set to `true` when the object is frozen. Use this property to detect
|
@@ -9350,8 +9974,7 @@ var get = Ember.get, set = Ember.set;
|
|
9350
9974
|
@uses Ember.Array
|
9351
9975
|
@uses Ember.MutableEnumerable
|
9352
9976
|
*/
|
9353
|
-
Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable
|
9354
|
-
/** @scope Ember.MutableArray.prototype */ {
|
9977
|
+
Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/** @scope Ember.MutableArray.prototype */ {
|
9355
9978
|
|
9356
9979
|
/**
|
9357
9980
|
__Required.__ You must implement this method to apply this mixin.
|
@@ -9622,7 +10245,6 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
9622
10245
|
|
9623
10246
|
});
|
9624
10247
|
|
9625
|
-
|
9626
10248
|
})();
|
9627
10249
|
|
9628
10250
|
|
@@ -9670,7 +10292,7 @@ var get = Ember.get, set = Ember.set;
|
|
9670
10292
|
For example:
|
9671
10293
|
|
9672
10294
|
```javascript
|
9673
|
-
Ember.Object.
|
10295
|
+
Ember.Object.extend({
|
9674
10296
|
valueObserver: function() {
|
9675
10297
|
// Executes whenever the "value" property changes
|
9676
10298
|
}.observes('value')
|
@@ -9689,8 +10311,8 @@ var get = Ember.get, set = Ember.set;
|
|
9689
10311
|
object.addObserver('propertyKey', targetObject, targetAction)
|
9690
10312
|
```
|
9691
10313
|
|
9692
|
-
This will call the `targetAction` method on the `targetObject`
|
9693
|
-
|
10314
|
+
This will call the `targetAction` method on the `targetObject` whenever
|
10315
|
+
the value of the `propertyKey` changes.
|
9694
10316
|
|
9695
10317
|
Note that if `propertyKey` is a computed property, the observer will be
|
9696
10318
|
called when any of the property dependencies are changed, even if the
|
@@ -9950,8 +10572,8 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9950
10572
|
|
9951
10573
|
This is the core method used to register an observer for a property.
|
9952
10574
|
|
9953
|
-
Once you call this method,
|
9954
|
-
will be notified. Note that the observers are triggered
|
10575
|
+
Once you call this method, any time the key's value is set, your observer
|
10576
|
+
will be notified. Note that the observers are triggered any time the
|
9955
10577
|
value is set, regardless of whether it has actually changed. Your
|
9956
10578
|
observer should be prepared to handle that.
|
9957
10579
|
|
@@ -10076,11 +10698,11 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
10076
10698
|
|
10077
10699
|
@method incrementProperty
|
10078
10700
|
@param {String} keyName The name of the property to increment
|
10079
|
-
@param {
|
10080
|
-
@return {
|
10701
|
+
@param {Number} increment The amount to increment by. Defaults to 1
|
10702
|
+
@return {Number} The new property value
|
10081
10703
|
*/
|
10082
10704
|
incrementProperty: function(keyName, increment) {
|
10083
|
-
if (
|
10705
|
+
if (Ember.isNone(increment)) { increment = 1; }
|
10084
10706
|
set(this, keyName, (get(this, keyName) || 0)+increment);
|
10085
10707
|
return get(this, keyName);
|
10086
10708
|
},
|
@@ -10095,12 +10717,12 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
10095
10717
|
|
10096
10718
|
@method decrementProperty
|
10097
10719
|
@param {String} keyName The name of the property to decrement
|
10098
|
-
@param {
|
10099
|
-
@return {
|
10720
|
+
@param {Number} decrement The amount to decrement by. Defaults to 1
|
10721
|
+
@return {Number} The new property value
|
10100
10722
|
*/
|
10101
|
-
decrementProperty: function(keyName,
|
10102
|
-
if (
|
10103
|
-
set(this, keyName, (get(this, keyName) || 0)-
|
10723
|
+
decrementProperty: function(keyName, decrement) {
|
10724
|
+
if (Ember.isNone(decrement)) { decrement = 1; }
|
10725
|
+
set(this, keyName, (get(this, keyName) || 0)-decrement);
|
10104
10726
|
return get(this, keyName);
|
10105
10727
|
},
|
10106
10728
|
|
@@ -10109,7 +10731,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
10109
10731
|
current value.
|
10110
10732
|
|
10111
10733
|
```javascript
|
10112
|
-
starship.toggleProperty('
|
10734
|
+
starship.toggleProperty('warpDriveEngaged');
|
10113
10735
|
```
|
10114
10736
|
|
10115
10737
|
@method toggleProperty
|
@@ -10141,7 +10763,6 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
10141
10763
|
}
|
10142
10764
|
});
|
10143
10765
|
|
10144
|
-
|
10145
10766
|
})();
|
10146
10767
|
|
10147
10768
|
|
@@ -10436,9 +11057,9 @@ Ember.Evented = Ember.Mixin.create({
|
|
10436
11057
|
(function() {
|
10437
11058
|
var RSVP = requireModule("rsvp");
|
10438
11059
|
|
10439
|
-
RSVP.async
|
11060
|
+
RSVP.configure('async', function(callback, binding) {
|
10440
11061
|
Ember.run.schedule('actions', binding, callback);
|
10441
|
-
};
|
11062
|
+
});
|
10442
11063
|
|
10443
11064
|
/**
|
10444
11065
|
@module ember
|
@@ -10460,9 +11081,22 @@ Ember.DeferredMixin = Ember.Mixin.create({
|
|
10460
11081
|
@param {Function} doneCallback a callback function to be called when done
|
10461
11082
|
@param {Function} failCallback a callback function to be called when failed
|
10462
11083
|
*/
|
10463
|
-
then: function(
|
10464
|
-
var promise
|
10465
|
-
|
11084
|
+
then: function(resolve, reject) {
|
11085
|
+
var deferred, promise, entity;
|
11086
|
+
|
11087
|
+
entity = this;
|
11088
|
+
deferred = get(this, '_deferred');
|
11089
|
+
promise = deferred.promise;
|
11090
|
+
|
11091
|
+
function fulfillmentHandler(fulfillment) {
|
11092
|
+
if (fulfillment === promise) {
|
11093
|
+
return resolve(entity);
|
11094
|
+
} else {
|
11095
|
+
return resolve(fulfillment);
|
11096
|
+
}
|
11097
|
+
}
|
11098
|
+
|
11099
|
+
return promise.then(resolve && fulfillmentHandler, reject);
|
10466
11100
|
},
|
10467
11101
|
|
10468
11102
|
/**
|
@@ -10471,7 +11105,16 @@ Ember.DeferredMixin = Ember.Mixin.create({
|
|
10471
11105
|
@method resolve
|
10472
11106
|
*/
|
10473
11107
|
resolve: function(value) {
|
10474
|
-
|
11108
|
+
var deferred, promise;
|
11109
|
+
|
11110
|
+
deferred = get(this, '_deferred');
|
11111
|
+
promise = deferred.promise;
|
11112
|
+
|
11113
|
+
if (value === this){
|
11114
|
+
deferred.resolve(promise);
|
11115
|
+
} else {
|
11116
|
+
deferred.resolve(value);
|
11117
|
+
}
|
10475
11118
|
},
|
10476
11119
|
|
10477
11120
|
/**
|
@@ -10480,11 +11123,11 @@ Ember.DeferredMixin = Ember.Mixin.create({
|
|
10480
11123
|
@method reject
|
10481
11124
|
*/
|
10482
11125
|
reject: function(value) {
|
10483
|
-
get(this, '
|
11126
|
+
get(this, '_deferred').reject(value);
|
10484
11127
|
},
|
10485
11128
|
|
10486
|
-
|
10487
|
-
return
|
11129
|
+
_deferred: Ember.computed(function() {
|
11130
|
+
return RSVP.defer();
|
10488
11131
|
})
|
10489
11132
|
});
|
10490
11133
|
|
@@ -10797,21 +11440,23 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
10797
11440
|
raised.
|
10798
11441
|
|
10799
11442
|
Note that destruction is scheduled for the end of the run loop and does not
|
10800
|
-
happen immediately.
|
11443
|
+
happen immediately. It will set an isDestroying flag immediately.
|
10801
11444
|
|
10802
11445
|
@method destroy
|
10803
11446
|
@return {Ember.Object} receiver
|
10804
11447
|
*/
|
10805
11448
|
destroy: function() {
|
10806
|
-
if (this.
|
10807
|
-
|
11449
|
+
if (this.isDestroying) { return; }
|
10808
11450
|
this.isDestroying = true;
|
10809
|
-
this._didCallDestroy = true;
|
10810
11451
|
|
11452
|
+
schedule('actions', this, this.willDestroy);
|
10811
11453
|
schedule('destroy', this, this._scheduledDestroy);
|
10812
11454
|
return this;
|
10813
11455
|
},
|
10814
11456
|
|
11457
|
+
/**
|
11458
|
+
Override to implement teardown.
|
11459
|
+
*/
|
10815
11460
|
willDestroy: Ember.K,
|
10816
11461
|
|
10817
11462
|
/**
|
@@ -10823,10 +11468,9 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
10823
11468
|
@method _scheduledDestroy
|
10824
11469
|
*/
|
10825
11470
|
_scheduledDestroy: function() {
|
10826
|
-
if (this.
|
11471
|
+
if (this.isDestroyed) { return; }
|
10827
11472
|
destroy(this);
|
10828
11473
|
this.isDestroyed = true;
|
10829
|
-
if (this.didDestroy) { this.didDestroy(); }
|
10830
11474
|
},
|
10831
11475
|
|
10832
11476
|
bind: function(to, from) {
|
@@ -11317,8 +11961,7 @@ var get = Ember.get, set = Ember.set;
|
|
11317
11961
|
@extends Ember.Object
|
11318
11962
|
@uses Ember.MutableArray
|
11319
11963
|
*/
|
11320
|
-
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray
|
11321
|
-
/** @scope Ember.ArrayProxy.prototype */ {
|
11964
|
+
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.ArrayProxy.prototype */ {
|
11322
11965
|
|
11323
11966
|
/**
|
11324
11967
|
The content array. Must be an object that implements `Ember.Array` and/or
|
@@ -11594,7 +12237,6 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
|
11594
12237
|
}
|
11595
12238
|
});
|
11596
12239
|
|
11597
|
-
|
11598
12240
|
})();
|
11599
12241
|
|
11600
12242
|
|
@@ -11694,8 +12336,7 @@ function contentPropertyDidChange(content, contentKey) {
|
|
11694
12336
|
@namespace Ember
|
11695
12337
|
@extends Ember.Object
|
11696
12338
|
*/
|
11697
|
-
Ember.ObjectProxy = Ember.Object.extend(
|
11698
|
-
/** @scope Ember.ObjectProxy.prototype */ {
|
12339
|
+
Ember.ObjectProxy = Ember.Object.extend(/** @scope Ember.ObjectProxy.prototype */ {
|
11699
12340
|
/**
|
11700
12341
|
The object whose properties will be forwarded.
|
11701
12342
|
|
@@ -12133,7 +12774,7 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Array) {
|
|
12133
12774
|
@submodule ember-runtime
|
12134
12775
|
*/
|
12135
12776
|
|
12136
|
-
var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor,
|
12777
|
+
var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor, isNone = Ember.isNone, fmt = Ember.String.fmt;
|
12137
12778
|
|
12138
12779
|
/**
|
12139
12780
|
An unordered collection of objects.
|
@@ -12491,7 +13132,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
12491
13132
|
// implements Ember.MutableEnumerable
|
12492
13133
|
addObject: function(obj) {
|
12493
13134
|
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
12494
|
-
if (
|
13135
|
+
if (isNone(obj)) return this; // nothing to do
|
12495
13136
|
|
12496
13137
|
var guid = guidFor(obj),
|
12497
13138
|
idx = this[guid],
|
@@ -12519,7 +13160,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
12519
13160
|
// implements Ember.MutableEnumerable
|
12520
13161
|
removeObject: function(obj) {
|
12521
13162
|
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
12522
|
-
if (
|
13163
|
+
if (isNone(obj)) return this; // nothing to do
|
12523
13164
|
|
12524
13165
|
var guid = guidFor(obj),
|
12525
13166
|
idx = this[guid],
|
@@ -12594,7 +13235,7 @@ Deferred.reopenClass({
|
|
12594
13235
|
promise: function(callback, binding) {
|
12595
13236
|
var deferred = Deferred.create();
|
12596
13237
|
callback.call(binding, deferred);
|
12597
|
-
return
|
13238
|
+
return deferred;
|
12598
13239
|
}
|
12599
13240
|
});
|
12600
13241
|
|
@@ -12605,6 +13246,8 @@ Ember.Deferred = Deferred;
|
|
12605
13246
|
|
12606
13247
|
|
12607
13248
|
(function() {
|
13249
|
+
var forEach = Ember.ArrayPolyfills.forEach;
|
13250
|
+
|
12608
13251
|
/**
|
12609
13252
|
@module ember
|
12610
13253
|
@submodule ember-runtime
|
@@ -12637,12 +13280,10 @@ Ember.onLoad = function(name, callback) {
|
|
12637
13280
|
@param object {Object} object to pass to callbacks
|
12638
13281
|
*/
|
12639
13282
|
Ember.runLoadHooks = function(name, object) {
|
12640
|
-
var hooks;
|
12641
|
-
|
12642
13283
|
loaded[name] = object;
|
12643
13284
|
|
12644
|
-
if (
|
12645
|
-
loadHooks[name]
|
13285
|
+
if (loadHooks[name]) {
|
13286
|
+
forEach.call(loadHooks[name], function(callback) {
|
12646
13287
|
callback(object);
|
12647
13288
|
});
|
12648
13289
|
}
|
@@ -12716,6 +13357,8 @@ Ember.ControllerMixin = Ember.Mixin.create({
|
|
12716
13357
|
|
12717
13358
|
container: null,
|
12718
13359
|
|
13360
|
+
parentController: null,
|
13361
|
+
|
12719
13362
|
store: null,
|
12720
13363
|
|
12721
13364
|
model: Ember.computed.alias('content'),
|
@@ -13058,6 +13701,10 @@ var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach,
|
|
13058
13701
|
});
|
13059
13702
|
```
|
13060
13703
|
|
13704
|
+
The itemController instances will have a `parentController` property set to
|
13705
|
+
either the the `parentController` property of the `ArrayController`
|
13706
|
+
or to the `ArrayController` instance itself.
|
13707
|
+
|
13061
13708
|
@class ArrayController
|
13062
13709
|
@namespace Ember
|
13063
13710
|
@extends Ember.ArrayProxy
|
@@ -13168,6 +13815,7 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
|
13168
13815
|
}
|
13169
13816
|
|
13170
13817
|
subController.set('target', this);
|
13818
|
+
subController.set('parentController', get(this, 'parentController') || this);
|
13171
13819
|
subController.set('content', object);
|
13172
13820
|
|
13173
13821
|
return subController;
|