dist/ember-runtime.js in ember-source-2.18.2 vs dist/ember-runtime.js in ember-source-3.0.0.beta.1

- old
+ new

@@ -1,20 +1,22 @@ (function() { /*! * @overview Ember - JavaScript Application Framework - * @copyright Copyright 2011-2017 Tilde Inc. and contributors + * @copyright Copyright 2011-2018 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 2.18.2 + * @version 3.0.0-beta.1 */ -/*global process */ +/*globals process */ var enifed, requireModule, Ember; -var mainContext = this; // Used in ember-environment/lib/global.js +// Used in ember-environment/lib/global.js +mainContext = this; // eslint-disable-line no-undef + (function() { function missingModule(name, referrerName) { if (referrerName) { throw new Error('Could not find module ' + name + ' required by: ' + referrerName); } else { @@ -111,43 +113,24 @@ enifed = Ember.__loader.define; requireModule = Ember.__loader.require; } })(); -enifed('container', ['exports', 'ember-babel', 'ember-utils', 'ember-debug', 'ember/features'], function (exports, _emberBabel, _emberUtils, _emberDebug, _features) { +enifed('container', ['exports', 'ember-babel', 'ember-utils', 'ember-debug', 'ember/features', 'ember-environment'], function (exports, _emberBabel, _emberUtils, _emberDebug, _features, _emberEnvironment) { 'use strict'; exports.Container = exports.privatize = exports.Registry = undefined; - - /* globals Proxy */ - var CONTAINER_OVERRIDE = (0, _emberUtils.symbol)('CONTAINER_OVERRIDE'); - - /** - A container used to instantiate and cache objects. - - Every `Container` must be associated with a `Registry`, which is referenced - to determine the factory and options that should be used to instantiate - objects. - - The public API for `Container` is still in flux and should not be considered - stable. - - @private - @class Container - */ - var Container = function () { function Container(registry) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; (0, _emberBabel.classCallCheck)(this, Container); this.registry = registry; this.owner = options.owner || null; this.cache = (0, _emberUtils.dictionary)(options.cache || null); this.factoryManagerCache = (0, _emberUtils.dictionary)(options.factoryManagerCache || null); - this[CONTAINER_OVERRIDE] = undefined; this.isDestroyed = false; if (true) { this.validationCache = (0, _emberUtils.dictionary)(options.validationCache || null); } @@ -295,11 +278,11 @@ * set on the manager. */ function wrapManagerInDeprecationProxy(manager) { if (_emberUtils.HAS_NATIVE_PROXY) { var validator = { - set: function (obj, prop, value) { + set: function (obj, prop) { throw new Error('You attempted to set "' + prop + '" on a factory manager created by container#factoryFor. A factory manager is a read-only construct.'); } }; // Note: @@ -556,10 +539,11 @@ return FactoryManager; }(); var VALID_FULL_NAME_REGEXP = /^[^:]+:[^:]+$/; + var missingResolverFunctionsDeprecation = 'Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.'; /** A registry used to store factory and option information keyed by type. @@ -579,11 +563,15 @@ (0, _emberBabel.classCallCheck)(this, Registry); this.fallback = options.fallback || null; this.resolver = options.resolver || null; - if (typeof this.resolver === 'function') { + if (_emberEnvironment.ENV._ENABLE_RESOLVER_FUNCTION_SUPPORT !== true) { + (true && !(typeof this.resolver !== 'function') && (0, _emberDebug.assert)(missingResolverFunctionsDeprecation, typeof this.resolver !== 'function')); + } + + if (typeof this.resolver === 'function' && _emberEnvironment.ENV._ENABLE_RESOLVER_FUNCTION_SUPPORT === true) { deprecateResolverFunction(this); } this.registrations = (0, _emberUtils.dictionary)(options.registrations || null); @@ -591,11 +579,11 @@ this._injections = (0, _emberUtils.dictionary)(null); this._localLookupCache = Object.create(null); this._normalizeCache = (0, _emberUtils.dictionary)(null); this._resolveCache = (0, _emberUtils.dictionary)(null); - this._failCache = (0, _emberUtils.dictionary)(null); + this._failSet = new Set(); this._options = (0, _emberUtils.dictionary)(null); this._typeOptions = (0, _emberUtils.dictionary)(null); } @@ -676,11 +664,11 @@ var normalizedName = this.normalize(fullName); (true && !(!this._resolveCache[normalizedName]) && (0, _emberDebug.assert)('Cannot re-register: \'' + fullName + '\', as it has already been resolved.', !this._resolveCache[normalizedName])); - delete this._failCache[normalizedName]; + this._failSet.delete(normalizedName); this.registrations[normalizedName] = factory; this._options[normalizedName] = options; }; Registry.prototype.unregister = function unregister(fullName) { @@ -691,12 +679,12 @@ this._localLookupCache = Object.create(null); delete this.registrations[normalizedName]; delete this._resolveCache[normalizedName]; - delete this._failCache[normalizedName]; delete this._options[normalizedName]; + this._failSet.delete(normalizedName); }; Registry.prototype.resolve = function resolve(fullName, options) { (true && !(this.isValidFullName(fullName)) && (0, _emberDebug.assert)('fullName must be a proper full name', this.isValidFullName(fullName))); @@ -830,13 +818,10 @@ injections.push({ property: property, fullName: normalizedInjectionName }); }; Registry.prototype.knownForType = function knownForType(type) { - var fallbackKnown = void 0, - resolverKnown = void 0; - var localKnown = (0, _emberUtils.dictionary)(null); var registeredNames = Object.keys(this.registrations); for (var index = 0; index < registeredNames.length; index++) { var fullName = registeredNames[index]; var itemType = fullName.split(':')[0]; @@ -844,10 +829,12 @@ if (itemType === type) { localKnown[fullName] = true; } } + var fallbackKnown = void 0, + resolverKnown = void 0; if (this.fallback !== null) { fallbackKnown = this.fallback.knownForType(type); } if (this.resolver !== null && this.resolver.knownForType) { @@ -905,11 +892,11 @@ return Registry; }(); function deprecateResolverFunction(registry) { - (true && !(false) && (0, _emberDebug.deprecate)('Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.', false, { id: 'ember-application.registry-resolver-as-function', until: '3.0.0', url: 'https://emberjs.com/deprecations/v2.x#toc_registry-resolver-as-function' })); + (true && !(false) && (0, _emberDebug.deprecate)(missingResolverFunctionsDeprecation, false, { id: 'ember-application.registry-resolver-as-function', until: '3.0.0', url: 'https://emberjs.com/deprecations/v2.x#toc_registry-resolver-as-function' })); registry.resolver = { resolve: registry.resolver }; } if (true) { @@ -989,11 +976,11 @@ var cacheKey = registry.resolverCacheKey(normalizedName, options); var cached = registry._resolveCache[cacheKey]; if (cached !== undefined) { return cached; } - if (registry._failCache[cacheKey]) { + if (registry._failSet.has(cacheKey)) { return; } var resolved = void 0; @@ -1004,11 +991,11 @@ if (resolved === undefined) { resolved = registry.registrations[normalizedName]; } if (resolved === undefined) { - registry._failCache[cacheKey] = true; + registry._failSet.add(cacheKey); } else { registry._resolveCache[cacheKey] = resolved; } return resolved; @@ -1118,142 +1105,52 @@ return call && (typeof call === 'object' || typeof call === 'function') ? call : self; }; var slice = exports.slice = Array.prototype.slice; }); -enifed('ember-console', ['exports', 'ember-environment'], function (exports, _emberEnvironment) { - 'use strict'; +enifed("ember-console", ["exports"], function (exports) { + "use strict"; - function K() {} - - function consoleMethod(name) { - var consoleObj = void 0; - if (_emberEnvironment.context.imports.console) { - consoleObj = _emberEnvironment.context.imports.console; - } else if (typeof console !== 'undefined') { - // eslint-disable-line no-undef - consoleObj = console; // eslint-disable-line no-undef - } - - var method = typeof consoleObj === 'object' ? consoleObj[name] : null; - - if (typeof method !== 'function') { - return; - } - - return method.bind(consoleObj); - } - - function assertPolyfill(test, message) { - if (!test) { - try { - // attempt to preserve the stack - throw new Error('assertion failed: ' + message); - } catch (error) { - setTimeout(function () { - throw error; - }, 0); - } - } - } - /** Inside Ember-Metal, simply uses the methods from `imports.console`. Override this to provide more robust logging functionality. @class Logger @namespace Ember @public */ var index = { - /** - Logs the arguments to the console. - You can pass as many arguments as you want and they will be joined together with a space. - ```javascript - var foo = 1; - Ember.Logger.log('log value of foo:', foo); - // "log value of foo: 1" will be printed to the console - ``` - @method log - @for Ember.Logger - @param {*} arguments - @public - */ - log: consoleMethod('log') || K, + log: function () { + var _console; - /** - Prints the arguments to the console with a warning icon. - You can pass as many arguments as you want and they will be joined together with a space. - ```javascript - Ember.Logger.warn('Something happened!'); - // "Something happened!" will be printed to the console with a warning icon. - ``` - @method warn - @for Ember.Logger - @param {*} arguments - @public - */ - warn: consoleMethod('warn') || K, + return (_console = console).log.apply(_console, arguments); + }, + warn: function () { + var _console2; - /** - Prints the arguments to the console with an error icon, red text and a stack trace. - You can pass as many arguments as you want and they will be joined together with a space. - ```javascript - Ember.Logger.error('Danger! Danger!'); - // "Danger! Danger!" will be printed to the console in red text. - ``` - @method error - @for Ember.Logger - @param {*} arguments - @public - */ - error: consoleMethod('error') || K, + return (_console2 = console).warn.apply(_console2, arguments); + }, + error: function () { + var _console3; - /** - Logs the arguments to the console. - You can pass as many arguments as you want and they will be joined together with a space. - ```javascript - var foo = 1; - Ember.Logger.info('log value of foo:', foo); - // "log value of foo: 1" will be printed to the console - ``` - @method info - @for Ember.Logger - @param {*} arguments - @public - */ - info: consoleMethod('info') || K, + return (_console3 = console).error.apply(_console3, arguments); + }, + info: function () { + var _console4; - /** - Logs the arguments to the console in blue text. - You can pass as many arguments as you want and they will be joined together with a space. - ```javascript - var foo = 1; - Ember.Logger.debug('log value of foo:', foo); - // "log value of foo: 1" will be printed to the console - ``` - @method debug - @for Ember.Logger - @param {*} arguments - @public - */ - debug: consoleMethod('debug') || consoleMethod('info') || K, + return (_console4 = console).info.apply(_console4, arguments); + }, + debug: function () { + var _console5, _console6; - /** - If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace. - ```javascript - Ember.Logger.assert(true); // undefined - Ember.Logger.assert(true === false); // Throws an Assertion failed error. - Ember.Logger.assert(true === false, 'Something invalid'); // Throws an Assertion failed error with message. - ``` - @method assert - @for Ember.Logger - @param {Boolean} bool Value to test - @param {String} message Assertion message on failed - @public - */ - assert: consoleMethod('assert') || assertPolyfill + return console.debug && (_console5 = console).debug.apply(_console5, arguments) || (_console6 = console).info.apply(_console6, arguments); // eslint-disable-line no-console + }, + assert: function () { + var _console7; + + return (_console7 = console).assert.apply(_console7, arguments); + } }; exports.default = index; }); enifed('ember-environment', ['exports'], function (exports) { @@ -1394,36 +1291,34 @@ // TODO: cleanup single source of truth issues with this stuff var environment = hasDOM ? { hasDOM: true, isChrome: !!window.chrome && !window.opera, isFirefox: typeof InstallTrigger !== 'undefined', - isPhantom: !!window.callPhantom, location: window.location, history: window.history, userAgent: window.navigator.userAgent, window: window } : { hasDOM: false, isChrome: false, isFirefox: false, - isPhantom: false, location: null, history: null, userAgent: 'Lynx (textmode)', window: null }; exports.ENV = ENV; exports.context = context; exports.environment = environment; }); -enifed('ember-metal', ['exports', 'ember-environment', 'ember-utils', 'ember-debug', 'ember-babel', 'ember/features', '@glimmer/reference', 'require', 'ember-console', 'backburner'], function (exports, emberEnvironment, emberUtils, emberDebug, emberBabel, ember_features, _glimmer_reference, require, Logger, Backburner) { +enifed('ember-metal', ['exports', 'ember-environment', 'ember-utils', 'ember-debug', 'ember/features', 'ember-babel', '@glimmer/reference', 'require', 'backburner', 'ember-console'], function (exports, emberEnvironment, emberUtils, emberDebug, features, emberBabel, reference, require, Backburner, Logger) { 'use strict'; - require = 'default' in require ? require['default'] : require; - Logger = 'default' in Logger ? Logger['default'] : Logger; - Backburner = 'default' in Backburner ? Backburner['default'] : Backburner; + require = require && require.hasOwnProperty('default') ? require['default'] : require; + Backburner = Backburner && Backburner.hasOwnProperty('default') ? Backburner['default'] : Backburner; + Logger = Logger && Logger.hasOwnProperty('default') ? Logger['default'] : Logger; /** @module ember */ @@ -1640,16 +1535,21 @@ @param {Boolean} once A flag whether a function should only be called once @public */ function addListener(obj, eventName, target, method, once) { true && !(!!obj && !!eventName) && emberDebug.assert('You must pass at least an object and event name to addListener', !!obj && !!eventName); - true && !(eventName !== 'didInitAttrs') && emberDebug.deprecate('didInitAttrs called in ' + (obj && obj.toString && obj.toString()) + '.', eventName !== 'didInitAttrs', { - id: 'ember-views.did-init-attrs', - until: '3.0.0', - url: 'https://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs' - }); + if (emberEnvironment.ENV._ENABLE_DID_INIT_ATTRS_SUPPORT === true) { + true && !(eventName !== 'didInitAttrs') && emberDebug.deprecate('didInitAttrs called in ' + (obj && obj.toString && obj.toString()) + '.', eventName !== 'didInitAttrs', { + id: 'ember-views.did-init-attrs', + until: '3.0.0', + url: 'https://emberjs.com/deprecations/v2.x#toc_ember-component-didinitattrs' + }); + } else { + true && !(eventName !== 'didInitAttrs') && emberDebug.assert('didInitAttrs called in ' + (obj && obj.toString && obj.toString()) + ' is no longer supported.', eventName !== 'didInitAttrs'); + } + if (!method && 'function' === typeof target) { method = target; target = null; } @@ -1744,11 +1644,11 @@ @static @for @ember/object/events @param obj */ function watchedEvents(obj) { - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); return meta$$1 !== undefined ? meta$$1.watchedEvents() : []; } /** Send an event. The execution of suspended listeners @@ -1767,11 +1667,11 @@ @return true @public */ function sendEvent(obj, eventName, params, actions, _meta) { if (actions === undefined) { - var meta$$1 = _meta === undefined ? exports.peekMeta(obj) : _meta; + var meta$$1 = _meta === undefined ? peekMeta(obj) : _meta; actions = typeof meta$$1 === 'object' && meta$$1 !== null && meta$$1.matchingListeners(eventName); } if (actions === undefined || actions.length === 0) { return false; @@ -1819,11 +1719,11 @@ @for @ember/object/events @param obj @param {String} eventName */ function hasListeners(obj, eventName) { - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); if (meta$$1 === undefined) { return false; } var matched = meta$$1.matchingListeners(eventName); return matched !== undefined && matched.length > 0; @@ -1837,11 +1737,11 @@ @param obj @param {String} eventName */ function listenersFor(obj, eventName) { var ret = []; - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); var actions = meta$$1 !== undefined ? meta$$1.matchingListeners(eventName) : undefined; if (actions === undefined) { return ret; } @@ -1910,16 +1810,16 @@ function setHasViews(fn) { hasViews = fn; } function makeTag() { - return new _glimmer_reference.DirtyableTag(); + return new reference.DirtyableTag(); } function tagForProperty(object, propertyKey, _meta) { if (typeof object !== 'object' || object === null) { - return _glimmer_reference.CONSTANT_TAG; + return reference.CONSTANT_TAG; } var meta$$1 = _meta === undefined ? meta(object) : _meta; if (meta$$1.isProxy()) { return tagFor(object, meta$$1); @@ -1937,11 +1837,11 @@ function tagFor(object, _meta) { if (typeof object === 'object' && object !== null) { var meta$$1 = _meta === undefined ? meta(object) : _meta; return meta$$1.writableTag(makeTag); } else { - return _glimmer_reference.CONSTANT_TAG; + return reference.CONSTANT_TAG; } } function markObjectAsDirty(meta$$1, propertyKey) { var objectTag = meta$$1.readableTag(); @@ -2047,196 +1947,38 @@ }; return ObserverSet; }(); - /** - @module ember - */ - var id = 0; - - // Returns whether Type(value) is Object according to the terminology in the spec - function isObject$1(value) { - return typeof value === 'object' && value !== null || typeof value === 'function'; - } - - /* - * @class Ember.WeakMap - * @public - * @category ember-metal-weakmap - * - * A partial polyfill for [WeakMap](http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-objects). - * - * There is a small but important caveat. This implementation assumes that the - * weak map will live longer (in the sense of garbage collection) than all of its - * keys, otherwise it is possible to leak the values stored in the weak map. In - * practice, most use cases satisfy this limitation which is why it is included - * in ember-metal. - */ - var WeakMapPolyfill = function () { - function WeakMapPolyfill(iterable) { - emberBabel.classCallCheck(this, WeakMapPolyfill); - - this._id = emberUtils.GUID_KEY + id++; - - if (iterable === null || iterable === undefined) { - return; - } else if (Array.isArray(iterable)) { - for (var i = 0; i < iterable.length; i++) { - var _iterable$i = iterable[i], - key = _iterable$i[0], - value = _iterable$i[1]; - - this.set(key, value); - } - } else { - throw new TypeError('The weak map constructor polyfill only supports an array argument'); - } - } - - /* - * @method get - * @param key {Object | Function} - * @return {Any} stored value - */ - - WeakMapPolyfill.prototype.get = function get(obj) { - if (!isObject$1(obj)) { - return undefined; - } - - var meta$$1 = exports.peekMeta(obj); - if (meta$$1 !== undefined) { - var map = meta$$1.readableWeak(); - if (map !== undefined) { - var val = map[this._id]; - if (val === UNDEFINED) { - return undefined; - } - return val; - } - } - }; - - /* - * @method set - * @param key {Object | Function} - * @param value {Any} - * @return {WeakMap} the weak map - */ - - WeakMapPolyfill.prototype.set = function set(obj, value) { - if (!isObject$1(obj)) { - throw new TypeError('Invalid value used as weak map key'); - } - - if (value === undefined) { - value = UNDEFINED; - } - - meta(obj).writableWeak()[this._id] = value; - - return this; - }; - - /* - * @method has - * @param key {Object | Function} - * @return {boolean} if the key exists - */ - - WeakMapPolyfill.prototype.has = function has(obj) { - if (!isObject$1(obj)) { - return false; - } - - var meta$$1 = exports.peekMeta(obj); - if (meta$$1 !== undefined) { - var map = meta$$1.readableWeak(); - if (map !== undefined) { - return map[this._id] !== undefined; - } - } - - return false; - }; - - /* - * @method delete - * @param key {Object | Function} - * @return {boolean} if the key was deleted - */ - - WeakMapPolyfill.prototype.delete = function _delete(obj) { - if (this.has(obj)) { - delete exports.peekMeta(obj).writableWeak()[this._id]; - return true; - } else { - return false; - } - }; - - /* - * @method toString - * @return {String} - */ - - WeakMapPolyfill.prototype.toString = function toString$$1() { - return '[object WeakMap]'; - }; - - return WeakMapPolyfill; - }(); - - var WeakMap$1 = emberUtils.HAS_NATIVE_WEAKMAP ? WeakMap : WeakMapPolyfill; - exports.runInTransaction = void 0; exports.didRender = void 0; exports.assertNotRendered = void 0; // detect-backtracking-rerender by default is debug build only - // detect-glimmer-allow-backtracking-rerender can be enabled in custom builds - if (ember_features.EMBER_GLIMMER_DETECT_BACKTRACKING_RERENDER || ember_features.EMBER_GLIMMER_ALLOW_BACKTRACKING_RERENDER) { + if (features.EMBER_GLIMMER_DETECT_BACKTRACKING_RERENDER) { - // there are 4 states + // there are 2 states - // NATIVE WEAKMAP AND DEBUG + // DEBUG // tracks lastRef and lastRenderedIn per rendered object and key during a transaction // release everything via normal weakmap semantics by just derefencing the weakmap - // NATIVE WEAKMAP AND RELEASE + // RELEASE // tracks transactionId per rendered object and key during a transaction // release everything via normal weakmap semantics by just derefencing the weakmap - // WEAKMAP POLYFILL AND DEBUG - // tracks lastRef and lastRenderedIn per rendered object and key during a transaction - // since lastRef retains a lot of app state (will have a ref to the Container) - // if the object rendered is retained (like a immutable POJO in module state) - // during acceptance tests this adds up and obfuscates finding other leaks. - - // WEAKMAP POLYFILL AND RELEASE - // tracks transactionId per rendered object and key during a transaction - // leaks it because small and likely not worth tracking it since it will only - // be leaked if the object is retained - var TransactionRunner = function () { function TransactionRunner() { emberBabel.classCallCheck(this, TransactionRunner); this.transactionId = 0; this.inTransaction = false; this.shouldReflush = false; - this.weakMap = new WeakMap$1(); + this.weakMap = new WeakMap(); { // track templates this.debugStack = undefined; - - if (!emberUtils.HAS_NATIVE_WEAKMAP) { - // DEBUG AND POLYFILL - // needs obj tracking - this.objs = []; - } } } TransactionRunner.prototype.runInTransaction = function runInTransaction(context$$1, methodName) { this.before(context$$1); @@ -2246,17 +1988,17 @@ this.after(); } return this.shouldReflush; }; - TransactionRunner.prototype.didRender = function didRender(object, key, reference) { + TransactionRunner.prototype.didRender = function didRender(object, key, reference$$1) { if (!this.inTransaction) { return; } { this.setKey(object, key, { - lastRef: reference, + lastRef: reference$$1, lastRenderedIn: this.debugStack.peek() }); } }; @@ -2284,17 +2026,11 @@ label = parts.join('.'); } else { label = 'the same value'; } - var message = 'You modified "' + label + '" twice on ' + object + ' in a single render. It was rendered in ' + lastRenderedIn + ' and modified in ' + currentlyIn + '. This was unreliable and slow in Ember 1.x and'; - - if (ember_features.EMBER_GLIMMER_ALLOW_BACKTRACKING_RERENDER) { - true && !false && emberDebug.deprecate(message + ' will be removed in Ember 3.0.', false, { id: 'ember-views.render-double-modify', until: '3.0.0' }); - } else { - true && !false && emberDebug.assert(message + ' is no longer supported. See https://github.com/emberjs/ember.js/issues/13948 for more details.', false); - } + true && !false && emberDebug.assert('You modified "' + label + '" twice on ' + object + ' in a single render. It was rendered in ' + lastRenderedIn + ' and modified in ' + currentlyIn + '. This was unreliable and slow in Ember 1.x and is no longer supported. See https://github.com/emberjs/ember.js/issues/13948 for more details.', false); } this.shouldReflush = true; } }; @@ -2327,15 +2063,10 @@ }; TransactionRunner.prototype.createMap = function createMap(object) { var map = Object.create(null); this.weakMap.set(object, map); - if (true && !emberUtils.HAS_NATIVE_WEAKMAP) { - // POLYFILL AND DEBUG - // requires tracking objects - this.objs.push(object); - } return map; }; TransactionRunner.prototype.getOrCreateMap = function getOrCreateMap(object) { var map = this.weakMap.get(object); @@ -2356,32 +2087,11 @@ return map[key]; } }; TransactionRunner.prototype.clearObjectMap = function clearObjectMap() { - if (emberUtils.HAS_NATIVE_WEAKMAP) { - // NATIVE AND (DEBUG OR RELEASE) - // if we have a real native weakmap - // releasing the ref will allow the values to be GCed - this.weakMap = new WeakMap$1(); - } else { - // POLYFILL AND DEBUG - // with a polyfill the weakmap keys must be cleared since - // they have the last reference, acceptance tests will leak - // the container if you render a immutable object retained - // in module scope. - var objs = this.objs, - weakMap = this.weakMap; - - this.objs = []; - for (var i = 0; i < objs.length; i++) { - weakMap.delete(objs[i]); - } - } - // POLYFILL AND RELEASE - // we leak the key map if the object is retained but this is - // a POJO of keys to transaction ids + this.weakMap = new WeakMap(); }; return TransactionRunner; }(); @@ -2396,11 +2106,187 @@ context$$1[methodName](); return false; }; } + function watchPath(obj, keyPath, meta$$1) { + if (typeof obj !== 'object' || obj === null) { + return; + } + var m = meta$$1 === undefined ? meta(obj) : meta$$1; + var counter = m.peekWatching(keyPath) || 0; + + m.writeWatching(keyPath, counter + 1); + if (counter === 0) { + // activate watching first time + m.writableChains(makeChainNode).add(keyPath); + } + } + + function unwatchPath(obj, keyPath, meta$$1) { + if (typeof obj !== 'object' || obj === null) { + return; + } + var m = meta$$1 === undefined ? peekMeta(obj) : meta$$1; + + if (m === undefined) { + return; + } + var counter = m.peekWatching(keyPath) || 0; + + if (counter === 1) { + m.writeWatching(keyPath, 0); + m.writableChains(makeChainNode).remove(keyPath); + } else if (counter > 1) { + m.writeWatching(keyPath, counter - 1); + } + } + /** + @module ember + */ + /** + Starts watching a property on an object. Whenever the property changes, + invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the + primitive used by observers and dependent keys; usually you will never call + this method directly but instead use higher level methods like + `Ember.addObserver()` + + @private + @method watch + @for Ember + @param obj + @param {String} _keyPath + */ + function watch(obj, _keyPath, m) { + if (isPath(_keyPath)) { + watchPath(obj, _keyPath, m); + } else { + watchKey(obj, _keyPath, m); + } + } + + function isWatching(obj, key) { + return watcherCount(obj, key) > 0; + } + + function watcherCount(obj, key) { + var meta$$1 = peekMeta(obj); + return meta$$1 !== undefined && meta$$1.peekWatching(key) || 0; + } + + function unwatch(obj, _keyPath, m) { + if (isPath(_keyPath)) { + unwatchPath(obj, _keyPath, m); + } else { + unwatchKey(obj, _keyPath, m); + } + } + + /** + @module @ember/object + */ + + var AFTER_OBSERVERS = ':change'; + var BEFORE_OBSERVERS = ':before'; + + function changeEvent(keyName) { + return keyName + AFTER_OBSERVERS; + } + + function beforeEvent(keyName) { + return keyName + BEFORE_OBSERVERS; + } + + /** + @method addObserver + @static + @for @ember/object/observers + @param obj + @param {String} _path + @param {Object|Function} target + @param {Function|String} [method] + @public + */ + function addObserver(obj, _path, target, method) { + addListener(obj, changeEvent(_path), target, method); + watch(obj, _path); + + return this; + } + + function observersFor(obj, path) { + return listenersFor(obj, changeEvent(path)); + } + + /** + @method removeObserver + @static + @for @ember/object/observers + @param obj + @param {String} path + @param {Object|Function} target + @param {Function|String} [method] + @public + */ + function removeObserver(obj, path, target, method) { + unwatch(obj, path); + removeListener(obj, changeEvent(path), target, method); + + return this; + } + + /** + @method _addBeforeObserver + @static + @for @ember/object/observers + @param obj + @param {String} path + @param {Object|Function} target + @param {Function|String} [method] + @deprecated + @private + */ + function _addBeforeObserver(obj, path, target, method) { + addListener(obj, beforeEvent(path), target, method); + watch(obj, path); + + return this; + } + + // Suspend observer during callback. + // + // This should only be used by the target of the observer + // while it is setting the observed path. + function _suspendObserver(obj, path, target, method, callback) { + return suspendListener(obj, changeEvent(path), target, method, callback); + } + + function _suspendObservers(obj, paths, target, method, callback) { + var events = paths.map(changeEvent); + return suspendListeners(obj, events, target, method, callback); + } + + /** + @method removeBeforeObserver + @static + @for @ember/object/observers + @param obj + @param {String} path + @param {Object|Function} target + @param {Function|String} [method] + @deprecated + @private + */ + function _removeBeforeObserver(obj, path, target, method) { + unwatch(obj, path); + removeListener(obj, beforeEvent(path), target, method); + + return this; + } + + /** @module ember @private */ var PROPERTY_DID_CHANGE = emberUtils.symbol('PROPERTY_DID_CHANGE'); @@ -2428,20 +2314,19 @@ @param {String} keyName The property key (or path) that will change. @return {void} @private */ function propertyWillChange(obj, keyName, _meta) { - var meta$$1 = _meta === undefined ? exports.peekMeta(obj) : _meta; + var meta$$1 = _meta === undefined ? peekMeta(obj) : _meta; if (meta$$1 !== undefined && !meta$$1.isInitialized(obj)) { return; } var watching = meta$$1 !== undefined && meta$$1.peekWatching(keyName) > 0; - var possibleDesc = obj[keyName]; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + var possibleDesc = descriptorFor(obj, keyName, meta$$1); - if (isDescriptor && possibleDesc.willChange) { + if (possibleDesc !== undefined && possibleDesc.willChange) { possibleDesc.willChange(obj, keyName); } if (watching) { dependentKeysWillChange(obj, keyName, meta$$1); @@ -2466,22 +2351,21 @@ @param {Meta} meta The objects meta. @return {void} @private */ function propertyDidChange(obj, keyName, _meta) { - var meta$$1 = _meta === undefined ? exports.peekMeta(obj) : _meta; + var meta$$1 = _meta === undefined ? peekMeta(obj) : _meta; var hasMeta = meta$$1 !== undefined; if (hasMeta && !meta$$1.isInitialized(obj)) { return; } - var possibleDesc = obj[keyName]; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + var possibleDesc = descriptorFor(obj, keyName, meta$$1); // shouldn't this mean that we're watching this key? - if (isDescriptor && possibleDesc.didChange) { + if (possibleDesc !== undefined && possibleDesc.didChange) { possibleDesc.didChange(obj, keyName); } if (hasMeta && meta$$1.peekWatching(keyName) > 0) { dependentKeysDidChange(obj, keyName, meta$$1); @@ -2498,11 +2382,11 @@ return; } markObjectAsDirty(meta$$1, keyName); } - if (ember_features.EMBER_GLIMMER_DETECT_BACKTRACKING_RERENDER || ember_features.EMBER_GLIMMER_ALLOW_BACKTRACKING_RERENDER) { + if (features.EMBER_GLIMMER_DETECT_BACKTRACKING_RERENDER) { exports.assertNotRendered(obj, keyName, meta$$1); } } var WILL_SEEN = void 0; @@ -2544,12 +2428,11 @@ DID_SEEN = null; } } function iterDeps(method, obj, depKey, seen, meta$$1) { - var possibleDesc = void 0, - isDescriptor = void 0; + var possibleDesc = void 0; var guid = emberUtils.guidFor(obj); var current = seen[guid]; if (!current) { current = seen[guid] = {}; @@ -2564,14 +2447,13 @@ meta$$1.forEachInDeps(depKey, function (key, value) { if (!value) { return; } - possibleDesc = obj[key]; - isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + possibleDesc = descriptorFor(obj, key, meta$$1); - if (isDescriptor && possibleDesc._suspended === obj) { + if (possibleDesc !== undefined && possibleDesc._suspended === obj) { return; } method(obj, key, meta$$1); }); @@ -2630,17 +2512,16 @@ }); ``` @method changeProperties @param {Function} callback - @param [binding] @private */ - function changeProperties(callback, binding) { + function changeProperties(callback) { beginPropertyChanges(); try { - callback.call(binding); + callback(); } finally { endPropertyChanges(); } } @@ -2683,11 +2564,11 @@ function notifyBeforeObservers(obj, keyName, meta$$1) { if (meta$$1.isSourceDestroying()) { return; } - var eventName = keyName + ':before'; + var eventName = beforeEvent(keyName); var listeners = void 0, added = void 0; if (deferred > 0) { listeners = beforeObserverSet.add(obj, keyName, eventName); added = accumulateListeners(obj, eventName, listeners, meta$$1); @@ -2698,11 +2579,11 @@ function notifyObservers(obj, keyName, meta$$1) { if (meta$$1.isSourceDestroying()) { return; } - var eventName = keyName + ':change'; + var eventName = changeEvent(keyName); var listeners = void 0; if (deferred > 0) { listeners = observerSet.add(obj, keyName, eventName); accumulateListeners(obj, eventName, listeners, meta$$1); } else { @@ -2727,33 +2608,17 @@ */ function Descriptor() { this.isDescriptor = true; } - var REDEFINE_SUPPORTED = function () { - // https://github.com/spalger/kibana/commit/b7e35e6737df585585332857a4c397dc206e7ff9 - var a = Object.create(Object.prototype, { - prop: { - configurable: true, - value: 1 - } - }); - - Object.defineProperty(a, 'prop', { - configurable: true, - value: 2 - }); - - return a.prop === 2; - }(); // .......................................................... // DEFINING PROPERTIES API // function MANDATORY_SETTER_FUNCTION(name) { function SETTER_FUNCTION(value) { - var m = exports.peekMeta(this); + var m = peekMeta(this); if (!m.isInitialized(this)) { m.writeValues(name, value); } else { true && !false && emberDebug.assert('You must use set() to set the `' + name + '` property (of ' + this + ') to `' + value + '`.', false); } @@ -2763,20 +2628,20 @@ return SETTER_FUNCTION; } function DEFAULT_GETTER_FUNCTION(name) { return function GETTER_FUNCTION() { - var meta$$1 = exports.peekMeta(this); + var meta$$1 = peekMeta(this); if (meta$$1 !== undefined) { return meta$$1.peekValues(name); } }; } function INHERITING_GETTER_FUNCTION(name) { function IGETTER_FUNCTION() { - var meta$$1 = exports.peekMeta(this); + var meta$$1 = peekMeta(this); var val = void 0; if (meta$$1 !== undefined) { val = meta$$1.readInheritedValue('values', name); } @@ -2790,10 +2655,82 @@ IGETTER_FUNCTION.isInheritingGetter = true; return IGETTER_FUNCTION; } + var DESCRIPTOR_GETTER_FUNCTION = void 0; + + if (features.EMBER_METAL_ES5_GETTERS) { + DESCRIPTOR_GETTER_FUNCTION = function (name, descriptor) { + return function CPGETTER_FUNCTION() { + return descriptor.get(this, name); + }; + }; + } else if (features.DESCRIPTOR_TRAP) { + // Future traveler, although this code looks scary. It merely exists in + // development to aid in development asertions. Production builds of + // ember strip this entire branch out. + var messageFor = function (obj, keyName, property, value) { + return 'You attempted to access the `' + keyName + '.' + property + '` property ' + ('(of ' + obj + '). Due to certain internal implementation details of Ember, ') + ('the `' + keyName + '` property previously contained an internal "descriptor" ') + ('object (a private API), therefore `' + keyName + '.' + property + '` would have ') + ('been `' + String(value).replace(/\n/g, ' ') + '`. This internal implementation ') + 'detail was never intended to be a public (or even intimate) API.\n\n' + 'This internal implementation detail has now changed and the (still private) ' + '"descriptor" object has been relocated to the object\'s "meta" (also a ' + ('private API). Soon, accessing `' + keyName + '` on this object will ') + 'return the computed value (see RFC #281 for more details).\n\n' + 'If you are seeing this error, you are likely using an addon that ' + 'relies on this now-defunct private implementation detail. If you can, ' + 'find out which addon is doing this from the stack trace below and ' + 'report this bug to the addon authors. If you feel stuck, the Ember ' + 'Community Slack (https://ember-community-slackin.herokuapp.com/) ' + 'may be able to offer some help.\n\n' + 'If you are an addon author and need help transitioning your code, ' + 'please get in touch in the #dev-ember channel in the Ember Community ' + 'Slack.'; + }; + + var trapFor = void 0; + + if (emberUtils.HAS_NATIVE_PROXY) { + /* globals Proxy */ + trapFor = function (obj, keyName, descriptor) { + return new Proxy(descriptor, { + get: function (descriptor, property) { + if (property === DESCRIPTOR) { + return descriptor; + } else if (property === 'toString' || property == 'valueOf' || Symbol && property === Symbol.toPrimitive) { + return function () { + return '[COMPUTED PROPERTY]'; + }; + } + + true && !false && emberDebug.assert(messageFor(obj, keyName, property, descriptor[property])); + } + }); + }; + } else { + trapFor = function (obj, keyName, descriptor) { + var trap = Object.create(null); + + Object.defineProperty(trap, DESCRIPTOR, { + configurable: false, + enumerable: false, + writable: false, + value: descriptor + }); + + trap.toString = trap.valueOf = function () { + return '[COMPUTED PROPERTY]'; + }; + + // Without a proxy, we can only trap the "likely" properties + ['isDescriptor', 'setup', 'teardown', 'get', '_getter', 'set', '_setter', 'meta'].forEach(function (property) { + Object.defineProperty(trap, property, { + configurable: false, + enumerable: false, + get: function () { + true && !false && emberDebug.assert(messageFor(obj, keyName, property, descriptor[property])); + } + }); + }); + + return trap; + }; + } + + DESCRIPTOR_GETTER_FUNCTION = function (name, descriptor) { + return function CPGETTER_FUNCTION() { + return trapFor(this, name, descriptor); + }; + }; + } + /** NOTE: This is a low-level method used by other parts of the API. You almost never want to call this method directly. Instead you should use `mixin()` to define new properties. @@ -2844,62 +2781,72 @@ meta$$1 = meta(obj); } var watchEntry = meta$$1.peekWatching(keyName); var watching = watchEntry !== undefined && watchEntry > 0; - var possibleDesc = obj[keyName]; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + var previousDesc = descriptorFor(obj, keyName, meta$$1); + var wasDescriptor = previousDesc !== undefined; - if (isDescriptor) { - possibleDesc.teardown(obj, keyName, meta$$1); + if (wasDescriptor) { + previousDesc.teardown(obj, keyName, meta$$1); + + if (features.EMBER_METAL_ES5_GETTERS) { + meta$$1.removeDescriptors(keyName); + } } var value = void 0; if (desc instanceof Descriptor) { value = desc; - if (ember_features.MANDATORY_SETTER) { - if (watching) { - Object.defineProperty(obj, keyName, { - configurable: true, - enumerable: true, - writable: true, - value: value - }); - } else { - obj[keyName] = value; - } + + if (features.EMBER_METAL_ES5_GETTERS || features.DESCRIPTOR_TRAP) { + Object.defineProperty(obj, keyName, { + configurable: true, + enumerable: true, + get: DESCRIPTOR_GETTER_FUNCTION(keyName, value) + }); + } else if (features.MANDATORY_SETTER && watching) { + Object.defineProperty(obj, keyName, { + configurable: true, + enumerable: true, + writable: true, + value: value + }); } else { obj[keyName] = value; } + if (features.EMBER_METAL_ES5_GETTERS) { + meta$$1.writeDescriptors(keyName, value); + } + didDefineComputedProperty(obj.constructor); if (typeof desc.setup === 'function') { desc.setup(obj, keyName); } } else if (desc === undefined || desc === null) { value = data; - if (ember_features.MANDATORY_SETTER) { - if (watching) { - meta$$1.writeValues(keyName, data); + if (features.MANDATORY_SETTER && watching) { + meta$$1.writeValues(keyName, data); - var defaultDescriptor = { - configurable: true, - enumerable: true, - set: MANDATORY_SETTER_FUNCTION(keyName), - get: DEFAULT_GETTER_FUNCTION(keyName) - }; + var defaultDescriptor = { + configurable: true, + enumerable: true, + set: MANDATORY_SETTER_FUNCTION(keyName), + get: DEFAULT_GETTER_FUNCTION(keyName) + }; - if (REDEFINE_SUPPORTED) { - Object.defineProperty(obj, keyName, defaultDescriptor); - } else { - handleBrokenPhantomDefineProperty(obj, keyName, defaultDescriptor); - } - } else { - obj[keyName] = data; - } + Object.defineProperty(obj, keyName, defaultDescriptor); + } else if ((features.EMBER_METAL_ES5_GETTERS || features.DESCRIPTOR_TRAP) && wasDescriptor) { + Object.defineProperty(obj, keyName, { + configurable: true, + enumerable: true, + writable: true, + value: value + }); } else { obj[keyName] = data; } } else { value = desc; @@ -2937,16 +2884,10 @@ if (cache && cache._computedProperties !== undefined) { cache._computedProperties = undefined; } } - function handleBrokenPhantomDefineProperty(obj, keyName, desc) { - // https://github.com/ariya/phantomjs/issues/11856 - Object.defineProperty(obj, keyName, { configurable: true, writable: true, value: 'iCry' }); - Object.defineProperty(obj, keyName, desc); - } - var handleMandatorySetter = void 0; function watchKey(obj, keyName, _meta) { if (typeof obj !== 'object' || obj === null) { return; @@ -2956,28 +2897,28 @@ var count = meta$$1.peekWatching(keyName) || 0; meta$$1.writeWatching(keyName, count + 1); if (count === 0) { // activate watching first time - var possibleDesc = obj[keyName]; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; - if (isDescriptor && possibleDesc.willWatch) { + var possibleDesc = descriptorFor(obj, keyName, meta$$1); + + if (possibleDesc !== undefined && possibleDesc.willWatch) { possibleDesc.willWatch(obj, keyName, meta$$1); } if (typeof obj.willWatchProperty === 'function') { obj.willWatchProperty(keyName); } - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { // NOTE: this is dropped for prod + minified builds handleMandatorySetter(meta$$1, obj, keyName); } } } - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { var _hasOwnProperty = function (obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); }; var _propertyIsEnumerable = function (obj, key) { return Object.prototype.propertyIsEnumerable.call(obj, key); @@ -2987,20 +2928,18 @@ // development to aid in development asertions. Production builds of // ember strip this entire block out handleMandatorySetter = function handleMandatorySetter(m, obj, keyName) { var descriptor = emberUtils.lookupDescriptor(obj, keyName); var hasDescriptor = descriptor !== null; + var possibleDesc = hasDescriptor && descriptor.value; + if (isDescriptor(possibleDesc)) { + return; + } var configurable = hasDescriptor ? descriptor.configurable : true; var isWritable = hasDescriptor ? descriptor.writable : true; var hasValue = hasDescriptor ? 'value' in descriptor : true; - var possibleDesc = hasDescriptor && descriptor.value; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; - if (isDescriptor) { - return; - } - // this x in Y deopts, so keeping it in this function is better; if (configurable && isWritable && hasValue && keyName in obj) { var desc = { configurable: true, set: MANDATORY_SETTER_FUNCTION(keyName), @@ -3022,42 +2961,42 @@ function unwatchKey(obj, keyName, _meta) { if (typeof obj !== 'object' || obj === null) { return; } - var meta$$1 = _meta === undefined ? exports.peekMeta(obj) : _meta; + var meta$$1 = _meta === undefined ? peekMeta(obj) : _meta; // do nothing of this object has already been destroyed if (meta$$1 === undefined || meta$$1.isSourceDestroyed()) { return; } var count = meta$$1.peekWatching(keyName); if (count === 1) { meta$$1.writeWatching(keyName, 0); - var possibleDesc = obj[keyName]; - var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + var possibleDesc = descriptorFor(obj, keyName, meta$$1); + var _isDescriptor = possibleDesc !== undefined; - if (isDescriptor && possibleDesc.didUnwatch) { + if (_isDescriptor && possibleDesc.didUnwatch) { possibleDesc.didUnwatch(obj, keyName, meta$$1); } if (typeof obj.didUnwatchProperty === 'function') { obj.didUnwatchProperty(keyName); } - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { // It is true, the following code looks quite WAT. But have no fear, It // exists purely to improve development ergonomics and is removed from // ember.min.js and ember.prod.js builds. // // Some further context: Once a property is watched by ember, bypassing `set` // for mutation, will bypass observation. This code exists to assert when // that occurs, and attempt to provide more helpful feedback. The alternative // is tricky to debug partially observable properties. - if (!isDescriptor && keyName in obj) { + if (!_isDescriptor && keyName in obj) { var maybeMandatoryDescriptor = emberUtils.lookupDescriptor(obj, keyName); if (maybeMandatoryDescriptor.set && maybeMandatoryDescriptor.set.isMandatorySetter) { if (maybeMandatoryDescriptor.get && maybeMandatoryDescriptor.get.isInheritingGetter) { var possibleValue = meta$$1.readInheritedValue('values', keyName); @@ -3080,59 +3019,23 @@ } else if (count > 1) { meta$$1.writeWatching(keyName, count - 1); } } - function makeChainNode(obj) { - return new ChainNode(null, null, obj); - } - - function watchPath(obj, keyPath, meta$$1) { - if (typeof obj !== 'object' || obj === null) { - return; - } - var m = meta$$1 === undefined ? meta(obj) : meta$$1; - var counter = m.peekWatching(keyPath) || 0; - - m.writeWatching(keyPath, counter + 1); - if (counter === 0) { - // activate watching first time - m.writableChains(makeChainNode).add(keyPath); - } - } - - function unwatchPath(obj, keyPath, meta$$1) { - if (typeof obj !== 'object' || obj === null) { - return; - } - var m = meta$$1 === undefined ? exports.peekMeta(obj) : meta$$1; - - if (m === undefined) { - return; - } - var counter = m.peekWatching(keyPath) || 0; - - if (counter === 1) { - m.writeWatching(keyPath, 0); - m.writableChains(makeChainNode).remove(keyPath); - } else if (counter > 1) { - m.writeWatching(keyPath, counter - 1); - } - } - var FIRST_KEY = /^([^\.]+)/; function firstKey(path) { return path.match(FIRST_KEY)[0]; } function isObject(obj) { return typeof obj === 'object' && obj !== null; } - function isVolatile(obj) { - return !(isObject(obj) && obj.isDescriptor && obj._volatile === false); + function isVolatile(obj, keyName, meta$$1) { + var desc = descriptorFor(obj, keyName, meta$$1); + return !(desc !== undefined && desc._volatile === false); } var ChainWatchers = function () { function ChainWatchers() { emberBabel.classCallCheck(this, ChainWatchers); @@ -3226,10 +3129,14 @@ function makeChainWatcher() { return new ChainWatchers(); } + function makeChainNode(obj) { + return new ChainNode(null, null, obj); + } + function addChainWatcher(obj, keyName, node) { var m = meta(obj); m.writableChainWatchers(makeChainWatcher).add(keyName, node); watchKey(obj, keyName, m); } @@ -3237,11 +3144,11 @@ function removeChainWatcher(obj, keyName, node, _meta) { if (!isObject(obj)) { return; } - var meta$$1 = _meta === undefined ? exports.peekMeta(obj) : _meta; + var meta$$1 = _meta === undefined ? peekMeta(obj) : _meta; if (meta$$1 === undefined || meta$$1.readableChainWatchers() === undefined) { return; } @@ -3308,11 +3215,11 @@ // copies a top level object only ChainNode.prototype.copy = function copy(obj) { - var ret = new ChainNode(null, null, obj); + var ret = makeChainNode(obj); var paths = this._paths; if (paths !== undefined) { var path = void 0; for (path in paths) { if (paths[path] > 0) { @@ -3450,19 +3357,19 @@ function lazyGet(obj, key) { if (!isObject(obj)) { return; } - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); // check if object meant only to be a prototype if (meta$$1 !== undefined && meta$$1.proto === obj) { return; } // Use `get` if the return value is an EachProxy or an uncacheable value. - if (isVolatile(obj[key])) { + if (isVolatile(obj, key, meta$$1)) { return get(obj, key); // Otherwise attempt to get the cached value of the computed property } else { var cache = meta$$1.readableCache(); if (cache !== undefined) { @@ -3507,11 +3414,10 @@ var SOURCE_DESTROYING = 1 << 1; var SOURCE_DESTROYED = 1 << 2; var META_DESTROYED = 1 << 3; var IS_PROXY = 1 << 4; - var META_FIELD = '__ember_meta__'; var NODE_STACK = []; var Meta = function () { function Meta(obj, parentMeta) { emberBabel.classCallCheck(this, Meta); @@ -3519,11 +3425,15 @@ { counters.metaInstantiated++; } this._cache = undefined; - this._weak = undefined; + + if (features.EMBER_METAL_ES5_GETTERS) { + this._descriptors = undefined; + } + this._watching = undefined; this._mixins = undefined; this._bindings = undefined; this._values = undefined; this._deps = undefined; @@ -3586,11 +3496,11 @@ // remove chainWatcher in node object if (node._watching) { nodeObject = node._object; if (nodeObject !== undefined) { - var foreignMeta = exports.peekMeta(nodeObject); + var foreignMeta = peekMeta(nodeObject); // avoid cleaning up chain watchers when both current and // foreign objects are being destroyed // if both are being destroyed manual cleanup is not needed // as they will be GC'ed and no non-destroyed references will // be remaining @@ -3722,13 +3632,13 @@ var map = pointer[key]; if (map !== undefined) { var innerMap = map[subkey]; if (innerMap !== undefined) { for (var innerKey in innerMap) { - seen = seen || Object.create(null); - if (seen[innerKey] === undefined) { - seen[innerKey] = true; + seen = seen === undefined ? new Set() : seen; + if (!seen.has(innerKey)) { + seen.add(innerKey); calls = calls || []; calls.push(innerKey, innerMap[innerKey]); } } } @@ -3749,18 +3659,10 @@ Meta.prototype.readableCache = function readableCache() { return this._cache; }; - Meta.prototype.writableWeak = function writableWeak() { - return this._getOrCreateOwnMap('_weak'); - }; - - Meta.prototype.readableWeak = function readableWeak() { - return this._weak; - }; - Meta.prototype.writableTags = function writableTags() { return this._getOrCreateOwnMap('_tags'); }; Meta.prototype.readableTags = function readableTags() { @@ -3841,13 +3743,13 @@ var seen = void 0; while (pointer !== undefined) { var map = pointer._mixins; if (map !== undefined) { for (var key in map) { - seen = seen || Object.create(null); - if (seen[key] === undefined) { - seen[key] = true; + seen = seen === undefined ? new Set() : seen; + if (!seen.has(key)) { + seen.add(key); fn(key, map[key]); } } } pointer = pointer.parent; @@ -3919,23 +3821,11 @@ for (var name in protoMethods) { Meta.prototype[name] = protoMethods[name]; } - var META_DESC = { - writable: true, - configurable: true, - enumerable: false, - value: null - }; - - var EMBER_META_PROPERTY = { - name: META_FIELD, - descriptor: META_DESC - }; - - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { Meta.prototype.readInheritedValue = function (key, subkey) { var internalKey = '_' + key; var pointer = this; @@ -3963,58 +3853,64 @@ obj[key] = value; } }; } - var setMeta = void 0; - exports.peekMeta = void 0; + if (features.EMBER_METAL_ES5_GETTERS) { + Meta.prototype.writeDescriptors = function (subkey, value) { + true && !!this.isMetaDestroyed() && emberDebug.assert('Cannot update descriptors for `' + subkey + '` on `' + emberUtils.toString(this.source) + '` after it has been destroyed.', !this.isMetaDestroyed()); - // choose the one appropriate for given platform - if (emberUtils.HAS_NATIVE_WEAKMAP) { - var getPrototypeOf = Object.getPrototypeOf; - var metaStore = new WeakMap(); + var map = this._getOrCreateOwnMap('_descriptors'); + map[subkey] = value; + }; - setMeta = function WeakMap_setMeta(obj, meta) { - { - counters.setCalls++; - } - metaStore.set(obj, meta); + Meta.prototype.peekDescriptors = function (subkey) { + var possibleDesc = this._findInherited('_descriptors', subkey); + return possibleDesc === UNDEFINED ? undefined : possibleDesc; }; - exports.peekMeta = function WeakMap_peekParentMeta(obj) { - var pointer = obj; - var meta = void 0; - while (pointer !== undefined && pointer !== null) { - meta = metaStore.get(pointer); - // jshint loopfunc:true - { - counters.peekCalls++; - } - if (meta !== undefined) { - return meta; - } + Meta.prototype.removeDescriptors = function (subkey) { + this.writeDescriptors(subkey, UNDEFINED); + }; + } - pointer = getPrototypeOf(pointer); - { - counters.peekPrototypeWalks++; - } + var getPrototypeOf = Object.getPrototypeOf; + var metaStore = new WeakMap(); + + function setMeta(obj, meta) { + true && !(obj !== null) && emberDebug.assert('Cannot call `setMeta` on null', obj !== null); + true && !(obj !== undefined) && emberDebug.assert('Cannot call `setMeta` on undefined', obj !== undefined); + true && !(typeof obj === 'object' || typeof obj === 'function') && emberDebug.assert('Cannot call `setMeta` on ' + typeof obj, typeof obj === 'object' || typeof obj === 'function'); + + { + counters.setCalls++; + } + metaStore.set(obj, meta); + } + + function peekMeta(obj) { + true && !(obj !== null) && emberDebug.assert('Cannot call `peekMeta` on null', obj !== null); + true && !(obj !== undefined) && emberDebug.assert('Cannot call `peekMeta` on undefined', obj !== undefined); + true && !(typeof obj === 'object' || typeof obj === 'function') && emberDebug.assert('Cannot call `peekMeta` on ' + typeof obj, typeof obj === 'object' || typeof obj === 'function'); + + var pointer = obj; + var meta = void 0; + while (pointer !== undefined && pointer !== null) { + meta = metaStore.get(pointer); + // jshint loopfunc:true + { + counters.peekCalls++; } - }; - } else { - setMeta = function Fallback_setMeta(obj, meta) { - if (obj.__defineNonEnumerable) { - obj.__defineNonEnumerable(EMBER_META_PROPERTY); - } else { - Object.defineProperty(obj, META_FIELD, META_DESC); + if (meta !== undefined) { + return meta; } - obj[META_FIELD] = meta; - }; - - exports.peekMeta = function Fallback_peekMeta(obj) { - return obj[META_FIELD]; - }; + pointer = getPrototypeOf(pointer); + { + counters.peekPrototypeWalks++; + } + } } /** Tears down the meta on an object so that it can be garbage collected. Multiple calls will have no effect. @@ -4024,15 +3920,19 @@ @param {Object} obj the object to destroy @return {void} @private */ function deleteMeta(obj) { + true && !(obj !== null) && emberDebug.assert('Cannot call `deleteMeta` on null', obj !== null); + true && !(obj !== undefined) && emberDebug.assert('Cannot call `deleteMeta` on undefined', obj !== undefined); + true && !(typeof obj === 'object' || typeof obj === 'function') && emberDebug.assert('Cannot call `deleteMeta` on ' + typeof obj, typeof obj === 'object' || typeof obj === 'function'); + { counters.deleteCalls++; } - var meta = exports.peekMeta(obj); + var meta = peekMeta(obj); if (meta !== undefined) { meta.destroy(); } } @@ -4053,15 +3953,19 @@ @param {Boolean} [writable=true] Pass `false` if you do not intend to modify the meta hash, allowing the method to avoid making an unnecessary copy. @return {Object} the meta hash for an object */ function meta(obj) { + true && !(obj !== null) && emberDebug.assert('Cannot call `meta` on null', obj !== null); + true && !(obj !== undefined) && emberDebug.assert('Cannot call `meta` on undefined', obj !== undefined); + true && !(typeof obj === 'object' || typeof obj === 'function') && emberDebug.assert('Cannot call `meta` on ' + typeof obj, typeof obj === 'object' || typeof obj === 'function'); + { counters.metaCalls++; } - var maybeMeta = exports.peekMeta(obj); + var maybeMeta = peekMeta(obj); var parent = void 0; // remove this code, in-favor of explicit parent if (maybeMeta !== undefined) { if (maybeMeta.source === obj) { @@ -4073,10 +3977,67 @@ var newMeta = new Meta(obj, parent); setMeta(obj, newMeta); return newMeta; } + // Using `symbol()` here causes some node test to fail, presumably + // because we define the CP with one copy of Ember and boot the app + // with a different copy, so the random key we generate do not line + // up. Is that testing a legit scenario? + var DESCRIPTOR = '__DESCRIPTOR__'; + + /** + Returns the CP descriptor assocaited with `obj` and `keyName`, if any. + + @method descriptorFor + @param {Object} obj the object to check + @param {String} keyName the key to check + @return {Descriptor} + @private + */ + function descriptorFor(obj, keyName, _meta) { + true && !(obj !== null) && emberDebug.assert('Cannot call `descriptorFor` on null', obj !== null); + true && !(obj !== undefined) && emberDebug.assert('Cannot call `descriptorFor` on undefined', obj !== undefined); + true && !(typeof obj === 'object' || typeof obj === 'function') && emberDebug.assert('Cannot call `descriptorFor` on ' + typeof obj, typeof obj === 'object' || typeof obj === 'function'); + + if (features.EMBER_METAL_ES5_GETTERS) { + var _meta2 = _meta === undefined ? peekMeta(obj) : _meta; + + if (_meta2 !== undefined) { + return _meta2.peekDescriptors(keyName); + } + } else { + var possibleDesc = obj[keyName]; + + if (features.DESCRIPTOR_TRAP && isDescriptorTrap(possibleDesc)) { + return possibleDesc[DESCRIPTOR]; + } else { + return isDescriptor(possibleDesc) ? possibleDesc : undefined; + } + } + } + + function isDescriptorTrap(possibleDesc) { + if (features.DESCRIPTOR_TRAP) { + return possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc[DESCRIPTOR] !== undefined; + } else { + throw new Error('Cannot call `isDescriptorTrap` in production'); + } + } + + /** + Check whether a value is a CP descriptor. + + @method descriptorFor + @param {any} possibleDesc the value to check + @return {boolean} + @private + */ + function isDescriptor(possibleDesc) { + return possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor; + } + var Cache = function () { function Cache(limit, func, key, store) { emberBabel.classCallCheck(this, Cache); this.size = 0; @@ -4242,18 +4203,44 @@ true && !(obj !== undefined && obj !== null) && emberDebug.assert('Cannot call get with \'' + keyName + '\' on an undefined object.', obj !== undefined && obj !== null); true && !(typeof keyName === 'string') && emberDebug.assert('The key provided to get must be a string, you passed ' + keyName, typeof keyName === 'string'); true && !(keyName.lastIndexOf('this.', 0) !== 0) && emberDebug.assert('\'this\' in paths is not supported', keyName.lastIndexOf('this.', 0) !== 0); true && !(keyName !== '') && emberDebug.assert('Cannot call `Ember.get` with an empty string', keyName !== ''); - var value = obj[keyName]; - var isDescriptor = value !== null && typeof value === 'object' && value.isDescriptor; + var type = typeof obj; - if (isDescriptor) { - return value.get(obj, keyName); - } else if (isPath(keyName)) { + var isObject = type === 'object'; + var isFunction = type === 'function'; + var isObjectLike = isObject || isFunction; + + var descriptor = undefined; + var value = void 0; + + if (isObjectLike) { + if (features.EMBER_METAL_ES5_GETTERS) { + descriptor = descriptorFor(obj, keyName); + } + + if (!features.EMBER_METAL_ES5_GETTERS || descriptor === undefined) { + value = obj[keyName]; + + if (features.DESCRIPTOR_TRAP && isDescriptorTrap(value)) { + descriptor = value[DESCRIPTOR]; + } else if (isDescriptor(value)) { + descriptor = value; + } + } + + if (descriptor !== undefined) { + return descriptor.get(obj, keyName); + } + } else { + value = obj[keyName]; + } + + if (isPath(keyName)) { return _getPath(obj, keyName); - } else if (value === undefined && 'object' === typeof obj && !(keyName in obj) && typeof obj.unknownProperty === 'function') { + } else if (value === undefined && isObject && !(keyName in obj) && typeof obj.unknownProperty === 'function') { return obj.unknownProperty(keyName); } else { return value; } } @@ -4338,25 +4325,38 @@ if (isPath(keyName)) { return setPath(obj, keyName, value, tolerant); } + if (features.EMBER_METAL_ES5_GETTERS) { + var possibleDesc = descriptorFor(obj, keyName); + + if (possibleDesc !== undefined) { + /* computed property */ + possibleDesc.set(obj, keyName, value); + return value; + } + } + var currentValue = obj[keyName]; - var isDescriptor = currentValue !== null && typeof currentValue === 'object' && currentValue.isDescriptor; - if (isDescriptor) { + if (features.DESCRIPTOR_TRAP && isDescriptorTrap(currentValue)) { + currentValue = currentValue[DESCRIPTOR]; + } + + if (isDescriptor(currentValue)) { /* computed property */ currentValue.set(obj, keyName, value); } else if (currentValue === undefined && 'object' === typeof obj && !(keyName in obj) && typeof obj.setUnknownProperty === 'function') { /* unknown property */ obj.setUnknownProperty(keyName, value); } else if (currentValue === value) {/* no change */ } else { - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); propertyWillChange(obj, keyName, meta$$1); - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { setWithMandatorySetter(meta$$1, obj, keyName, value); } else { obj[keyName] = value; } @@ -4364,11 +4364,11 @@ } return value; } - if (ember_features.MANDATORY_SETTER) { + if (features.MANDATORY_SETTER) { var setWithMandatorySetter = function (meta$$1, obj, keyName, value) { if (meta$$1 !== undefined && meta$$1.peekWatching(keyName) > 0) { makeEnumerable(obj, keyName); meta$$1.writeValue(obj, keyName, value); } else { @@ -4491,51 +4491,10 @@ dive(prefix + tempArr[i++], after, newStart, callback); } } } - /** - @module ember - */ - /** - Starts watching a property on an object. Whenever the property changes, - invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the - primitive used by observers and dependent keys; usually you will never call - this method directly but instead use higher level methods like - `Ember.addObserver()` - - @private - @method watch - @for Ember - @param obj - @param {String} _keyPath - */ - function watch(obj, _keyPath, m) { - if (isPath(_keyPath)) { - watchPath(obj, _keyPath, m); - } else { - watchKey(obj, _keyPath, m); - } - } - - function isWatching(obj, key) { - return watcherCount(obj, key) > 0; - } - - function watcherCount(obj, key) { - var meta$$1 = exports.peekMeta(obj); - return meta$$1 !== undefined && meta$$1.peekWatching(key) || 0; - } - - function unwatch(obj, _keyPath, m) { - if (isPath(_keyPath)) { - unwatchPath(obj, _keyPath, m); - } else { - unwatchKey(obj, _keyPath, m); - } - } - // .......................................................... // DEPENDENT KEYS // function addDependentKeys(desc, obj, keyName, meta) { @@ -4869,11 +4828,11 @@ if (this._volatile || this._suspended === obj) { return; } // don't create objects just to invalidate - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); if (meta$$1 === undefined || meta$$1.source !== obj) { return; } var cache = meta$$1.readableCache(); @@ -5114,11 +5073,11 @@ to return @return {Object} the cached value @public */ function cacheFor(obj, key) { - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); var cache = meta$$1 !== undefined ? meta$$1.source === obj && meta$$1.readableCache() : undefined; var ret = cache !== undefined ? cache[key] : undefined; if (ret === UNDEFINED) { return undefined; @@ -5216,10 +5175,11 @@ return AliasedProperty; }(Descriptor); function AliasedProperty_readOnlySet(obj, keyName, value) { + // eslint-disable-line no-unused-vars throw new emberDebug.Error('Cannot set read-only property \'' + keyName + '\' on object: ' + emberUtils.inspect(obj)); } function AliasedProperty_oneWaySet(obj, keyName, value) { defineProperty(obj, keyName, null); @@ -5421,11 +5381,11 @@ return callback.call(binding); } } exports.flaggedInstrument = void 0; - if (ember_features.EMBER_IMPROVED_INSTRUMENTATION) { + if (features.EMBER_IMPROVED_INSTRUMENTATION) { exports.flaggedInstrument = instrument; } else { exports.flaggedInstrument = function (name, payload, callback) { return callback(); }; @@ -5770,11 +5730,10 @@ function onEnd(current, next) { run.currentRunLoop = next; } var backburner$1 = new Backburner(['sync', 'actions', 'destroy'], { - GUID_KEY: emberUtils.GUID_KEY, sync: { before: beginPropertyChanges, after: endPropertyChanges }, defaultQueue: 'actions', @@ -5897,11 +5856,11 @@ tinymce.init({ selector: '#' + this.$().prop('id'), setup: Ember.run.bind(this, this.setupEditor) }); }), - + didInsertElement() { tinymce.init({ selector: '#' + this.$().prop('id'), setup: Ember.run.bind(this, this.setupEditor) }); @@ -6580,11 +6539,11 @@ }; return Libraries; }(); - if (ember_features.EMBER_LIBRARIES_ISREGISTERED) { + if (features.EMBER_LIBRARIES_ISREGISTERED) { Libraries.prototype.isRegistered = function (name) { return !!this._getLibraryByName(name); }; } @@ -7161,112 +7120,10 @@ }); return properties; } /** - @module @ember/object - */ - - var AFTER_OBSERVERS = ':change'; - var BEFORE_OBSERVERS = ':before'; - - function changeEvent(keyName) { - return keyName + AFTER_OBSERVERS; - } - - function beforeEvent(keyName) { - return keyName + BEFORE_OBSERVERS; - } - - /** - @method addObserver - @static - @for @ember/object/observers - @param obj - @param {String} _path - @param {Object|Function} target - @param {Function|String} [method] - @public - */ - function addObserver(obj, _path, target, method) { - addListener(obj, changeEvent(_path), target, method); - watch(obj, _path); - - return this; - } - - function observersFor(obj, path) { - return listenersFor(obj, changeEvent(path)); - } - - /** - @method removeObserver - @static - @for @ember/object/observers - @param obj - @param {String} path - @param {Object|Function} target - @param {Function|String} [method] - @public - */ - function removeObserver(obj, path, target, method) { - unwatch(obj, path); - removeListener(obj, changeEvent(path), target, method); - - return this; - } - - /** - @method _addBeforeObserver - @static - @for @ember/object/observers - @param obj - @param {String} path - @param {Object|Function} target - @param {Function|String} [method] - @deprecated - @private - */ - function _addBeforeObserver(obj, path, target, method) { - addListener(obj, beforeEvent(path), target, method); - watch(obj, path); - - return this; - } - - // Suspend observer during callback. - // - // This should only be used by the target of the observer - // while it is setting the observed path. - function _suspendObserver(obj, path, target, method, callback) { - return suspendListener(obj, changeEvent(path), target, method, callback); - } - - function _suspendObservers(obj, paths, target, method, callback) { - var events = paths.map(changeEvent); - return suspendListeners(obj, events, target, method, callback); - } - - /** - @method removeBeforeObserver - @static - @for @ember/object/observers - @param obj - @param {String} path - @param {Object|Function} target - @param {Function|String} [method] - @deprecated - @private - */ - function _removeBeforeObserver(obj, path, target, method) { - unwatch(obj, path); - removeListener(obj, beforeEvent(path), target, method); - - return this; - } - - /** @module ember */ // .......................................................... // BINDING @@ -7467,16 +7324,18 @@ // /* Called when the from side changes. */ Binding.prototype.fromDidChange = function fromDidChange(target) { + // eslint-disable-line no-unused-vars this._scheduleSync('fwd'); }; /* Called when the to side changes. */ Binding.prototype.toDidChange = function toDidChange(target) { + // eslint-disable-line no-unused-vars this._scheduleSync('back'); }; Binding.prototype._scheduleSync = function _scheduleSync(dir) { var existingDir = this._direction; @@ -7791,14 +7650,11 @@ } // If we didn't find the original descriptor in a parent mixin, find // it on the original object. if (!superProperty) { - var possibleDesc = base[key]; - var superDesc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined; - - superProperty = superDesc; + superProperty = descriptorFor(base, key, meta$$1); } if (superProperty === undefined || !(superProperty instanceof ComputedProperty)) { return property; } @@ -7818,28 +7674,30 @@ return property; } function giveMethodSuper(obj, key, method, values, descs) { - var superMethod = void 0; - // Methods overwrite computed properties, and do not call super to them. - if (descs[key] === undefined) { - // Find the original method in a parent mixin - superMethod = values[key]; + if (descs[key] !== undefined) { + return method; } + // Find the original method in a parent mixin + var superMethod = values[key]; + // If we didn't find the original value in a parent mixin, find it in // the original object - superMethod = superMethod || obj[key]; + if (superMethod === undefined && (!features.EMBER_METAL_ES5_GETTERS || descriptorFor(obj, key) === undefined)) { + superMethod = obj[key]; + } // Only wrap the new method if the original method was a function - if (superMethod === undefined || 'function' !== typeof superMethod) { - return method; + if (typeof superMethod === 'function') { + return emberUtils.wrap(method, superMethod); } - return emberUtils.wrap(method, superMethod); + return method; } function applyConcatenatedProperties(obj, key, value, values) { var baseValue = values[key] || obj[key]; var ret = void 0; @@ -7902,11 +7760,11 @@ return newBase; } function addNormalizedProperty(base, key, value, meta$$1, descs, values, concats, mergings) { if (value instanceof Descriptor) { - if (value === REQUIRED && descs[key]) { + if (emberEnvironment.ENV._ENABLE_PROPERTY_REQUIRED_SUPPORT && value === REQUIRED && descs[key]) { return CONTINUE; } // Wrap descriptor function to implement // _super() if needed @@ -7950,10 +7808,11 @@ if (props === CONTINUE) { continue; } if (props) { + // remove willMergeMixin after 3.4 as it was used for _actions if (base.willMergeMixin) { base.willMergeMixin(props); } concats = concatenatedMixinProperties('concatenatedProperties', props, values, base); mergings = concatenatedMixinProperties('mergedProperties', props, values, base); @@ -8018,11 +7877,11 @@ var value = void 0; var possibleDesc = void 0; if (descs[altKey] || values[altKey]) { value = values[altKey]; desc = descs[altKey]; - } else if ((possibleDesc = obj[altKey]) && possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) { + } else if ((possibleDesc = descriptorFor(obj, altKey)) !== undefined) { desc = possibleDesc; value = undefined; } else { desc = undefined; value = obj[altKey]; @@ -8037,23 +7896,21 @@ updateMethod(obj, paths[i], null, key); } } } - function replaceObserversAndListeners(obj, key, observerOrListener) { - var prev = obj[key]; - + function replaceObserversAndListeners(obj, key, prev, next) { if (typeof prev === 'function') { updateObserversAndListeners(obj, key, prev.__ember_observesBefore__, _removeBeforeObserver); updateObserversAndListeners(obj, key, prev.__ember_observes__, removeObserver); updateObserversAndListeners(obj, key, prev.__ember_listens__, removeListener); } - if (typeof observerOrListener === 'function') { - updateObserversAndListeners(obj, key, observerOrListener.__ember_observesBefore__, _addBeforeObserver); - updateObserversAndListeners(obj, key, observerOrListener.__ember_observes__, addObserver); - updateObserversAndListeners(obj, key, observerOrListener.__ember_listens__, addListener); + if (typeof next === 'function') { + updateObserversAndListeners(obj, key, next.__ember_observesBefore__, _addBeforeObserver); + updateObserversAndListeners(obj, key, next.__ember_observes__, addObserver); + updateObserversAndListeners(obj, key, next.__ember_listens__, addListener); } } function applyMixin(obj, mixins, partial) { var descs = {}; @@ -8082,11 +7939,11 @@ } desc = descs[key]; value = values[key]; - if (desc === REQUIRED) { + if (emberEnvironment.ENV._ENABLE_PROPERTY_REQUIRED_SUPPORT && desc === REQUIRED) { continue; } while (desc && desc instanceof Alias) { var followed = followAlias(obj, desc, descs, values); @@ -8096,11 +7953,15 @@ if (desc === undefined && value === undefined) { continue; } - replaceObserversAndListeners(obj, key, value); + if (features.EMBER_METAL_ES5_GETTERS && descriptorFor(obj, key) !== undefined) { + replaceObserversAndListeners(obj, key, null, value); + } else { + replaceObserversAndListeners(obj, key, obj[key], value); + } if (detectBinding(key)) { meta$$1.writeBindings(key, value); } @@ -8276,11 +8137,11 @@ // returns the mixins currently applied to the specified object // TODO: Make `mixin` Mixin.mixins = function mixins(obj) { - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); var ret = []; if (meta$$1 === undefined) { return ret; } @@ -8355,11 +8216,11 @@ return false; } if (obj instanceof Mixin) { return _detect(obj, this, {}); } - var meta$$1 = exports.peekMeta(obj); + var meta$$1 = peekMeta(obj); if (meta$$1 === undefined) { return false; } return !!meta$$1.peekMixins(emberUtils.guidFor(this)); }; @@ -8531,28 +8392,17 @@ @return func @public @static */ function observer() { - var _paths = void 0, - func = void 0; - for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { args[_key5] = arguments[_key5]; } - if (typeof args[args.length - 1] !== 'function') { - // revert to old, soft-deprecated argument ordering - true && !false && emberDebug.deprecate('Passing the dependentKeys after the callback function in observer is deprecated. Ensure the callback function is the last argument.', false, { id: 'ember-metal.observer-argument-order', until: '3.0.0' }); + var func = args.pop(); + var _paths = args; - func = args.shift(); - _paths = args; - } else { - func = args.pop(); - _paths = args; - } - true && !(typeof func === 'function') && emberDebug.assert('observer called without a function', typeof func === 'function'); true && !(_paths.length > 0 && _paths.every(function (p) { return typeof p === 'string' && p.length; })) && emberDebug.assert('observer called without valid path', _paths.length > 0 && _paths.every(function (p) { return typeof p === 'string' && p.length; @@ -8570,48 +8420,10 @@ func.__ember_observes__ = paths; return func; } /** - Specify a method that observes property changes. - - ```javascript - import EmberObject from '@ember/object'; - - EmberObject.extend({ - valueObserver: Ember.immediateObserver('value', function() { - // Executes whenever the "value" property changes - }) - }); - ``` - - In the future, `observer` may become asynchronous. In this event, - `immediateObserver` will maintain the synchronous behavior. - - Also available as `Function.prototype.observesImmediately` if prototype extensions are - enabled. - - @method _immediateObserver - @for Ember - @param {String} propertyNames* - @param {Function} func - @deprecated Use `observer` instead. - @return func - @private - */ - function _immediateObserver() { - true && !false && emberDebug.deprecate('Usage of `Ember.immediateObserver` is deprecated, use `observer` instead.', false, { id: 'ember-metal.immediate-observer', until: '3.0.0' }); - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - true && !(typeof arg !== 'string' || arg.indexOf('.') === -1) && emberDebug.assert('Immediate observers must observe internal properties only, not properties on other objects.', typeof arg !== 'string' || arg.indexOf('.') === -1); - } - - return observer.apply(this, arguments); - } - - /** When observers fire, they are called with the arguments `obj`, `keyName`. Note, `@each.property` observer is called per each add or replace of an element and it's not called with a specific enumeration item. @@ -8628,36 +8440,24 @@ function _beforeObserver() { for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { args[_key6] = arguments[_key6]; } - var func = args[args.length - 1]; - var paths = void 0; + var func = args.pop(); + var _paths = args; + true && !(typeof func === 'function') && emberDebug.assert('_beforeObserver called without a function', typeof func === 'function'); + + var paths = []; var addWatchedProperty = function (path) { paths.push(path); }; - var _paths = args.slice(0, -1); - - if (typeof func !== 'function') { - // revert to old, soft-deprecated argument ordering - - func = args[0]; - _paths = args.slice(1); - } - - paths = []; - for (var i = 0; i < _paths.length; ++i) { expandProperties(_paths[i], addWatchedProperty); } - if (typeof func !== 'function') { - throw new emberDebug.EmberError('_beforeObserver called without a function'); - } - func.__ember_observesBefore__ = paths; return func; } /** @@ -8683,14 +8483,14 @@ this._super$Constructor(injectedPropertyGet); AliasedPropertyPrototype.oneWay.call(this); } function injectedPropertyGet(keyName) { - var desc = this[keyName]; + var desc = descriptorFor(this, keyName); var owner = emberUtils.getOwner(this) || this.container; // fallback to `container` for backwards compat - true && !(desc && desc.isDescriptor && desc.type) && emberDebug.assert('InjectedProperties should be defined with the inject computed property macros.', desc && desc.isDescriptor && desc.type); + true && !(desc && desc.type) && emberDebug.assert('InjectedProperties should be defined with the inject computed property macros.', desc && desc.type); true && !owner && emberDebug.assert('Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container.', owner); return owner.lookup(desc.type + ':' + (desc.name || keyName)); } @@ -8735,11 +8535,11 @@ return ret; } function isProxy(value) { if (typeof value === 'object' && value !== null) { - var meta$$1 = exports.peekMeta(value); + var meta$$1 = peekMeta(value); return meta$$1 === undefined ? false : meta$$1.isProxy(); } return false; } @@ -8771,12 +8571,20 @@ Descriptor$$1.prototype.setup = function setup(obj, key) { Object.defineProperty(obj, key, this.desc); }; - Descriptor$$1.prototype.teardown = function teardown(obj, key) {}; + Descriptor$$1.prototype.get = function get(obj, key) { + return obj[key]; + }; + Descriptor$$1.prototype.set = function set(obj, key, value) { + return obj[key] = value; + }; + + Descriptor$$1.prototype.teardown = function teardown() {}; + return Descriptor$$1; }(Descriptor); exports['default'] = Ember; exports.computed = computed; @@ -8792,21 +8600,20 @@ exports.instrumentationUnsubscribe = unsubscribe; exports.getOnerror = getOnerror; exports.setOnerror = setOnerror; exports.setDispatchOverride = setDispatchOverride; exports.getDispatchOverride = getDispatchOverride; - exports.META_DESC = META_DESC; + exports.descriptorFor = descriptorFor; exports.meta = meta; + exports.peekMeta = peekMeta; exports.deleteMeta = deleteMeta; exports.Cache = Cache; exports._getPath = _getPath; exports.get = get; exports.getWithDefault = getWithDefault; exports.set = set; exports.trySet = trySet; - exports.WeakMap = WeakMap$1; - exports.WeakMapPolyfill = WeakMapPolyfill; exports.addListener = addListener; exports.hasListeners = hasListeners; exports.listenersFor = listenersFor; exports.on = on; exports.removeListener = removeListener; @@ -8856,11 +8663,10 @@ exports.removeObserver = removeObserver; exports._addBeforeObserver = _addBeforeObserver; exports._removeBeforeObserver = _removeBeforeObserver; exports.Mixin = Mixin; exports.aliasMethod = aliasMethod; - exports._immediateObserver = _immediateObserver; exports._beforeObserver = _beforeObserver; exports.mixin = mixin; exports.observer = observer; exports.required = required; exports.REQUIRED = REQUIRED; @@ -11146,19 +10952,14 @@ scheduleFlush$1 = attemptVertex(); } else { scheduleFlush$1 = useSetTimeout(); } - var platform = void 0; - /* global self */ if (typeof self === 'object') { - platform = self; /* global global */ - } else if (typeof global === 'object') { - platform = global; - } else { + } else if (typeof global === 'object') {} else { throw new Error('no global: `self` or `global` found'); } // defaults config.async = asap;