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

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff