dist/ember-runtime.js in ember-source-2.8.3 vs dist/ember-runtime.js in ember-source-2.9.0.alpha.2

- old
+ new

@@ -4,11 +4,11 @@ * @copyright Copyright 2011-2016 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.8.3 + * @version v2.9.0-alpha.2 */ var enifed, requireModule, require, Ember; var mainContext = this; @@ -4663,43 +4663,45 @@ function EmptyObject() {} EmptyObject.prototype = proto; exports.default = EmptyObject; }); -enifed('ember-metal/error', ['exports'], function (exports) { - 'use strict'; +enifed("ember-metal/error", ["exports"], function (exports) { - exports.default = EmberError; - var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; - /** A subclass of the JavaScript Error object for use in Ember. @class Error @namespace Ember @extends Error @constructor @public */ + "use strict"; - function EmberError() { - var tmp = Error.apply(this, arguments); + exports.default = EmberError; - // Adds a `stack` property to the given error object that will yield the - // stack trace at the time captureStackTrace was called. - // When collecting the stack trace all frames above the topmost call - // to this function, including that call, will be left out of the - // stack trace. - // This is useful because we can hide Ember implementation details - // that are not very helpful for the user. + function EmberError(message) { + if (!(this instanceof EmberError)) { + return new EmberError(message); + } + + var error = Error.call(this, message); + if (Error.captureStackTrace) { Error.captureStackTrace(this, EmberError); + } else { + this.stack = error.stack; } - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. - for (var idx = 0; idx < errorProps.length; idx++) { - this[errorProps[idx]] = tmp[errorProps[idx]]; - } + + this.description = error.description; + this.fileName = error.fileName; + this.lineNumber = error.lineNumber; + this.message = error.message; + this.name = error.name; + this.number = error.number; + this.code = error.code; } EmberError.prototype = Object.create(Error.prototype); }); enifed('ember-metal/error_handler', ['exports', 'ember-console', 'ember-metal/testing'], function (exports, _emberConsole, _emberMetalTesting) { @@ -4713,11 +4715,11 @@ // To maintain stacktrace consistency across browsers var getStack = function (error) { var stack = error.stack; var message = error.message; - if (stack && stack.indexOf(message) === -1) { + if (stack.indexOf(message) === -1) { stack = message + '\n' + stack; } return stack; }; @@ -6720,10 +6722,15 @@ chainWatchers: ownCustomObject, chains: inheritedCustomObject, tag: ownCustomObject }; + if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender') || _emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + members.lastRendered = ownMap; + members.lastRenderedFrom = ownMap; // FIXME: not used in production, remove me from prod builds + } + var memberNames = Object.keys(members); var META_FIELD = '__ember_meta__'; function Meta(obj, parentMeta) { this._cache = undefined; @@ -6748,10 +6755,15 @@ // explicitly instead of using prototypical inheritance because we // have detailed knowledge of how each property should really be // inherited, and we can optimize it much better than JS runtimes. this.parent = parentMeta; + if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender') || _emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + this._lastRendered = undefined; + this._lastRenderedFrom = undefined; // FIXME: not used in production, remove me from prod builds + } + this._initializeListeners(); } Meta.prototype.isInitialized = function (obj) { return this.proto !== obj; @@ -7874,11 +7886,11 @@ @param obj @return {Boolean} @private */ MixinPrototype.detect = function (obj) { - if (!obj) { + if (typeof obj !== 'object' || obj === null) { return false; } if (obj instanceof Mixin) { return _detect(obj, this, {}); } @@ -8667,11 +8679,11 @@ // https://github.com/ariya/phantomjs/issues/11856 Object.defineProperty(obj, keyName, { configurable: true, writable: true, value: 'iCry' }); Object.defineProperty(obj, keyName, desc); } }); -enifed('ember-metal/property_events', ['exports', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/events', 'ember-metal/tags', 'ember-metal/observer_set', 'ember-metal/symbol'], function (exports, _emberMetalUtils, _emberMetalMeta, _emberMetalEvents, _emberMetalTags, _emberMetalObserver_set, _emberMetalSymbol) { +enifed('ember-metal/property_events', ['exports', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/events', 'ember-metal/tags', 'ember-metal/observer_set', 'ember-metal/symbol', 'ember-metal/features', 'ember-metal/transaction'], function (exports, _emberMetalUtils, _emberMetalMeta, _emberMetalEvents, _emberMetalTags, _emberMetalObserver_set, _emberMetalSymbol, _emberMetalFeatures, _emberMetalTransaction) { 'use strict'; var PROPERTY_DID_CHANGE = _emberMetalSymbol.default('PROPERTY_DID_CHANGE'); exports.PROPERTY_DID_CHANGE = PROPERTY_DID_CHANGE; @@ -8764,11 +8776,18 @@ if (obj[PROPERTY_DID_CHANGE]) { obj[PROPERTY_DID_CHANGE](keyName); } + if (obj.isDestroying) { + return; + } _emberMetalTags.markObjectAsDirty(m); + + if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender') || _emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + _emberMetalTransaction.assertNotRendered(obj, keyName, m); + } } var WILL_SEEN = undefined, DID_SEEN = undefined; // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...) @@ -9523,17 +9542,16 @@ @param {Object} [target] target object to use as the context when invoking a method. @param {String|Function} method The method to invoke. If you pass a string it will be resolved on the target object at the time the scheduled item is invoked allowing you to change the target function. @param {Object} [arguments*] Optional arguments to be passed to the queued method. - @return {*} Timer information for use in cancelling, see `run.cancel`. + @return {void} @public */ run.schedule = function () /* queue, target, method */{ _emberMetalDebug.assert('You have turned on testing mode, which disabled the run-loop\'s autorun. ' + 'You will need to wrap any code with asynchronous side-effects in a run', run.currentRunLoop || !_emberMetalTesting.isTesting()); - - return backburner.schedule.apply(backburner, arguments); + backburner.schedule.apply(backburner, arguments); }; // Used by global test teardown run.hasScheduledTimers = function () { return backburner.hasTimers(); @@ -10026,11 +10044,11 @@ function tagFor(object, _meta) { if (!hasGlimmer) { throw new Error('Cannot call tagFor without Glimmer'); } - if (object && typeof object === 'object') { + if (typeof object === 'object' && object) { var meta = _meta || _emberMetalMeta.meta(object); return meta.writableTag(makeTag); } else { return CONSTANT_TAG; } @@ -10080,10 +10098,112 @@ function setTesting(value) { testing = !!value; } }); +enifed('ember-metal/transaction', ['exports', 'ember-metal/meta', 'ember-metal/debug', 'ember-metal/features'], function (exports, _emberMetalMeta, _emberMetalDebug, _emberMetalFeatures) { + 'use strict'; + + var runInTransaction = undefined, + didRender = undefined, + assertNotRendered = undefined; + + if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender') || _emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + _emberMetalDebug.assert('It appears you are trying to use the backtracking rerender feature without the "ember-glimmer" flag turned on. Please make sure that "ember-glimmer" is turned on.', _emberMetalFeatures.default('ember-glimmer')); + } + + var raise = _emberMetalDebug.assert; + if (_emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + raise = function (message, test) { + _emberMetalDebug.deprecate(message, test, { id: 'ember-views.render-double-modify', until: '3.0.0' }); + }; + } + + var implication = undefined; + if (_emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + implication = 'will be removed in Ember 3.0.'; + } else if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender')) { + implication = 'is no longer supported. See https://github.com/emberjs/ember.js/issues/13948 for more details.'; + } + + if (_emberMetalFeatures.default('ember-glimmer-detect-backtracking-rerender') || _emberMetalFeatures.default('ember-glimmer-allow-backtracking-rerender')) { + (function () { + var counter = 0; + var inTransaction = false; + var shouldReflush = undefined; + + exports.default = runInTransaction = function (callback) { + shouldReflush = false; + inTransaction = true; + callback(); + inTransaction = false; + counter++; + return shouldReflush; + }; + + exports.didRender = didRender = function (object, key, reference) { + if (!inTransaction) { + return; + } + var meta = _emberMetalMeta.meta(object); + var lastRendered = meta.writableLastRendered(); + lastRendered[key] = counter; + + _emberMetalDebug.runInDebug(function () { + var lastRenderedFrom = meta.writableLastRenderedFrom(); + lastRenderedFrom[key] = reference; + }); + }; + + exports.assertNotRendered = assertNotRendered = function (object, key, _meta) { + var meta = _meta || _emberMetalMeta.meta(object); + var lastRendered = meta.readableLastRendered(); + + if (lastRendered && lastRendered[key] === counter) { + raise((function () { + var ref = meta.readableLastRenderedFrom(); + var parts = []; + var lastRef = ref[key]; + + var label = undefined; + + if (lastRef) { + while (lastRef && lastRef._propertyKey && lastRef._parentReference) { + parts.unshift(lastRef._propertyKey); + lastRef = lastRef._parentReference; + } + + label = parts.join(); + } else { + label = 'the same value'; + } + + return 'You modified ' + parts.join('.') + ' twice in a single render. This was unreliable and slow in Ember 1.x and ' + implication; + })(), false); + + shouldReflush = true; + } + }; + })(); + } else { + exports.default = runInTransaction = function () { + throw new Error('Cannot call runInTransaction without Glimmer'); + }; + + exports.didRender = didRender = function () { + throw new Error('Cannot call didRender without Glimmer'); + }; + + exports.assertNotRendered = assertNotRendered = function () { + throw new Error('Cannot call assertNotRendered without Glimmer'); + }; + } + + exports.default = runInTransaction; + exports.didRender = didRender; + exports.assertNotRendered = assertNotRendered; +}); enifed('ember-metal/utils', ['exports'], function (exports) { 'no use strict'; // Remove "use strict"; from transpiled module until // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed @@ -10279,11 +10399,15 @@ @param {Object} obj any object, string, number, Element, or primitive @return {String} the unique guid for this instance. */ function guidFor(obj) { - if (obj && obj[GUID_KEY]) { + var type = typeof obj; + var isObject = type === 'object' && obj !== null; + var isFunction = type === 'function'; + + if ((isObject || isFunction) && obj[GUID_KEY]) { return obj[GUID_KEY]; } // special cases where we don't want to add a key to object if (obj === undefined) { @@ -10293,11 +10417,10 @@ if (obj === null) { return '(null)'; } var ret = undefined; - var type = typeof obj; // Don't allow prototype changes to String etc. to change the guidFor switch (type) { case 'number': ret = numberCache[obj]; @@ -14042,21 +14165,21 @@ Returns `true` if the passed object can be found in the array. This method is a Polyfill for ES 2016 Array.includes. If no `startAt` argument is given, the starting location to search is 0. If it's negative, searches from the index of `this.length + startAt` by asc. - ```javascript + ```javascript [1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, 3].includes(3, 2); // true [1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true [1, 2, 3].includes(1, -1); // false [1, 2, 3].includes(1, -4); // true [1, 2, NaN].includes(NaN); // true ``` - @method includes + @method includes @param {Object} obj The object to search for. @param {Number} startAt optional starting location to search, default 0 @return {Boolean} `true` if object is found in the array. @public */ @@ -14889,11 +15012,11 @@ */ getEach: _emberMetalMixin.aliasMethod('mapBy'), /** Sets the value on the named property for each member. This is more - ergonomic than using other methods defined on this helper. If the object + efficient than using other methods defined on this helper. If the object implements Ember.Observable, the value will be changed to `set(),` otherwise it will be set directly. `null` objects are skipped. @method setEach @param {String} key The key to set @param {Object} value The object to set @@ -15644,18 +15767,18 @@ if (_emberMetalFeatures.default('ember-runtime-enumerable-includes')) { Enumerable.reopen({ /** Returns `true` if the passed object can be found in the enumerable. - ```javascript + ```javascript [1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, undefined].includes(undefined); // true [1, 2, null].includes(null); // true [1, 2, NaN].includes(NaN); // true ``` - @method includes + @method includes @param {Object} obj The object to search for. @return {Boolean} `true` if object is found in the enumerable. @public */ includes: function (obj) { @@ -17850,15 +17973,15 @@ var arr = this.toArray(); return arr.slice.apply(arr, arguments); }, arrangedContentArrayWillChange: function (item, idx, removedCnt, addedCnt) { - this.arrayContentWillChange(idx, removedCnt, addedCnt); + _emberRuntimeMixinsArray.arrayContentWillChange(this, idx, removedCnt, addedCnt); }, arrangedContentArrayDidChange: function (item, idx, removedCnt, addedCnt) { - this.arrayContentDidChange(idx, removedCnt, addedCnt); + _emberRuntimeMixinsArray.arrayContentDidChange(this, idx, removedCnt, addedCnt); }, init: function () { this._super.apply(this, arguments); this._setupContent(); @@ -18001,11 +18124,23 @@ } } finishPartial(this, m); - this.init.apply(this, arguments); + if (arguments.length === 0) { + this.init(); + } else if (arguments.length === 1) { + this.init(arguments[0]); + } else { + // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709 + // we may want to keep this around till this ages out on mobile + var args = new Array(arguments.length); + for (var x = 0; x < arguments.length; x++) { + args[x] = arguments[x]; + } + this.init.apply(this, args); + } this[POST_INIT](); m.proto = proto; _emberMetalChains.finishChains(this); @@ -19878,15 +20013,15 @@ } }); enifed("ember/features", ["exports"], function (exports) { "use strict"; - exports.default = {}; + exports.default = { "features-stripped-test": false, "ember-routing-route-configured-query-params": false, "ember-libraries-isregistered": false, "ember-application-engines": true, "ember-glimmer": true, "ember-runtime-computed-uniq-by": true, "ember-improved-instrumentation": false, "ember-runtime-enumerable-includes": true, "ember-string-ishtmlsafe": true, "ember-testing-check-waiters": true, "ember-metal-weakmap": false, "ember-glimmer-allow-backtracking-rerender": false, "mandatory-setter": true, "ember-glimmer-detect-backtracking-rerender": true }; }); enifed("ember/version", ["exports"], function (exports) { "use strict"; - exports.default = "2.8.3"; + exports.default = "v2.9.0-alpha.2"; }); enifed('rsvp', ['exports', 'rsvp/promise', 'rsvp/events', 'rsvp/node', 'rsvp/all', 'rsvp/all-settled', 'rsvp/race', 'rsvp/hash', 'rsvp/hash-settled', 'rsvp/rethrow', 'rsvp/defer', 'rsvp/config', 'rsvp/map', 'rsvp/resolve', 'rsvp/reject', 'rsvp/filter', 'rsvp/asap'], function (exports, _rsvpPromise, _rsvpEvents, _rsvpNode, _rsvpAll, _rsvpAllSettled, _rsvpRace, _rsvpHash, _rsvpHashSettled, _rsvpRethrow, _rsvpDefer, _rsvpConfig, _rsvpMap, _rsvpResolve, _rsvpReject, _rsvpFilter, _rsvpAsap) { 'use strict'; // defaults