dist/ember.prod.js in ember-source-1.13.3 vs dist/ember.prod.js in ember-source-1.13.4

- old
+ new

@@ -3,11 +3,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 1.13.3 + * @version 1.13.4 */ (function() { var enifed, requireModule, eriuqer, requirejs, Ember; var mainContext = this; @@ -5890,11 +5890,35 @@ if (_emberMetalCore["default"].FEATURES.isEnabled("ember-htmlbars-helper")) { _emberHtmlbarsHelper["default"].helper = _emberHtmlbarsHelper.helper; _emberMetalCore["default"].Helper = _emberHtmlbarsHelper["default"]; } }); +/** + &nbsp; + + @module ember + @submodule ember-templates + @main ember-templates + @public +*/ + +/** + + [HTMLBars](https://github.com/tildeio/htmlbars) is a [Handlebars](http://handlebarsjs.com/) + compatible templating engine used by Ember.js. The classes and namespaces + covered by this documentation attempt to focus on APIs for interacting + with HTMLBars itself. For more general guidance on Ember.js templates and + helpers, please see the [ember-templates](/api/modules/ember-templates.html) + package. + + @module ember + @submodule ember-htmlbars + @main ember-htmlbars + @public +*/ + // importing adds template bootstrapping // initializer to enable embedded templates // importing ember-htmlbars/compat updates the // Ember.Handlebars global if htmlbars is enabled @@ -6100,12 +6124,10 @@ /** @module ember @submodule ember-htmlbars */ - //import Helper from "ember-htmlbars/system/helper"; - /** A helper function used by `registerBoundHelper`. Takes the provided Handlebars helper function fn and returns it in wrapped bound helper form. @@ -6350,36 +6372,125 @@ var domHelper = _emberMetalEnvironment["default"].hasDOM ? new _emberHtmlbarsSystemDomHelper["default"]() : null; exports.domHelper = domHelper; }); -enifed("ember-htmlbars/helper", ["exports", "ember-runtime/system/object"], function (exports, _emberRuntimeSystemObject) { +enifed('ember-htmlbars/helper', ['exports', 'ember-runtime/system/object'], function (exports, _emberRuntimeSystemObject) { exports.helper = helper; - // Ember.Helper.extend({ compute(params, hash) {} }); + /** + Ember Helpers are functions that can compute values, and are used in templates. + For example, this code calls a helper named `format-currency`: + + ```handlebars + <div>{{format-currency cents currency="$"}}</div> + ``` + + Additionally a helper can be called as a nested helper (sometimes called a + subexpression). In this example, the computed value of a helper is passed + to a component named `show-money`: + + ```handlebars + {{show-money amount=(format-currency cents currency="$")}} + ``` + + Helpers defined using a class must provide a `compute` function. For example: + + ```js + export default Ember.Helper.extend({ + compute(params, hash) { + let cents = params[0]; + let currency = hash.currency; + return `${currency}${cents * 0.01}`; + } + }); + ``` + + Each time the input to a helper changes, the `compute` function will be + called again. + + As instances, these helpers also have access to the container an will accept + injected dependencies. + + Additionally, class helpers can call `recompute` to force a new computation. + + @class Ember.Helper + @public + */ var Helper = _emberRuntimeSystemObject["default"].extend({ isHelper: true, + + /** + On a class-based helper, it may be useful to force a recomputation of that + helpers value. This is akin to `rerender` on a component. + For example, this component will rerender when the `currentUser` on a + session service changes: + ```js + // app/helpers/current-user-email.js + export default Ember.Helper.extend({ + session: Ember.inject.service(), + onNewUser: Ember.observer('session.currentUser', function() { + this.recompute(); + }), + compute() { + return this.get('session.currentUser.email'); + } + }); + ``` + @method recompute + @public + */ recompute: function () { this._stream.notify(); } + + /** + Override this function when writing a class-based helper. + @method compute + @param {Array} params The positional arguments to the helper + @param {Object} hash The named arguments to the helper + @public + */ }); Helper.reopenClass({ isHelperFactory: true }); - // Ember.Helper.helper(function(params, hash) {}); + /** + In many cases, the ceremony of a full `Ember.Helper` class is not required. + The `helper` method create pure-function helpers without instances. For + example: + + ```js + // app/helpers/format-currency.js + export default Ember.Helper.helper(function(params, hash) { + let cents = params[0]; + let currency = hash.currency; + return `${currency}${cents * 0.01}`; + }); + ``` + + @static + @param {Function} helper The helper function + @method helper + @public + */ function helper(helperFn) { return { isHelperInstance: true, compute: helperFn }; } exports["default"] = Helper; }); +/** +@module ember +@submodule ember-templates +*/ enifed("ember-htmlbars/helpers", ["exports", "ember-metal/platform/create"], function (exports, _emberMetalPlatformCreate) { exports.registerHelper = registerHelper; /** @private @@ -6824,11 +6935,11 @@ <p>Sorry, nobody is available for this task.</p> {{/each}} ``` @method each - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @public */ function eachHelper(params, hash, blocks) { var list = params[0]; @@ -6916,11 +7027,11 @@ ```handlebars {{some-component height=(if isBig "100" "10")}} ``` @method if - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @public */ function ifHelper(params, hash, options) { return ifUnless(params, hash, options, _emberViewsStreamsShould_display["default"](params[0])); } @@ -6929,11 +7040,11 @@ The `unless` helper is the inverse of the `if` helper. Its block will be rendered if the expression contains a falsey value. All forms of the `if` helper can also be used with `unless`. @method unless - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @public */ function unlessHelper(params, hash, options) { return ifUnless(params, hash, options, !_emberViewsStreamsShould_display["default"](params[0])); } @@ -6959,45 +7070,50 @@ exports.ifHelper = ifHelper; exports.unlessHelper = unlessHelper; }); /** @module ember -@submodule ember-htmlbars +@submodule ember-templates */ // Ember.assert enifed('ember-htmlbars/helpers/loc', ['exports', 'ember-runtime/system/string'], function (exports, _emberRuntimeSystemString) { exports["default"] = locHelper; /** @module ember - @submodule ember-htmlbars + @submodule ember-templates */ /** Calls [Ember.String.loc](/api/classes/Ember.String.html#method_loc) with the - provided string. - This is a convenient way to localize text within a template: + provided string. This is a convenient way to localize text within a template. + For example: + ```javascript Ember.STRINGS = { '_welcome_': 'Bonjour' }; ``` + ```handlebars <div class='message'> {{loc '_welcome_'}} </div> ``` + ```html <div class='message'> Bonjour </div> ``` + See [Ember.String.loc](/api/classes/Ember.String.html#method_loc) for how to set up localized string references. + @method loc - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @param {String} str The string to format @see {Ember.String#loc} @public */ @@ -7009,26 +7125,28 @@ exports["default"] = logHelper; /** `log` allows you to output the value of variables in the current rendering context. `log` also accepts primitive types such as strings or numbers. + ```handlebars {{log "myVariable:" myVariable }} ``` + @method log - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @param {*} values @public */ function logHelper(values) { _emberMetalLogger["default"].log.apply(null, values); } }); /** @module ember -@submodule ember-htmlbars +@submodule ember-templates */ enifed("ember-htmlbars/helpers/with", ["exports", "ember-htmlbars/utils/normalize-self", "ember-views/streams/should_display"], function (exports, _emberHtmlbarsUtilsNormalizeSelf, _emberViewsStreamsShould_display) { exports["default"] = withHelper; /** @@ -7056,11 +7174,11 @@ NOTE: The alias should not reuse a name from the bound property path. For example: `{{#with foo.bar as |foo|}}` is not supported because it attempts to alias using the first part of the property path, `foo`. Instead, use `{{#with foo.bar as |baz|}}`. @method with - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @param {Object} options @return {String} HTML string @public */ @@ -7091,11 +7209,11 @@ } } }); /** @module ember -@submodule ember-htmlbars +@submodule ember-templates */ enifed("ember-htmlbars/hooks/bind-local", ["exports", "ember-metal/streams/stream", "ember-metal/streams/proxy-stream"], function (exports, _emberMetalStreamsStream, _emberMetalStreamsProxyStream) { exports["default"] = bindLocal; function bindLocal(env, scope, key, value) { @@ -7134,11 +7252,10 @@ newStream(scope.locals, "controller", controller || self); } if (self && self.isView) { - scope.view = self; newStream(scope.locals, "view", self, null); newStream(scope.locals, "controller", scope.locals.view.getKey("controller")); newStream(scope, "self", scope.locals.view.getKey("context"), null, true); return; } @@ -7291,17 +7408,63 @@ @module ember @submodule ember-htmlbars */ enifed("ember-htmlbars/hooks/create-fresh-scope", ["exports"], function (exports) { exports["default"] = createFreshScope; + /* + Ember's implementation of HTMLBars creates an enriched scope. + + * self: same as HTMLBars, this field represents the dynamic lookup + of root keys that are not special keywords or block arguments. + * blocks: same as HTMLBars, a bundle of named blocks the layout + can yield to. + * component: indicates that the scope is the layout of a component, + which is used to trigger lifecycle hooks for the component when + one of the streams in its layout fires. + * attrs: a map of key-value attributes sent in by the invoker of + a template, and available in the component's layout. + * locals: a map of locals, produced by block params (`as |a b|`) + * localPresent: a map of available locals to avoid expensive + `hasOwnProperty` checks. + + The `self` field has two special meanings: + + * If `self` is a view (`isView`), the actual HTMLBars `self` becomes + the view's `context`. This is legacy semantics; components always + use the component itself as the `this`. + * If `self` is a view, two special locals are created: `view` and + `controller`. These locals are legacy semantics. + * If self has a `hasBoundController` property, it is coming from + a legacy form of #with or #each + (`{{#with something controller=someController}}`). This has + the special effect of giving the child scope the supplied + `controller` keyword, with an unrelated `self`. This is + legacy functionality, as both the `view` and `controller` + keywords have been deprecated. + + **IMPORTANT**: There are two places in Ember where the ambient + controller is looked up. Both of those places use the presence + of `scope.locals.view` to indicate that the controller lookup + should be dynamic off of the ambient view. If `scope.locals.view` + does not exist, the code assumes that it is inside of a top-level + template (without a view) and uses the `self` itself as the + controller. This means that if you remove `scope.locals.view` + (perhaps because we are finally ready to shed the view keyword), + there may be unexpected consequences on controller semantics. + If this happens to you, I hope you find this comment. - YK & TD + + In practice, this means that with the exceptions of top-level + view-less templates and the legacy `controller=foo` semantics, + the controller hierarchy is managed dynamically by looking at + the current view's `controller`. + */ function createFreshScope() { return { self: null, blocks: {}, component: null, - view: null, attrs: null, locals: {}, localPresent: {} }; } @@ -7328,14 +7491,13 @@ }); enifed("ember-htmlbars/hooks/did-cleanup-tree", ["exports"], function (exports) { exports["default"] = didCleanupTree; function didCleanupTree(env) { - var view; - if (view = env.view) { - view.ownerView.isDestroyingSubtree = false; - } + // Once we have finsihed cleaning up the render node and sub-nodes, reset + // state tracking which view those render nodes belonged to. + env.view.ownerView._destroyingSubtreeForView = null; } }); enifed("ember-htmlbars/hooks/did-render-node", ["exports"], function (exports) { exports["default"] = didRenderNode; @@ -7565,11 +7727,11 @@ case "if": params[0] = shouldDisplay(params[0]);break; case "each": params[0] = eachParam(params[0]);break; default: - helper = _emberHtmlbarsSystemLookupHelper.findHelper(path, scope.view, env); + helper = _emberHtmlbarsSystemLookupHelper.findHelper(path, env.view, env); if (helper && helper.isHandlebarsCompat && params[0]) { params[0] = processHandlebarsCompatDepKeys(params[0], helper._dependentKeys); } } @@ -7747,11 +7909,10 @@ _emberHtmlbarsUtilsUpdateScope["default"](scope.locals, "controller", controller || self); } if (self && self.isView) { - scope.view = self; _emberHtmlbarsUtilsUpdateScope["default"](scope.locals, "view", self, null); _emberHtmlbarsUtilsUpdateScope["default"](scope, "self", _emberMetalProperty_get.get(self, "context"), null, true); return; } @@ -7763,19 +7924,41 @@ @submodule ember-htmlbars */ enifed("ember-htmlbars/hooks/will-cleanup-tree", ["exports"], function (exports) { exports["default"] = willCleanupTree; - function willCleanupTree(env, morph, destroySelf) { - var view = morph.emberView; - if (destroySelf && view && view.parentView) { - view.parentView.removeChild(view); - } + function willCleanupTree(env) { + var view = env.view; - if (view = env.view) { - view.ownerView.isDestroyingSubtree = true; - } + // When we go to clean up the render node and all of its children, we may + // encounter views/components associated with those nodes along the way. In + // those cases, we need to make sure we need to sever the link between the + // existing view hierarchy and those views. + // + // However, we do *not* need to remove the child views of child views, since + // severing the connection to their parent effectively severs them from the + // view graph. + // + // For example, imagine the following view graph: + // + // A + // / \ + // B C + // / \ + // D E + // + // If we are cleaning up the node for view C, we need to remove that view + // from A's child views. However, we do not need to remove D and E from C's + // child views, since removing C transitively removes D and E as well. + // + // To accomplish this, we track the nearest view to this render node on the + // owner view, the root-most view in the graph (A in the example above). If + // we detect a view that is a direct child of that view, we remove it from + // the `childViews` array. Other parent/child view relationships are + // untouched. This view is then cleared once cleanup is complete in + // `didCleanupTree`. + view.ownerView._destroyingSubtreeForView = view; } }); enifed("ember-htmlbars/keywords", ["exports", "htmlbars-runtime", "ember-metal/platform/create"], function (exports, _htmlbarsRuntime, _emberMetalPlatformCreate) { exports.registerKeyword = registerKeyword; @@ -7812,11 +7995,11 @@ exports["default"] = { setupState: function (state, env, scope, params, hash) { var read = env.hooks.getValue; return _emberMetalMerge.assign({}, state, { - parentView: read(scope.locals.view), + parentView: env.view, viewClassOrInstance: getView(read(params[0]), env.container) }); }, rerender: function (morph, env, scope, params, hash, template, inverse, visitor) { @@ -7869,11 +8052,59 @@ }); /** @module ember @submodule ember-htmlbars */ -enifed("ember-htmlbars/keywords/component", ["exports", "ember-metal/merge"], function (exports, _emberMetalMerge) { +enifed('ember-htmlbars/keywords/component', ['exports', 'ember-metal/merge'], function (exports, _emberMetalMerge) { + + /** + The `{{component}}` helper lets you add instances of `Ember.Component` to a + template. See [Ember.Component](/api/classes/Ember.Component.html) for + additional information on how a `Component` functions. + `{{component}}`'s primary use is for cases where you want to dynamically + change which type of component is rendered as the state of your application + changes. The provided block will be applied as the template for the component. + Given an empty `<body>` the following template: + + ```handlebars + {{! application.hbs }} + {{component infographicComponentName}} + ``` + + And the following application code: + + ```javascript + export default Ember.Controller.extend({ + infographicComponentName: computed('isMarketOpen', { + get() { + if (this.get('isMarketOpen')) { + return 'live-updating-chart'; + } else { + return 'market-close-summary'; + } + } + }) + }); + ``` + + The `live-updating-chart` component will be appended when `isMarketOpen` is + `true`, and the `market-close-summary` component will be appended when + `isMarketOpen` is `false`. If the value changes while the app is running, + the component will be automatically swapped out accordingly. + Note: You should not use this helper when you are consistently rendering the same + component. In that case, use standard component syntax, for example: + + ```handlebars + {{! application.hbs }} + {{live-updating-chart}} + ``` + + @method component + @since 1.11.0 + @for Ember.Templates.helpers + @public + */ exports["default"] = { setupState: function (lastState, env, scope, params, hash) { var componentPath = env.hooks.getValue(params[0]); return _emberMetalMerge.assign({}, lastState, { componentPath: componentPath, isComponentHelper: true }); }, @@ -7908,10 +8139,15 @@ } env.hooks.component(morph, env, scope, componentPath, params, hash, { "default": template, inverse: inverse }, visitor); } }); +/** + @module ember + @submodule ember-templates + @public +*/ enifed("ember-htmlbars/keywords/customized_outlet", ["exports", "ember-htmlbars/node-managers/view-node-manager", "ember-views/streams/utils", "ember-metal/streams/utils"], function (exports, _emberHtmlbarsNodeManagersViewNodeManager, _emberViewsStreamsUtils, _emberMetalStreamsUtils) { exports["default"] = { setupState: function (state, env, scope, params, hash) { var read = env.hooks.getValue; var viewClass = read(hash.viewClass) || _emberViewsStreamsUtils.readViewFactory(read(hash.view), env.container); @@ -7974,11 +8210,11 @@ ``` > context ``` @method debugger - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @public */ function debuggerKeyword(morph, env, scope) { /* jshint unused: false, debug: true */ @@ -8226,11 +8462,11 @@ return true; } }); enifed("ember-htmlbars/keywords/real_outlet", ["exports", "ember-metal/property_get", "ember-htmlbars/node-managers/view-node-manager", "ember-htmlbars/templates/top-level-view"], function (exports, _emberMetalProperty_get, _emberHtmlbarsNodeManagersViewNodeManager, _emberHtmlbarsTemplatesTopLevelView) { - _emberHtmlbarsTemplatesTopLevelView["default"].meta.revision = "Ember@1.13.3"; + _emberHtmlbarsTemplatesTopLevelView["default"].meta.revision = "Ember@1.13.4"; exports["default"] = { willRender: function (renderNode, env) { env.view.ownerView._outlets.push(renderNode); }, @@ -8423,15 +8659,15 @@ viewClassOrInstance = getView(read(params[0]), env.container); } // if parentView exists, use its controller (the default // behavior), otherwise use `scope.self` as the controller - var controller = scope.view ? null : read(scope.self); + var controller = scope.locals.view ? null : read(scope.self); return { manager: state.manager, - parentView: scope.view, + parentView: env.view, controller: controller, targetObject: targetObject, viewClassOrInstance: viewClassOrInstance }; }, @@ -8519,21 +8755,27 @@ }); /** @module ember @submodule ember-htmlbars */ -enifed("ember-htmlbars/keywords/with", ["exports", "htmlbars-runtime", "ember-metal/property_get"], function (exports, _htmlbarsRuntime, _emberMetalProperty_get) { +enifed('ember-htmlbars/keywords/with', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'htmlbars-runtime', 'ember-metal/streams/utils'], function (exports, _emberMetalCore, _emberMetalProperty_get, _htmlbarsRuntime, _emberMetalStreamsUtils) { exports["default"] = { setupState: function (state, env, scope, params, hash) { var controller = hash.controller; if (controller) { if (!state.controller) { var context = params[0]; - var controllerFactory = env.container.lookupFactory("controller:" + controller); - var parentController = scope.view ? _emberMetalProperty_get.get(scope.view, "context") : null; + var controllerFactory = env.container.lookupFactory('controller:' + controller); + var parentController = null; + if (scope.locals.controller) { + parentController = _emberMetalStreamsUtils.read(scope.locals.controller); + } else if (scope.locals.view) { + parentController = _emberMetalProperty_get.get(_emberMetalStreamsUtils.read(scope.locals.view), 'context'); + } + var controllerInstance = controllerFactory.create({ model: env.hooks.getValue(context), parentController: parentController, target: parentController }); @@ -8565,15 +8807,15 @@ if (template && template.arity === 0) { } - _htmlbarsRuntime.internal.continueBlock(morph, env, scope, "with", params, hash, template, inverse, visitor); + _htmlbarsRuntime.internal.continueBlock(morph, env, scope, 'with', params, hash, template, inverse, visitor); }, rerender: function (morph, env, scope, params, hash, template, inverse, visitor) { - _htmlbarsRuntime.internal.continueBlock(morph, env, scope, "with", params, hash, template, inverse, visitor); + _htmlbarsRuntime.internal.continueBlock(morph, env, scope, 'with', params, hash, template, inverse, visitor); } }; }); enifed("ember-htmlbars/morphs/attr-morph", ["exports", "ember-metal/core", "dom-helper", "ember-metal/platform/create"], function (exports, _emberMetalCore, _domHelper, _emberMetalPlatformCreate) { @@ -8632,18 +8874,17 @@ this.emberToDestroy = this.emberToDestroy || []; this.emberToDestroy.push(toDestroy); }; proto.cleanup = function () { - var view; + var view = this.emberView; - if (view = this.emberView) { - if (!view.ownerView.isDestroyingSubtree) { - view.ownerView.isDestroyingSubtree = true; - if (view.parentView) { - view.parentView.removeChild(view); - } + if (view) { + var parentView = view.parentView; + + if (parentView && view.ownerView._destroyingSubtreeForView === parentView) { + parentView.removeChild(view); } } var toDestroy = this.emberToDestroy; if (toDestroy) { @@ -8928,11 +9169,11 @@ component._renderNode = null; component.destroy(); }; function createComponent(_component, isAngleBracket, _props, renderNode, env) { - var attrs = arguments[5] === undefined ? {} : arguments[5]; + var attrs = arguments.length <= 5 || arguments[5] === undefined ? {} : arguments[5]; var props = _emberMetalMerge.assign({}, _props); if (!isAngleBracket) { var hasSuppliedController = ("controller" in attrs); // 2.0TODO remove @@ -8962,10 +9203,11 @@ } } component._renderNode = renderNode; renderNode.emberView = component; + renderNode.buildChildEnv = buildChildEnv; return component; } function shadowedAttrs(target, attrs) { var shadowed = {}; @@ -9015,10 +9257,14 @@ } } return target; } + + function buildChildEnv(state, env) { + return env.childWithView(this.emberView); + } }); // In theory this should come through the env, but it should // be safe to import this until we make the hook system public // and it gets actively used in addons or other downstream @@ -9167,17 +9413,21 @@ function getTemplate(componentOrView) { return componentOrView.isComponent ? _emberMetalProperty_get.get(componentOrView, "_template") : _emberMetalProperty_get.get(componentOrView, "template"); } function createOrUpdateComponent(component, options, createOptions, renderNode, env) { - var attrs = arguments[5] === undefined ? {} : arguments[5]; + var attrs = arguments.length <= 5 || arguments[5] === undefined ? {} : arguments[5]; var snapshot = takeSnapshot(attrs); var props = _emberMetalMerge["default"]({}, options); var defaultController = _emberViewsViewsView["default"].proto().controller; var hasSuppliedController = "controller" in attrs || "controller" in props; + if (!props.ownerView && options.parentView) { + props.ownerView = options.parentView.ownerView; + } + props.attrs = snapshot; if (component.create) { var proto = component.proto(); if (createOptions) { @@ -9424,26 +9674,26 @@ // Ember.assert enifed("ember-htmlbars/system/bootstrap", ["exports", "ember-metal/core", "ember-views/component_lookup", "ember-views/system/jquery", "ember-metal/error", "ember-runtime/system/lazy_load", "ember-template-compiler/system/compile", "ember-metal/environment"], function (exports, _emberMetalCore, _emberViewsComponent_lookup, _emberViewsSystemJquery, _emberMetalError, _emberRuntimeSystemLazy_load, _emberTemplateCompilerSystemCompile, _emberMetalEnvironment) { /** @module ember - @submodule ember-handlebars + @submodule ember-htmlbars */ /** Find templates stored in the head tag as script tags and make them available to `Ember.CoreView` in the global `Ember.TEMPLATES` object. This will be run as as jQuery DOM-ready callback. Script tags with `text/x-handlebars` will be compiled - with Ember's Handlebars and are suitable for use as a view's template. + with Ember's template compiler and are suitable for use as a view's template. Those with type `text/x-raw-handlebars` will be compiled with regular Handlebars and are suitable for use in views' computed properties. @private @method bootstrap - @for Ember.Handlebars + @for Ember.HTMLBars @static @param ctx */ function bootstrap(ctx) { var selectors = "script[type=\"text/x-handlebars\"], script[type=\"text/x-raw-handlebars\"]"; @@ -9558,18 +9808,13 @@ exports["default"] = EmberDOMHelper; }); enifed("ember-htmlbars/system/helper", ["exports"], function (exports) { /** @module ember - @submodule ember-htmlbars + @submodule ember-templates */ - /** - @class Helper - @namespace Ember.HTMLBars - @private - */ function Helper(helper) { this.helperFunction = helper; this.isHelper = true; this.isHTMLBars = true; @@ -9668,11 +9913,11 @@ to the given name @private @method resolveHelper @param {String} name the name of the helper to lookup - @return {Handlebars Helper} + @return {Helper} */ function findHelper(name, view, env) { var helper = env.helpers[name]; @@ -9830,11 +10075,11 @@ knownHelpers: this.knownHelpers }); }; RenderEnv.prototype.childWithOutletState = function (outletState) { - var hasParentOutlet = arguments[1] === undefined ? this.hasParentOutlet : arguments[1]; + var hasParentOutlet = arguments.length <= 1 || arguments[1] === undefined ? this.hasParentOutlet : arguments[1]; return new RenderEnv({ view: this.view, outletState: outletState, container: this.container, @@ -10822,13 +11067,13 @@ } }); enifed("ember-htmlbars/utils/string", ["exports", "htmlbars-util", "ember-runtime/system/string"], function (exports, _htmlbarsUtil, _emberRuntimeSystemString) { /** - Mark a string as safe for unescaped output with Handlebars. If you - return HTML from a Handlebars helper, use this function to - ensure Handlebars does not escape the HTML. + Mark a string as safe for unescaped output with Ember templates. If you + return HTML from a helper, use this function to + ensure Ember's rendering layer does not escape the HTML. ```javascript Ember.String.htmlSafe('<div>someString</div>') ``` @@ -10849,22 +11094,10 @@ return new _htmlbarsUtil.SafeString(str); } _emberRuntimeSystemString["default"].htmlSafe = htmlSafe; if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) { - - /** - Mark a string as being safe for unescaped output with Handlebars. - ```javascript - '<div>someString</div>'.htmlSafe() - ``` - See [Ember.String.htmlSafe](/api/classes/Ember.String.html#method_htmlSafe). - @method htmlSafe - @for String - @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars - @public - */ String.prototype.htmlSafe = function () { return htmlSafe(this); }; } @@ -11314,24 +11547,24 @@ _emberMetalCore["default"].cacheFor = _emberMetalComputed.cacheFor; _emberMetalCore["default"].addObserver = _emberMetalObserver.addObserver; _emberMetalCore["default"].observersFor = _emberMetalObserver.observersFor; _emberMetalCore["default"].removeObserver = _emberMetalObserver.removeObserver; - _emberMetalCore["default"].addBeforeObserver = _emberMetalObserver.addBeforeObserver; + _emberMetalCore["default"].addBeforeObserver = _emberMetalCore["default"].deprecateFunc("Ember.addBeforeObserver is deprecated and will be removed in the near future.", { url: "http://emberjs.com/deprecations/v1.x/#toc_beforeobserver" }, _emberMetalObserver._addBeforeObserver); _emberMetalCore["default"]._suspendBeforeObserver = _emberMetalObserver._suspendBeforeObserver; _emberMetalCore["default"]._suspendBeforeObservers = _emberMetalObserver._suspendBeforeObservers; _emberMetalCore["default"]._suspendObserver = _emberMetalObserver._suspendObserver; _emberMetalCore["default"]._suspendObservers = _emberMetalObserver._suspendObservers; - _emberMetalCore["default"].beforeObserversFor = _emberMetalObserver.beforeObserversFor; - _emberMetalCore["default"].removeBeforeObserver = _emberMetalObserver.removeBeforeObserver; + _emberMetalCore["default"].beforeObserversFor = _emberMetalCore["default"].deprecateFunc("Ember.beforeObserversFor is deprecated and will be removed in the near future.", { url: "http://emberjs.com/deprecations/v1.x/#toc_beforeobserver" }, _emberMetalObserver._beforeObserversFor); + _emberMetalCore["default"].removeBeforeObserver = _emberMetalCore["default"].deprecateFunc("Ember.removeBeforeObserver is deprecated and will be removed in the near future.", { url: "http://emberjs.com/deprecations/v1.x/#toc_beforeobserver" }, _emberMetalObserver._removeBeforeObserver); _emberMetalCore["default"].IS_BINDING = _emberMetalMixin.IS_BINDING; _emberMetalCore["default"].required = _emberMetalMixin.required; _emberMetalCore["default"].aliasMethod = _emberMetalMixin.aliasMethod; _emberMetalCore["default"].observer = _emberMetalMixin.observer; - _emberMetalCore["default"].immediateObserver = _emberMetalMixin.immediateObserver; - _emberMetalCore["default"].beforeObserver = _emberMetalMixin.beforeObserver; + _emberMetalCore["default"].immediateObserver = _emberMetalMixin._immediateObserver; + _emberMetalCore["default"].beforeObserver = _emberMetalCore["default"].deprecateFunc("Ember.beforeObserver is deprecated and will be removed in the near future.", { url: "http://emberjs.com/deprecations/v1.x/#toc_beforeobserver" }, _emberMetalMixin._beforeObserver); _emberMetalCore["default"].mixin = _emberMetalMixin.mixin; _emberMetalCore["default"].Mixin = _emberMetalMixin.Mixin; _emberMetalCore["default"].oneWay = _emberMetalBinding.oneWay; _emberMetalCore["default"].bind = _emberMetalBinding.bind; @@ -13986,11 +14219,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 1.13.3 + @version 1.13.4 @public */ if ('undefined' === typeof Ember) { // Create core object. Make it act like an instance of Ember.Namespace so that @@ -14018,15 +14251,15 @@ /** The semantic version. @property VERSION @type String - @default '1.13.3' + @default '1.13.4' @static @public */ - Ember.VERSION = '1.13.3'; + Ember.VERSION = '1.13.4'; /** 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 @@ -16610,12 +16843,12 @@ enifed("ember-metal/mixin", ["exports", "ember-metal/core", "ember-metal/merge", "ember-metal/array", "ember-metal/platform/create", "ember-metal/property_get", "ember-metal/property_set", "ember-metal/utils", "ember-metal/expand_properties", "ember-metal/properties", "ember-metal/computed", "ember-metal/binding", "ember-metal/observer", "ember-metal/events", "ember-metal/streams/utils"], function (exports, _emberMetalCore, _emberMetalMerge, _emberMetalArray, _emberMetalPlatformCreate, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _emberMetalExpand_properties, _emberMetalProperties, _emberMetalComputed, _emberMetalBinding, _emberMetalObserver, _emberMetalEvents, _emberMetalStreamsUtils) { exports.mixin = mixin; exports.required = required; exports.aliasMethod = aliasMethod; exports.observer = observer; - exports.immediateObserver = immediateObserver; - exports.beforeObserver = beforeObserver; + exports._immediateObserver = _immediateObserver; + exports._beforeObserver = _beforeObserver; // Remove "use strict"; from transpiled module until // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed // "REMOVE_USE_STRICT: true"; @@ -17001,17 +17234,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_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_observesBefore__", _emberMetalObserver._addBeforeObserver); updateObserversAndListeners(obj, key, observerOrListener, "__ember_observes__", _emberMetalObserver.addObserver); updateObserversAndListeners(obj, key, observerOrListener, "__ember_listens__", _emberMetalEvents.addListener); } } @@ -17482,20 +17715,20 @@ `Ember.immediateObserver` will maintain the synchronous behavior. Also available as `Function.prototype.observesImmediately` if prototype extensions are enabled. - @method immediateObserver + @method _immediateObserver @for Ember @param {String} propertyNames* @param {Function} func @deprecated Use `Ember.observer` instead. @return func @private */ - function immediateObserver() { + function _immediateObserver() { for (var i = 0, l = arguments.length; i < l; i++) { var arg = arguments[i]; } @@ -17506,13 +17739,13 @@ 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` fires before a property changes. - A `beforeObserver` is an alternative form of `.observesBefore()`. + A `_beforeObserver` is an alternative form of `.observesBefore()`. ```javascript App.PersonView = Ember.View.extend({ friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }], @@ -17541,14 +17774,15 @@ @method beforeObserver @for Ember @param {String} propertyNames* @param {Function} func @return func + @deprecated @private */ - function beforeObserver() { + 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]; @@ -17594,17 +17828,17 @@ // warn, assert, wrap, et; enifed("ember-metal/observer", ["exports", "ember-metal/watching", "ember-metal/array", "ember-metal/events"], function (exports, _emberMetalWatching, _emberMetalArray, _emberMetalEvents) { exports.addObserver = addObserver; exports.observersFor = observersFor; exports.removeObserver = removeObserver; - exports.addBeforeObserver = addBeforeObserver; + exports._addBeforeObserver = _addBeforeObserver; exports._suspendBeforeObserver = _suspendBeforeObserver; exports._suspendObserver = _suspendObserver; exports._suspendBeforeObservers = _suspendBeforeObservers; exports._suspendObservers = _suspendObservers; - exports.beforeObserversFor = beforeObserversFor; - exports.removeBeforeObserver = removeBeforeObserver; + exports._beforeObserversFor = _beforeObserversFor; + exports._removeBeforeObserver = _removeBeforeObserver; /** @module ember-metal */ @@ -17656,20 +17890,21 @@ return this; } /** - @method addBeforeObserver + @method _addBeforeObserver @for Ember @param obj @param {String} path @param {Object|Function} target @param {Function|String} [method] + @deprecated @private */ - function addBeforeObserver(obj, path, target, method) { + function _addBeforeObserver(obj, path, target, method) { _emberMetalEvents.addListener(obj, beforeEvent(path), target, method); _emberMetalWatching.watch(obj, path); return this; } @@ -17695,25 +17930,26 @@ function _suspendObservers(obj, paths, target, method, callback) { var events = _emberMetalArray.map.call(paths, changeEvent); return _emberMetalEvents.suspendListeners(obj, events, target, method, callback); } - function beforeObserversFor(obj, path) { + function _beforeObserversFor(obj, path) { return _emberMetalEvents.listenersFor(obj, beforeEvent(path)); } /** @method removeBeforeObserver @for Ember @param obj @param {String} path @param {Object|Function} target @param {Function|String} [method] + @deprecated @private */ - function removeBeforeObserver(obj, path, target, method) { + function _removeBeforeObserver(obj, path, target, method) { _emberMetalWatching.unwatch(obj, path); _emberMetalEvents.removeListener(obj, beforeEvent(path), target, method); return this; } @@ -21835,21 +22071,23 @@ */ enifed("ember-routing-htmlbars/helpers/query-params", ["exports", "ember-metal/core", "ember-routing/system/query_params"], function (exports, _emberMetalCore, _emberRoutingSystemQuery_params) { exports.queryParamsHelper = queryParamsHelper; /** - This is a sub-expression to be used in conjunction with the link-to helper. + This is a helper to be used in conjunction with the link-to helper. It will supply url query parameters to the target route. Example + ```handlebars {{#link-to 'posts' (query-params direction="asc")}}Sort{{/link-to}} + ``` @method query-params - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @param {Object} hash takes a hash of query parameters - @return {String} HTML string + @return {Object} A `QueryParams` object for `{{link-to}}` @public */ function queryParamsHelper(params, hash) { @@ -21865,64 +22103,155 @@ // assert enifed("ember-routing-htmlbars/keywords/action", ["exports", "htmlbars-runtime/hooks", "ember-routing-htmlbars/keywords/closure-action"], function (exports, _htmlbarsRuntimeHooks, _emberRoutingHtmlbarsKeywordsClosureAction) { /** - The `{{action}}` helper provides a useful shortcut for registering an HTML - element within a template for a single DOM event and forwarding that - interaction to the template's controller or specified `target` option. + The `{{action}}` helper provides a way to pass triggers for behavior (usually + just a function) between components, and into components from controllers. - If the controller does not implement the specified action, the event is sent - to the current route, and it bubbles up the route hierarchy from there. + ### Passing functions with the action helper - For more advanced event handling see [Ember.Component](/api/classes/Ember.Component.html) + There are three contexts an action helper can be used in. The first two + contexts to discuss are attribute context, and Handlebars value context. + ```handlebars + {{! An example of attribute context }} + <div onclick={{action "save"}}></div> + {{! Examples of Handlebars value context }} + {{input on-input=(action "save")}} + {{yield (action "refreshData") andAnotherParam}} + ``` - ### Use - Given the following application Handlebars template on the page + In these contexts, + the helper is called a "closure action" helper. It's behavior is simple: + If passed a function name, read that function off the `actions` property + of the current context. Once that function is read (or if a function was + passed), create a closure over that function and any arguments. + The resulting value of an action helper used this way is simply a function. + For example with this attribute context example: + ```handlebars - <div {{action 'anActionName'}}> - click me - </div> + {{! An example of attribute context }} + <div onclick={{action "save"}}></div> ``` - And application code + The resulting template render logic would be: - ```javascript - App.ApplicationController = Ember.Controller.extend({ + ```js + var div = document.createElement('div'); + var actionFunction = (function(context){ + return function() { + return context.actions.save.apply(context, arguments); + }; + })(context); + div.onclick = actionFunction; + ``` + + Thus when the div is clicked, the action on that context is called. + Because the `actionFunction` is just a function, closure actions can be + passed between components the still execute in the correct context. + + Here is an example action handler on a component: + + ```js + export default Ember.Component.extend({ actions: { - anActionName: function() { + save(/* event *\/) { + this.get('model').save(); } } }); ``` - Will result in the following rendered HTML + Actions are always looked up on the `actions` property of the current context. + This avoids collisions in the naming of common actions, such as `destroy`. - ```html - <div class="ember-view"> - <div data-ember-action="1"> - click me - </div> - </div> + Two options can be passed to the `action` helper when it is used in this way. + + * `target=someProperty` will look to `someProperty` instead of the current + context for the `actions` hash. This can be useful when targetting a + service for actions. + * `value="target.value"` will read the path `target.value` off the first + argument to the action when it is called and rewrite the first argument + to be that value. This is useful when attaching actions to event listeners. + + ### Invoking an action + + Closure actions curry both their scope and any arguments. When invoked, any + additional arguments are added to the already curried list. + + Actions should be invoked using the [sendAction](/api/classes/Ember.Component.html#method_sendAction) + method. The first argument to `sendAction` is the action to be called, and + additional arguments are passed to the action function. This has interesting + properties combined with currying of arguments. For example: + + ```js + export default Ember.Component.extend({ + actions: { + // Usage {{input on-input=(action (action 'setName' model) value="target.value")}} + setName(model, name) { + model.set('name', name); + } + } + }); ``` - Clicking "click me" will trigger the `anActionName` action of the - `App.ApplicationController`. In this case, no additional parameters will be passed. + The first argument (`model`) was curried over, and the run-time argument (`event`) + becomes a second argument. Action calls be nested this way because each simply + returns a function. Any function can be passed to the `{{action` helper, including + other actions. - If you provide additional parameters to the helper: + Actions invoked with `sendAction` have the same currying behavior as demonstrated + with `on-input` above. For example: + ```js + export default Ember.Component.extend({ + actions: { + setName(model, name) { + model.set('name', name); + } + } + }); + ``` + ```handlebars - <button {{action 'edit' post}}>Edit</button> + {{my-input submit=(action 'setName' model)}} ``` - Those parameters will be passed along as arguments to the JavaScript - function implementing the action. + ```js + // app/components/my-component.js + export default Ember.Component.extend({ + click() { + // Note that model is not passed, it was curried in the template + this.sendAction('submit', 'bob'); + } + }); + ``` + ### Attaching actions to DOM + + The third context the `{{action` helper can be used in we call "element space". + For example: + + ```handlebars + {{! An example of element space }} + <div {{action "save"}}></div> + ``` + + Used this way, the `{{action}}` helper provides a useful shortcut for + registering an HTML element within a template for a single DOM event and + forwarding that interaction to the template's context (controller or component). + + If the context of a template is a controller, actions used this way will + bubble to routes when the controller does not implement the specified action. + Once an action hits a route, it will bubble through the route hierarchy. + ### Event Propagation + `{{action` helpers called in element space can control event bubbling. + Events triggered through the action helper will automatically have `.preventDefault()` called on them. You do not need to do so in your event handlers. If you need to allow event propagation (to handle file inputs for example) you can supply the `preventDefault=false` option to the `{{action}}` helper: @@ -21943,24 +22272,28 @@ own event handler, or use event methods on your view class. See [Ember.View](/api/classes/Ember.View.html) 'Responding to Browser Events' for more information. ### Specifying DOM event type + `{{action` helpers called in element space can specify an event type. + By default the `{{action}}` helper registers for DOM `click` events. You can supply an `on` option to the helper to specify a different DOM event name: ```handlebars - <div {{action "anActionName" on="doubleClick"}}> + <div {{action "anActionName" on="double-click"}}> click me </div> ``` - See `Ember.View` 'Responding to Browser Events' for a list of + See [Event Names](/api/classes/Ember.View.html#toc_event-names) for a list of acceptable DOM event names. ### Specifying whitelisted modifier keys + `{{action` helpers called in element space can specify modifier keys. + By default the `{{action}}` helper will ignore click event with pressed modifier keys. You can supply an `allowedKeys` option to specify which keys should not be ignored. ```handlebars <div {{action "anActionName" allowedKeys="alt"}}> @@ -21978,55 +22311,30 @@ </div> ``` ### Specifying a Target - There are several possible target objects for `{{action}}` helpers: - - In a typical Ember application, where templates are managed through use of the - `{{outlet}}` helper, actions will bubble to the current controller, then - to the current route, and then up the route hierarchy. - - Alternatively, a `target` option can be provided to the helper to change + A `target` option can be provided to the helper to change which object will receive the method call. This option must be a path to an object, accessible in the current context: ```handlebars - {{! the application template }} - <div {{action "anActionName" target=view}}> + {{! app/templates/application.hbs }} + <div {{action "anActionName" target=someService}}> click me </div> ``` ```javascript - App.ApplicationView = Ember.View.extend({ - actions: { - anActionName: function() {} - } + // app/controllers/application.js + export default Ember.Controller.extend({ + someService: Ember.inject.service() }); - ``` - ### Additional Parameters - - You may specify additional parameters to the `{{action}}` helper. These - parameters are passed along as the arguments to the JavaScript function - implementing the action. - - ```handlebars - {{#each people as |person|}} - <div {{action "edit" person}}> - click me - </div> - {{/each}} - ``` - - Clicking "click me" will trigger the `edit` method on the current controller - with the value of `person` as a parameter. - @method action - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @public */ exports["default"] = function (morph, env, scope, params, hash, template, inverse, visitor) { @@ -22038,11 +22346,11 @@ return _emberRoutingHtmlbarsKeywordsClosureAction["default"](morph, env, scope, params, hash, template, inverse, visitor); }; }); /** @module ember -@submodule ember-htmlbars +@submodule ember-templates */ enifed("ember-routing-htmlbars/keywords/closure-action", ["exports", "ember-metal/streams/stream", "ember-metal/array", "ember-metal/streams/utils", "ember-metal/keys", "ember-metal/utils", "ember-metal/property_get", "ember-metal/error"], function (exports, _emberMetalStreamsStream, _emberMetalArray, _emberMetalStreamsUtils, _emberMetalKeys, _emberMetalUtils, _emberMetalProperty_get, _emberMetalError) { exports["default"] = closureAction; var INVOKE = _emberMetalUtils.symbol("INVOKE"); exports.INVOKE = INVOKE; @@ -22553,11 +22861,11 @@ eventName: 'customEventName' }); ``` @method link-to - @for Ember.Handlebars.helpers + @for Ember.Templates.helpers @param {String} routeName @param {Object} [context]* @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkComponent @return {String} HTML string @see {Ember.LinkComponent} @@ -22618,11 +22926,11 @@ setupState: function (prevState, env, scope, params, hash) { var name = params[0]; return { - parentView: scope.view, + parentView: env.view, manager: prevState.manager, controller: prevState.controller, childOutletState: childOutletState(name, env) }; }, @@ -22830,11 +23138,11 @@ /** @module ember @submodule ember-routing-views */ enifed("ember-routing-views/views/link", ["exports", "ember-metal/core", "ember-metal/property_get", "ember-metal/property_set", "ember-metal/computed", "ember-views/system/utils", "ember-views/views/component", "ember-runtime/inject", "ember-runtime/mixins/controller", "ember-htmlbars/templates/link-to"], function (exports, _emberMetalCore, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed, _emberViewsSystemUtils, _emberViewsViewsComponent, _emberRuntimeInject, _emberRuntimeMixinsController, _emberHtmlbarsTemplatesLinkTo) { - _emberHtmlbarsTemplatesLinkTo["default"].meta.revision = "Ember@1.13.3"; + _emberHtmlbarsTemplatesLinkTo["default"].meta.revision = "Ember@1.13.4"; var linkComponentClassNameBindings = ["active", "loading", "disabled"]; if (_emberMetalCore["default"].FEATURES.isEnabled("ember-routing-transitioning-classes")) { linkComponentClassNameBindings = ["active", "loading", "disabled", "transitioningIn", "transitioningOut"]; } @@ -23173,11 +23481,11 @@ var params = this.attrs.params.slice(); var lastParam = params[params.length - 1]; if (lastParam && lastParam.isQueryParams) { params.pop(); } - var onlyQueryParamsSupplied = params.length === 0; + var onlyQueryParamsSupplied = this.attrs.hasBlock ? params.length === 0 : params.length === 1; if (onlyQueryParamsSupplied) { var appController = this.container.lookup("controller:application"); if (appController) { return _emberMetalProperty_get.get(appController, "currentRouteName"); } @@ -23354,11 +23662,11 @@ @submodule ember-routing-views */ // FEATURES, Logger, assert enifed("ember-routing-views/views/outlet", ["exports", "ember-views/views/view", "ember-htmlbars/templates/top-level-view"], function (exports, _emberViewsViewsView, _emberHtmlbarsTemplatesTopLevelView) { - _emberHtmlbarsTemplatesTopLevelView["default"].meta.revision = "Ember@1.13.3"; + _emberHtmlbarsTemplatesTopLevelView["default"].meta.revision = "Ember@1.13.4"; var CoreOutletView = _emberViewsViewsView["default"].extend({ defaultTemplate: _emberHtmlbarsTemplatesTopLevelView["default"], init: function () { @@ -26164,11 +26472,11 @@ send: function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } - if (this.router || !_emberMetalCore["default"].testing) { + if (this.router && this.router.router || !_emberMetalCore["default"].testing) { var _router; (_router = this.router).send.apply(_router, args); } else { var name = args[0]; @@ -26384,10 +26692,14 @@ // model passed in, so model hook not called thePost = store.find('post', 1); this.transitionTo('post', thePost); // integer passed in, model hook is called this.transitionTo('post', 1); + // model id passed in, model hook is called + // useful for forcing the hook to execute + thePost = store.find('post', 1); + this.transitionTo('post', thePost.id); ``` This hook follows the asynchronous/promise semantics described in the documentation for `beforeModel`. In particular, if a promise returned from `model` fails, the error will be handled by the `error` hook on `Ember.Route`. @@ -28786,11 +29098,11 @@ _emberMetalEnumerable_utils.forEach(dependentArray, function (item, index) { var observerContext = this.createPropertyObserverContext(dependentArray, index, this.trackedArraysByGuid[dependentKey]); observerContexts[index] = observerContext; _emberMetalEnumerable_utils.forEach(itemPropertyKeys, function (propertyKey) { - _emberMetalObserver.addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver); + _emberMetalObserver._addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver); _emberMetalObserver.addObserver(item, propertyKey, this, observerContext.observer); }, this); }, this); }, @@ -28813,11 +29125,11 @@ beforeObserver = observerContext.beforeObserver; observer = observerContext.observer; item = observerContext.item; _emberMetalEnumerable_utils.forEach(itemPropertyKeys, function (propertyKey) { - _emberMetalObserver.removeBeforeObserver(item, propertyKey, dependentArrayObserver, beforeObserver); + _emberMetalObserver._removeBeforeObserver(item, propertyKey, dependentArrayObserver, beforeObserver); _emberMetalObserver.removeObserver(item, propertyKey, dependentArrayObserver, observer); }); }); }); }, @@ -28903,11 +29215,11 @@ observerContexts = this.trackRemove(dependentKey, normalizedIndex, normalizedRemoveCount); function removeObservers(propertyKey) { observerContexts[sliceIndex].destroyed = true; - _emberMetalObserver.removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver); + _emberMetalObserver._removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver); _emberMetalObserver.removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer); } for (sliceIndex = normalizedRemoveCount - 1; sliceIndex >= 0; --sliceIndex) { itemIndex = normalizedIndex + sliceIndex; @@ -28944,11 +29256,11 @@ if (itemPropertyKeys) { observerContext = this.createPropertyObserverContext(dependentArray, normalizedIndex + sliceIndex, this.trackedArraysByGuid[dependentKey]); observerContexts[sliceIndex] = observerContext; _emberMetalEnumerable_utils.forEach(itemPropertyKeys, function (propertyKey) { - _emberMetalObserver.addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver); + _emberMetalObserver._addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver); _emberMetalObserver.addObserver(item, propertyKey, this, observerContext.observer); }, this); } changeMeta = new ChangeMeta(dependentArray, item, normalizedIndex + sliceIndex, this.instanceMeta.propertyName, this.cp, addedCount); @@ -30591,11 +30903,12 @@ // calling `objectAt` this._super(idx, removedCnt, addedCnt); }, init: function () { - this._super.apply(this, arguments); + + this._super.apply(this, arguments); this._subControllers = []; }, model: _emberMetalComputed.computed({ get: function (key) { @@ -30967,12 +31280,11 @@ valueObserver: function() { // Executes whenever the "value" property changes }.observes('value') }); ``` - In the future this method may become asynchronous. If you want to ensure - synchronous behavior, use `observesImmediately`. + In the future this method may become asynchronous. See `Ember.observer`. @method observes @for Function @public */ @@ -30983,10 +31295,15 @@ args.push(this); return _emberMetalMixin.observer.apply(this, args); }; + FunctionPrototype._observesImmediately = function () { + + // observes handles property expansion + return this.observes.apply(this, arguments); + }; /** The `observesImmediately` extension of Javascript's Function prototype is available when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default. You can observe property changes simply by adding the `observesImmediately` @@ -31002,17 +31319,14 @@ In the future, `observes` may become asynchronous. In this event, `observesImmediately` will maintain the synchronous behavior. See `Ember.immediateObserver`. @method observesImmediately @for Function + @deprecated @private */ - FunctionPrototype.observesImmediately = function () { - - // observes handles property expansion - return this.observes.apply(this, arguments); - }; + FunctionPrototype.observesImmediately = _emberMetalCore["default"].deprecateFunc('Function#observesImmediately is deprecated. Use Function#observes instead', FunctionPrototype._observesImmediately); /** The `observesBefore` extension of Javascript's Function prototype is available when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default. @@ -31378,17 +31692,17 @@ _debugContainerKey: null, willWatchProperty: function (key) { var contentKey = "content." + key; - _emberMetalObserver.addBeforeObserver(this, contentKey, null, contentPropertyWillChange); + _emberMetalObserver._addBeforeObserver(this, contentKey, null, contentPropertyWillChange); _emberMetalObserver.addObserver(this, contentKey, null, contentPropertyDidChange); }, didUnwatchProperty: function (key) { var contentKey = "content." + key; - _emberMetalObserver.removeBeforeObserver(this, contentKey, null, contentPropertyWillChange); + _emberMetalObserver._removeBeforeObserver(this, contentKey, null, contentPropertyWillChange); _emberMetalObserver.removeObserver(this, contentKey, null, contentPropertyDidChange); }, unknownProperty: function (key) { var content = _emberMetalProperty_get.get(this, "content"); @@ -32478,11 +32792,11 @@ var arr = []; arr.get('firstObject'); // undefined ``` @property firstObject @return {Object} the object or undefined - @private + @public */ firstObject: _emberMetalComputed.computed('[]', function () { if (_emberMetalProperty_get.get(this, 'length') === 0) { return undefined; } @@ -32506,11 +32820,11 @@ var arr = []; arr.get('lastObject'); // undefined ``` @property lastObject @return {Object} the last object or undefined - @private + @public */ lastObject: _emberMetalComputed.computed('[]', function () { var len = _emberMetalProperty_get.get(this, 'length'); if (len === 0) { @@ -32542,11 +32856,11 @@ arr.contains('z'); // false ``` @method contains @param {Object} obj The object to search for. @return {Boolean} `true` if object is found in enumerable. - @private + @public */ contains: function (obj) { var found = this.find(function (item) { return item === obj; }); @@ -32603,11 +32917,11 @@ /** Alias for `mapBy` @method getEach @param {String} key name of the property @return {Array} The mapped array. - @private + @public */ getEach: _emberMetalMixin.aliasMethod('mapBy'), /** Sets the value on the named property for each member. This is more @@ -32616,11 +32930,11 @@ 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 @return {Object} receiver - @private + @public */ setEach: function (key, value) { return this.forEach(function (item) { _emberMetalProperty_set.set(item, key, value); }); @@ -32643,11 +32957,11 @@ to give your iterator function access to the current object. @method map @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Array} The mapped array. - @private + @public */ map: function (callback, target) { var ret = _emberMetalCore["default"].A(); this.forEach(function (x, idx, i) { @@ -32661,11 +32975,11 @@ Similar to map, this specialized function returns the value of the named property on all items in the enumeration. @method mapBy @param {String} key name of the property @return {Array} The mapped array. - @private + @public */ mapBy: function (key) { return this.map(function (next) { return _emberMetalProperty_get.get(next, key); }); @@ -32702,11 +33016,11 @@ to give your iterator function access to the current object. @method filter @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Array} A filtered array. - @private + @public */ filter: function (callback, target) { var ret = _emberMetalCore["default"].A(); this.forEach(function (x, idx, i) { @@ -32735,11 +33049,11 @@ to give your iterator function access to the current object. @method reject @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Array} A rejected array. - @private + @public */ reject: function (callback, target) { return this.filter(function () { return !callback.apply(target, arguments); }); @@ -32751,11 +33065,11 @@ this will match any property that evaluates to `true`. @method filterBy @param {String} key the property to test @param {*} [value] optional value to test against. @return {Array} filtered array - @private + @public */ filterBy: function (key, value) { return this.filter(iter.apply(this, arguments)); }, @@ -32778,11 +33092,11 @@ this will match any property that evaluates to false. @method rejectBy @param {String} key the property to test @param {String} [value] optional value to test against. @return {Array} rejected array - @private + @public */ rejectBy: function (key, value) { var exactValue = function (item) { return _emberMetalProperty_get.get(item, key) === value; }; @@ -32828,11 +33142,11 @@ to give your iterator function access to the current object. @method find @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Object} Found item or `undefined`. - @private + @public */ find: function (callback, target) { var len = _emberMetalProperty_get.get(this, 'length'); if (target === undefined) { @@ -32867,11 +33181,11 @@ This method works much like the more generic `find()` method. @method findBy @param {String} key the property to test @param {String} [value] optional value to test against. @return {Object} found item or `undefined` - @private + @public */ findBy: function (key, value) { return this.find(iter.apply(this, arguments)); }, @@ -32926,11 +33240,11 @@ @method everyBy @param {String} key the property to test @param {String} [value] optional value to test against. @deprecated Use `isEvery` instead @return {Boolean} - @private + @public */ everyBy: _emberMetalMixin.aliasMethod('isEvery'), /** @method everyProperty @@ -32941,15 +33255,16 @@ @private */ everyProperty: _emberMetalMixin.aliasMethod('isEvery'), /** - Returns `true` if the passed property resolves to `true` for all items in - the enumerable. This method is often simpler/faster than using a callback. + Returns `true` if the passed property resolves to the value of the second + argument for all items in the enumerable. This method is often simpler/faster + than using a callback. @method isEvery @param {String} key the property to test - @param {String} [value] optional value to test against. + @param {String} [value] optional value to test against. Defaults to `true` @return {Boolean} @since 1.3.0 @public */ isEvery: function (key, value) { @@ -33036,15 +33351,16 @@ @private */ some: _emberMetalMixin.aliasMethod('any'), /** - Returns `true` if the passed property resolves to `true` for any item in - the enumerable. This method is often simpler/faster than using a callback. + Returns `true` if the passed property resolves to the value of the second + argument for any item in the enumerable. This method is often simpler/faster + than using a callback. @method isAny @param {String} key the property to test - @param {String} [value] optional value to test against. + @param {String} [value] optional value to test against. Defaults to `true` @return {Boolean} @since 1.3.0 @private */ isAny: function (key, value) { @@ -34433,12 +34749,12 @@ this.propertyWillChange(keyName); this.propertyDidChange(keyName); return this; }, - addBeforeObserver: function (key, target, method) { - _emberMetalObserver.addBeforeObserver(this, key, target, method); + _addBeforeObserver: function (key, target, method) { + _emberMetalObserver._addBeforeObserver(this, key, target, method); }, /** Adds an observer on a property. This is the core method used to register an observer for a property. @@ -34969,11 +35285,11 @@ return content; } }), - _contentWillChange: _emberMetalMixin.beforeObserver("content", function () { + _contentWillChange: _emberMetalMixin._beforeObserver("content", function () { var content = _emberMetalProperty_get.get(this, "content"); var sortProperties = _emberMetalProperty_get.get(this, "sortProperties"); if (content && sortProperties) { _emberMetalEnumerable_utils.forEach(content, function (item) { @@ -34984,19 +35300,19 @@ } this._super.apply(this, arguments); }), - sortPropertiesWillChange: _emberMetalMixin.beforeObserver("sortProperties", function () { + sortPropertiesWillChange: _emberMetalMixin._beforeObserver("sortProperties", function () { this._lastSortAscending = undefined; }), sortPropertiesDidChange: _emberMetalMixin.observer("sortProperties", function () { this._lastSortAscending = undefined; }), - sortAscendingWillChange: _emberMetalMixin.beforeObserver("sortAscending", function () { + sortAscendingWillChange: _emberMetalMixin._beforeObserver("sortAscending", function () { this._lastSortAscending = _emberMetalProperty_get.get(this, "sortAscending"); }), sortAscendingDidChange: _emberMetalMixin.observer("sortAscending", function () { if (this._lastSortAscending !== undefined && _emberMetalProperty_get.get(this, "sortAscending") !== this._lastSortAscending) { @@ -35355,11 +35671,11 @@ 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 () { + _contentWillChange: _emberMetalMixin._beforeObserver("content", function () { this._teardownContent(); }), _teardownContent: function () { var content = _emberMetalProperty_get.get(this, "content"); @@ -35416,11 +35732,11 @@ didChange: "contentArrayDidChange" }); } }, - _arrangedContentWillChange: _emberMetalMixin.beforeObserver("arrangedContent", function () { + _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); @@ -36460,11 +36776,11 @@ } while (--loc >= idx) { var item = content.objectAt(loc); if (item) { - _emberMetalObserver.addBeforeObserver(item, keyName, proxy, "contentKeyWillChange"); + _emberMetalObserver._addBeforeObserver(item, keyName, proxy, "contentKeyWillChange"); _emberMetalObserver.addObserver(item, keyName, proxy, "contentKeyDidChange"); // keep track of the index each item was found at so we can map // it back when the obj changes. guid = _emberMetalUtils.guidFor(item); @@ -36486,11 +36802,11 @@ var indices, guid; while (--loc >= idx) { var item = content.objectAt(loc); if (item) { - _emberMetalObserver.removeBeforeObserver(item, keyName, proxy, "contentKeyWillChange"); + _emberMetalObserver._removeBeforeObserver(item, keyName, proxy, "contentKeyWillChange"); _emberMetalObserver.removeObserver(item, keyName, proxy, "contentKeyDidChange"); guid = _emberMetalUtils.guidFor(item); indices = objects[guid]; indices[_emberMetalArray.indexOf.call(indices, loc)] = null; @@ -36662,18 +36978,18 @@ var loadHooks = _emberMetalCore["default"].ENV.EMBER_LOAD_HOOKS || {}; var loaded = {}; /** - Detects when a specific package of Ember (e.g. 'Ember.Handlebars') + Detects when a specific package of Ember (e.g. 'Ember.Application') has fully loaded and is available for extension. The provided `callback` will be called with the `name` passed resolved from a string into the object: ``` javascript - Ember.onLoad('Ember.Handlebars' function(hbars) { + Ember.onLoad('Ember.Application' function(hbars) { hbars.registerHelper(...); }); ``` @method onLoad @@ -36693,11 +37009,11 @@ callback(object); } } /** - Called when an Ember.js package (e.g Ember.Handlebars) has finished + Called when an Ember.js package (e.g Ember.Application) has finished loading. Triggers any callbacks registered for this event. @method runLoadHooks @for Ember @param name {String} name of hook @@ -39968,11 +40284,11 @@ } options.plugins = plugins; options.buildMeta = function buildMeta(program) { return { - revision: "Ember@1.13.3", + revision: "Ember@1.13.4", loc: program.loc, moduleName: options.moduleName }; }; @@ -40175,21 +40491,21 @@ if (this._isAngleBracket || key === "attrs") { return; } var attrsKey = "attrs." + key; - _emberMetalObserver.addBeforeObserver(this, attrsKey, null, attrsWillChange); + _emberMetalObserver._addBeforeObserver(this, attrsKey, null, attrsWillChange); _emberMetalObserver.addObserver(this, attrsKey, null, attrsDidChange); }, didUnwatchProperty: function (key) { if (this._isAngleBracket || key === "attrs") { return; } var attrsKey = "attrs." + key; - _emberMetalObserver.removeBeforeObserver(this, attrsKey, null, attrsWillChange); + _emberMetalObserver._removeBeforeObserver(this, attrsKey, null, attrsWillChange); _emberMetalObserver.removeObserver(this, attrsKey, null, attrsDidChange); }, legacyDidReceiveAttrs: _emberMetalEvents.on("didReceiveAttrs", function () { if (this._isAngleBracket) { @@ -41689,11 +42005,11 @@ */ enifed("ember-views/mixins/view_child_views_support", ["exports", "ember-metal/core", "ember-metal/mixin", "ember-metal/enumerable_utils", "ember-metal/property_get", "ember-metal/property_set", "ember-metal/set_properties"], function (exports, _emberMetalCore, _emberMetalMixin, _emberMetalEnumerable_utils, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalSet_properties) { var EMPTY_ARRAY = []; - var ViewChildViewsSupport = _emberMetalMixin.Mixin.create({ + exports["default"] = _emberMetalMixin.Mixin.create({ /** Array of child views. You should never edit this array directly. Instead, use `appendChild` and `removeFromParent`. @property childViews @type Array @@ -41706,11 +42022,11 @@ this._super.apply(this, arguments); // setup child views. be sure to clone the child views array first // 2.0TODO: Remove Ember.A() here this.childViews = _emberMetalCore["default"].A(this.childViews.slice()); - this.ownerView = this; + this.ownerView = this.ownerView || this; }, appendChild: function (view) { this.linkChild(view); this.childViews.push(view); @@ -41767,10 +42083,12 @@ return maybeViewClass; } var attrs = _attrs || {}; var view; + + attrs.parentView = this; attrs.renderer = this.renderer; attrs._viewRegistry = this._viewRegistry; if (maybeViewClass.isViewFactory) { attrs.container = this.container; @@ -41798,22 +42116,23 @@ return view; }, linkChild: function (instance) { instance.container = this.container; - _emberMetalProperty_set.set(instance, "parentView", this); - instance.trigger("parentViewDidChange"); + if (_emberMetalProperty_get.get(instance, "parentView") !== this) { + // linkChild should be idempotentj + _emberMetalProperty_set.set(instance, "parentView", this); + instance.trigger("parentViewDidChange"); + } instance.ownerView = this.ownerView; }, unlinkChild: function (instance) { _emberMetalProperty_set.set(instance, "parentView", null); instance.trigger("parentViewDidChange"); } }); - - exports["default"] = ViewChildViewsSupport; }); /** @module ember @submodule ember-views */ @@ -43013,11 +43332,11 @@ /** The internal class used to create text inputs when the `{{input}}` helper is used with `type` of `checkbox`. - See [handlebars.helpers.input](/api/classes/Ember.Handlebars.helpers.html#method_input) for usage details. + See [Ember.Templates.helpers.input](/api/classes/Ember.Templates.helpers.html#method_input) for usage details. ## Direct manipulation of `checked` The `checked` attribute of an `Ember.Checkbox` object should always be set through the Ember object or by interacting with its rendered element @@ -43101,11 +43420,11 @@ var App = Ember.Application.create(); App.ItemListView = Ember.CollectionView.extend({ classNames: ['a-collection'], content: ['A','B','C'], itemViewClass: Ember.View.extend({ - template: Ember.Handlebars.compile("the letter: {{view.content}}") + template: Ember.HTMLBars.compile("the letter: {{view.content}}") }) }); ``` And a simple application template: @@ -43136,11 +43455,11 @@ var App = Ember.Application.create(); App.UnorderedListView = Ember.CollectionView.create({ tagName: 'ul', content: ['A','B','C'], itemViewClass: Ember.View.extend({ - template: Ember.Handlebars.compile("the letter: {{view.content}}") + template: Ember.HTMLBars.compile("the letter: {{view.content}}") }) }); ``` And a simple application template: @@ -43196,11 +43515,11 @@ var App = Ember.Application.create(); App.ListWithNothing = Ember.CollectionView.create({ classNames: ['nothing'], content: null, emptyView: Ember.View.extend({ - template: Ember.Handlebars.compile("The collection is empty") + template: Ember.HTMLBars.compile("The collection is empty") }) }); ``` And a simple application template: @@ -43267,11 +43586,11 @@ 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 () { + _contentWillChange: _emberMetalMixin._beforeObserver("content", function () { var content = this.get("content"); if (content) { content.removeArrayObserver(this); } @@ -43691,75 +44010,76 @@ var parentView = _emberMetalProperty_get.get(this, "parentView"); return parentView ? _emberMetalProperty_get.get(parentView, "controller") : null; }), /** - Triggers a named action on the controller context where the component is used if - this controller has registered for notifications of the action. + Calls a action passed to a component. For example a component for playing or pausing music may translate click events into action notifications of "play" or "stop" depending on some internal state of the component: - ```javascript - App.PlayButtonComponent = Ember.Component.extend({ - click: function() { + ```javascript + // app/components/play-button.js + export default Ember.Component.extend({ + click() { if (this.get('isPlaying')) { this.sendAction('play'); } else { this.sendAction('stop'); } } }); ``` - When used inside a template these component actions are configured to - trigger actions in the outer application context: + The actions "play" and "stop" must be passed to this `play-button` component: ```handlebars - {{! application.hbs }} - {{play-button play="musicStarted" stop="musicStopped"}} + {{! app/templates/application.hbs }} + {{play-button play=(action "musicStarted") stop=(action "musicStopped")}} ``` When the component receives a browser `click` event it translate this interaction into application-specific semantics ("play" or "stop") and - triggers the specified action name on the controller for the template - where the component is used: - ```javascript - App.ApplicationController = Ember.Controller.extend({ + calls the specified action. + ```javascript + // app/controller/application.js + export default Ember.Controller.extend({ actions: { - musicStarted: function() { + musicStarted() { // called when the play button is clicked // and the music started playing }, - musicStopped: function() { + musicStopped() { // called when the play button is clicked // and the music stopped playing } } }); ``` - If no action name is passed to `sendAction` a default name of "action" + If no action is passed to `sendAction` a default name of "action" is assumed. ```javascript - App.NextButtonComponent = Ember.Component.extend({ - click: function() { + // app/components/next-button.js + export default Ember.Component.extend({ + click() { this.sendAction(); } }); ``` ```handlebars - {{! application.hbs }} - {{next-button action="playNextSongInAlbum"}} + {{! app/templates/application.hbs }} + {{next-button action=(action "playNextSongInAlbum")}} ``` ```javascript + // app/controllers/application.js App.ApplicationController = Ember.Controller.extend({ actions: { - playNextSongInAlbum: function() { + playNextSongInAlbum() { ... } } }); ``` @method sendAction - @param [action] {String} the action to trigger - @param [context] {*} a context to send with the action + @param [action] {String} the action to call + @param [params] {*} arguments for the action @public */ sendAction: function (action) { var actionName; @@ -43880,11 +44200,11 @@ exports["default"] = Component; }); // Ember.assert, Ember.Handlebars enifed("ember-views/views/container_view", ["exports", "ember-metal/core", "ember-runtime/mixins/mutable_array", "ember-views/views/view", "ember-metal/property_get", "ember-metal/property_set", "ember-metal/enumerable_utils", "ember-metal/mixin", "ember-metal/events", "ember-htmlbars/templates/container-view"], function (exports, _emberMetalCore, _emberRuntimeMixinsMutable_array, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalEnumerable_utils, _emberMetalMixin, _emberMetalEvents, _emberHtmlbarsTemplatesContainerView) { - _emberHtmlbarsTemplatesContainerView["default"].meta.revision = "Ember@1.13.3"; + _emberHtmlbarsTemplatesContainerView["default"].meta.revision = "Ember@1.13.4"; /** @module ember @submodule ember-views */ @@ -43940,14 +44260,14 @@ ```javascript aContainer = Ember.ContainerView.create({ classNames: ['the-container'], childViews: ['aView', 'bView'], aView: Ember.View.create({ - template: Ember.Handlebars.compile("A") + template: Ember.HTMLBars.compile("A") }), bView: Ember.View.create({ - template: Ember.Handlebars.compile("B") + template: Ember.HTMLBars.compile("B") }) }); aContainer.appendTo('body'); ``` @@ -43985,14 +44305,14 @@ ```javascript aContainer = Ember.ContainerView.create({ classNames: ['the-container'], childViews: ['aView', 'bView'], aView: Ember.View.create({ - template: Ember.Handlebars.compile("A") + template: Ember.HTMLBars.compile("A") }), bView: Ember.View.create({ - template: Ember.Handlebars.compile("B") + template: Ember.HTMLBars.compile("B") }) }); aContainer.appendTo('body'); ``` @@ -44008,11 +44328,11 @@ Adding a view ```javascript AnotherViewClass = Ember.View.extend({ - template: Ember.Handlebars.compile("Another view") + template: Ember.HTMLBars.compile("Another view") }); aContainer.toArray(); // [aContainer.aView, aContainer.bView] aContainer.pushObject(AnotherViewClass.create()); aContainer.toArray(); // [aContainer.aView, aContainer.bView, <AnotherViewClass instance>] @@ -44090,11 +44410,11 @@ if (view.parentView !== this) { this.linkChild(view); } }, - _currentViewWillChange: _emberMetalMixin.beforeObserver("currentView", function () { + _currentViewWillChange: _emberMetalMixin._beforeObserver("currentView", function () { var currentView = _emberMetalProperty_get.get(this, "currentView"); if (currentView) { currentView.destroy(); } }), @@ -44109,11 +44429,11 @@ layout: _emberHtmlbarsTemplatesContainerView["default"], replace: function (idx, removedCount) { var _this = this; - var addedViews = arguments[2] === undefined ? [] : arguments[2]; + var addedViews = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; var addedCount = _emberMetalProperty_get.get(addedViews, "length"); var childViews = _emberMetalProperty_get.get(this, "childViews"); @@ -44218,11 +44538,11 @@ var DOMHelper = domHelper(); renderer = renderer || new _emberMetalViewsRenderer["default"](new DOMHelper()); this.renderer = renderer; } - this.isDestroyingSubtree = false; + this._destroyingSubtreeForView = null; this._dispatching = null; }, /** If the view is currently inserted into the DOM of a parent view, this @@ -44268,27 +44588,24 @@ has: function (name) { return _emberRuntimeUtils.typeOf(this[name]) === "function" || this._super(name); }, destroy: function () { - var parent = this.parentView; - if (!this._super.apply(this, arguments)) { return; } this.currentState.cleanup(this); - if (!this.ownerView.isDestroyingSubtree) { - this.ownerView.isDestroyingSubtree = true; - if (parent) { - parent.removeChild(this); - } - if (this._renderNode) { - _htmlbarsRuntime.internal.clearMorph(this._renderNode, this.ownerView.env, true); - } - this.ownerView.isDestroyingSubtree = false; + // If the destroyingSubtreeForView property is not set but we have an + // associated render node, it means this view is being destroyed from user + // code and not via a change in the templating layer (like an {{if}} + // becoming falsy, for example). In this case, it is our responsibility to + // make sure that any render nodes created as part of the rendering process + // are cleaned up. + if (!this.ownerView._destroyingSubtreeForView && this._renderNode) { + _htmlbarsRuntime.internal.clearMorph(this._renderNode, this.ownerView.env, true); } return this; }, @@ -44892,11 +45209,11 @@ } _emberMetalProperty_set.set(this, "selection", content.objectAt(selectedIndex)); }, _selectedIndex: function (value) { - var defaultIndex = arguments[1] === undefined ? 0 : arguments[1]; + var defaultIndex = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; var content = _emberMetalProperty_get.get(this, "contentValues"); var selectionIndex = _emberMetalEnumerable_utils.indexOf(content, value); @@ -45213,11 +45530,11 @@ /** @module ember @submodule ember-views */ -enifed("ember-views/views/states/in_dom", ["exports", "ember-metal/platform/create", "ember-metal/merge", "ember-metal/error", "ember-metal/observer", "ember-views/views/states/has_element"], function (exports, _emberMetalPlatformCreate, _emberMetalMerge, _emberMetalError, _emberMetalObserver, _emberViewsViewsStatesHas_element) { +enifed('ember-views/views/states/in_dom', ['exports', 'ember-metal/core', 'ember-metal/platform/create', 'ember-metal/merge', 'ember-metal/error', 'ember-metal/observer', 'ember-views/views/states/has_element'], function (exports, _emberMetalCore, _emberMetalPlatformCreate, _emberMetalMerge, _emberMetalError, _emberMetalObserver, _emberViewsViewsStatesHas_element) { /** @module ember @submodule ember-views */ @@ -45225,11 +45542,11 @@ _emberMetalMerge["default"](inDOM, { enter: function (view) { // Register the view for event handling. This hash is used by // Ember.EventDispatcher to dispatch incoming events. - if (view.tagName !== "") { + if (view.tagName !== '') { view._register(); } }, @@ -45246,11 +45563,11 @@ childViews.push(attrNode); attrNode.parentView = view; view.renderer.appendAttrTo(attrNode, view.element, attrNode.attrName); - view.propertyDidChange("childViews"); + view.propertyDidChange('childViews'); return attrNode; } }); @@ -45278,11 +45595,11 @@ /** The internal class used to create textarea element when the `{{textarea}}` helper is used. - See [handlebars.helpers.textarea](/api/classes/Ember.Handlebars.helpers.html#method_textarea) for usage details. + See [Ember.Templates.helpers.textarea](/api/classes/Ember.Templates.helpers.html#method_textarea) for usage details. ## Layout and LayoutName properties Because HTML `textarea` elements do not contain inner HTML the `layout` and `layoutName` properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s @@ -45340,11 +45657,11 @@ /** The internal class used to create text inputs when the `{{input}}` helper is used with `type` of `text`. - See [Handlebars.helpers.input](/api/classes/Ember.Handlebars.helpers.html#method_input) for usage details. + See [Ember.Templates.helpers.input](/api/classes/Ember.Templates.helpers.html#method_input) for usage details. ## Layout and LayoutName properties Because HTML `input` elements are self closing `layout` and `layoutName` properties will not be applied. See [Ember.View](/api/classes/Ember.View.html)'s @@ -45749,15 +46066,15 @@ The HTML contents of a view's rendered representation are determined by its template. Templates can be any function that accepts an optional context parameter and returns a string of HTML that will be inserted within the view's tag. Most typically in Ember this function will be a compiled - `Ember.Handlebars` template. + template. ```javascript AView = Ember.View.extend({ - template: Ember.Handlebars.compile('I am the template') + template: Ember.HTMLBars.compile('I am the template') }); ``` Will result in view instances with an HTML representation of: @@ -45796,22 +46113,22 @@ AView = Ember.View.extend({ templateName: 'posts/new' }); ``` - Using a value for `templateName` that does not have a Handlebars template + Using a value for `templateName` that does not have a template with a matching `data-template-name` attribute will throw an error. For views classes that may have a template later defined (e.g. as the block - portion of a `{{view}}` Handlebars helper call in another template or in + portion of a `{{view}}` helper call in another template or in a subclass), you can provide a `defaultTemplate` property set to compiled template function. If a template is not later provided for the view instance the `defaultTemplate` value will be used: ```javascript AView = Ember.View.extend({ - defaultTemplate: Ember.Handlebars.compile('I was the default'), + defaultTemplate: Ember.HTMLBars.compile('I was the default'), template: null, templateName: null }); ``` @@ -45824,15 +46141,15 @@ If a `template` or `templateName` is provided it will take precedence over `defaultTemplate`: ```javascript AView = Ember.View.extend({ - defaultTemplate: Ember.Handlebars.compile('I was the default') + defaultTemplate: Ember.HTMLBars.compile('I was the default') }); aView = AView.create({ - template: Ember.Handlebars.compile('I was the template, not default') + template: Ember.HTMLBars.compile('I was the template, not default') }); ``` Will result in the following HTML representation when rendered: @@ -45844,11 +46161,11 @@ The default context of the compiled template is the view's controller: ```javascript AView = Ember.View.extend({ - template: Ember.Handlebars.compile('Hello {{excitedGreeting}}') + template: Ember.HTMLBars.compile('Hello {{excitedGreeting}}') }); aController = Ember.Object.create({ firstName: 'Barry', excitedGreeting: function() { @@ -45877,24 +46194,23 @@ primary templates, layouts can be any function that accepts an optional context parameter and returns a string of HTML that will be inserted inside view's tag. Views whose HTML element is self closing (e.g. `<input />`) cannot have a layout and this property will be ignored. - Most typically in Ember a layout will be a compiled `Ember.Handlebars` - template. + Most typically in Ember a layout will be a compiled template. A view's layout can be set directly with the `layout` property or reference - an existing Handlebars template by name with the `layoutName` property. + an existing template by name with the `layoutName` property. - A template used as a layout must contain a single use of the Handlebars + A template used as a layout must contain a single use of the `{{yield}}` helper. The HTML contents of a view's rendered `template` will be inserted at this location: ```javascript AViewWithLayout = Ember.View.extend({ - layout: Ember.Handlebars.compile("<div class='my-decorative-class'>{{yield}}</div>"), - template: Ember.Handlebars.compile("I got wrapped") + layout: Ember.HTMLBars.compile("<div class='my-decorative-class'>{{yield}}</div>"), + template: Ember.HTMLBars.compile("I got wrapped") }); ``` Will result in view instances with an HTML representation of: @@ -45904,11 +46220,11 @@ I got wrapped </div> </div> ``` - See [Ember.Handlebars.helpers.yield](/api/classes/Ember.Handlebars.helpers.html#method_yield) + See [Ember.Templates.helpers.yield](/api/classes/Ember.Templates.helpers.html#method_yield) for more information. ## Responding to Browser Events Views can respond to user-initiated events in one of three ways: method @@ -45978,11 +46294,11 @@ on the descendant. ```javascript var App = Ember.Application.create(); App.OuterView = Ember.View.extend({ - template: Ember.Handlebars.compile("outer {{#view 'inner'}}inner{{/view}} outer"), + template: Ember.HTMLBars.compile("outer {{#view 'inner'}}inner{{/view}} outer"), eventManager: Ember.Object.create({ mouseEnter: function(event, view) { // view might be instance of either // OuterView or InnerView depending on // where on the page the user interaction occurred @@ -46001,13 +46317,13 @@ // an OuterView. } }); ``` - ### Handlebars `{{action}}` Helper + ### `{{action}}` Helper - See [Handlebars.helpers.action](/api/classes/Ember.Handlebars.helpers.html#method_action). + See [Ember.Templates.helpers.action](/api/classes/Ember.Templates.helpers.html#method_action). ### Event Names All of the event handling approaches described above respond to the same set of events. The names of the built-in events are listed below. (The hash of @@ -46056,14 +46372,14 @@ * `dragLeave` * `dragOver` * `dragEnd` * `drop` - ## Handlebars `{{view}}` Helper + ## `{{view}}` Helper Other `Ember.View` instances can be included as part of a view's template by - using the `{{view}}` Handlebars helper. See [Ember.Handlebars.helpers.view](/api/classes/Ember.Handlebars.helpers.html#method_view) + using the `{{view}}` helper. See [Ember.Templates.helpers.view](/api/classes/Ember.Templates.helpers.html#method_view) for additional information. @class View @namespace Ember @extends Ember.CoreView @@ -47746,10 +48062,10 @@ `{{yield}}` is used. Optionally provide a non-default block name that can be targeted by `{{yield to=blockName}}`. */ function bindBlock(env, scope, block) { - var name = arguments[3] === undefined ? "default" : arguments[3]; + var name = arguments.length <= 3 || arguments[3] === undefined ? "default" : arguments[3]; scope.blocks[name] = block; } /** \ No newline at end of file