Revision 326c136c
b/snf-cyclades-app/synnefo/ui/new_ui/ui/javascripts/vendor/ember.js | ||
---|---|---|
1 |
// ==========================================================================
|
|
2 |
// Project: Ember - JavaScript Application Framework
|
|
3 |
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors
|
|
4 |
// Portions Copyright 2006-2011 Strobe Inc.
|
|
5 |
// Portions Copyright 2008-2011 Apple Inc. All rights reserved.
|
|
6 |
// License: Licensed under MIT license
|
|
7 |
// See https://raw.github.com/emberjs/ember.js/master/LICENSE
|
|
8 |
// ==========================================================================
|
|
9 |
|
|
1 |
/*!
|
|
2 |
* @overview Ember - JavaScript Application Framework
|
|
3 |
* @copyright Copyright 2011-2014 Tilde Inc. and contributors
|
|
4 |
* Portions Copyright 2006-2011 Strobe Inc.
|
|
5 |
* Portions Copyright 2008-2011 Apple Inc. All rights reserved.
|
|
6 |
* @license Licensed under MIT license
|
|
7 |
* See https://raw.github.com/emberjs/ember.js/master/LICENSE
|
|
8 |
* @version 1.4.0
|
|
9 |
*/ |
|
10 | 10 |
|
11 |
// Version: 1.2.0 |
|
12 | 11 |
|
13 | 12 |
(function() { |
14 | 13 |
/*global __fail__*/ |
... | ... | |
32 | 31 |
} |
33 | 32 |
} |
34 | 33 |
|
35 |
Ember.ENV = 'undefined' === typeof ENV ? {} : ENV; |
|
34 |
// This needs to be kept in sync with the logic in |
|
35 |
// `packages/ember-metal/lib/core.js`. |
|
36 |
// |
|
37 |
// This is duplicated here to ensure that `Ember.ENV` |
|
38 |
// is setup even if `Ember` is not loaded yet. |
|
39 |
if (Ember.ENV) { |
|
40 |
// do nothing if Ember.ENV is already setup |
|
41 |
} else if ('undefined' !== typeof EmberENV) { |
|
42 |
Ember.ENV = EmberENV; |
|
43 |
} else if('undefined' !== typeof ENV) { |
|
44 |
Ember.ENV = ENV; |
|
45 |
} else { |
|
46 |
Ember.ENV = {}; |
|
47 |
} |
|
36 | 48 |
|
37 | 49 |
if (!('MANDATORY_SETTER' in Ember.ENV)) { |
38 | 50 |
Ember.ENV.MANDATORY_SETTER = true; // default to true for debug dist |
... | ... | |
58 | 70 |
*/ |
59 | 71 |
Ember.assert = function(desc, test) { |
60 | 72 |
if (!test) { |
61 |
Ember.Logger.assert(test, desc); |
|
62 |
} |
|
63 |
|
|
64 |
if (Ember.testing && !test) { |
|
65 |
// when testing, ensure test failures when assertions fail |
|
66 | 73 |
throw new Ember.Error("Assertion Failed: " + desc); |
67 | 74 |
} |
68 | 75 |
}; |
... | ... | |
173 | 180 |
|
174 | 181 |
// Inform the developer about the Ember Inspector if not installed. |
175 | 182 |
if (!Ember.testing) { |
176 |
if (typeof window !== 'undefined' && window.chrome && window.addEventListener) { |
|
183 |
var isFirefox = typeof InstallTrigger !== 'undefined'; |
|
184 |
var isChrome = !!window.chrome && !window.opera; |
|
185 |
|
|
186 |
if (typeof window !== 'undefined' && (isFirefox || isChrome) && window.addEventListener) { |
|
177 | 187 |
window.addEventListener("load", function() { |
178 | 188 |
if (document.body && document.body.dataset && !document.body.dataset.emberExtension) { |
179 |
Ember.debug('For more advanced debugging, install the Ember Inspector from https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi'); |
|
189 |
var downloadURL; |
|
190 |
|
|
191 |
if(isChrome) { |
|
192 |
downloadURL = 'https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi'; |
|
193 |
} else if(isFirefox) { |
|
194 |
downloadURL = 'https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/' |
|
195 |
} |
|
196 |
|
|
197 |
Ember.debug('For more advanced debugging, install the Ember Inspector from ' + downloadURL); |
|
180 | 198 |
} |
181 | 199 |
}, false); |
182 | 200 |
} |
... | ... | |
184 | 202 |
|
185 | 203 |
})(); |
186 | 204 |
|
187 |
// ==========================================================================
|
|
188 |
// Project: Ember - JavaScript Application Framework
|
|
189 |
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors
|
|
190 |
// Portions Copyright 2006-2011 Strobe Inc.
|
|
191 |
// Portions Copyright 2008-2011 Apple Inc. All rights reserved.
|
|
192 |
// License: Licensed under MIT license
|
|
193 |
// See https://raw.github.com/emberjs/ember.js/master/LICENSE
|
|
194 |
// ==========================================================================
|
|
195 |
|
|
205 |
/*!
|
|
206 |
* @overview Ember - JavaScript Application Framework
|
|
207 |
* @copyright Copyright 2011-2014 Tilde Inc. and contributors
|
|
208 |
* Portions Copyright 2006-2011 Strobe Inc.
|
|
209 |
* Portions Copyright 2008-2011 Apple Inc. All rights reserved.
|
|
210 |
* @license Licensed under MIT license
|
|
211 |
* See https://raw.github.com/emberjs/ember.js/master/LICENSE
|
|
212 |
* @version 1.4.0
|
|
213 |
*/ |
|
196 | 214 |
|
197 |
// Version: 1.2.0 |
|
198 | 215 |
|
199 | 216 |
(function() { |
200 |
var define, requireModule; |
|
217 |
var define, requireModule, require, requirejs;
|
|
201 | 218 |
|
202 | 219 |
(function() { |
203 | 220 |
var registry = {}, seen = {}; |
... | ... | |
206 | 223 |
registry[name] = { deps: deps, callback: callback }; |
207 | 224 |
}; |
208 | 225 |
|
209 |
requireModule = function(name) { |
|
226 |
requirejs = require = requireModule = function(name) { |
|
227 |
requirejs._eak_seen = registry; |
|
228 |
|
|
210 | 229 |
if (seen[name]) { return seen[name]; } |
211 | 230 |
seen[name] = {}; |
212 | 231 |
|
213 |
var mod, deps, callback, reified, exports; |
|
214 |
|
|
215 |
mod = registry[name]; |
|
216 |
|
|
217 |
if (!mod) { |
|
218 |
throw new Error("Module '" + name + "' not found."); |
|
232 |
if (!registry[name]) { |
|
233 |
throw new Error("Could not find module " + name); |
|
219 | 234 |
} |
220 | 235 |
|
221 |
deps = mod.deps; |
|
222 |
callback = mod.callback; |
|
223 |
reified = []; |
|
236 |
var mod = registry[name], |
|
237 |
deps = mod.deps, |
|
238 |
callback = mod.callback, |
|
239 |
reified = [], |
|
240 |
exports; |
|
224 | 241 |
|
225 | 242 |
for (var i=0, l=deps.length; i<l; i++) { |
226 | 243 |
if (deps[i] === 'exports') { |
227 | 244 |
reified.push(exports = {}); |
228 | 245 |
} else { |
229 |
reified.push(requireModule(deps[i]));
|
|
246 |
reified.push(requireModule(resolve(deps[i])));
|
|
230 | 247 |
} |
231 | 248 |
} |
232 | 249 |
|
233 | 250 |
var value = callback.apply(this, reified); |
234 | 251 |
return seen[name] = exports || value; |
252 |
|
|
253 |
function resolve(child) { |
|
254 |
if (child.charAt(0) !== '.') { return child; } |
|
255 |
var parts = child.split("/"); |
|
256 |
var parentBase = name.split("/").slice(0, -1); |
|
257 |
|
|
258 |
for (var i=0, l=parts.length; i<l; i++) { |
|
259 |
var part = parts[i]; |
|
260 |
|
|
261 |
if (part === '..') { parentBase.pop(); } |
|
262 |
else if (part === '.') { continue; } |
|
263 |
else { parentBase.push(part); } |
|
264 |
} |
|
265 |
|
|
266 |
return parentBase.join("/"); |
|
267 |
} |
|
235 | 268 |
}; |
236 | 269 |
})(); |
237 | 270 |
(function() { |
238 |
/*globals Em:true ENV */ |
|
271 |
/*globals Em:true ENV EmberENV MetamorphENV:true */
|
|
239 | 272 |
|
240 | 273 |
/** |
241 | 274 |
@module ember |
... | ... | |
259 | 292 |
|
260 | 293 |
@class Ember |
261 | 294 |
@static |
262 |
@version 1.2.0
|
|
295 |
@version 1.4.0
|
|
263 | 296 |
*/ |
264 | 297 |
|
265 | 298 |
if ('undefined' === typeof Ember) { |
... | ... | |
286 | 319 |
/** |
287 | 320 |
@property VERSION |
288 | 321 |
@type String |
289 |
@default '1.2.0'
|
|
290 |
@final
|
|
322 |
@default '1.4.0'
|
|
323 |
@static
|
|
291 | 324 |
*/ |
292 |
Ember.VERSION = '1.2.0';
|
|
325 |
Ember.VERSION = '1.4.0';
|
|
293 | 326 |
|
294 | 327 |
/** |
295 |
Standard environmental variables. You can define these in a global `ENV` |
|
296 |
variable before loading Ember to control various configuration |
|
297 |
settings. |
|
328 |
Standard environmental variables. You can define these in a global `EmberENV` |
|
329 |
variable before loading Ember to control various configuration settings. |
|
330 |
|
|
331 |
For backwards compatibility with earlier versions of Ember the global `ENV` |
|
332 |
variable will be used if `EmberENV` is not defined. |
|
298 | 333 |
|
299 | 334 |
@property ENV |
300 | 335 |
@type Hash |
301 | 336 |
*/ |
302 | 337 |
|
303 |
if ('undefined' === typeof ENV) { |
|
304 |
exports.ENV = {}; |
|
338 |
// This needs to be kept in sync with the logic in |
|
339 |
// `packages/ember-debug/lib/main.js`. |
|
340 |
if (Ember.ENV) { |
|
341 |
// do nothing if Ember.ENV is already setup |
|
342 |
} else if ('undefined' !== typeof EmberENV) { |
|
343 |
Ember.ENV = EmberENV; |
|
344 |
} else if('undefined' !== typeof ENV) { |
|
345 |
Ember.ENV = ENV; |
|
346 |
} else { |
|
347 |
Ember.ENV = {}; |
|
305 | 348 |
} |
306 | 349 |
|
350 |
Ember.config = Ember.config || {}; |
|
351 |
|
|
307 | 352 |
// We disable the RANGE API by default for performance reasons |
308 |
if ('undefined' === typeof ENV.DISABLE_RANGE_API) { |
|
309 |
ENV.DISABLE_RANGE_API = true; |
|
353 |
if ('undefined' === typeof Ember.ENV.DISABLE_RANGE_API) {
|
|
354 |
Ember.ENV.DISABLE_RANGE_API = true;
|
|
310 | 355 |
} |
311 | 356 |
|
357 |
if ("undefined" === typeof MetamorphENV) { |
|
358 |
exports.MetamorphENV = {}; |
|
359 |
} |
|
312 | 360 |
|
313 |
Ember.ENV = Ember.ENV || ENV; |
|
314 |
|
|
315 |
Ember.config = Ember.config || {}; |
|
361 |
MetamorphENV.DISABLE_RANGE_API = Ember.ENV.DISABLE_RANGE_API; |
|
316 | 362 |
|
317 | 363 |
/** |
318 | 364 |
Hash of enabled Canary features. Add to before creating your application. |
... | ... | |
751 | 797 |
return -1; |
752 | 798 |
}; |
753 | 799 |
|
754 |
/** |
|
755 |
Array polyfills to support ES5 features in older browsers. |
|
756 | 800 |
|
757 |
@namespace Ember |
|
758 |
@property ArrayPolyfills |
|
759 |
*/ |
|
760 |
Ember.ArrayPolyfills = { |
|
761 |
map: arrayMap, |
|
762 |
forEach: arrayForEach, |
|
763 |
indexOf: arrayIndexOf |
|
764 |
}; |
|
801 |
/** |
|
802 |
Array polyfills to support ES5 features in older browsers. |
|
803 |
|
|
804 |
@namespace Ember |
|
805 |
@property ArrayPolyfills |
|
806 |
*/ |
|
807 |
Ember.ArrayPolyfills = { |
|
808 |
map: arrayMap, |
|
809 |
forEach: arrayForEach, |
|
810 |
indexOf: arrayIndexOf |
|
811 |
}; |
|
812 |
|
|
765 | 813 |
|
766 | 814 |
if (Ember.SHIM_ES5) { |
767 | 815 |
if (!Array.prototype.map) { |
... | ... | |
795 | 843 |
Ember.Error = function() { |
796 | 844 |
var tmp = Error.apply(this, arguments); |
797 | 845 |
|
846 |
// Adds a `stack` property to the given error object that will yield the |
|
847 |
// stack trace at the time captureStackTrace was called. |
|
848 |
// When collecting the stack trace all frames above the topmost call |
|
849 |
// to this function, including that call, will be left out of the |
|
850 |
// stack trace. |
|
851 |
// This is useful because we can hide Ember implementation details |
|
852 |
// that are not very helpful for the user. |
|
853 |
if (Error.captureStackTrace) { |
|
854 |
Error.captureStackTrace(this, Ember.Error); |
|
855 |
} |
|
798 | 856 |
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. |
799 | 857 |
for (var idx = 0; idx < errorProps.length; idx++) { |
800 | 858 |
this[errorProps[idx]] = tmp[errorProps[idx]]; |
... | ... | |
828 | 886 |
Ember.onerror = null; |
829 | 887 |
|
830 | 888 |
/** |
831 |
@private |
|
832 |
|
|
833 | 889 |
Wrap code block in a try/catch if `Ember.onerror` is set. |
834 | 890 |
|
891 |
@private |
|
835 | 892 |
@method handleErrors |
836 | 893 |
@for Ember |
837 | 894 |
@param {Function} func |
... | ... | |
861 | 918 |
*/ |
862 | 919 |
|
863 | 920 |
/** |
864 |
@private |
|
865 |
|
|
866 | 921 |
Prefix used for guids through out Ember. |
867 |
|
|
922 |
@private |
|
868 | 923 |
*/ |
869 | 924 |
Ember.GUID_PREFIX = 'ember'; |
870 | 925 |
|
... | ... | |
880 | 935 |
var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; |
881 | 936 |
|
882 | 937 |
/** |
883 |
@private |
|
884 |
|
|
885 | 938 |
A unique key used to assign guids and other private metadata to objects. |
886 | 939 |
If you inspect an object in your browser debugger you will often see these. |
887 | 940 |
They can be safely ignored. |
... | ... | |
889 | 942 |
On browsers that support it, these properties are added with enumeration |
890 | 943 |
disabled so they won't show up when you iterate over your properties. |
891 | 944 |
|
945 |
@private |
|
892 | 946 |
@property GUID_KEY |
893 | 947 |
@for Ember |
894 | 948 |
@type String |
... | ... | |
904 | 958 |
}; |
905 | 959 |
|
906 | 960 |
/** |
907 |
@private |
|
908 |
|
|
909 | 961 |
Generates a new guid, optionally saving the guid to the object that you |
910 | 962 |
pass in. You will rarely need to use this method. Instead you should |
911 | 963 |
call `Ember.guidFor(obj)`, which return an existing guid if available. |
912 | 964 |
|
965 |
@private |
|
913 | 966 |
@method generateGuid |
914 | 967 |
@for Ember |
915 | 968 |
@param {Object} [obj] Object the guid will be used for. If passed in, the guid will |
... | ... | |
932 | 985 |
}; |
933 | 986 |
|
934 | 987 |
/** |
935 |
@private |
|
936 |
|
|
937 | 988 |
Returns a unique id for the object. If the object does not yet have a guid, |
938 | 989 |
one will be assigned to it. You can call this on any object, |
939 | 990 |
`Ember.Object`-based or not, but be aware that it will add a `_guid` |
... | ... | |
941 | 992 |
|
942 | 993 |
You can also use this method on DOM Element objects. |
943 | 994 |
|
995 |
@private |
|
944 | 996 |
@method guidFor |
945 | 997 |
@for Ember |
946 | 998 |
@param {Object} obj any object, string, number, Element, or primitive |
... | ... | |
985 | 1037 |
// META |
986 | 1038 |
// |
987 | 1039 |
|
988 |
var META_DESC = { |
|
1040 |
var META_DESC = Ember.META_DESC = {
|
|
989 | 1041 |
writable: true, |
990 | 1042 |
configurable: false, |
991 | 1043 |
enumerable: false, |
... | ... | |
1005 | 1057 |
*/ |
1006 | 1058 |
Ember.META_KEY = META_KEY; |
1007 | 1059 |
|
1008 |
// Placeholder for non-writable metas. |
|
1009 |
var EMPTY_META = { |
|
1010 |
descs: {}, |
|
1011 |
watching: {} |
|
1012 |
}; |
|
1013 |
|
|
1014 |
if (MANDATORY_SETTER) { EMPTY_META.values = {}; } |
|
1015 |
|
|
1016 |
Ember.EMPTY_META = EMPTY_META; |
|
1017 |
|
|
1018 |
if (Object.freeze) Object.freeze(EMPTY_META); |
|
1019 |
|
|
1020 | 1060 |
var isDefinePropertySimulated = Ember.platform.defineProperty.isSimulated; |
1021 | 1061 |
|
1022 | 1062 |
function Meta(obj) { |
... | ... | |
1026 | 1066 |
this.source = obj; |
1027 | 1067 |
} |
1028 | 1068 |
|
1069 |
Meta.prototype = { |
|
1070 |
descs: null, |
|
1071 |
deps: null, |
|
1072 |
watching: null, |
|
1073 |
listeners: null, |
|
1074 |
cache: null, |
|
1075 |
source: null, |
|
1076 |
mixins: null, |
|
1077 |
bindings: null, |
|
1078 |
chains: null, |
|
1079 |
chainWatchers: null, |
|
1080 |
values: null, |
|
1081 |
proto: null |
|
1082 |
}; |
|
1083 |
|
|
1029 | 1084 |
if (isDefinePropertySimulated) { |
1030 | 1085 |
// on platforms that don't support enumerable false |
1031 | 1086 |
// make meta fail jQuery.isPlainObject() to hide from |
... | ... | |
1038 | 1093 |
Meta.prototype.toJSON = function () { }; |
1039 | 1094 |
} |
1040 | 1095 |
|
1096 |
// Placeholder for non-writable metas. |
|
1097 |
var EMPTY_META = new Meta(null); |
|
1098 |
|
|
1099 |
if (MANDATORY_SETTER) { EMPTY_META.values = {}; } |
|
1100 |
|
|
1101 |
Ember.EMPTY_META = EMPTY_META; |
|
1102 |
|
|
1041 | 1103 |
/** |
1042 | 1104 |
Retrieves the meta hash for an object. If `writable` is true ensures the |
1043 | 1105 |
hash is writable for this object as well. |
... | ... | |
1157 | 1219 |
}; |
1158 | 1220 |
|
1159 | 1221 |
/** |
1160 |
@private |
|
1161 |
|
|
1162 | 1222 |
Wraps the passed function so that `this._super` will point to the superFunc |
1163 | 1223 |
when the function is invoked. This is the primitive we use to implement |
1164 | 1224 |
calls to super. |
1165 | 1225 |
|
1226 |
@private |
|
1166 | 1227 |
@method wrap |
1167 | 1228 |
@for Ember |
1168 | 1229 |
@param {Function} func The function to call |
... | ... | |
1472 | 1533 |
| 'undefined' | Undefined value | |
1473 | 1534 |
| 'function' | A function | |
1474 | 1535 |
| 'array' | An instance of Array | |
1536 |
| 'regexp' | An instance of RegExp | |
|
1537 |
| 'date' | An instance of Date | |
|
1475 | 1538 |
| 'class' | An Ember class (created using Ember.Object.extend()) | |
1476 | 1539 |
| 'instance' | An Ember object instance | |
1477 | 1540 |
| 'error' | An instance of the Error object | |
... | ... | |
1491 | 1554 |
Ember.typeOf(new Boolean(true)); // 'boolean' |
1492 | 1555 |
Ember.typeOf(Ember.makeArray); // 'function' |
1493 | 1556 |
Ember.typeOf([1,2,90]); // 'array' |
1557 |
Ember.typeOf(/abc/); // 'regexp' |
|
1558 |
Ember.typeOf(new Date()); // 'date' |
|
1494 | 1559 |
Ember.typeOf(Ember.Object.extend()); // 'class' |
1495 | 1560 |
Ember.typeOf(Ember.Object.create()); // 'instance' |
1496 | 1561 |
Ember.typeOf(new Error('teamocil')); // 'error' |
... | ... | |
1514 | 1579 |
} else if (ret === 'object') { |
1515 | 1580 |
if (item instanceof Error) ret = 'error'; |
1516 | 1581 |
else if (Ember.Object && item instanceof Ember.Object) ret = 'instance'; |
1517 |
else ret = 'object';
|
|
1582 |
else if (item instanceof Date) ret = 'date';
|
|
1518 | 1583 |
} |
1519 | 1584 |
|
1520 | 1585 |
return ret; |
1521 | 1586 |
}; |
1522 | 1587 |
|
1588 |
/** |
|
1589 |
Convenience method to inspect an object. This method will attempt to |
|
1590 |
convert the object into a useful string description. |
|
1591 |
|
|
1592 |
It is a pretty simple implementation. If you want something more robust, |
|
1593 |
use something like JSDump: https://github.com/NV/jsDump |
|
1594 |
|
|
1595 |
@method inspect |
|
1596 |
@for Ember |
|
1597 |
@param {Object} obj The object you want to inspect. |
|
1598 |
@return {String} A description of the object |
|
1599 |
*/ |
|
1600 |
Ember.inspect = function(obj) { |
|
1601 |
var type = Ember.typeOf(obj); |
|
1602 |
if (type === 'array') { |
|
1603 |
return '[' + obj + ']'; |
|
1604 |
} |
|
1605 |
if (type !== 'object') { |
|
1606 |
return obj + ''; |
|
1607 |
} |
|
1608 |
|
|
1609 |
var v, ret = []; |
|
1610 |
for(var key in obj) { |
|
1611 |
if (obj.hasOwnProperty(key)) { |
|
1612 |
v = obj[key]; |
|
1613 |
if (v === 'toString') { continue; } // ignore useless items |
|
1614 |
if (Ember.typeOf(v) === 'function') { v = "function() { ... }"; } |
|
1615 |
ret.push(key + ": " + v); |
|
1616 |
} |
|
1617 |
} |
|
1618 |
return "{" + ret.join(", ") + "}"; |
|
1619 |
}; |
|
1620 |
|
|
1621 |
|
|
1622 |
|
|
1523 | 1623 |
})(); |
1524 | 1624 |
|
1525 | 1625 |
|
... | ... | |
1734 | 1834 |
|
1735 | 1835 |
|
1736 | 1836 |
(function() { |
1737 |
var map, forEach, indexOf, splice; |
|
1837 |
var map, forEach, indexOf, splice, filter;
|
|
1738 | 1838 |
map = Array.prototype.map || Ember.ArrayPolyfills.map; |
1739 | 1839 |
forEach = Array.prototype.forEach || Ember.ArrayPolyfills.forEach; |
1740 | 1840 |
indexOf = Array.prototype.indexOf || Ember.ArrayPolyfills.indexOf; |
1841 |
filter = Array.prototype.filter || Ember.ArrayPolyfills.filter; |
|
1741 | 1842 |
splice = Array.prototype.splice; |
1742 | 1843 |
|
1844 |
/** |
|
1845 |
* Defines some convenience methods for working with Enumerables. |
|
1846 |
* `Ember.EnumerableUtils` uses `Ember.ArrayPolyfills` when necessary. |
|
1847 |
* |
|
1848 |
* @class EnumerableUtils |
|
1849 |
* @namespace Ember |
|
1850 |
* @static |
|
1851 |
* */ |
|
1743 | 1852 |
var utils = Ember.EnumerableUtils = { |
1853 |
/** |
|
1854 |
* Calls the map function on the passed object with a specified callback. This |
|
1855 |
* uses `Ember.ArrayPolyfill`'s-map method when necessary. |
|
1856 |
* |
|
1857 |
* @method map |
|
1858 |
* @param {Object} obj The object that should be mapped |
|
1859 |
* @param {Function} callback The callback to execute |
|
1860 |
* @param {Object} thisArg Value to use as this when executing *callback* |
|
1861 |
* |
|
1862 |
* @return {Array} An array of mapped values. |
|
1863 |
*/ |
|
1744 | 1864 |
map: function(obj, callback, thisArg) { |
1745 | 1865 |
return obj.map ? obj.map.call(obj, callback, thisArg) : map.call(obj, callback, thisArg); |
1746 | 1866 |
}, |
1747 | 1867 |
|
1868 |
/** |
|
1869 |
* Calls the forEach function on the passed object with a specified callback. This |
|
1870 |
* uses `Ember.ArrayPolyfill`'s-forEach method when necessary. |
|
1871 |
* |
|
1872 |
* @method forEach |
|
1873 |
* @param {Object} obj The object to call forEach on |
|
1874 |
* @param {Function} callback The callback to execute |
|
1875 |
* @param {Object} thisArg Value to use as this when executing *callback* |
|
1876 |
* |
|
1877 |
*/ |
|
1748 | 1878 |
forEach: function(obj, callback, thisArg) { |
1749 | 1879 |
return obj.forEach ? obj.forEach.call(obj, callback, thisArg) : forEach.call(obj, callback, thisArg); |
1750 | 1880 |
}, |
1751 | 1881 |
|
1882 |
/** |
|
1883 |
* Calls the filter function on the passed object with a specified callback. This |
|
1884 |
* uses `Ember.ArrayPolyfill`'s-filter method when necessary. |
|
1885 |
* |
|
1886 |
* @method filter |
|
1887 |
* @param {Object} obj The object to call filter on |
|
1888 |
* @param {Function} callback The callback to execute |
|
1889 |
* @param {Object} thisArg Value to use as this when executing *callback* |
|
1890 |
* |
|
1891 |
* @return {Array} An array containing the filtered values |
|
1892 |
*/ |
|
1893 |
filter: function(obj, callback, thisArg) { |
|
1894 |
return obj.filter ? obj.filter.call(obj, callback, thisArg) : filter.call(obj, callback, thisArg); |
|
1895 |
}, |
|
1896 |
|
|
1897 |
/** |
|
1898 |
* Calls the indexOf function on the passed object with a specified callback. This |
|
1899 |
* uses `Ember.ArrayPolyfill`'s-indexOf method when necessary. |
|
1900 |
* |
|
1901 |
* @method indexOf |
|
1902 |
* @param {Object} obj The object to call indexOn on |
|
1903 |
* @param {Function} callback The callback to execute |
|
1904 |
* @param {Object} index The index to start searching from |
|
1905 |
* |
|
1906 |
*/ |
|
1752 | 1907 |
indexOf: function(obj, element, index) { |
1753 | 1908 |
return obj.indexOf ? obj.indexOf.call(obj, element, index) : indexOf.call(obj, element, index); |
1754 | 1909 |
}, |
1755 | 1910 |
|
1911 |
/** |
|
1912 |
* Returns an array of indexes of the first occurrences of the passed elements |
|
1913 |
* on the passed object. |
|
1914 |
* |
|
1915 |
* ```javascript |
|
1916 |
* var array = [1, 2, 3, 4, 5]; |
|
1917 |
* Ember.EnumerableUtils.indexesOf(array, [2, 5]); // [1, 4] |
|
1918 |
* |
|
1919 |
* var fubar = "Fubarr"; |
|
1920 |
* Ember.EnumerableUtils.indexesOf(fubar, ['b', 'r']); // [2, 4] |
|
1921 |
* ``` |
|
1922 |
* |
|
1923 |
* @method indexesOf |
|
1924 |
* @param {Object} obj The object to check for element indexes |
|
1925 |
* @param {Array} elements The elements to search for on *obj* |
|
1926 |
* |
|
1927 |
* @return {Array} An array of indexes. |
|
1928 |
* |
|
1929 |
*/ |
|
1756 | 1930 |
indexesOf: function(obj, elements) { |
1757 | 1931 |
return elements === undefined ? [] : utils.map(elements, function(item) { |
1758 | 1932 |
return utils.indexOf(obj, item); |
1759 | 1933 |
}); |
1760 | 1934 |
}, |
1761 | 1935 |
|
1936 |
/** |
|
1937 |
* Adds an object to an array. If the array already includes the object this |
|
1938 |
* method has no effect. |
|
1939 |
* |
|
1940 |
* @method addObject |
|
1941 |
* @param {Array} array The array the passed item should be added to |
|
1942 |
* @param {Object} item The item to add to the passed array |
|
1943 |
* |
|
1944 |
* @return 'undefined' |
|
1945 |
*/ |
|
1762 | 1946 |
addObject: function(array, item) { |
1763 | 1947 |
var index = utils.indexOf(array, item); |
1764 | 1948 |
if (index === -1) { array.push(item); } |
1765 | 1949 |
}, |
1766 | 1950 |
|
1951 |
/** |
|
1952 |
* Removes an object from an array. If the array does not contain the passed |
|
1953 |
* object this method has no effect. |
|
1954 |
* |
|
1955 |
* @method removeObject |
|
1956 |
* @param {Array} array The array to remove the item from. |
|
1957 |
* @param {Object} item The item to remove from the passed array. |
|
1958 |
* |
|
1959 |
* @return 'undefined' |
|
1960 |
*/ |
|
1767 | 1961 |
removeObject: function(array, item) { |
1768 | 1962 |
var index = utils.indexOf(array, item); |
1769 | 1963 |
if (index !== -1) { array.splice(index, 1); } |
... | ... | |
1789 | 1983 |
return ret; |
1790 | 1984 |
}, |
1791 | 1985 |
|
1986 |
/** |
|
1987 |
* Replaces objects in an array with the passed objects. |
|
1988 |
* |
|
1989 |
* ```javascript |
|
1990 |
* var array = [1,2,3]; |
|
1991 |
* Ember.EnumerableUtils.replace(array, 1, 2, [4, 5]); // [1, 4, 5] |
|
1992 |
* |
|
1993 |
* var array = [1,2,3]; |
|
1994 |
* Ember.EnumerableUtils.replace(array, 1, 1, [4, 5]); // [1, 4, 5, 3] |
|
1995 |
* |
|
1996 |
* var array = [1,2,3]; |
|
1997 |
* Ember.EnumerableUtils.replace(array, 10, 1, [4, 5]); // [1, 2, 3, 4, 5] |
|
1998 |
* ``` |
|
1999 |
* |
|
2000 |
* @method replace |
|
2001 |
* @param {Array} array The array the objects should be inserted into. |
|
2002 |
* @param {Number} idx Starting index in the array to replace. If *idx* >= |
|
2003 |
* length, then append to the end of the array. |
|
2004 |
* @param {Number} amt Number of elements that should be remove from the array, |
|
2005 |
* starting at *idx* |
|
2006 |
* @param {Array} objects An array of zero or more objects that should be |
|
2007 |
* inserted into the array at *idx* |
|
2008 |
* |
|
2009 |
* @return {Array} The changed array. |
|
2010 |
*/ |
|
1792 | 2011 |
replace: function(array, idx, amt, objects) { |
1793 | 2012 |
if (array.replace) { |
1794 | 2013 |
return array.replace(idx, amt, objects); |
... | ... | |
1797 | 2016 |
} |
1798 | 2017 |
}, |
1799 | 2018 |
|
2019 |
/** |
|
2020 |
* Calculates the intersection of two arrays. This method returns a new array |
|
2021 |
* filled with the records that the two passed arrays share with each other. |
|
2022 |
* If there is no intersection, an empty array will be returned. |
|
2023 |
* |
|
2024 |
* ```javascript |
|
2025 |
* var array1 = [1, 2, 3, 4, 5]; |
|
2026 |
* var array2 = [1, 3, 5, 6, 7]; |
|
2027 |
* |
|
2028 |
* Ember.EnumerableUtils.intersection(array1, array2); // [1, 3, 5] |
|
2029 |
* |
|
2030 |
* var array1 = [1, 2, 3]; |
|
2031 |
* var array2 = [4, 5, 6]; |
|
2032 |
* |
|
2033 |
* Ember.EnumerableUtils.intersection(array1, array2); // [] |
|
2034 |
* ``` |
|
2035 |
* |
|
2036 |
* @method intersection |
|
2037 |
* @param {Array} array1 The first array |
|
2038 |
* @param {Array} array2 The second array |
|
2039 |
* |
|
2040 |
* @return {Array} The intersection of the two passed arrays. |
|
2041 |
*/ |
|
1800 | 2042 |
intersection: function(array1, array2) { |
1801 | 2043 |
var intersection = []; |
1802 | 2044 |
|
... | ... | |
1903 | 2145 |
} |
1904 | 2146 |
|
1905 | 2147 |
/** |
1906 |
@private |
|
1907 |
|
|
1908 | 2148 |
Normalizes a target/path pair to reflect that actual target/path that should |
1909 | 2149 |
be observed, etc. This takes into account passing in global property |
1910 | 2150 |
paths (i.e. a path beginning with a captial letter not defined on the |
1911 | 2151 |
target) and * separators. |
1912 | 2152 |
|
2153 |
@private |
|
1913 | 2154 |
@method normalizeTuple |
1914 | 2155 |
@for Ember |
1915 | 2156 |
@param {Object} target The current target. May be `null`. |
... | ... | |
1931 | 2172 |
} |
1932 | 2173 |
|
1933 | 2174 |
// must return some kind of path to be valid else other things will break. |
1934 |
if (!path || path.length===0) throw new Ember.Error('Invalid Path');
|
|
2175 |
if (!path || path.length===0) throw new Ember.Error('Path cannot be empty');
|
|
1935 | 2176 |
|
1936 | 2177 |
return [ target, path ]; |
1937 | 2178 |
}; |
... | ... | |
2158 | 2399 |
} |
2159 | 2400 |
|
2160 | 2401 |
/** |
2161 |
@private |
|
2162 |
|
|
2163 | 2402 |
Suspend listener during callback. |
2164 | 2403 |
|
2165 | 2404 |
This should only be used by the target of the event listener |
... | ... | |
2167 | 2406 |
an object might suspend its property change listener while it is |
2168 | 2407 |
setting that property. |
2169 | 2408 |
|
2409 |
@private |
|
2170 | 2410 |
@method suspendListener |
2171 | 2411 |
@for Ember |
2172 | 2412 |
@param obj |
... | ... | |
2195 | 2435 |
} |
2196 | 2436 |
|
2197 | 2437 |
/** |
2198 |
@private |
|
2199 |
|
|
2200 | 2438 |
Suspends multiple listeners during a callback. |
2201 | 2439 |
|
2202 |
|
|
2440 |
@private |
|
2203 | 2441 |
@method suspendListeners |
2204 | 2442 |
@for Ember |
2205 | 2443 |
@param obj |
... | ... | |
2243 | 2481 |
} |
2244 | 2482 |
|
2245 | 2483 |
/** |
2246 |
@private |
|
2247 |
|
|
2248 | 2484 |
Return a list of currently watched events |
2249 | 2485 |
|
2486 |
@private |
|
2250 | 2487 |
@method watchedEvents |
2251 | 2488 |
@for Ember |
2252 | 2489 |
@param obj |
... | ... | |
2267 | 2504 |
is skipped, and once listeners are removed. A listener without |
2268 | 2505 |
a target is executed on the passed object. If an array of actions |
2269 | 2506 |
is not passed, the actions stored on the passed object are invoked. |
2270 |
|
|
2507 |
|
|
2271 | 2508 |
@method sendEvent |
2272 | 2509 |
@for Ember |
2273 | 2510 |
@param obj |
... | ... | |
2346 | 2583 |
Define a property as a function that should be executed when |
2347 | 2584 |
a specified event or events are triggered. |
2348 | 2585 |
|
2349 |
var Job = Ember.Object.extend({ |
|
2350 |
logCompleted: Ember.on('completed', function(){ |
|
2351 |
console.log('Job completed!'); |
|
2352 |
}) |
|
2353 |
}); |
|
2354 |
var job = Job.create(); |
|
2355 |
Ember.sendEvent(job, 'completed'); // Logs "Job completed!" |
|
2586 |
|
|
2587 |
``` javascript |
|
2588 |
var Job = Ember.Object.extend({ |
|
2589 |
logCompleted: Ember.on('completed', function(){ |
|
2590 |
console.log('Job completed!'); |
|
2591 |
}) |
|
2592 |
}); |
|
2593 |
var job = Job.create(); |
|
2594 |
Ember.sendEvent(job, 'completed'); // Logs "Job completed!" |
|
2595 |
``` |
|
2356 | 2596 |
|
2357 | 2597 |
@method on |
2358 | 2598 |
@for Ember |
... | ... | |
2451 | 2691 |
|
2452 | 2692 |
|
2453 | 2693 |
(function() { |
2454 |
var metaFor = Ember.meta,
|
|
2694 |
var META_KEY = Ember.META_KEY,
|
|
2455 | 2695 |
guidFor = Ember.guidFor, |
2456 | 2696 |
tryFinally = Ember.tryFinally, |
2457 | 2697 |
sendEvent = Ember.sendEvent, |
... | ... | |
2482 | 2722 |
@return {void} |
2483 | 2723 |
*/ |
2484 | 2724 |
function propertyWillChange(obj, keyName) { |
2485 |
var m = metaFor(obj, false),
|
|
2486 |
watching = m.watching[keyName] > 0 || keyName === 'length',
|
|
2487 |
proto = m.proto, |
|
2488 |
desc = m.descs[keyName]; |
|
2725 |
var m = obj[META_KEY],
|
|
2726 |
watching = (m && m.watching[keyName] > 0) || keyName === 'length',
|
|
2727 |
proto = m && m.proto,
|
|
2728 |
desc = m && m.descs[keyName];
|
|
2489 | 2729 |
|
2490 | 2730 |
if (!watching) { return; } |
2491 | 2731 |
if (proto === obj) { return; } |
... | ... | |
2512 | 2752 |
@return {void} |
2513 | 2753 |
*/ |
2514 | 2754 |
function propertyDidChange(obj, keyName) { |
2515 |
var m = metaFor(obj, false),
|
|
2516 |
watching = m.watching[keyName] > 0 || keyName === 'length',
|
|
2517 |
proto = m.proto, |
|
2518 |
desc = m.descs[keyName]; |
|
2755 |
var m = obj[META_KEY],
|
|
2756 |
watching = (m && m.watching[keyName] > 0) || keyName === 'length',
|
|
2757 |
proto = m && m.proto,
|
|
2758 |
desc = m && m.descs[keyName];
|
|
2519 | 2759 |
|
2520 | 2760 |
if (proto === obj) { return; } |
2521 | 2761 |
|
... | ... | |
2588 | 2828 |
} |
2589 | 2829 |
|
2590 | 2830 |
function chainsDidChange(obj, keyName, m, suppressEvents) { |
2591 |
if (!(m.hasOwnProperty('chainWatchers') && |
|
2831 |
if (!(m && m.hasOwnProperty('chainWatchers') &&
|
|
2592 | 2832 |
m.chainWatchers[keyName])) { |
2593 | 2833 |
return; |
2594 | 2834 |
} |
... | ... | |
2704 | 2944 |
property is not defined but the object implements the `setUnknownProperty` |
2705 | 2945 |
method then that will be invoked as well. |
2706 | 2946 |
|
2707 |
If you plan to run on IE8 and older browsers then you should use this |
|
2708 |
method anytime you want to set a property on an object that you don't |
|
2709 |
know for sure is private. (Properties beginning with an underscore '_' |
|
2710 |
are considered private.) |
|
2711 |
|
|
2712 |
On all newer browsers, you only need to use this method to set |
|
2713 |
properties if the property might not be defined on the object and you want |
|
2714 |
to respect the `setUnknownProperty` handler. Otherwise you can ignore this |
|
2715 |
method. |
|
2716 |
|
|
2717 | 2947 |
@method set |
2718 | 2948 |
@for Ember |
2719 | 2949 |
@param {Object} obj The object to modify. |
... | ... | |
2760 | 2990 |
if (value !== currentValue) { |
2761 | 2991 |
Ember.propertyWillChange(obj, keyName); |
2762 | 2992 |
if (MANDATORY_SETTER) { |
2763 |
if (currentValue === undefined && !(keyName in obj)) {
|
|
2993 |
if ((currentValue === undefined && !(keyName in obj)) || !obj.propertyIsEnumerable(keyName)) {
|
|
2764 | 2994 |
Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter |
2765 | 2995 |
} else { |
2766 | 2996 |
meta.values[keyName] = value; |
... | ... | |
2791 | 3021 |
keyName = path.slice(path.lastIndexOf('.') + 1); |
2792 | 3022 |
|
2793 | 3023 |
// get the first part of the part |
2794 |
path = path.slice(0, path.length-(keyName.length+1)); |
|
3024 |
path = (path === keyName) ? keyName : path.slice(0, path.length-(keyName.length+1));
|
|
2795 | 3025 |
|
2796 | 3026 |
// unless the path is this, look up the first part to |
2797 | 3027 |
// get the root |
... | ... | |
2800 | 3030 |
} |
2801 | 3031 |
|
2802 | 3032 |
if (!keyName || keyName.length === 0) { |
2803 |
throw new Ember.Error('You passed an empty path'); |
|
3033 |
throw new Ember.Error('Property set failed: You passed an empty path');
|
|
2804 | 3034 |
} |
2805 | 3035 |
|
2806 | 3036 |
if (!root) { |
2807 | 3037 |
if (tolerant) { return; } |
2808 |
else { throw new Ember.Error('Object in path '+path+' could not be found or was destroyed.'); }
|
|
3038 |
else { throw new Ember.Error('Property set failed: object in path "'+path+'" could not be found or was destroyed.'); }
|
|
2809 | 3039 |
} |
2810 | 3040 |
|
2811 | 3041 |
return set(root, keyName, value); |
... | ... | |
3215 | 3445 |
|
3216 | 3446 |
(function() { |
3217 | 3447 |
function consoleMethod(name) { |
3218 |
var consoleObj; |
|
3448 |
var consoleObj, logToConsole;
|
|
3219 | 3449 |
if (Ember.imports.console) { |
3220 | 3450 |
consoleObj = Ember.imports.console; |
3221 | 3451 |
} else if (typeof console !== 'undefined') { |
... | ... | |
3227 | 3457 |
if (method) { |
3228 | 3458 |
// Older IE doesn't support apply, but Chrome needs it |
3229 | 3459 |
if (method.apply) { |
3230 |
return function() {
|
|
3460 |
logToConsole = function() {
|
|
3231 | 3461 |
method.apply(consoleObj, arguments); |
3232 | 3462 |
}; |
3463 |
logToConsole.displayName = 'console.' + name; |
|
3464 |
return logToConsole; |
|
3233 | 3465 |
} else { |
3234 | 3466 |
return function() { |
3235 | 3467 |
var message = Array.prototype.join.call(arguments, ', '); |
... | ... | |
3274 | 3506 |
@param {*} arguments |
3275 | 3507 |
*/ |
3276 | 3508 |
log: consoleMethod('log') || Ember.K, |
3509 |
|
|
3277 | 3510 |
/** |
3278 | 3511 |
Prints the arguments to the console with a warning icon. |
3279 | 3512 |
You can pass as many arguments as you want and they will be joined together with a space. |
... | ... | |
3287 | 3520 |
@param {*} arguments |
3288 | 3521 |
*/ |
3289 | 3522 |
warn: consoleMethod('warn') || Ember.K, |
3523 |
|
|
3290 | 3524 |
/** |
3291 |
Prints the arguments to the console with an error icon, red text and a stack race. |
|
3525 |
Prints the arguments to the console with an error icon, red text and a stack trace.
|
|
3292 | 3526 |
You can pass as many arguments as you want and they will be joined together with a space. |
3293 | 3527 |
|
3294 | 3528 |
```javascript |
... | ... | |
3300 | 3534 |
@param {*} arguments |
3301 | 3535 |
*/ |
3302 | 3536 |
error: consoleMethod('error') || Ember.K, |
3537 |
|
|
3303 | 3538 |
/** |
3304 | 3539 |
Logs the arguments to the console. |
3305 | 3540 |
You can pass as many arguments as you want and they will be joined together with a space. |
... | ... | |
3314 | 3549 |
@param {*} arguments |
3315 | 3550 |
*/ |
3316 | 3551 |
info: consoleMethod('info') || Ember.K, |
3552 |
|
|
3317 | 3553 |
/** |
3318 | 3554 |
Logs the arguments to the console in blue text. |
3319 | 3555 |
You can pass as many arguments as you want and they will be joined together with a space. |
... | ... | |
3328 | 3564 |
@param {*} arguments |
3329 | 3565 |
*/ |
3330 | 3566 |
debug: consoleMethod('debug') || consoleMethod('info') || Ember.K, |
3331 |
/** |
|
3332 | 3567 |
|
3333 |
If the value passed into Ember.Logger.assert is not truthy it will throw an error with a stack trace. |
|
3568 |
/** |
|
3569 |
If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace. |
|
3334 | 3570 |
|
3335 | 3571 |
```javascript |
3336 | 3572 |
Ember.Logger.assert(true); // undefined |
... | ... | |
3393 | 3629 |
}; |
3394 | 3630 |
|
3395 | 3631 |
/** |
3396 |
@private |
|
3397 |
|
|
3398 | 3632 |
NOTE: This is a low-level method used by other parts of the API. You almost |
3399 | 3633 |
never want to call this method directly. Instead you should use |
3400 | 3634 |
`Ember.mixin()` to define new properties. |
... | ... | |
3428 | 3662 |
}).property('firstName', 'lastName')); |
3429 | 3663 |
``` |
3430 | 3664 |
|
3665 |
@private |
|
3431 | 3666 |
@method defineProperty |
3432 | 3667 |
@for Ember |
3433 | 3668 |
@param {Object} obj the object to define this property on. This may be a prototype. |
... | ... | |
3464 | 3699 |
} else { |
3465 | 3700 |
obj[keyName] = undefined; // make enumerable |
3466 | 3701 |
} |
3467 |
} else { |
|
3702 |
|
|
3703 |
} else { |
|
3468 | 3704 |
descs[keyName] = undefined; // shadow descriptor in proto |
3469 | 3705 |
if (desc == null) { |
3470 | 3706 |
value = data; |
... | ... | |
3586 | 3822 |
MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER, |
3587 | 3823 |
o_defineProperty = Ember.platform.defineProperty; |
3588 | 3824 |
|
3589 |
Ember.watchKey = function(obj, keyName) { |
|
3825 |
Ember.watchKey = function(obj, keyName, meta) {
|
|
3590 | 3826 |
// can't watch length on Array - it is special... |
3591 | 3827 |
if (keyName === 'length' && typeOf(obj) === 'array') { return; } |
3592 | 3828 |
|
3593 |
var m = metaFor(obj), watching = m.watching; |
|
3829 |
var m = meta || metaFor(obj), watching = m.watching;
|
|
3594 | 3830 |
|
3595 | 3831 |
// activate watching first time |
3596 | 3832 |
if (!watching[keyName]) { |
... | ... | |
3604 | 3840 |
m.values[keyName] = obj[keyName]; |
3605 | 3841 |
o_defineProperty(obj, keyName, { |
3606 | 3842 |
configurable: true, |
3607 |
enumerable: true,
|
|
3843 |
enumerable: obj.propertyIsEnumerable(keyName),
|
|
3608 | 3844 |
set: Ember.MANDATORY_SETTER_FUNCTION, |
3609 | 3845 |
get: Ember.DEFAULT_GETTER_FUNCTION(keyName) |
3610 | 3846 |
}); |
... | ... | |
3615 | 3851 |
}; |
3616 | 3852 |
|
3617 | 3853 |
|
3618 |
Ember.unwatchKey = function(obj, keyName) { |
|
3619 |
var m = metaFor(obj), watching = m.watching; |
|
3854 |
Ember.unwatchKey = function(obj, keyName, meta) {
|
|
3855 |
var m = meta || metaFor(obj), watching = m.watching;
|
|
3620 | 3856 |
|
3621 | 3857 |
if (watching[keyName] === 1) { |
3622 | 3858 |
watching[keyName] = 0; |
... | ... | |
3628 | 3864 |
if (MANDATORY_SETTER && keyName in obj) { |
3629 | 3865 |
o_defineProperty(obj, keyName, { |
3630 | 3866 |
configurable: true, |
3631 |
enumerable: true, |
|
3632 |
writable: true, |
|
3633 |
value: m.values[keyName] |
|
3867 |
enumerable: obj.propertyIsEnumerable(keyName), |
|
3868 |
set: function(val) { |
|
3869 |
// redefine to set as enumerable |
|
3870 |
o_defineProperty(obj, keyName, { |
|
3871 |
configurable: true, |
|
3872 |
writable: true, |
|
3873 |
enumerable: true, |
|
3874 |
value: val |
|
3875 |
}); |
|
3876 |
delete m.values[keyName]; |
|
3877 |
}, |
|
3878 |
get: Ember.DEFAULT_GETTER_FUNCTION(keyName) |
|
3634 | 3879 |
}); |
3635 |
delete m.values[keyName]; |
|
3636 | 3880 |
} |
3637 | 3881 |
} else if (watching[keyName] > 1) { |
3638 | 3882 |
watching[keyName]--; |
... | ... | |
3651 | 3895 |
warn = Ember.warn, |
3652 | 3896 |
watchKey = Ember.watchKey, |
3653 | 3897 |
unwatchKey = Ember.unwatchKey, |
3654 |
FIRST_KEY = /^([^\.\*]+)/; |
|
3898 |
FIRST_KEY = /^([^\.\*]+)/, |
|
3899 |
META_KEY = Ember.META_KEY; |
|
3655 | 3900 |
|
3656 | 3901 |
function firstKey(path) { |
3657 | 3902 |
return path.match(FIRST_KEY)[0]; |
... | ... | |
3685 | 3930 |
|
3686 | 3931 |
if (!nodes[keyName]) { nodes[keyName] = []; } |
3687 | 3932 |
nodes[keyName].push(node); |
3688 |
watchKey(obj, keyName); |
|
3933 |
watchKey(obj, keyName, m);
|
|
3689 | 3934 |
} |
3690 | 3935 |
|
3691 | 3936 |
var removeChainWatcher = Ember.removeChainWatcher = function(obj, keyName, node) { |
3692 | 3937 |
if (!obj || 'object' !== typeof obj) { return; } // nothing to do |
3693 | 3938 |
|
3694 |
var m = metaFor(obj, false);
|
|
3695 |
if (!m.hasOwnProperty('chainWatchers')) { return; } // nothing to do |
|
3939 |
var m = obj[META_KEY];
|
|
3940 |
if (m && !m.hasOwnProperty('chainWatchers')) { return; } // nothing to do
|
|
3696 | 3941 |
|
3697 |
var nodes = m.chainWatchers; |
|
3942 |
var nodes = m && m.chainWatchers;
|
|
3698 | 3943 |
|
3699 |
if (nodes[keyName]) { |
|
3944 |
if (nodes && nodes[keyName]) {
|
|
3700 | 3945 |
nodes = nodes[keyName]; |
3701 | 3946 |
for (var i = 0, l = nodes.length; i < l; i++) { |
3702 | 3947 |
if (nodes[i] === node) { nodes.splice(i, 1); } |
3703 | 3948 |
} |
3704 | 3949 |
} |
3705 |
unwatchKey(obj, keyName); |
|
3950 |
unwatchKey(obj, keyName, m);
|
|
3706 | 3951 |
}; |
3707 | 3952 |
|
3708 | 3953 |
// A ChainNode watches a single key on an object. If you provide a starting |
... | ... | |
3742 | 3987 |
function lazyGet(obj, key) { |
3743 | 3988 |
if (!obj) return undefined; |
3744 | 3989 |
|
3745 |
var meta = metaFor(obj, false);
|
|
3990 |
var meta = obj[META_KEY];
|
|
3746 | 3991 |
// check if object meant only to be a prototype |
3747 |
if (meta.proto === obj) return undefined; |
|
3992 |
if (meta && meta.proto === obj) return undefined;
|
|
3748 | 3993 |
|
3749 | 3994 |
if (key === "@each") return get(obj, key); |
3750 | 3995 |
|
3751 | 3996 |
// if a CP only return cached value |
3752 |
var desc = meta.descs[key]; |
|
3997 |
var desc = meta && meta.descs[key];
|
|
3753 | 3998 |
if (desc && desc._cacheable) { |
3754 | 3999 |
if (key in meta.cache) { |
3755 | 4000 |
return meta.cache[key]; |
... | ... | |
3961 | 4206 |
}; |
3962 | 4207 |
|
3963 | 4208 |
Ember.finishChains = function(obj) { |
3964 |
var m = metaFor(obj, false), chains = m.chains; |
|
4209 |
// We only create meta if we really have to |
|
4210 |
var m = obj[META_KEY], chains = m && m.chains; |
|
3965 | 4211 |
if (chains) { |
3966 | 4212 |
if (chains.value() !== obj) { |
3967 |
m.chains = chains = chains.copy(obj); |
|
4213 |
metaFor(obj).chains = chains = chains.copy(obj); |
|
4214 |
} else { |
|
4215 |
chains.didChange(null); |
|
3968 | 4216 |
} |
3969 |
chains.didChange(null); |
|
3970 | 4217 |
} |
3971 | 4218 |
}; |
3972 | 4219 |
|
... | ... | |
3977 | 4224 |
(function() { |
3978 | 4225 |
/** |
3979 | 4226 |
@module ember-metal |
3980 |
*/ |
|
4227 |
*/ |
|
4228 |
|
|
4229 |
var forEach = Ember.EnumerableUtils.forEach, |
|
4230 |
BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/; |
|
4231 |
|
|
4232 |
/** |
|
4233 |
Expands `pattern`, invoking `callback` for each expansion. |
|
4234 |
|
|
4235 |
The only pattern supported is brace-expansion, anything else will be passed |
|
4236 |
once to `callback` directly. Brace expansion can only appear at the end of a |
|
4237 |
pattern, for example as the last item in a chain. |
|
4238 |
|
|
4239 |
Example |
|
4240 |
```js |
|
4241 |
function echo(arg){ console.log(arg); } |
|
4242 |
|
|
4243 |
Ember.expandProperties('foo.bar', echo); //=> 'foo.bar' |
|
4244 |
Ember.expandProperties('{foo,bar}', echo); //=> 'foo', 'bar' |
|
4245 |
Ember.expandProperties('foo.{bar,baz}', echo); //=> 'foo.bar', 'foo.baz' |
|
4246 |
Ember.expandProperties('{foo,bar}.baz', echo); //=> '{foo,bar}.baz' |
|
4247 |
``` |
|
4248 |
|
|
4249 |
@method |
|
4250 |
@private |
|
4251 |
@param {string} pattern The property pattern to expand. |
|
4252 |
@param {function} callback The callback to invoke. It is invoked once per |
|
4253 |
expansion, and is passed the expansion. |
|
4254 |
*/ |
|
4255 |
Ember.expandProperties = function (pattern, callback) { |
|
4256 |
var match, prefix, list; |
|
3981 | 4257 |
|
4258 |
if (match = BRACE_EXPANSION.exec(pattern)) { |
|
4259 |
prefix = match[1]; |
|
4260 |
list = match[2]; |
|
4261 |
|
|
4262 |
forEach(list.split(','), function (suffix) { |
|
4263 |
callback(prefix + suffix); |
|
4264 |
}); |
|
4265 |
} else { |
|
4266 |
callback(pattern); |
|
4267 |
} |
|
4268 |
}; |
|
3982 | 4269 |
|
3983 | 4270 |
})(); |
3984 | 4271 |
|
... | ... | |
3992 | 4279 |
// get the chains for the current object. If the current object has |
3993 | 4280 |
// chains inherited from the proto they will be cloned and reconfigured for |
3994 | 4281 |
// the current object. |
3995 |
function chainsFor(obj) { |
|
3996 |
var m = metaFor(obj), ret = m.chains; |
|
4282 |
function chainsFor(obj, meta) {
|
|
4283 |
var m = meta || metaFor(obj), ret = m.chains;
|
|
3997 | 4284 |
if (!ret) { |
3998 | 4285 |
ret = m.chains = new ChainNode(null, null, obj); |
3999 | 4286 |
} else if (ret.value() !== obj) { |
... | ... | |
4002 | 4289 |
return ret; |
4003 | 4290 |
} |
4004 | 4291 |
|
4005 |
Ember.watchPath = function(obj, keyPath) { |
|
4292 |
Ember.watchPath = function(obj, keyPath, meta) {
|
|
4006 | 4293 |
// can't watch length on Array - it is special... |
4007 | 4294 |
if (keyPath === 'length' && typeOf(obj) === 'array') { return; } |
4008 | 4295 |
|
4009 |
var m = metaFor(obj), watching = m.watching; |
|
4296 |
var m = meta || metaFor(obj), watching = m.watching;
|
|
4010 | 4297 |
|
4011 | 4298 |
if (!watching[keyPath]) { // activate watching first time |
4012 | 4299 |
watching[keyPath] = 1; |
4013 |
chainsFor(obj).add(keyPath); |
|
4300 |
chainsFor(obj, m).add(keyPath);
|
|
4014 | 4301 |
} else { |
4015 | 4302 |
watching[keyPath] = (watching[keyPath] || 0) + 1; |
4016 | 4303 |
} |
4017 | 4304 |
}; |
4018 | 4305 |
|
4019 |
Ember.unwatchPath = function(obj, keyPath) { |
|
4020 |
var m = metaFor(obj), watching = m.watching; |
|
4306 |
Ember.unwatchPath = function(obj, keyPath, meta) {
|
|
4307 |
var m = meta || metaFor(obj), watching = m.watching;
|
|
4021 | 4308 |
|
4022 | 4309 |
if (watching[keyPath] === 1) { |
4023 | 4310 |
watching[keyPath] = 0; |
4024 |
chainsFor(obj).remove(keyPath); |
|
4311 |
chainsFor(obj, m).remove(keyPath);
|
|
4025 | 4312 |
} else if (watching[keyPath] > 1) { |
4026 | 4313 |
watching[keyPath]--; |
4027 | 4314 |
} |
... | ... | |
4047 | 4334 |
generateGuid = Ember.generateGuid, |
4048 | 4335 |
IS_PATH = /[\.\*]/; |
4049 | 4336 |
|
4050 |
|
|
4051 | 4337 |
// returns true if the passed path is just a keyName |
4052 | 4338 |
function isKeyName(path) { |
4053 | 4339 |
return path==='*' || !IS_PATH.test(path); |
4054 | 4340 |
} |
4055 | 4341 |
|
4056 | 4342 |
/** |
4057 |
@private |
|
4058 |
|
|
4059 | 4343 |
Starts watching a property on an object. Whenever the property changes, |
4060 | 4344 |
invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the |
4061 | 4345 |
primitive used by observers and dependent keys; usually you will never call |
4062 | 4346 |
this method directly but instead use higher level methods like |
4063 | 4347 |
`Ember.addObserver()` |
4064 | 4348 |
|
4349 |
@private |
|
4065 | 4350 |
@method watch |
4066 | 4351 |
@for Ember |
4067 | 4352 |
@param obj |
4068 | 4353 |
@param {String} keyName |
4069 | 4354 |
*/ |
4070 |
Ember.watch = function(obj, _keyPath) { |
|
4355 |
Ember.watch = function(obj, _keyPath, m) {
|
|
4071 | 4356 |
// can't watch length on Array - it is special... |
4072 | 4357 |
if (_keyPath === 'length' && typeOf(obj) === 'array') { return; } |
4073 | 4358 |
|
4074 |
|
|
4075 |
if (isKeyName(_keyPath)) { |
|
4076 |
watchKey(obj, _keyPath); |
|
4077 |
} else { |
|
4078 |
watchPath(obj, _keyPath); |
|
4079 |
} |
|
4080 |
|
|
4359 |
if (isKeyName(_keyPath)) { |
|
4360 |
watchKey(obj, _keyPath, m); |
|
4361 |
} else { |
|
4362 |
watchPath(obj, _keyPath, m); |
|
4363 |
} |
|
4081 | 4364 |
}; |
4082 | 4365 |
|
4083 | 4366 |
Ember.isWatching = function isWatching(obj, key) { |
... | ... | |
4087 | 4370 |
|
4088 | 4371 |
Ember.watch.flushPending = Ember.flushPendingChains; |
4089 | 4372 |
|
4090 |
Ember.unwatch = function(obj, _keyPath) { |
|
4373 |
Ember.unwatch = function(obj, _keyPath, m) {
|
|
4091 | 4374 |
// can't watch length on Array - it is special... |
4092 | 4375 |
if (_keyPath === 'length' && typeOf(obj) === 'array') { return; } |
4093 | 4376 |
|
4094 |
|
|
4095 |
if (isKeyName(_keyPath)) { |
|
4096 |
unwatchKey(obj, _keyPath); |
|
4097 |
} else { |
|
4098 |
unwatchPath(obj, _keyPath); |
|
4099 |
} |
|
4100 |
|
|
4377 |
if (isKeyName(_keyPath)) { |
|
4378 |
unwatchKey(obj, _keyPath, m); |
|
4379 |
} else { |
|
4380 |
unwatchPath(obj, _keyPath, m); |
|
4381 |
} |
|
4101 | 4382 |
}; |
4102 | 4383 |
|
4103 | 4384 |
/** |
4104 |
@private |
|
4105 |
|
|
4106 | 4385 |
Call on an object when you first beget it from another object. This will |
4107 | 4386 |
setup any chained watchers on the object instance as needed. This method is |
4108 | 4387 |
safe to call multiple times. |
4109 | 4388 |
|
4389 |
@private |
|
4110 | 4390 |
@method rewatch |
4111 | 4391 |
@for Ember |
4112 | 4392 |
@param obj |
4113 | 4393 |
*/ |
4114 | 4394 |
Ember.rewatch = function(obj) { |
4115 |
var m = metaFor(obj, false), chains = m.chains;
|
|
4395 |
var m = obj[META_KEY], chains = m && m.chains;
|
|
4116 | 4396 |
|
4117 | 4397 |
// make sure the object has its own guid. |
4118 | 4398 |
if (GUID_KEY in obj && !obj.hasOwnProperty(GUID_KEY)) { |
... | ... | |
4189 | 4469 |
watch = Ember.watch, |
4190 | 4470 |
unwatch = Ember.unwatch; |
4191 | 4471 |
|
4472 |
var expandProperties = Ember.expandProperties; |
|
4192 | 4473 |
|
4193 | 4474 |
// .......................................................... |
4194 | 4475 |
// DEPENDENT KEYS |
... | ... | |
4238 | 4519 |
// Increment the number of times depKey depends on keyName. |
4239 | 4520 |
keys[keyName] = (keys[keyName] || 0) + 1; |
4240 | 4521 |
// Watch the depKey |
4241 |
watch(obj, depKey); |
|
4522 |
watch(obj, depKey, meta);
|
|
4242 | 4523 |
} |
4243 | 4524 |
} |
4244 | 4525 |
|
... | ... | |
4257 | 4538 |
// Increment the number of times depKey depends on keyName. |
4258 | 4539 |
keys[keyName] = (keys[keyName] || 0) - 1; |
4259 | 4540 |
// Watch the depKey |
4260 |
unwatch(obj, depKey); |
|
4541 |
unwatch(obj, depKey, meta);
|
|
4261 | 4542 |
} |
4262 | 4543 |
} |
4263 | 4544 |
|
... | ... | |
4348 | 4629 |
*/ |
4349 | 4630 |
function ComputedProperty(func, opts) { |
4350 | 4631 |
this.func = func; |
4632 |
|
|
4633 |
this._dependentKeys = opts && opts.dependentKeys; |
|
4634 |
|
|
4351 | 4635 |
|
4352 | 4636 |
this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true; |
4353 |
this._dependentKeys = opts && opts.dependentKeys; |
|
4354 | 4637 |
this._readOnly = opts && (opts.readOnly !== undefined || !!opts.readOnly); |
4355 | 4638 |
} |
4356 | 4639 |
|
... | ... | |
4359 | 4642 |
|
4360 | 4643 |
var ComputedPropertyPrototype = ComputedProperty.prototype; |
4361 | 4644 |
|
4645 |
|
|
4362 | 4646 |
/** |
4363 | 4647 |
Properties are cacheable by default. Computed property will automatically |
4364 | 4648 |
cache the return value of your function until one of the dependent keys changes. |
... | ... | |
4384 | 4668 |
mode the computed property will not automatically cache the return value. |
4385 | 4669 |
|
4386 | 4670 |
```javascript |
4387 |
MyApp.outsideService = Ember.Object.create({
|
|
4671 |
MyApp.outsideService = Ember.Object.extend({
|
|
4388 | 4672 |
value: function() { |
4389 | 4673 |
return OutsideService.getValue(); |
4390 | 4674 |
}.property().volatile() |
4391 |
}); |
|
4675 |
}).create();
|
|
4392 | 4676 |
``` |
4393 | 4677 |
|
4394 | 4678 |
@method volatile |
... | ... | |
4404 | 4688 |
mode the computed property will throw an error when set. |
4405 | 4689 |
|
4406 | 4690 |
```javascript |
4407 |
MyApp.person = Ember.Object.create({
|
|
4691 |
MyApp.Person = Ember.Object.extend({
|
|
4408 | 4692 |
guid: function() { |
4409 | 4693 |
return 'guid-guid-guid'; |
4410 | 4694 |
}.property().readOnly() |
4411 | 4695 |
}); |
4412 | 4696 |
|
4697 |
MyApp.person = MyApp.Person.create(); |
|
4698 |
|
|
4413 | 4699 |
MyApp.person.set('guid', 'new-guid'); // will throw an exception |
4414 | 4700 |
``` |
4415 | 4701 |
|
... | ... | |
4427 | 4713 |
arguments containing key paths that this computed property depends on. |
4428 | 4714 |
|
4429 | 4715 |
```javascript |
4430 |
MyApp.president = Ember.Object.create({
|
|
4716 |
MyApp.President = Ember.Object.extend({
|
|
4431 | 4717 |
fullName: Ember.computed(function() { |
4432 | 4718 |
return this.get('firstName') + ' ' + this.get('lastName'); |
4433 | 4719 |
|
... | ... | |
4435 | 4721 |
// and lastName |
4436 | 4722 |
}).property('firstName', 'lastName') |
4437 | 4723 |
}); |
4724 |
|
|
4725 |
MyApp.president = MyApp.President.create({ |
|
4726 |
firstName: 'Barack', |
|
4727 |
lastName: 'Obama', |
|
4728 |
}); |
|
4729 |
MyApp.president.get('fullName'); // Barack Obama |
|
4438 | 4730 |
``` |
4439 | 4731 |
|
4440 | 4732 |
@method property |
... | ... | |
4443 | 4735 |
@chainable |
4444 | 4736 |
*/ |
4445 | 4737 |
ComputedPropertyPrototype.property = function() { |
4446 |
var addArg;
|
|
4738 |
var args;
|
|
4447 | 4739 |
|
4448 |
|
|
4449 |
var args = []; |
|
4740 |
var addArg = function (property) { |
|
4741 |
args.push(property); |
|
4742 |
}; |
|
4743 |
|
|
4744 |
args = []; |
|
4450 | 4745 |
for (var i = 0, l = arguments.length; i < l; i++) { |
4451 |
|
|
4452 |
args.push(arguments[i]); |
|
4453 |
|
|
4746 |
expandProperties(arguments[i], addArg); |
|
4454 | 4747 |
} |
4455 |
this._dependentKeys = args; |
|
4748 |
|
|
4749 |
|
|
4750 |
this._dependentKeys = args; |
|
4751 |
|
|
4752 |
|
|
4456 | 4753 |
return this; |
4457 | 4754 |
}; |
4458 | 4755 |
|
... | ... | |
4579 | 4876 |
funcArgLength, cachedValue, ret; |
4580 | 4877 |
|
4581 | 4878 |
if (this._readOnly) { |
4582 |
throw new Ember.Error('Cannot Set: ' + keyName + ' on: ' + obj.toString() );
|
|
4879 |
throw new Ember.Error('Cannot Set: ' + keyName + ' on: ' + Ember.inspect(obj));
|
|
4583 | 4880 |
} |
4584 | 4881 |
|
4585 | 4882 |
this._suspended = obj; |
... | ... | |
4695 | 4992 |
@return {Object} the cached value |
4696 | 4993 |
*/ |
4697 | 4994 |
Ember.cacheFor = function cacheFor(obj, key) { |
4698 |
var cache = metaFor(obj, false).cache; |
|
4995 |
var meta = obj[META_KEY], |
|
4996 |
cache = meta && meta.cache; |
|
4699 | 4997 |
|
4700 | 4998 |
if (cache && key in cache) { |
4701 | 4999 |
return cache[key]; |
... | ... | |
4710 | 5008 |
return ret; |
4711 | 5009 |
} |
4712 | 5010 |
|
4713 |
function registerComputed(name, macro) { |
|
4714 |
Ember.computed[name] = function(dependentKey) { |
|
4715 |
var args = a_slice.call(arguments); |
|
4716 |
return Ember.computed(dependentKey, function() { |
|
4717 |
return macro.apply(this, args); |
|
4718 |
}); |
|
5011 |
var registerComputed, registerComputedWithProperties; |
|
5012 |
|
|
5013 |
|
|
5014 |
|
|
5015 |
registerComputed = function (name, macro) { |
|
5016 |
Ember.computed[name] = function(dependentKey) { |
|
5017 |
var args = a_slice.call(arguments); |
|
5018 |
return Ember.computed(dependentKey, function() { |
|
5019 |
return macro.apply(this, args); |
|
5020 |
}); |
|
5021 |
}; |
|
4719 | 5022 |
}; |
4720 |
} |
|
4721 | 5023 |
|
4722 |
function registerComputedWithProperties(name, macro) {
|
|
4723 |
Ember.computed[name] = function() { |
|
4724 |
var properties = a_slice.call(arguments); |
|
5024 |
registerComputedWithProperties = function(name, macro) {
|
|
5025 |
Ember.computed[name] = function() {
|
|
5026 |
var properties = a_slice.call(arguments);
|
|
4725 | 5027 |
|
Also available in: Unified diff