ember-source 1.0.0.rc3.5 → 1.0.0.rc4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/dist/ember-runtime.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');
|
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.
|
3777
3804
|
|
3778
|
-
|
3779
|
-
|
3780
|
-
}.property('firstName', 'lastName')
|
3781
|
-
|
3782
|
-
initials: function() {
|
3783
|
-
return this.get('firstName')[0] + this.get('lastName')[0];
|
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
|
-
|
4567
|
-
|
4756
|
+
hasTimers: function() {
|
4757
|
+
return !!timers.length || autorun;
|
4758
|
+
},
|
4759
|
+
|
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
|
+
};
|
4568
4773
|
|
4569
|
-
|
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
|
+
}
|
4606
4912
|
|
4607
|
-
|
4608
|
-
|
4609
|
-
queueName = queueNames[idx];
|
4610
|
-
queue = this._queues && this._queues[queueName];
|
4611
|
-
delete this._queues[queueName];
|
4913
|
+
__exports__.DeferredActionQueues = DeferredActionQueues;
|
4914
|
+
});
|
4612
4915
|
|
4613
|
-
|
4614
|
-
|
4615
|
-
|
4616
|
-
|
4617
|
-
|
4618
|
-
|
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
|
+
},
|
4619
4938
|
|
4620
|
-
|
4939
|
+
pushUnique: function(target, method, args, stack) {
|
4940
|
+
var queue = this._queue, currentTarget, currentMethod, i, l;
|
4621
4941
|
|
4622
|
-
|
4942
|
+
for (i = 0, l = queue.length; i < l; i += 4) {
|
4943
|
+
currentTarget = queue[i];
|
4944
|
+
currentMethod = queue[i+1];
|
4623
4945
|
|
4624
|
-
|
4625
|
-
|
4626
|
-
|
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
|
4627
4950
|
}
|
4628
4951
|
}
|
4629
4952
|
|
4630
|
-
|
4631
|
-
|
4632
|
-
|
4633
|
-
|
4634
|
-
|
4635
|
-
|
4953
|
+
this._queue.push(target, method, args, stack);
|
4954
|
+
return {queue: this, target: target, method: method};
|
4955
|
+
},
|
4956
|
+
|
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);
|
4975
|
+
} else {
|
4976
|
+
method.call(target);
|
4636
4977
|
}
|
4637
4978
|
}
|
4979
|
+
if (l && after) { after(); }
|
4638
4980
|
|
4639
|
-
|
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;
|
4987
|
+
}
|
4988
|
+
},
|
4989
|
+
|
4990
|
+
cancel: function(actionToCancel) {
|
4991
|
+
var queue = this._queue, currentTarget, currentMethod, i, l;
|
4992
|
+
|
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
|
+
})();
|
4642
5009
|
|
4643
|
-
return this;
|
4644
|
-
}
|
4645
5010
|
|
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;
|