dist/ember-template-compiler.js in ember-source-2.3.0 vs dist/ember-template-compiler.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; @@ -3024,11 +3024,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++) { @@ -4128,11 +4127,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'; @@ -4172,15 +4171,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 @@ -4913,10 +4912,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. @@ -4957,14 +4958,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 = []; @@ -6839,10 +6840,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; @@ -7162,15 +7164,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); } } @@ -7605,12 +7609,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') { @@ -7670,10 +7672,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; }); @@ -10823,10 +10901,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; } @@ -11202,10 +11281,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, @@ -11238,10 +11318,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)) { @@ -12566,11 +12651,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 }; }; @@ -18193,13 +18278,13 @@ function assembleAttributeValue(parts, isQuoted, isDynamic, line) { if (isDynamic) { if (isQuoted) { return assembleConcatenatedValue(parts); } else { - if (parts.length === 1) { + if (parts.length === 1 || parts.length === 2 && parts[1] === '/') { return parts[0]; } else { - throw new Error("An unquoted attribute value must be a string or a mustache, " + "preceeded by whitespace or a '=' character, and " + ("followed by whitespace or a '>' character (on line " + line + ")")); + throw new Error("An unquoted attribute value must be a string or a mustache, " + "preceeded by whitespace or a '=' character, and " + ("followed by whitespace, a '>' character or a '/>' (on line " + line + ")")); } } } else { return _htmlbarsSyntaxBuilders.default.text(parts.length > 0 ? parts[0] : ""); } \ No newline at end of file