dist/ember.js in ember-source-2.3.0 vs dist/ember.js in ember-source-2.3.1

- old
+ new

@@ -4,11 +4,11 @@ * @copyright Copyright 2011-2015 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.3.0 + * @version 2.3.1 */ var enifed, requireModule, require, requirejs, Ember; var mainContext = this; @@ -10135,11 +10135,11 @@ @submodule ember-templates */ 'use strict'; - _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = 'Ember@2.3.0'; + _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = 'Ember@2.3.1'; /** The `{{outlet}}` helper lets you specify where a child routes will render in your template. An important use of the `{{outlet}}` helper is in your application's `application.hbs` file: @@ -14778,11 +14778,10 @@ */ ComputedPropertyPrototype.property = function () { var args; var addArg = function (property) { - _emberMetalDebug.assert('Depending on arrays using a dependent key ending with `@each` is no longer supported. ' + ('Please refactor from `Ember.computed(\'' + property + '\', function() {});` to `Ember.computed(\'' + property.slice(0, -6) + '.[]\', function() {})`.'), property.slice(-5) !== '@each'); args.push(property); }; args = []; for (var i = 0, l = arguments.length; i < l; i++) { @@ -15882,11 +15881,11 @@ cross-platform libraries such as jQuery. For more details, see [Ember-Runtime](http://emberjs.com/api/modules/ember-runtime.html). @class Ember @static - @version 2.3.0 + @version 2.3.1 @public */ 'use strict'; @@ -15926,15 +15925,15 @@ /** The semantic version. @property VERSION @type String - @default '2.3.0' + @default '2.3.1' @static @public */ - Ember.VERSION = '2.3.0'; + Ember.VERSION = '2.3.1'; /** The hash of environment variables used to control various configuration settings. To specify your own or override default settings, add the desired properties to a global hash named `EmberENV` (or `ENV` for @@ -16667,10 +16666,12 @@ @submodule ember-metal */ var SPLIT_REGEX = /\{|\}/; + var END_WITH_EACH_REGEX = /\.@each$/; + /** Expands `pattern`, invoking `callback` for each expansion. The only pattern supported is brace-expansion, anything else will be passed once to `callback` directly. @@ -16711,14 +16712,14 @@ properties = duplicateAndReplace(properties, part.split(','), index); } }); properties.forEach(function (property) { - callback(property.join('')); + callback(property.join('').replace(END_WITH_EACH_REGEX, '.[]')); }); } else { - callback(pattern); + callback(pattern.replace(END_WITH_EACH_REGEX, '.[]')); } } function duplicateAndReplace(properties, currentParts, index) { var all = []; @@ -18593,10 +18594,11 @@ exports.default = Mixin; exports.required = required; exports.aliasMethod = aliasMethod; exports.observer = observer; exports._immediateObserver = _immediateObserver; + exports._beforeObserver = _beforeObserver; function ROOT() {} ROOT.__hasSuper = false; var REQUIRED; @@ -18916,15 +18918,17 @@ function replaceObserversAndListeners(obj, key, observerOrListener) { var prev = obj[key]; if ('function' === typeof prev) { + updateObserversAndListeners(obj, key, prev, '__ember_observesBefore__', _emberMetalObserver._removeBeforeObserver); updateObserversAndListeners(obj, key, prev, '__ember_observes__', _emberMetalObserver.removeObserver); updateObserversAndListeners(obj, key, prev, '__ember_listens__', _emberMetalEvents.removeListener); } if ('function' === typeof observerOrListener) { + updateObserversAndListeners(obj, key, observerOrListener, '__ember_observesBefore__', _emberMetalObserver._addBeforeObserver); updateObserversAndListeners(obj, key, observerOrListener, '__ember_observes__', _emberMetalObserver.addObserver); updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', _emberMetalEvents.addListener); } } @@ -19359,12 +19363,10 @@ var func = args.slice(-1)[0]; var paths; var addWatchedProperty = function (path) { - _emberMetalDebug.assert('Depending on arrays using a dependent key ending with `@each` is no longer supported. ' + ('Please refactor from `Ember.observer(\'' + path + '\', function() {});` to `Ember.observer(\'' + path.slice(0, -6) + '.[]\', function() {})`.'), path.slice(-5) !== '@each'); - paths.push(path); }; var _paths = args.slice(0, -1); if (typeof func !== 'function') { @@ -19424,10 +19426,86 @@ } 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. + + A `_beforeObserver` fires before a property changes. + + A `_beforeObserver` is an alternative form of `.observesBefore()`. + + ```javascript + App.PersonView = Ember.View.extend({ + friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }], + + valueDidChange: Ember.observer('content.value', function(obj, keyName) { + // only run if updating a value already in the DOM + if (this.get('state') === 'inDOM') { + var color = obj.get(keyName) > this.changingFrom ? 'green' : 'red'; + // logic + } + }), + + friendsDidChange: Ember.observer('friends.@each.name', function(obj, keyName) { + // some logic + // obj.get(keyName) returns friends array + }) + }); + ``` + + Also available as `Function.prototype.observesBefore` if prototype extensions are + enabled. + + @method beforeObserver + @for Ember + @param {String} propertyNames* + @param {Function} func + @return func + @deprecated + @private + */ + + function _beforeObserver() { + for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + args[_key5] = arguments[_key5]; + } + + var func = args.slice(-1)[0]; + 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) { + _emberMetalExpand_properties.default(_paths[i], addWatchedProperty); + } + + if (typeof func !== 'function') { + throw new _emberMetalCore.default.Error('Ember.beforeObserver called without a function'); + } + + func.__ember_observesBefore__ = paths; + return func; + } + exports.IS_BINDING = IS_BINDING; exports.Mixin = Mixin; exports.required = required; exports.REQUIRED = REQUIRED; }); @@ -22577,10 +22655,11 @@ return ret; } superWrapper.wrappedFunction = func; superWrapper.__ember_observes__ = func.__ember_observes__; + superWrapper.__ember_observesBefore__ = func.__ember_observesBefore__; superWrapper.__ember_listens__ = func.__ember_listens__; return superWrapper; } @@ -22956,10 +23035,11 @@ */ 'use strict'; exports.isWatching = isWatching; + exports.watcherCount = watcherCount; exports.unwatch = unwatch; exports.destroy = destroy; /** Starts watching a property on an object. Whenever the property changes, @@ -22992,10 +23072,15 @@ function isWatching(obj, key) { var meta = _emberMetalMeta.peekMeta(obj); return (meta && meta.peekWatching(key)) > 0; } + function watcherCount(obj, key) { + var meta = _emberMetalMeta.peekMeta(obj); + return meta && meta.peekWatching(key) || 0; + } + watch.flushPending = _emberMetalChains.flushPendingChains; function unwatch(obj, _keyPath, m) { // can't watch length on Array - it is special... if (_keyPath === 'length' && Array.isArray(obj)) { @@ -25589,10 +25674,14 @@ redirecting `transitionTo`, since `willTransition` doesn't fire when there is already a transition underway. If you want subsequent `willTransition` actions to fire for the redirecting transition, you must first explicitly call `transition.abort()`. + To allow the `willTransition` event to continue bubbling to the parent + route, use `return true;`. When the `willTransition` method has a + return value of `true` then the parent route's `willTransition` method + will be fired, enabling "bubbling" behavior for the event. @event willTransition @param {Transition} transition @public */ @@ -29673,11 +29762,11 @@ @submodule ember-routing-views */ 'use strict'; - _emberHtmlbarsTemplatesLinkTo.default.meta.revision = 'Ember@2.3.0'; + _emberHtmlbarsTemplatesLinkTo.default.meta.revision = 'Ember@2.3.1'; /** `Ember.LinkComponent` renders an element whose `click` event triggers a transition of the application's instance of `Ember.Router` to a supplied route by name. @@ -30163,11 +30252,11 @@ @submodule ember-routing-views */ 'use strict'; - _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = 'Ember@2.3.0'; + _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = 'Ember@2.3.1'; var CoreOutletView = _emberViewsViewsView.default.extend({ defaultTemplate: _emberHtmlbarsTemplatesTopLevelView.default, init: function () { @@ -31396,12 +31485,10 @@ }; } }); // Ember.EXTEND_PROTOTYPES enifed('ember-runtime/ext/rsvp', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/logger', 'ember-metal/run_loop', 'rsvp'], function (exports, _emberMetalCore, _emberMetalDebug, _emberMetalLogger, _emberMetalRun_loop, _rsvp) { - /* globals RSVP:true */ - 'use strict'; exports.onerrorDefault = onerrorDefault; exports.after = after; @@ -32674,17 +32761,14 @@ /** The object to which actions from the view should be sent. For example, when a Handlebars template uses the `{{action}}` helper, it will attempt to send the action to the view's controller's `target`. By default, the value of the target property is set to the router, and - is injected when a controller is instantiated. This injection is defined - in Ember.Application#buildContainer, and is applied as part of the - applications initialization process. It can also be set after a controller - has been instantiated, for instance when using the render helper in a - template, or when a controller is used as an `itemController`. In most - cases the `target` property will automatically be set to the logical - consumer of actions for the controller. + is injected when a controller is instantiated. This injection is applied + as part of the application's initialization process. In most cases the + `target` property will automatically be set to the logical consumer of + actions for the controller. @property target @default null @public */ target: null, @@ -35623,33 +35707,19 @@ `Ember.MutableArray.` @property content @type Ember.Array @private */ - content: _emberMetalComputed.computed({ - get: function () { - return this._content; - }, - set: function (k, v) { - if (this._didInitArrayProxy) { - var oldContent = this._content; - var len = oldContent ? _emberMetalProperty_get.get(oldContent, 'length') : 0; - this.arrangedContentArrayWillChange(this, 0, len, undefined); - this.arrangedContentWillChange(this); - } - this._content = v; - return v; - } - }), + content: null, /** The array that the proxy pretends to be. In the default `ArrayProxy` implementation, this and `content` are the same. Subclasses of `ArrayProxy` can override this property to provide things like sorting and filtering. @property arrangedContent @private - */ + */ arrangedContent: _emberMetalAlias.default('content'), /** Should actually retrieve the object at the specified index from the content. You can override this method in subclasses to transform the @@ -35679,11 +35749,23 @@ */ replaceContent: function (idx, amt, objects) { _emberMetalProperty_get.get(this, 'content').replace(idx, amt, objects); }, - _teardownContent: function (content) { + /** + Invoked when the content property is about to change. Notifies observers that the + entire array content will change. + @private + @method _contentWillChange + */ + _contentWillChange: _emberMetalMixin._beforeObserver('content', function () { + this._teardownContent(); + }), + + _teardownContent: function () { + var content = _emberMetalProperty_get.get(this, 'content'); + if (content) { content.removeArrayObserver(this, { willChange: 'contentArrayWillChange', didChange: 'contentArrayDidChange' }); @@ -35717,20 +35799,18 @@ @private @method _contentDidChange */ _contentDidChange: _emberMetalMixin.observer('content', function () { var content = _emberMetalProperty_get.get(this, 'content'); - this._teardownContent(this._prevContent); _emberMetalDebug.assert('Can\'t set ArrayProxy\'s content to itself', content !== this); this._setupContent(); }), _setupContent: function () { var content = _emberMetalProperty_get.get(this, 'content'); - this._prevContent = content; if (content) { _emberMetalDebug.assert('ArrayProxy expects an Array or Ember.ArrayProxy, but you passed ' + typeof content, _emberRuntimeUtils.isArray(content) || content.isDestroyed); content.addArrayObserver(this, { @@ -35738,12 +35818,21 @@ didChange: 'contentArrayDidChange' }); } }, + _arrangedContentWillChange: _emberMetalMixin._beforeObserver('arrangedContent', function () { + var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent'); + var len = arrangedContent ? _emberMetalProperty_get.get(arrangedContent, 'length') : 0; + + this.arrangedContentArrayWillChange(this, 0, len, undefined); + this.arrangedContentWillChange(this); + + this._teardownArrangedContent(arrangedContent); + }), + _arrangedContentDidChange: _emberMetalMixin.observer('arrangedContent', function () { - this._teardownArrangedContent(this._prevArrangedContent); var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent'); var len = arrangedContent ? _emberMetalProperty_get.get(arrangedContent, 'length') : 0; _emberMetalDebug.assert('Can\'t set ArrayProxy\'s content to itself', arrangedContent !== this); @@ -35753,11 +35842,10 @@ this.arrangedContentArrayDidChange(this, 0, undefined, len); }), _setupArrangedContent: function () { var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent'); - this._prevArrangedContent = arrangedContent; if (arrangedContent) { _emberMetalDebug.assert('ArrayProxy expects an Array or Ember.ArrayProxy, but you passed ' + typeof arrangedContent, _emberRuntimeUtils.isArray(arrangedContent) || arrangedContent.isDestroyed); arrangedContent.addArrayObserver(this, { @@ -35907,19 +35995,18 @@ arrangedContentArrayDidChange: function (item, idx, removedCnt, addedCnt) { this.arrayContentDidChange(idx, removedCnt, addedCnt); }, init: function () { - this._didInitArrayProxy = true; this._super.apply(this, arguments); this._setupContent(); this._setupArrangedContent(); }, willDestroy: function () { this._teardownArrangedContent(); - this._teardownContent(this.get('content')); + this._teardownContent(); } }); exports.default = ArrayProxy; }); @@ -39106,11 +39193,11 @@ options.plugins = plugins; options.buildMeta = function buildMeta(program) { return { fragmentReason: fragmentReason(program), - revision: 'Ember@2.3.0', + revision: 'Ember@2.3.1', loc: program.loc, moduleName: options.moduleName }; }; @@ -40604,11 +40691,11 @@ var templateFullName = 'template:components/' + name; return owner.lookup(templateFullName); } }); }); -enifed('ember-views/components/component', ['exports', 'ember-metal/debug', 'ember-runtime/mixins/target_action_support', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/utils', 'ember-metal/computed', 'ember-views/compat/attrs-proxy', 'container/owner'], function (exports, _emberMetalDebug, _emberRuntimeMixinsTarget_action_support, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalUtils, _emberMetalComputed, _emberViewsCompatAttrsProxy, _containerOwner) { +enifed('ember-views/components/component', ['exports', 'ember-metal/debug', 'ember-metal/environment', 'ember-runtime/mixins/target_action_support', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/utils', 'ember-metal/computed', 'ember-views/compat/attrs-proxy', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalEnvironment, _emberRuntimeMixinsTarget_action_support, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalUtils, _emberMetalComputed, _emberViewsCompatAttrsProxy, _containerOwner) { 'use strict'; function validateAction(component, actionName) { if (actionName && actionName[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) { actionName = actionName.value; @@ -40749,11 +40836,11 @@ this.layout = this.defaultLayout; } // If in a tagless component, assert that no event handlers are defined - _emberMetalDebug.assert('You can not define a function that handles DOM events in the `' + this + '` tagless component since it doesn\'t have any DOM element.', this.tagName !== '' || !(function () { + _emberMetalDebug.assert('You can not define a function that handles DOM events in the `' + this + '` tagless component since it doesn\'t have any DOM element.', this.tagName !== '' || !_emberMetalEnvironment.default.hasDOM || !(function () { var eventDispatcher = _containerOwner.getOwner(_this).lookup('event_dispatcher:main'); var events = eventDispatcher && eventDispatcher._finalEvents || {}; for (var key in events) { var methodName = events[key]; @@ -43464,11 +43551,11 @@ var classNameBindings = component.classNameBindings; return !classNameBindings || classNameBindings.length === 0; })()); } }); -enifed('ember-views/system/event_dispatcher', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-views/system/action_manager', 'ember-views/views/view', 'ember-metal/assign', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberViewsSystemJquery, _emberViewsSystemAction_manager, _emberViewsViewsView, _emberMetalAssign, _containerOwner) { +enifed('ember-views/system/event_dispatcher', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-views/system/action_manager', 'ember-views/views/view', 'ember-metal/assign', 'container/owner', 'ember-metal/environment'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberViewsSystemJquery, _emberViewsSystemAction_manager, _emberViewsViewsView, _emberMetalAssign, _containerOwner, _emberMetalEnvironment) { /** @module ember @submodule ember-views */ @@ -43583,10 +43670,15 @@ @since 1.7.0 @private */ canDispatchToEventManager: true, + init: function () { + this._super(); + _emberMetalDebug.assert('EventDispatcher should never be instantiated in fastboot mode. Please report this as an Ember bug.', _emberMetalEnvironment.default.hasDOM); + }, + /** Sets up event listeners for standard browser events. This will be called after the browser sends a `DOMContentReady` event. By default, it will set up all of the listeners on the document body. If you would like to register the listeners on a different element, set the event @@ -44394,11 +44486,11 @@ exports.DeprecatedCollectionView = DeprecatedCollectionView; }); enifed('ember-views/views/container_view', ['exports', 'ember-metal/core', 'ember-metal/debug', 'ember-runtime/mixins/mutable_array', 'ember-runtime/system/native_array', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/mixin', 'ember-metal/events', 'ember-htmlbars/templates/container-view'], function (exports, _emberMetalCore, _emberMetalDebug, _emberRuntimeMixinsMutable_array, _emberRuntimeSystemNative_array, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMixin, _emberMetalEvents, _emberHtmlbarsTemplatesContainerView) { 'use strict'; - _emberHtmlbarsTemplatesContainerView.default.meta.revision = 'Ember@2.3.0'; + _emberHtmlbarsTemplatesContainerView.default.meta.revision = 'Ember@2.3.1'; /** @module ember @submodule ember-views */ @@ -49359,11 +49451,19 @@ return this.domHelper.getPropertyStrict(this.element, this.attrName); } function updateProperty(value) { if (this._renderedInitially === true || !_domHelperProp.isAttrRemovalValue(value)) { - // do not render if initial value is undefined or null - this.domHelper.setPropertyStrict(this.element, this.attrName, value); + var element = this.element; + var attrName = this.attrName; + + if (attrName === 'value' && element.tagName === 'INPUT' && element.value === value) { + // Do nothing. Attempts to avoid accidently changing the input cursor location. + // See https://github.com/tildeio/htmlbars/pull/447 for more details. + } else { + // do not render if initial value is undefined or null + this.domHelper.setPropertyStrict(element, attrName, value); + } } this._renderedInitially = true; }