diff --git a/modules/internal/targets.js b/modules/internal/targets.js index a16352c4..74371cbf 100644 --- a/modules/internal/targets.js +++ b/modules/internal/targets.js @@ -204,7 +204,7 @@ targets.setLastVersion = function (type, version) { } else if (type.startsWith('/ember.js/2.')) { return '2.18.2'; } else if (type.startsWith('/ember.js/3.')) { - return '3.24.1'; + return '3.25.0'; } else if (type.startsWith('/ethjs')) { return '0.3.4'; } else if (type.startsWith('/ext-core/3.')) { diff --git a/pages/updates/updates.html b/pages/updates/updates.html index 6434ca77..d7f7f1d3 100644 --- a/pages/updates/updates.html +++ b/pages/updates/updates.html @@ -30,6 +30,7 @@
  • Updated: highlight.js v10.5.0 -> v10.6.0 (#265)
  • Updated: algoliasearch v4.8.4 -> v4.8.5 (#266)
  • Updated: Google Material Icons v76 -> v77 (#267)
  • +
  • Updated: ember.js v3.24.1 -> v3.25.0 (#268)
  • diff --git a/resources/ember.js/3.24.1/ember.min.jsm b/resources/ember.js/3.25.0/ember.min.jsm similarity index 92% rename from resources/ember.js/3.24.1/ember.min.jsm rename to resources/ember.js/3.25.0/ember.min.jsm index 3434fc60..10246709 100644 --- a/resources/ember.js/3.24.1/ember.min.jsm +++ b/resources/ember.js/3.25.0/ember.min.jsm @@ -6,7 +6,7 @@ * 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 3.24.1 + * @version 3.25.0 */ /*globals process */ var define, require, Ember; // Used in @ember/-internals/environment/lib/global.js @@ -133,7 +133,7 @@ define("@ember/-internals/browser-environment/index", ["exports"], function (_ex _exports.history = history$1; var userAgent = hasDom ? self.navigator.userAgent : 'Lynx (textmode)'; _exports.userAgent = userAgent; - var isChrome = hasDom ? Boolean(window.chrome) && !window.opera : false; + var isChrome = hasDom ? typeof chrome === 'object' && !(typeof opera === 'object') : false; _exports.isChrome = isChrome; var isFirefox = hasDom ? typeof InstallTrigger !== 'undefined' : false; _exports.isFirefox = isFirefox; @@ -185,7 +185,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); return console.log(...arguments); // eslint-disable-line no-console }, @@ -206,7 +210,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); return console.warn(...arguments); // eslint-disable-line no-console }, @@ -227,7 +235,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); return console.error(...arguments); // eslint-disable-line no-console }, @@ -249,7 +261,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); return console.info(...arguments); // eslint-disable-line no-console }, @@ -271,7 +287,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); /* eslint-disable no-console */ @@ -300,7 +320,11 @@ define("@ember/-internals/console/index", ["exports", "@ember/debug", "@ember/de (true && !(false) && (0, _debug.deprecate)(DEPRECATION_MESSAGE, false, { id: DEPRECATION_ID, until: '4.0.0', - url: DEPRECATION_URL + url: DEPRECATION_URL, + for: 'ember-source', + since: { + enabled: '3.2.0' + } })); return console.assert(...arguments); // eslint-disable-line no-console } @@ -2373,7 +2397,7 @@ define("@ember/-internals/extension-support/lib/data_adapter", ["exports", "@emb _exports.default = _default; }); -define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glimmer/opcode-compiler", "@ember/-internals/metal", "@ember/-internals/owner", "@ember/-internals/runtime", "@ember/-internals/utils", "@ember/-internals/views", "@ember/debug", "@glimmer/reference", "@glimmer/runtime", "@glimmer/validator", "@ember/-internals/browser-environment", "@ember/engine", "@ember/instrumentation", "@ember/service", "@ember/runloop", "@glimmer/util", "@ember/-internals/environment", "@ember/deprecated-features", "@ember/string", "@ember/-internals/container", "@glimmer/node", "@glimmer/global-context", "@ember/-internals/routing", "@ember/component/template-only", "@ember/error", "@glimmer/program", "rsvp"], function (_exports, _polyfills, _opcodeCompiler, _metal, _owner, _runtime, _utils, _views, _debug, _reference, _runtime2, _validator, _browserEnvironment, _engine, _instrumentation, _service, _runloop, _util, _environment2, _deprecatedFeatures, _string, _container, _node, _globalContext, _routing, _templateOnly, _error, _program, _rsvp) { +define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glimmer/opcode-compiler", "@ember/-internals/metal", "@ember/debug", "@ember/deprecated-features", "@ember/string", "@glimmer/reference", "@glimmer/validator", "@ember/-internals/views", "@glimmer/destroyable", "@glimmer/manager", "@ember/-internals/utils", "@ember/instrumentation", "@ember/runloop", "@glimmer/util", "@ember/-internals/owner", "@glimmer/runtime", "@ember/-internals/runtime", "@ember/-internals/browser-environment", "@ember/engine", "@ember/service", "@ember/-internals/environment", "@ember/-internals/container", "@glimmer/node", "@ember/-internals/glimmer", "@glimmer/global-context", "@ember/-internals/routing", "@ember/error", "@glimmer/program", "rsvp"], function (_exports, _polyfills, _opcodeCompiler, _metal, _debug, _deprecatedFeatures, _string, _reference, _validator, _views, _destroyable, _manager2, _utils, _instrumentation, _runloop, _util, _owner2, _runtime, _runtime2, _browserEnvironment, _engine, _service, _environment2, _container, _node, _glimmer, _globalContext, _routing, _error, _program, _rsvp) { "use strict"; Object.defineProperty(_exports, "__esModule", { @@ -2382,7 +2406,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim _exports.helper = helper; _exports.escapeExpression = escapeExpression; _exports.htmlSafe = htmlSafe; - _exports.isHTMLSafe = isHTMLSafe; + _exports.isHTMLSafe = isHTMLSafe$1; _exports._resetRenderers = _resetRenderers; _exports.renderSettled = renderSettled; _exports.getTemplate = getTemplate; @@ -2392,12 +2416,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim _exports.setTemplates = setTemplates; _exports.setupEngineRegistry = setupEngineRegistry; _exports.setupApplicationRegistry = setupApplicationRegistry; - _exports._registerMacros = registerMacros; _exports.setComponentManager = setComponentManager$1; - _exports.capabilities = capabilities; - _exports.modifierCapabilities = capabilities$1; - _exports.helperCapabilities = helperCapabilities; - _exports.invokeHelper = invokeHelper; Object.defineProperty(_exports, "template", { enumerable: true, get: function () { @@ -2410,34 +2429,22 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return _opcodeCompiler.templateCacheCounters; } }); - Object.defineProperty(_exports, "setComponentTemplate", { - enumerable: true, - get: function () { - return _runtime2.setComponentTemplate; - } - }); - Object.defineProperty(_exports, "getComponentTemplate", { - enumerable: true, - get: function () { - return _runtime2.getComponentTemplate; - } - }); Object.defineProperty(_exports, "DOMChanges", { enumerable: true, get: function () { - return _runtime2.DOMChanges; + return _runtime.DOMChanges; } }); Object.defineProperty(_exports, "DOMTreeConstruction", { enumerable: true, get: function () { - return _runtime2.DOMTreeConstruction; + return _runtime.DOMTreeConstruction; } }); Object.defineProperty(_exports, "isSerializationFirstNode", { enumerable: true, get: function () { - return _runtime2.isSerializationFirstNode; + return _runtime.isSerializationFirstNode; } }); Object.defineProperty(_exports, "NodeDOMTreeConstruction", { @@ -2446,112 +2453,1302 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return _node.NodeDOMTreeConstruction; } }); - _exports.OutletView = _exports.INVOKE = _exports._experimentalMacros = _exports.InteractiveRenderer = _exports.InertRenderer = _exports.Renderer = _exports.SafeString = _exports.Helper = _exports.Component = _exports.LinkComponent = _exports.TextArea = _exports.TextField = _exports.Checkbox = _exports.RootTemplate = void 0; + _exports.OutletView = _exports.INVOKE = _exports.Renderer = _exports.SafeString = _exports.Helper = _exports.Component = _exports.Input = _exports.LinkComponent = _exports.TextArea = _exports.TextField = _exports.Checkbox = _exports.RootTemplate = void 0; var RootTemplate = (0, _opcodeCompiler.templateFactory)({ - "id": "gxklthW0", - "block": "{\"symbols\":[],\"statements\":[[1,[30,[36,0],[[32,0]],null]]],\"hasEval\":false,\"upvars\":[\"component\"]}", - "moduleName": "packages/@ember/-internals/glimmer/lib/templates/root.hbs" + "id": "9BtKrod8", + "block": "[[[46,[30,0],null,null,null]],[],false,[\"component\"]]", + "moduleName": "packages/@ember/-internals/glimmer/lib/templates/root.hbs", + "isStrictMode": false }); _exports.RootTemplate = RootTemplate; - var ARGS = (0, _utils.enumerableSymbol)('ARGS'); - var HAS_BLOCK = (0, _utils.enumerableSymbol)('HAS_BLOCK'); - var DIRTY_TAG = (0, _utils.symbol)('DIRTY_TAG'); - var IS_DISPATCHING_ATTRS = (0, _utils.symbol)('IS_DISPATCHING_ATTRS'); - var BOUNDS = (0, _utils.symbol)('BOUNDS'); + + function isTemplateFactory(template) { + return typeof template === 'function'; + } /** - @module @ember/component + @module @ember/template + */ + + + class SafeString { + constructor(string) { + this.string = string; + } + + toString() { + return `${this.string}`; + } + + toHTML() { + return this.toString(); + } + + } + + _exports.SafeString = SafeString; + var escape = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`', + '=': '=' + }; + var possible = /[&<>"'`=]/; + var badChars = /[&<>"'`=]/g; + + function escapeChar(chr) { + return escape[chr]; + } + + function escapeExpression(string) { + if (typeof string !== 'string') { + // don't escape SafeStrings, since they're already safe + if (string && string.toHTML) { + return string.toHTML(); + } else if (string === null || string === undefined) { + return ''; + } else if (!string) { + return String(string); + } // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + + + string = String(string); + } + + if (!possible.test(string)) { + return string; + } + + return string.replace(badChars, escapeChar); + } + /** + 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 + import { htmlSafe } from '@ember/template'; + + htmlSafe('
    someString
    ') + ``` + + @method htmlSafe + @for @ember/template + @static + @return {SafeString} A string that will not be HTML escaped by Handlebars. + @public + */ + + + function htmlSafe(str) { + if (str === null || str === undefined) { + str = ''; + } else if (typeof str !== 'string') { + str = String(str); + } + + return new SafeString(str); + } + /** + Detects if a string was decorated using `htmlSafe`. + + ```javascript + import { htmlSafe, isHTMLSafe } from '@ember/template'; + + var plainString = 'plain string', + safeString = htmlSafe('
    someValue
    '); + + isHTMLSafe(plainString); // false + isHTMLSafe(safeString); // true + ``` + + @method isHTMLSafe + @for @ember/template + @static + @return {Boolean} `true` if the string was decorated with `htmlSafe`, `false` otherwise. + @public + */ + + + function isHTMLSafe$1(str) { + return str !== null && typeof str === 'object' && typeof str.toHTML === 'function'; + } + + function referenceForParts(rootRef, parts) { + var isAttrs = parts[0] === 'attrs'; // TODO deprecate this + + if (isAttrs) { + parts.shift(); + + if (parts.length === 1) { + return (0, _reference.childRefFor)(rootRef, parts[0]); + } + } + + return (0, _reference.childRefFromParts)(rootRef, parts); + } + + function parseAttributeBinding(microsyntax) { + var colonIndex = microsyntax.indexOf(':'); + + if (colonIndex === -1) { + (true && !(microsyntax !== 'class') && (0, _debug.assert)('You cannot use class as an attributeBinding, use classNameBindings instead.', microsyntax !== 'class')); + return [microsyntax, microsyntax, true]; + } else { + var prop = microsyntax.substring(0, colonIndex); + var attribute = microsyntax.substring(colonIndex + 1); + (true && !(attribute !== 'class') && (0, _debug.assert)('You cannot use class as an attributeBinding, use classNameBindings instead.', attribute !== 'class')); + return [prop, attribute, false]; + } + } + + function installAttributeBinding(component, rootRef, parsed, operations) { + var [prop, attribute, isSimple] = parsed; + + if (attribute === 'id') { + var elementId = (0, _metal.get)(component, prop); + + if (elementId === undefined || elementId === null) { + elementId = component.elementId; + } + + elementId = (0, _reference.createPrimitiveRef)(elementId); + operations.setAttribute('id', elementId, true, null); + return; + } + + var isPath = prop.indexOf('.') > -1; + var reference = isPath ? referenceForParts(rootRef, prop.split('.')) : (0, _reference.childRefFor)(rootRef, prop); + (true && !(!(isSimple && isPath)) && (0, _debug.assert)(`Illegal attributeBinding: '${prop}' is not a valid attribute name.`, !(isSimple && isPath))); + + if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE && attribute === 'style' && createStyleBindingRef !== undefined) { + reference = createStyleBindingRef(reference, (0, _reference.childRefFor)(rootRef, 'isVisible')); + } + + operations.setAttribute(attribute, reference, false, null); + } + + var DISPLAY_NONE = 'display: none;'; + var SAFE_DISPLAY_NONE = htmlSafe(DISPLAY_NONE); + var createStyleBindingRef; + var installIsVisibleBinding; + + if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE) { + createStyleBindingRef = (inner, isVisibleRef) => { + return (0, _reference.createComputeRef)(() => { + var value = (0, _reference.valueForRef)(inner); + var isVisible = (0, _reference.valueForRef)(isVisibleRef); + + if (true + /* DEBUG */ + && isVisible !== undefined) { + (true && !(false) && (0, _debug.deprecate)(`The \`isVisible\` property on classic component classes is deprecated. Was accessed:\n\n${(0, _validator.logTrackingStack)()}`, false, { + id: 'ember-component.is-visible', + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-is-visible', + for: 'ember-source', + since: { + enabled: '3.15.0-beta.1' + } + })); + } + + if (isVisible !== false) { + return value; + } else if (!value) { + return SAFE_DISPLAY_NONE; + } else { + var style = value + ' ' + DISPLAY_NONE; + return isHTMLSafe$1(value) ? htmlSafe(style) : style; + } + }); + }; + + installIsVisibleBinding = (rootRef, operations) => { + operations.setAttribute('style', createStyleBindingRef(_reference.UNDEFINED_REFERENCE, (0, _reference.childRefFor)(rootRef, 'isVisible')), false, null); + }; + } + + function createClassNameBindingRef(rootRef, microsyntax, operations) { + var [prop, truthy, falsy] = microsyntax.split(':'); + var isStatic = prop === ''; + + if (isStatic) { + operations.setAttribute('class', (0, _reference.createPrimitiveRef)(truthy), true, null); + } else { + var isPath = prop.indexOf('.') > -1; + var parts = isPath ? prop.split('.') : []; + var value = isPath ? referenceForParts(rootRef, parts) : (0, _reference.childRefFor)(rootRef, prop); + var ref; + + if (truthy === undefined) { + ref = createSimpleClassNameBindingRef(value, isPath ? parts[parts.length - 1] : prop); + } else { + ref = createColonClassNameBindingRef(value, truthy, falsy); + } + + operations.setAttribute('class', ref, false, null); + } + } + + function createSimpleClassNameBindingRef(inner, path) { + var dasherizedPath; + return (0, _reference.createComputeRef)(() => { + var value = (0, _reference.valueForRef)(inner); + + if (value === true) { + (true && !(path !== undefined) && (0, _debug.assert)('You must pass a path when binding a to a class name using classNameBindings', path !== undefined)); + return dasherizedPath || (dasherizedPath = (0, _string.dasherize)(path)); + } else if (value || value === 0) { + return String(value); + } else { + return null; + } + }); + } + + function createColonClassNameBindingRef(inner, truthy, falsy) { + return (0, _reference.createComputeRef)(() => { + return (0, _reference.valueForRef)(inner) ? truthy : falsy; + }); + } + + function NOOP() {} + /** + @module ember */ /** - A component is an isolated piece of UI, represented by a template and an - optional class. When a component has a class, its template's `this` value - is an instance of the component class. + Represents the internal state of the component. - ## Template-only Components + @class ComponentStateBucket + @private + */ + + + class ComponentStateBucket { + constructor(component, args, argsTag, finalizer, hasWrappedElement, isInteractive) { + this.component = component; + this.args = args; + this.argsTag = argsTag; + this.finalizer = finalizer; + this.hasWrappedElement = hasWrappedElement; + this.isInteractive = isInteractive; + this.classRef = null; + this.classRef = null; + this.argsRevision = args === null ? 0 : (0, _validator.valueForTag)(argsTag); + this.rootRef = (0, _reference.createConstRef)(component, 'this'); + (0, _destroyable.registerDestructor)(this, () => this.willDestroy(), true); + (0, _destroyable.registerDestructor)(this, () => this.component.destroy()); + } + + willDestroy() { + var { + component, + isInteractive + } = this; + + if (isInteractive) { + (0, _validator.beginUntrackFrame)(); + component.trigger('willDestroyElement'); + component.trigger('willClearRender'); + (0, _validator.endUntrackFrame)(); + var element = (0, _views.getViewElement)(component); + + if (element) { + (0, _views.clearElementView)(element); + (0, _views.clearViewElement)(component); + } + } + + component.renderer.unregister(component); + } + + finalize() { + var { + finalizer + } = this; + finalizer(); + this.finalizer = NOOP; + } + + } + + function internalHelper(helper) { + return (0, _manager2.setInternalHelperManager)(helper, {}); + } + /** + @module ember + */ + + + var ACTIONS = new _util._WeakSet(); + var INVOKE = (0, _utils.symbol)('INVOKE'); + /** + The `{{action}}` helper provides a way to pass triggers for behavior (usually + just a function) between components, and into components from controllers. - The simplest way to create a component is to create a template file in - `app/templates/components`. For example, if you name a template - `app/templates/components/person-profile.hbs`: + ### Passing functions with the action helper - ```app/templates/components/person-profile.hbs -

    {{@person.name}}

    - -

    {{@person.signature}}

    - ``` - - You will be able to use `` to invoke this component elsewhere - in your application: - - ```app/templates/application.hbs - - ``` - - Note that component names are capitalized here in order to distinguish them - from regular HTML elements, but they are dasherized in the file system. - - While the angle bracket invocation form is generally preferred, it is also - possible to invoke the same component with the `{{person-profile}}` syntax: - - ```app/templates/application.hbs - {{person-profile person=this.currentUser}} - ``` - - Note that with this syntax, you use dashes in the component name and - arguments are passed without the `@` sign. - - In both cases, Ember will render the content of the component template we - created above. The end result will be something like this: - - ```html -

    Tomster

    - -

    Out of office this week

    - ``` - - ## File System Nesting - - Components can be nested inside sub-folders for logical groupping. For - example, if we placed our template in - `app/templates/components/person/short-profile.hbs`, we can invoke it as - ``: - - ```app/templates/application.hbs - - ``` - - Or equivalently, `{{person/short-profile}}`: - - ```app/templates/application.hbs - {{person/short-profile person=this.currentUser}} - ``` - - ## Yielding Contents - - You can use `yield` inside a template to include the **contents** of any block - attached to the component. The block will be executed in its original context: + 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 - -

    Admin mode

    - {{! Executed in the current context. }} -
    + {{! An example of attribute context }} +
    + {{! Examples of Handlebars value context }} + {{input on-input=(action "save")}} + {{yield (action "refreshData") andAnotherParam}} + ``` + + In these contexts, + the helper is called a "closure action" helper. Its 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 immediately 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, in the attribute context: + + ```handlebars + {{! An example of attribute context }} +
    + ``` + + The resulting template render logic would be: + + ```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 and still execute in the correct context. + + Here is an example action handler on a component: + + ```app/components/my-component.js + import Component from '@glimmer/component'; + import { action } from '@ember/object'; + + export default class extends Component { + @action + save() { + this.model.save(); + } + } + ``` + + 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`. + 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 targeting 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](/ember/release/classes/Component/methods/sendAction?anchor=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: + + ```app/components/update-name.js + import Component from '@glimmer/component'; + import { action } from '@ember/object'; + + export default class extends Component { + @action + setName(model, name) { + model.set('name', name); + } + } + ``` + + ```app/components/update-name.hbs + {{input on-input=(action (action 'setName' @model) value="target.value")}} + ``` + + The first argument (`@model`) was curried over, and the run-time argument (`event`) + becomes a second argument. Action calls can be nested this way because each simply + returns a function. Any function can be passed to the `{{action}}` helper, including + other actions. + + Actions invoked with `sendAction` have the same currying behavior as demonstrated + with `on-input` above. For example: + + ```app/components/my-input.js + import Component from '@glimmer/component'; + import { action } from '@ember/object'; + + export default class extends Component { + @action + setName(model, name) { + model.set('name', name); + } + } + ``` + + ```handlebars + ``` or ```handlebars - {{#person-profile person=this.currentUser}} -

    Admin mode

    - {{! Executed in the current context. }} - {{/person-profile}} + {{my-input submit=(action 'setName' @model)}} ``` - ```app/templates/components/person-profile.hbs -

    {{@person.name}}

    - {{yield}} + ```app/components/my-component.js + import Component from '@ember/component'; + + export default Component.extend({ + click() { + // Note that model is not passed, it was curried in the template + this.sendAction('submit', 'bob'); + } + }); ``` - ## Customizing Components With JavaScript + ### Attaching actions to DOM elements + + The third context of the `{{action}}` helper can be called "element space". + For example: + + ```handlebars + {{! An example of element space }} +
    + ``` + + Used this way, the `{{action}}` helper provides a useful shortcut for + registering an HTML element in 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. Note + that the closure style actions cannot. + + 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: + + ```handlebars +
    + + +
    + ``` + + To disable bubbling, pass `bubbles=false` to the helper: + + ```handlebars + + ``` + + To disable bubbling with closure style actions you must create your own + wrapper helper that makes use of `event.stopPropagation()`: + + ```handlebars +
    Hello
    + ``` + + ```app/helpers/disable-bubbling.js + import { helper } from '@ember/component/helper'; + + export function disableBubbling([action]) { + return function(event) { + event.stopPropagation(); + return action(event); + }; + } + export default helper(disableBubbling); + ``` + + If you need the default handler to trigger you should either register your + own event handler, or use event methods on your view class. See + ["Responding to Browser Events"](/ember/release/classes/Component) + in the documentation for `Component` 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 +
    + click me +
    + ``` + + See ["Event Names"](/ember/release/classes/Component) 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 events with pressed modifier + keys. You can supply an `allowedKeys` option to specify which keys should not be ignored. + + ```handlebars +
    + click me +
    + ``` + + This way the action will fire when clicking with the alt key pressed down. + Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys. + + ```handlebars +
    + click me with any key pressed +
    + ``` + + ### Specifying a Target + + 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: + + ```app/templates/application.hbs +
    + click me +
    + ``` + + ```app/controllers/application.js + import Controller from '@ember/controller'; + import { inject as service } from '@ember/service'; + + export default class extends Controller { + @service someService; + } + ``` + + @method action + @for Ember.Templates.helpers + @public + */ + + _exports.INVOKE = INVOKE; + var action = internalHelper(args => { + var { + named, + positional + } = args; + var capturedArgs = positional.capture(); // The first two argument slots are reserved. + // pos[0] is the context (or `this`) + // pos[1] is the action name or function + // Anything else is an action argument. + + var [context, action, ...restArgs] = capturedArgs; + var debugKey = action.debugLabel; + var target = named.has('target') ? named.get('target') : context; + var processArgs = makeArgsProcessor(named.has('value') && named.get('value'), restArgs); + var fn$$1; + + if ((0, _reference.isInvokableRef)(action)) { + fn$$1 = makeClosureAction(action, action, invokeRef, processArgs, debugKey); + } else { + fn$$1 = makeDynamicClosureAction((0, _reference.valueForRef)(context), target, action, processArgs, debugKey); + } + + ACTIONS.add(fn$$1); + return (0, _reference.createUnboundRef)(fn$$1, '(result of an `action` helper)'); + }); + + function NOOP$1(args) { + return args; + } + + function makeArgsProcessor(valuePathRef, actionArgsRef) { + var mergeArgs; + + if (actionArgsRef.length > 0) { + mergeArgs = args => { + return actionArgsRef.map(_reference.valueForRef).concat(args); + }; + } + + var readValue; + + if (valuePathRef) { + readValue = args => { + var valuePath = (0, _reference.valueForRef)(valuePathRef); + + if (valuePath && args.length > 0) { + args[0] = (0, _metal.get)(args[0], valuePath); + } + + return args; + }; + } + + if (mergeArgs && readValue) { + return args => { + return readValue(mergeArgs(args)); + }; + } else { + return mergeArgs || readValue || NOOP$1; + } + } + + function makeDynamicClosureAction(context, targetRef, actionRef, processArgs, debugKey) { + // We don't allow undefined/null values, so this creates a throw-away action to trigger the assertions + if (true + /* DEBUG */ + ) { + makeClosureAction(context, (0, _reference.valueForRef)(targetRef), (0, _reference.valueForRef)(actionRef), processArgs, debugKey); + } + + return (...args) => { + return makeClosureAction(context, (0, _reference.valueForRef)(targetRef), (0, _reference.valueForRef)(actionRef), processArgs, debugKey)(...args); + }; + } + + function makeClosureAction(context, target, action, processArgs, debugKey) { + var self; + var fn$$1; + (true && !(action !== undefined && action !== null) && (0, _debug.assert)(`Action passed is null or undefined in (action) from ${target}.`, action !== undefined && action !== null)); + + if (typeof action[INVOKE] === 'function') { + (true && !(false) && (0, _debug.deprecate)(`Usage of the private INVOKE API to make an object callable via action or fn is no longer supported. Please update to pass in a callback function instead. Received: ${String(action)}`, false, { + until: '3.25.0', + id: 'actions.custom-invoke-invokable', + for: 'ember-source', + since: { + enabled: '3.23.0-beta.1' + } + })); + self = action; + fn$$1 = action[INVOKE]; + } else { + var typeofAction = typeof action; + + if (typeofAction === 'string') { + self = target; + fn$$1 = target.actions && target.actions[action]; + (true && !(Boolean(fn$$1)) && (0, _debug.assert)(`An action named '${action}' was not found in ${target}`, Boolean(fn$$1))); + } else if (typeofAction === 'function') { + self = context; + fn$$1 = action; + } else { + // tslint:disable-next-line:max-line-length + (true && !(false) && (0, _debug.assert)(`An action could not be made for \`${debugKey || action}\` in ${target}. Please confirm that you are using either a quoted action name (i.e. \`(action '${debugKey || 'myAction'}')\`) or a function available in ${target}.`, false)); + } + } + + return (...args) => { + var payload = { + target: self, + args, + label: '@glimmer/closure-action' + }; + return (0, _instrumentation.flaggedInstrument)('interaction.ember-action', payload, () => { + return (0, _runloop.join)(self, fn$$1, ...processArgs(args)); + }); + }; + } // The code above: + // 1. Finds an action function, usually on the `actions` hash + // 2. Calls it with the target as the correct `this` context + // Previously, `UPDATE_REFERENCED_VALUE` was a method on the reference itself, + // so this made a bit more sense. Now, it isn't, and so we need to create a + // function that can have `this` bound to it when called. This allows us to use + // the same codepath to call `updateRef` on the reference. + + + function invokeRef(value) { + (0, _reference.updateRef)(this, value); + } // inputs needed by CurlyComponents (attrs and props, with mutable + // cells, etc). + + + function processComponentArgs(namedArgs) { + var attrs = Object.create(null); + var props = Object.create(null); + props[ARGS] = namedArgs; + + for (var name in namedArgs) { + var ref = namedArgs[name]; + var value = (0, _reference.valueForRef)(ref); + var isAction = typeof value === 'function' && ACTIONS.has(value); + + if ((0, _reference.isUpdatableRef)(ref) && !isAction) { + attrs[name] = new MutableCell(ref, value); + } else { + attrs[name] = value; + } + + props[name] = value; + } + + props.attrs = attrs; + return props; + } + + var REF = (0, _utils.symbol)('REF'); + + class MutableCell { + constructor(ref, value) { + this[_views.MUTABLE_CELL] = true; + this[REF] = ref; + this.value = value; + } + + update(val) { + (0, _reference.updateRef)(this[REF], val); + } + + } + + var __rest = undefined && undefined.__rest || function (s, e) { + var t = {}; + + for (var p in s) { + if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + } + + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; + } + return t; + }; + + var ARGS = (0, _utils.enumerableSymbol)('ARGS'); + var HAS_BLOCK = (0, _utils.enumerableSymbol)('HAS_BLOCK'); + var DIRTY_TAG = (0, _utils.symbol)('DIRTY_TAG'); + var IS_DISPATCHING_ATTRS = (0, _utils.symbol)('IS_DISPATCHING_ATTRS'); + var BOUNDS = (0, _utils.symbol)('BOUNDS'); + var EMBER_VIEW_REF = (0, _reference.createPrimitiveRef)('ember-view'); + + function aliasIdToElementId(args, props) { + if (args.named.has('id')) { + // tslint:disable-next-line:max-line-length + (true && !(!args.named.has('elementId')) && (0, _debug.assert)(`You cannot invoke a component with both 'id' and 'elementId' at the same time.`, !args.named.has('elementId'))); + props.elementId = props.id; + } + } // We must traverse the attributeBindings in reverse keeping track of + // what has already been applied. This is essentially refining the concatenated + // properties applying right to left. + + + function applyAttributeBindings(attributeBindings, component, rootRef, operations) { + var seen = []; + var i = attributeBindings.length - 1; + + while (i !== -1) { + var binding = attributeBindings[i]; + var parsed = parseAttributeBinding(binding); + var attribute = parsed[1]; + + if (seen.indexOf(attribute) === -1) { + seen.push(attribute); + installAttributeBinding(component, rootRef, parsed, operations); + } + + i--; + } + + if (seen.indexOf('id') === -1) { + var id = component.elementId ? component.elementId : (0, _utils.guidFor)(component); + operations.setAttribute('id', (0, _reference.createPrimitiveRef)(id), false, null); + } + + if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE && installIsVisibleBinding !== undefined && seen.indexOf('style') === -1) { + installIsVisibleBinding(rootRef, operations); + } + } + + var EMPTY_POSITIONAL_ARGS = []; + (0, _debug.debugFreeze)(EMPTY_POSITIONAL_ARGS); + + class CurlyComponentManager { + templateFor(component) { + var { + layout, + layoutName + } = component; + var owner = (0, _owner2.getOwner)(component); + var factory; + + if (layout === undefined) { + if (layoutName !== undefined) { + var _factory = owner.lookup(`template:${layoutName}`); + + (true && !(_factory !== undefined) && (0, _debug.assert)(`Layout \`${layoutName}\` not found!`, _factory !== undefined)); + factory = _factory; + } else { + return null; + } + } else if (isTemplateFactory(layout)) { + factory = layout; + } else { + // no layout was found, use the default layout + return null; + } + + return (0, _util.unwrapTemplate)(factory(owner)).asWrappedLayout(); + } + + getDynamicLayout(bucket) { + return this.templateFor(bucket.component); + } + + getTagName(state) { + var { + component, + hasWrappedElement + } = state; + + if (!hasWrappedElement) { + return null; + } + + return component && component.tagName || 'div'; + } + + getCapabilities() { + return CURLY_CAPABILITIES; + } + + prepareArgs(ComponentClass, args) { + var _a; + + if (args.named.has('__ARGS__')) { + var _b = args.named.capture(), + { + __ARGS__ + } = _b, + rest = __rest(_b, ["__ARGS__"]); + + var prepared = { + positional: EMPTY_POSITIONAL_ARGS, + named: (0, _polyfills.assign)((0, _polyfills.assign)({}, rest), (0, _reference.valueForRef)(__ARGS__)) + }; + return prepared; + } + + var { + positionalParams + } = (_a = ComponentClass.class) !== null && _a !== void 0 ? _a : ComponentClass; // early exits + + if (positionalParams === undefined || positionalParams === null || args.positional.length === 0) { + return null; + } + + var named; + + if (typeof positionalParams === 'string') { + (true && !(!args.named.has(positionalParams)) && (0, _debug.assert)(`You cannot specify positional parameters and the hash argument \`${positionalParams}\`.`, !args.named.has(positionalParams))); + var captured = args.positional.capture(); + named = { + [positionalParams]: (0, _reference.createComputeRef)(() => (0, _runtime.reifyPositional)(captured)) + }; + (0, _polyfills.assign)(named, args.named.capture()); + } else if (Array.isArray(positionalParams) && positionalParams.length > 0) { + var count = Math.min(positionalParams.length, args.positional.length); + named = {}; + (0, _polyfills.assign)(named, args.named.capture()); + + for (var i = 0; i < count; i++) { + // As of TS 3.7, tsc is giving us the following error on this line without the type annotation + // + // TS7022: 'name' implicitly has type 'any' because it does not have a type annotation and is + // referenced directly or indirectly in its own initializer. + // + // This is almost certainly a TypeScript bug, feel free to try and remove the annotation after + // upgrading if it is not needed anymore. + var name = positionalParams[i]; + (true && !(!args.named.has(name)) && (0, _debug.assert)(`You cannot specify both a positional param (at position ${i}) and the hash argument \`${name}\`.`, !args.named.has(name))); + named[name] = args.positional.at(i); + } + } else { + return null; + } + + return { + positional: _util.EMPTY_ARRAY, + named + }; + } + /* + * This hook is responsible for actually instantiating the component instance. + * It also is where we perform additional bookkeeping to support legacy + * features like exposed by view mixins like ChildViewSupport, ActionSupport, + * etc. + */ + + + create(owner, ComponentClass, args, { + isInteractive + }, dynamicScope, callerSelfRef, hasBlock) { + // Get the nearest concrete component instance from the scope. "Virtual" + // components will be skipped. + var parentView = dynamicScope.view; // Capture the arguments, which tells Glimmer to give us our own, stable + // copy of the Arguments object that is safe to hold on to between renders. + + var capturedArgs = args.named.capture(); + (0, _validator.beginTrackFrame)(); + var props = processComponentArgs(capturedArgs); + var argsTag = (0, _validator.endTrackFrame)(); // Alias `id` argument to `elementId` property on the component instance. + + aliasIdToElementId(args, props); // Set component instance's parentView property to point to nearest concrete + // component. + + props.parentView = parentView; // Set whether this component was invoked with a block + // (`{{#my-component}}{{/my-component}}`) or without one + // (`{{my-component}}`). + + props[HAS_BLOCK] = hasBlock; // Save the current `this` context of the template as the component's + // `_target`, so bubbled actions are routed to the right place. + + props._target = (0, _reference.valueForRef)(callerSelfRef); + (0, _owner2.setOwner)(props, owner); // caller: + // + // + // callee: + // + // Now that we've built up all of the properties to set on the component instance, + // actually create it. + + (0, _validator.beginUntrackFrame)(); + var component = ComponentClass.create(props); + var finalizer = (0, _instrumentation._instrumentStart)('render.component', initialRenderInstrumentDetails, component); // We become the new parentView for downstream components, so save our + // component off on the dynamic scope. + + dynamicScope.view = component; // Unless we're the root component, we need to add ourselves to our parent + // component's childViews array. + + if (parentView !== null && parentView !== undefined) { + (0, _views.addChildView)(parentView, component); + } + + component.trigger('didReceiveAttrs'); + var hasWrappedElement = component.tagName !== ''; // We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components + + if (!hasWrappedElement) { + if (isInteractive) { + component.trigger('willRender'); + } + + component._transitionTo('hasElement'); + + if (isInteractive) { + component.trigger('willInsertElement'); + } + } // Track additional lifecycle metadata about this component in a state bucket. + // Essentially we're saving off all the state we'll need in the future. + + + var bucket = new ComponentStateBucket(component, capturedArgs, argsTag, finalizer, hasWrappedElement, isInteractive); + + if (args.named.has('class')) { + bucket.classRef = args.named.get('class'); + } + + if (true + /* DEBUG */ + ) { + processComponentInitializationAssertions(component, props); + } + + if (isInteractive && hasWrappedElement) { + component.trigger('willRender'); + } + + (0, _validator.endUntrackFrame)(); // consume every argument so we always run again + + (0, _validator.consumeTag)(bucket.argsTag); + (0, _validator.consumeTag)(component[DIRTY_TAG]); + return bucket; + } + + getDebugName(definition) { + var _a; + + return definition.fullName || definition.normalizedName || ((_a = definition.class) === null || _a === void 0 ? void 0 : _a.name) || definition.name; + } + + getSelf({ + rootRef + }) { + return rootRef; + } + + didCreateElement({ + component, + classRef, + isInteractive, + rootRef + }, element, operations) { + (0, _views.setViewElement)(component, element); + (0, _views.setElementView)(element, component); + var { + attributeBindings, + classNames, + classNameBindings + } = component; + + if (attributeBindings && attributeBindings.length) { + applyAttributeBindings(attributeBindings, component, rootRef, operations); + } else { + var id = component.elementId ? component.elementId : (0, _utils.guidFor)(component); + operations.setAttribute('id', (0, _reference.createPrimitiveRef)(id), false, null); + + if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE) { + installIsVisibleBinding(rootRef, operations); + } + } + + if (classRef) { + var ref = createSimpleClassNameBindingRef(classRef); + operations.setAttribute('class', ref, false, null); + } + + if (classNames && classNames.length) { + classNames.forEach(name => { + operations.setAttribute('class', (0, _reference.createPrimitiveRef)(name), false, null); + }); + } + + if (classNameBindings && classNameBindings.length) { + classNameBindings.forEach(binding => { + createClassNameBindingRef(rootRef, binding, operations); + }); + } + + operations.setAttribute('class', EMBER_VIEW_REF, false, null); + + if ('ariaRole' in component) { + operations.setAttribute('role', (0, _reference.childRefFor)(rootRef, 'ariaRole'), false, null); + } + + component._transitionTo('hasElement'); + + if (isInteractive) { + (0, _validator.beginUntrackFrame)(); + component.trigger('willInsertElement'); + (0, _validator.endUntrackFrame)(); + } + } + + didRenderLayout(bucket, bounds) { + bucket.component[BOUNDS] = bounds; + bucket.finalize(); + } + + didCreate({ + component, + isInteractive + }) { + if (isInteractive) { + component._transitionTo('inDOM'); + + component.trigger('didInsertElement'); + component.trigger('didRender'); + } + } + + update(bucket) { + var { + component, + args, + argsTag, + argsRevision, + isInteractive + } = bucket; + bucket.finalizer = (0, _instrumentation._instrumentStart)('render.component', rerenderInstrumentDetails, component); + (0, _validator.beginUntrackFrame)(); + + if (args !== null && !(0, _validator.validateTag)(argsTag, argsRevision)) { + (0, _validator.beginTrackFrame)(); + var props = processComponentArgs(args); + argsTag = bucket.argsTag = (0, _validator.endTrackFrame)(); + bucket.argsRevision = (0, _validator.valueForTag)(argsTag); + component[IS_DISPATCHING_ATTRS] = true; + component.setProperties(props); + component[IS_DISPATCHING_ATTRS] = false; + component.trigger('didUpdateAttrs'); + component.trigger('didReceiveAttrs'); + } + + if (isInteractive) { + component.trigger('willUpdate'); + component.trigger('willRender'); + } + + (0, _validator.endUntrackFrame)(); + (0, _validator.consumeTag)(argsTag); + (0, _validator.consumeTag)(component[DIRTY_TAG]); + } + + didUpdateLayout(bucket) { + bucket.finalize(); + } + + didUpdate({ + component, + isInteractive + }) { + if (isInteractive) { + component.trigger('didUpdate'); + component.trigger('didRender'); + } + } + + getDestroyable(bucket) { + return bucket; + } + + } + + function processComponentInitializationAssertions(component, props) { + (true && !((() => { + var { + classNameBindings + } = component; + + for (var i = 0; i < classNameBindings.length; i++) { + var binding = classNameBindings[i]; + + if (typeof binding !== 'string' || binding.length === 0) { + return false; + } + } + + return true; + })()) && (0, _debug.assert)(`classNameBindings must be non-empty strings: ${component}`, (() => { + var { + classNameBindings + } = component; + + for (var i = 0; i < classNameBindings.length; i++) { + var binding = classNameBindings[i]; + + if (typeof binding !== 'string' || binding.length === 0) { + return false; + } + } + + return true; + })())); + (true && !((() => { + var { + classNameBindings + } = component; + + for (var i = 0; i < classNameBindings.length; i++) { + var binding = classNameBindings[i]; + + if (binding.split(' ').length > 1) { + return false; + } + } + + return true; + })()) && (0, _debug.assert)(`classNameBindings must not have spaces in them: ${component}`, (() => { + var { + classNameBindings + } = component; + + for (var i = 0; i < classNameBindings.length; i++) { + var binding = classNameBindings[i]; + + if (binding.split(' ').length > 1) { + return false; + } + } + + return true; + })())); + (true && !(component.tagName !== '' || !component.classNameBindings || component.classNameBindings.length === 0) && (0, _debug.assert)(`You cannot use \`classNameBindings\` on a tag-less component: ${component}`, component.tagName !== '' || !component.classNameBindings || component.classNameBindings.length === 0)); + (true && !(component.tagName !== '' || props.id === component.elementId || !component.elementId && component.elementId !== '') && (0, _debug.assert)(`You cannot use \`elementId\` on a tag-less component: ${component}`, component.tagName !== '' || props.id === component.elementId || !component.elementId && component.elementId !== '')); + (true && !(component.tagName !== '' || !component.attributeBindings || component.attributeBindings.length === 0) && (0, _debug.assert)(`You cannot use \`attributeBindings\` on a tag-less component: ${component}`, component.tagName !== '' || !component.attributeBindings || component.attributeBindings.length === 0)); + } + + function initialRenderInstrumentDetails(component) { + return component.instrumentDetails({ + initialRender: true + }); + } + + function rerenderInstrumentDetails(component) { + return component.instrumentDetails({ + initialRender: false + }); + } + + var CURLY_CAPABILITIES = { + dynamicLayout: true, + dynamicTag: true, + prepareArgs: true, + createArgs: true, + attributeHook: true, + elementHook: true, + createCaller: true, + dynamicScope: true, + updateHook: true, + createInstance: true, + wrapped: true, + willDestroy: true, + hasSubOwner: false + }; + var CURLY_COMPONENT_MANAGER = new CurlyComponentManager(); + + function isCurlyManager(manager) { + return manager === CURLY_COMPONENT_MANAGER; + } + /** + @module @ember/component + */ + + /** + A component is a reusable UI element that consists of a `.hbs` template and an + optional JavaScript class that defines its behavior. For example, someone + might make a `button` in the template and handle the click behavior in the + JavaScript file that shares the same name as the template. + + Components are broken down into two categories: + + - Components _without_ JavaScript, that are based only on a template. These + are called Template-only or TO components. + - Components _with_ JavaScript, which consist of a template and a backing + class. + + Ember ships with two types of JavaScript classes for components: + + 1. Glimmer components, imported from `@glimmer/component`, which are the + default component's for Ember Octane (3.15) and more recent editions. + 2. Classic components, imported from `@ember/component`, which were the + default for older editions of Ember (pre 3.15). + + Below is the documentation for Classic components. If you are looking for the + API documentation for Template-only or Glimmer components, it is + [available here](/ember/release/modules/@glimmer%2Fcomponent). + + ## Defining a Classic Component If you want to customize the component in order to handle events, transform arguments or maintain internal state, you implement a subclass of `Component`. @@ -2563,7 +3760,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim export default Component.extend({ displayName: computed('person.title', 'person.firstName', 'person.lastName', function() { - let { title, firstName, lastName } = this; + let { title, firstName, lastName } = this.person; if (title) { return `${title} ${lastName}`; @@ -2581,7 +3778,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim {{yield}} ``` - ## Customizing a Component's HTML Element in JavaScript + ## Customizing a Classic Component's HTML Element in JavaScript ### HTML Tag @@ -3142,7 +4339,8 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @public */ - var Component = _views.CoreView.extend(_views.ChildViewsSupport, _views.ViewStateSupport, _views.ClassNamesSupport, _runtime.TargetActionSupport, _views.ActionSupport, _views.ViewMixin, { + + var Component = _views.CoreView.extend(_views.ChildViewsSupport, _views.ViewStateSupport, _views.ClassNamesSupport, _runtime2.TargetActionSupport, _views.ActionSupport, _views.ViewMixin, { isComponent: true, init() { @@ -3154,9 +4352,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim if (true /* DEBUG */ - && this.renderer._destinedForDOM && this.tagName === '') { + && this.renderer._isInteractive && this.tagName === '') { var eventNames = []; - var eventDispatcher = (0, _owner.getOwner)(this).lookup('event_dispatcher:main'); + var eventDispatcher = (0, _owner2.getOwner)(this).lookup('event_dispatcher:main'); var events = eventDispatcher && eventDispatcher._finalEvents || {}; // tslint:disable-next-line:forin for (var key in events) { @@ -3263,7 +4461,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim var { type, normalized - } = (0, _runtime2.normalizeProperty)(element, name); + } = (0, _runtime.normalizeProperty)(element, name); if (isSVG || type === 'attr') { return element.getAttribute(normalized); @@ -3437,10 +4635,12 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim isComponentFactory: true, positionalParams: [] }); + (0, _manager2.setInternalComponentManager)(CURLY_COMPONENT_MANAGER, Component); var layout = (0, _opcodeCompiler.templateFactory)({ - "id": "3IKjaxWN", - "block": "{\"symbols\":[],\"statements\":[],\"hasEval\":false,\"upvars\":[]}", - "moduleName": "packages/@ember/-internals/glimmer/lib/templates/empty.hbs" + "id": "14evwHqT", + "block": "[[],[],false,[]]", + "moduleName": "packages/@ember/-internals/glimmer/lib/templates/empty.hbs", + "isStrictMode": false }); /** @module @ember/component @@ -3892,9 +5092,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim TextArea.toString = () => '@ember/component/text-area'; var layout$1 = (0, _opcodeCompiler.templateFactory)({ - "id": "ddnfgiDJ", - "block": "{\"symbols\":[\"&default\"],\"statements\":[[6,[37,0],[[27,[32,1]]],null,[[\"default\",\"else\"],[{\"statements\":[[18,1,null]],\"parameters\":[]},{\"statements\":[[1,[32,0,[\"linkTitle\"]]]],\"parameters\":[]}]]]],\"hasEval\":false,\"upvars\":[\"if\"]}", - "moduleName": "packages/@ember/-internals/glimmer/lib/templates/link-to.hbs" + "id": "Hma8ydcX", + "block": "[[[41,[48,[30,1]],[[[18,1,null]],[]],[[[1,[30,0,[\"linkTitle\"]]]],[]]]],[\"&default\"],false,[\"if\",\"has-block\",\"yield\"]]", + "moduleName": "packages/@ember/-internals/glimmer/lib/templates/link-to.hbs", + "isStrictMode": false }); /** @module ember @@ -4116,8 +5317,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim ``` - In general, this is not recommended. Instead, you can use the `transition-to` helper together - with a click event handler on the HTML tag of your choosing. + In general, this is not recommended. ### Supplying query parameters @@ -4368,10 +5568,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim _currentRouterState: (0, _metal.alias)('_routing.currentState'), _targetRouterState: (0, _metal.alias)('_routing.targetState'), _isEngine: (0, _metal.computed)(function () { - return (0, _engine.getEngineParent)((0, _owner.getOwner)(this)) !== undefined; + return (0, _engine.getEngineParent)((0, _owner2.getOwner)(this)) !== undefined; }), _engineMountPoint: (0, _metal.computed)(function () { - return (0, _owner.getOwner)(this).mountPoint; + return (0, _owner2.getOwner)(this).mountPoint; }), _route: (0, _metal.computed)('route', '_currentRouterState', function computeLinkToComponentRoute() { var { @@ -4626,7 +5826,8 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return routing.generateURL(route, models, query); } catch (e) { // tslint:disable-next-line:max-line-length - (true && !(false) && (0, _debug.assert)(`You attempted to generate a link for the "${this.route}" route, but did not ` + `pass the models required for generating its dynamic segments. ` + e.message)); + e.message = `While generating link to route "${this.route}": ${e.message}`; + throw e; } } else { return routing.generateURL(route, models, query); @@ -4735,616 +5936,245 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim LinkComponent.reopenClass({ positionalParams: 'params' }); + var CAPABILITIES = { + dynamicLayout: false, + dynamicTag: false, + prepareArgs: false, + createArgs: true, + attributeHook: false, + elementHook: false, + createCaller: true, + dynamicScope: false, + updateHook: false, + createInstance: true, + wrapped: false, + willDestroy: false, + hasSubOwner: false + }; - function convertToInt(prop) { - if (typeof prop === 'symbol') return null; - var num = Number(prop); - if (isNaN(num)) return null; - return num % 1 === 0 ? num : null; - } + class InternalManager { + constructor(ComponentClass, name) { + this.ComponentClass = ComponentClass; + this.name = name; + } - function tagForNamedArg(namedArgs, key) { - return (0, _validator.track)(() => { - if (key in namedArgs) { - (0, _reference.valueForRef)(namedArgs[key]); - } - }); - } + getCapabilities() { + return CAPABILITIES; + } - function tagForPositionalArg(positionalArgs, key) { - return (0, _validator.track)(() => { - if (key === '[]') { - // consume all of the tags in the positional array - positionalArgs.forEach(_reference.valueForRef); - } - - var parsed = convertToInt(key); - - if (parsed !== null && parsed < positionalArgs.length) { - // consume the tag of the referenced index - (0, _reference.valueForRef)(positionalArgs[parsed]); - } - }); - } - - var argsProxyFor; - - if (_utils.HAS_NATIVE_PROXY) { - argsProxyFor = (capturedArgs, type) => { + create(owner, _definition, args, env, _dynamicScope, caller) { + (true && !((0, _reference.isConstRef)(caller)) && (0, _debug.assert)('caller must be const', (0, _reference.isConstRef)(caller))); + (true && !(args.positional.length === 0) && (0, _debug.assert)(`The ${this.name} component does not take any positional arguments`, args.positional.length === 0)); var { - named, - positional - } = capturedArgs; - - var getNamedTag = key => tagForNamedArg(named, key); - - var getPositionalTag = key => tagForPositionalArg(positional, key); - - var namedHandler = { - get(_target, prop) { - var ref = named[prop]; - - if (ref !== undefined) { - return (0, _reference.valueForRef)(ref); - } else if (prop === _metal.CUSTOM_TAG_FOR) { - return getNamedTag; - } - }, - - has(_target, prop) { - return prop in named; - }, - - ownKeys(_target) { - return Object.keys(named); - }, - - isExtensible() { - return false; - }, - - getOwnPropertyDescriptor(_target, prop) { - (true && !(prop in named) && (0, _debug.assert)('args proxies do not have real property descriptors, so you should never need to call getOwnPropertyDescriptor yourself. This code exists for enumerability, such as in for-in loops and Object.keys()', prop in named)); - return { - enumerable: true, - configurable: true - }; - } - + ComponentClass + } = this; + var instance = new ComponentClass(owner, args.named.capture(), (0, _reference.valueForRef)(caller)); + var state = { + env, + instance }; - var positionalHandler = { - get(target, prop) { - if (prop === 'length') { - return positional.length; - } + return state; + } - var parsed = convertToInt(prop); + didCreate() {} - if (parsed !== null && parsed < positional.length) { - return (0, _reference.valueForRef)(positional[parsed]); - } + didUpdate() {} - if (prop === _metal.CUSTOM_TAG_FOR) { - return getPositionalTag; - } + didRenderLayout() {} - return target[prop]; - }, + didUpdateLayout() {} - isExtensible() { - return false; - }, + getDebugName() { + return this.name; + } - has(_target, prop) { - var parsed = convertToInt(prop); - return parsed !== null && parsed < positional.length; - } + getSelf({ + instance + }) { + return (0, _reference.createConstRef)(instance, 'this'); + } - }; - var namedTarget = Object.create(null); - var positionalTarget = []; + getDestroyable(state) { + return state.instance; + } - if (true - /* DEBUG */ - ) { - var setHandler = function (_target, prop) { - throw new Error(`You attempted to set ${String(prop)} on the arguments of a component, helper, or modifier. Arguments are immutable and cannot be updated directly, they always represent the values that is passed down. If you want to set default values, you should use a getter and local tracked state instead.`); - }; + } - var forInDebugHandler = () => { - throw new Error(`Object.keys() was called on the positional arguments array for a ${type}, which is not supported. This function is a low-level function that should not need to be called for positional argument arrays. You may be attempting to iterate over the array using for...in instead of for...of.`); - }; + var InputTemplate = (0, _opcodeCompiler.templateFactory)({ + "id": "sAKl8rD7", + "block": "[[[44,[[50,\"-checkbox\",0,null,null],[50,\"-text-field\",0,null,null]],[[[41,[30,0,[\"isCheckbox\"]],[[[8,[30,1],[[17,3]],[[\"@target\",\"@__ARGS__\"],[[30,0,[\"caller\"]],[30,0,[\"args\"]]]],null]],[]],[[[8,[30,2],[[17,3]],[[\"@target\",\"@__ARGS__\"],[[30,0,[\"caller\"]],[30,0,[\"args\"]]]],null]],[]]]],[1,2]]]],[\"Checkbox\",\"TextField\",\"&attrs\"],false,[\"let\",\"component\",\"if\"]]", + "moduleName": "packages/@ember/-internals/glimmer/lib/templates/input.hbs", + "isStrictMode": false + }); - namedHandler.set = setHandler; - positionalHandler.set = setHandler; - positionalHandler.ownKeys = forInDebugHandler; - } + class InternalComponent { + constructor(owner, args, caller) { + this.owner = owner; + this.args = args; + this.caller = caller; + (0, _owner2.setOwner)(this, owner); + } - return { - named: new Proxy(namedTarget, namedHandler), - positional: new Proxy(positionalTarget, positionalHandler) - }; - }; - } else { - argsProxyFor = (capturedArgs, _type) => { - var { - named, - positional - } = capturedArgs; + static get class() { + return this; + } - var getNamedTag = key => tagForNamedArg(named, key); + static get fullName() { + return this.name; + } - var getPositionalTag = key => tagForPositionalArg(positional, key); + static get normalizedName() { + return this.name; + } - var namedProxy = {}; - Object.defineProperty(namedProxy, _metal.CUSTOM_TAG_FOR, { - configurable: false, - enumerable: false, - value: getNamedTag - }); - Object.keys(named).forEach(name => { - Object.defineProperty(namedProxy, name, { - enumerable: true, - configurable: true, + arg(key) { + var ref = this.args[key]; + return ref ? (0, _reference.valueForRef)(ref) : undefined; + } - get() { - return (0, _reference.valueForRef)(named[name]); - } + toString() { + return `<${this.constructor.toString()}:${(0, _utils.guidFor)(this)}>`; + } - }); - }); - var positionalProxy = []; - Object.defineProperty(positionalProxy, _metal.CUSTOM_TAG_FOR, { - configurable: false, - enumerable: false, - value: getPositionalTag - }); - positional.forEach((ref, index) => { - Object.defineProperty(positionalProxy, index, { - enumerable: true, - configurable: true, - - get() { - return (0, _reference.valueForRef)(ref); - } - - }); - }); - - if (true - /* DEBUG */ - ) { - // Prevent mutations in development mode. This will not prevent the - // proxy from updating, but will prevent assigning new values or pushing - // for instance. - Object.freeze(namedProxy); - Object.freeze(positionalProxy); - } - - return { - named: namedProxy, - positional: positionalProxy - }; - }; } /** - @module @ember/helper + @module @ember/component */ /** - `capabilities` returns a capabilities configuration which can be used to modify - the behavior of the manager. Manager capabilities _must_ be provided using the - `capabilities` function, as the underlying implementation can change over time. + See [Ember.Templates.components.Input](/ember/release/classes/Ember.Templates.components/methods/Input?anchor=Input). - The first argument to capabilities is a version string, which is the version of - Ember that the capabilities were defined in. Ember can add new versions at any - time, and these may have entirely different behaviors, but it will not remove - old versions until the next major version. + @method input + @for Ember.Templates.helpers + @param {Hash} options + @public + */ + + /** + The `Input` component lets you create an HTML `` element. - ```js - capabilities('3.23'); + ```handlebars + ``` - The second argument is an object of capabilities and boolean values indicating - whether they are enabled or disabled. + creates an `` element with `type="text"` and value set to 987. - ```js - capabilities('3.23', { - hasValue: true, - hasDestructor: true, - }); + ### Text field + + If no `type` argument is specified, a default of type 'text' is used. + + ```handlebars + Search: + ``` - If no value is specified, then the default value will be used. + In this example, the initial value in the `` will be set to the value of + `this.searchWord`. If the user changes the text, the value of `this.searchWord` will also be + updated. - ### `3.23` capabilities + ### Actions - #### `hasDestroyable` + The `Input` component takes a number of arguments with callbacks that are invoked in response to + user events. - - Default value: false + * `enter` + * `insert-newline` + * `escape-press` + * `focus-in` + * `focus-out` + * `key-down` + * `key-press` + * `key-up` - Determines if the helper has a destroyable to include in the destructor - hierarchy. If enabled, the `getDestroyable` hook will be called, and its result - will be associated with the destroyable parent block. + These callbacks are passed to `Input` like this: - #### `hasValue` + ```handlebars + + ``` - - Default value: false + ### `` HTML Attributes to Avoid - Determines if the helper has a value which can be used externally. The helper's - `getValue` hook will be run whenever the value of the helper is accessed if this - capability is enabled. + In most cases, if you want to pass an attribute to the underlying HTML `` element, you + can pass the attribute directly, just like any other Ember component. - @method capabilities - @for @ember/helper - @static - @param {String} managerApiVersion The version of capabilities that are being used - @param options The capabilities values - @return {Capabilities} The capabilities object instance + ```handlebars + + ``` + + In this example, the `size` attribute will be applied to the underlying `` element in the + outputted HTML. + + However, there are a few attributes where you **must** use the `@` version. + + * `@type`: This argument is used to control which Ember component is used under the hood + * `@value`: The `@value` argument installs a two-way binding onto the element. If you wanted a + one-way binding, use `` with the `value` property and the `input` event instead. + * `@checked` (for checkboxes): like `@value`, the `@checked` argument installs a two-way binding + onto the element. If you wanted a one-way binding, use `` with + `checked` and the `input` event instead. + + ### Extending `TextField` + + Internally, `` creates an instance of `TextField`, passing arguments from + the helper to `TextField`'s `create` method. Subclassing `TextField` is supported but not + recommended. + + See [TextField](/ember/release/classes/TextField) + + ### Checkbox + + To create an ``: + + ```handlebars + Emberize Everything: + + ``` + + This will bind the checked state of this checkbox to the value of `isEmberized` -- if either one + changes, it will be reflected in the other. + + ### Extending `Checkbox` + + Internally, `` creates an instance of `Checkbox`. Subclassing + `TextField` is supported but not recommended. + + See [Checkbox](/ember/release/classes/Checkbox) + + @method Input + @for Ember.Templates.components + @see {TextField} + @see {Checkbox} + @param {Hash} options @public */ - function helperCapabilities(managerAPI, options = {}) { - (true && !(managerAPI === '3.23') && (0, _debug.assert)('Invalid helper manager compatibility specified', managerAPI === '3.23')); - (true && !((options.hasValue || options.hasScheduledEffect) && !(options.hasValue && options.hasScheduledEffect)) && (0, _debug.assert)('You must pass either the `hasValue` OR the `hasScheduledEffect` capability when defining a helper manager. Passing neither, or both, is not permitted.', (options.hasValue || options.hasScheduledEffect) && !(options.hasValue && options.hasScheduledEffect))); - (true && !(!options.hasScheduledEffect) && (0, _debug.assert)('The `hasScheduledEffect` capability has not yet been implemented for helper managers. Please pass `hasValue` instead', !options.hasScheduledEffect)); - return (0, _runtime2.buildCapabilities)({ - hasValue: Boolean(options.hasValue), - hasDestroyable: Boolean(options.hasDestroyable), - hasScheduledEffect: Boolean(options.hasScheduledEffect) - }); - } - /** - Sets the helper manager for an object or function. - - ```js - setHelperManager((owner) => new ClassHelperManager(owner), Helper) - ``` - - When a value is used as a helper in a template, the helper manager is looked up - on the object by walking up its prototype chain and finding the first helper - manager. This manager then receives the value and can create and manage an - instance of a helper from it. This provides a layer of indirection that allows - users to design high-level helper APIs, without Ember needing to worry about the - details. High-level APIs can be experimented with and iterated on while the - core of Ember helpers remains stable, and new APIs can be introduced gradually - over time to existing code bases. - - `setHelperManager` receives two arguments: - - 1. A factory function, which receives the `owner` and returns an instance of a - helper manager. - 2. A helper definition, which is the object or function to associate the factory function with. - - The first time the object is looked up, the factory function will be called to - create the helper manager. It will be cached, and in subsequent lookups the - cached helper manager will be used instead. - - Only one helper manager is guaranteed to exist per `owner` and per usage of - `setHelperManager`, so many helpers will end up using the same instance of the - helper manager. As such, you should only store state that is related to the - manager itself. If you want to store state specific to a particular helper - definition, you should assign a unique helper manager to that helper. In - general, most managers should either be stateless, or only have the `owner` they - were created with as state. - - Helper managers must fulfill the following interface (This example uses - [TypeScript interfaces](https://www.typescriptlang.org/docs/handbook/interfaces.html) - for precision, you do not need to write helper managers using TypeScript): - - ```ts - interface HelperManager { - capabilities: HelperCapabilities; - - createHelper(definition: HelperDefinition, args: TemplateArgs): HelperStateBucket; - - getValue?(bucket: HelperStateBucket): unknown; - - runEffect?(bucket: HelperStateBucket): void; - - getDestroyable?(bucket: HelperStateBucket): object; - } - ``` - - The capabilities property _must_ be provided using the `capabilities()` function - imported from the same module as `setHelperManager`: - - ```js - import { capabilities } from '@ember/helper'; - - class MyHelperManager { - capabilities = capabilities('3.21.0', { hasValue: true }); - - // ...snip... - } - ``` - - Below is a description of each of the methods on the interface and their - functions. - - #### `createHelper` - - `createHelper` is a required hook on the HelperManager interface. The hook is - passed the definition of the helper that is currently being created, and is - expected to return a _state bucket_. This state bucket is what represents the - current state of the helper, and will be passed to the other lifecycle hooks at - appropriate times. It is not necessarily related to the definition of the - helper itself - for instance, you could return an object _containing_ an - instance of the helper: - - ```js - class MyManager { - createHelper(Definition, args) { - return { - instance: new Definition(args); - }; - } - } - ``` - - This allows the manager to store metadata that it doesn't want to expose to the - user. - - This hook is _not_ autotracked - changes to tracked values used within this hook - will _not_ result in a call to any of the other lifecycle hooks. This is because - it is unclear what should happen if it invalidates, and rather than make a - decision at this point, the initial API is aiming to allow as much expressivity - as possible. This could change in the future with changes to capabilities and - their behaviors. - - If users do want to autotrack some values used during construction, they can - either create the instance of the helper in `runEffect` or `getValue`, or they - can use the `cache` API to autotrack the `createHelper` hook themselves. This - provides maximum flexibility and expressiveness to manager authors. - - This hook has the following timing semantics: - - **Always** - - called as discovered during DOM construction - - called in definition order in the template - - #### `getValue` - - `getValue` is an optional hook that should return the value of the helper. This - is the value that is returned from the helper and passed into the template. - - This hook is called when the value is requested from the helper (e.g. when the - template is rendering and the helper value is needed). The hook is autotracked, - and will rerun whenever any tracked values used inside of it are updated. - Otherwise it does not rerun. - - > Note: This means that arguments which are not _consumed_ within the hook will - > not trigger updates. - - This hook is only called for helpers with the `hasValue` capability enabled. - This hook has the following timing semantics: - - **Always** - - called the first time the helper value is requested - - called after autotracked state has changed - - **Never** - - called if the `hasValue` capability is disabled - - #### `runEffect` - - `runEffect` is an optional hook that should run the effect that the helper is - applying, setting it up or updating it. - - This hook is scheduled to be called some time after render and prior to paint. - There is not a guaranteed, 1-to-1 relationship between a render pass and this - hook firing. For instance, multiple render passes could occur, and the hook may - only trigger once. It may also never trigger if it was dirtied in one render - pass and then destroyed in the next. - - The hook is autotracked, and will rerun whenever any tracked values used inside - of it are updated. Otherwise it does not rerun. - - The hook is also run during a time period where state mutations are _disabled_ - in Ember. Any tracked state mutation will throw an error during this time, - including changes to tracked properties, changes made using `Ember.set`, updates - to computed properties, etc. This is meant to prevent infinite rerenders and - other antipatterns. - - This hook is only called for helpers with the `hasScheduledEffect` capability - enabled. This hook is also not called in SSR currently, though this could be - added as a capability in the future. It has the following timing semantics: - - **Always** - - called after the helper was first created, if the helper has not been - destroyed since creation - - called after autotracked state has changed, if the helper has not been - destroyed during render - - **Never** - - called if the `hasScheduledEffect` capability is disabled - - called in SSR - - #### `getDestroyable` - - `getDestroyable` is an optional hook that users can use to register a - destroyable object for the helper. This destroyable will be registered to the - containing block or template parent, and will be destroyed when it is destroyed. - See the [Destroyables RFC](https://github.com/emberjs/rfcs/blob/master/text/0580-destroyables.md) - for more details. - - `getDestroyable` is only called if the `hasDestroyable` capability is enabled. - - This hook has the following timing semantics: - - **Always** - - called immediately after the `createHelper` hook is called - - **Never** - - called if the `hasDestroyable` capability is disabled - - @method setHelperManager - @for @ember/helper - @static - @param {Function} factory A factory function which receives an optional owner, and returns a helper manager - @param {object} definition The definition to associate the manager factory with - @return {object} The definition passed into setHelperManager - @public - */ - - - function hasValue(manager) { - return manager.capabilities.hasValue; - } - - function hasDestroyable(manager) { - return manager.capabilities.hasDestroyable; - } - - var ARGS_CACHES = true - /* DEBUG */ - ? new WeakMap() : undefined; - - function getArgs(proxy) { - return (0, _validator.getValue)(true - /* DEBUG */ - ? ARGS_CACHES.get(proxy) : proxy.argsCache); - } - - class SimpleArgsProxy { - constructor(context, computeArgs = () => _runtime2.EMPTY_ARGS) { - var argsCache = (0, _validator.createCache)(() => computeArgs(context)); - - if (true - /* DEBUG */ - ) { - ARGS_CACHES.set(this, argsCache); - Object.freeze(this); - } else { - this.argsCache = argsCache; - } + class Input extends InternalComponent { + get isCheckbox() { + return this.arg('type') === 'checkbox'; } - get named() { - return getArgs(this).named || _runtime2.EMPTY_NAMED; + } // Use an opaque handle so implementation details are + + + var InputComponent = { + // Factory interface + create() { + throw (0, _debug.assert)('Use constructor instead of create'); } - get positional() { - return getArgs(this).positional || _runtime2.EMPTY_POSITIONAL; - } + }; + _exports.Input = InputComponent; + (0, _manager2.setInternalComponentManager)(new InternalManager(Input, 'input'), InputComponent); + (0, _manager2.setComponentTemplate)(InputTemplate, InputComponent); - } - /** - The `invokeHelper` function can be used to create a helper instance in - JavaScript. - - ```js - // app/components/data-loader.js - import Component from '@glimmer/component'; - import Helper from '@ember/component/helper'; - import { invokeHelper } from '@ember/helper'; - - class PlusOne extends Helper { - compute([num]) { - return number + 1; - } - } - - export default class PlusOne extends Component { - plusOne = invokeHelper(this, RemoteData, () => { - return { - positional: [this.args.number], - }; - }); - } - ``` - ```hbs - {{this.plusOne.value}} - ``` - - It receives three arguments: - - * `context`: The parent context of the helper. When the parent is torn down and - removed, the helper will be as well. - * `definition`: The definition of the helper. - * `computeArgs`: An optional function that produces the arguments to the helper. - The function receives the parent context as an argument, and must return an - object with a `positional` property that is an array and/or a `named` - property that is an object. - - And it returns a Cache instance that contains the most recent value of the - helper. You can access the helper using `getValue()` like any other cache. The - cache is also destroyable, and using the `destroy()` function on it will cause - the helper to be torn down. - - Note that using `getValue()` on helpers that have scheduled effects will not - trigger the effect early. Effects will continue to run at their scheduled time. - - @method invokeHelper - @for @ember/helper - @static - @param {object} context The parent context of the helper - @param {object} definition The helper definition - @param {Function} computeArgs An optional function that produces args - @returns - @public - */ - - - function invokeHelper(context, definition, computeArgs) { - (true && !(context !== null && typeof context === 'object') && (0, _debug.assert)(`Expected a context object to be passed as the first parameter to invokeHelper, got ${context}`, context !== null && typeof context === 'object')); - var owner = (0, _owner.getOwner)(context); - var manager = (0, _runtime2.getHelperManager)(owner, definition); // TODO: figure out why assert isn't using the TS assert thing - - (true && !(manager) && (0, _debug.assert)(`Expected a helper definition to be passed as the second parameter to invokeHelper, but no helper manager was found. The definition value that was passed was \`${(0, _utils.getDebugName)(definition)}\`. Did you use setHelperManager to associate a helper manager with this value?`, manager)); - (true && !(!(0, _runtime2.isInternalHelper)(manager)) && (0, _debug.assert)('Invoke helper does not support internal helpers yet', !(0, _runtime2.isInternalHelper)(manager))); - var args = new SimpleArgsProxy(context, computeArgs); - var bucket = manager.createHelper(definition, args); - var cache; - - if (hasValue(manager)) { - cache = (0, _validator.createCache)(() => { - (true && !(!(0, _runtime2.isDestroying)(cache) && !(0, _runtime2.isDestroyed)(cache)) && (0, _debug.assert)(`You attempted to get the value of a helper after the helper was destroyed, which is not allowed`, !(0, _runtime2.isDestroying)(cache) && !(0, _runtime2.isDestroyed)(cache))); - return manager.getValue(bucket); - }); - (0, _runtime2.associateDestroyableChild)(context, cache); - } else { - throw new Error('TODO: unreachable, to be implemented with hasScheduledEffect'); - } - - if (hasDestroyable(manager)) { - var destroyable = manager.getDestroyable(bucket); - (0, _runtime2.associateDestroyableChild)(cache, destroyable); - } - - return cache; - } - - function customHelper(manager, definition) { - return (vmArgs, vm) => { - var args = argsProxyFor(vmArgs.capture(), 'helper'); - var bucket = manager.createHelper(definition, args); - - if (hasDestroyable(manager)) { - vm.associateDestroyable(manager.getDestroyable(bucket)); - } - - if (hasValue(manager)) { - return (0, _reference.createComputeRef)(() => manager.getValue(bucket), null, true - /* DEBUG */ - && manager.getDebugName && manager.getDebugName(definition)); - } else { - return _reference.UNDEFINED_REFERENCE; - } - }; - } + Input.toString = () => '@ember/component/input'; /** @module @ember/component */ var RECOMPUTE_TAG = (0, _utils.symbol)('RECOMPUTE_TAG'); - var CLASSIC_HELPER_MANAGERS = new _util._WeakSet(); - - function isClassicHelperManager(obj) { - return CLASSIC_HELPER_MANAGERS.has(obj); - } /** Ember Helpers are functions that can compute values, and are used in templates. For example, this code calls a helper named `format-currency`: @@ -5390,8 +6220,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @since 1.13.0 */ - - var Helper = _runtime.FrameworkObject.extend({ + var Helper = _runtime2.FrameworkObject.extend({ init() { this._super(...arguments); @@ -5428,17 +6257,22 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim }); _exports.Helper = Helper; + var IS_CLASSIC_HELPER = (0, _utils.symbol)('IS_CLASSIC_HELPER'); Helper.isHelperFactory = true; + Helper[IS_CLASSIC_HELPER] = true; + + function isClassicHelper(obj) { + return obj[IS_CLASSIC_HELPER] === true; + } class ClassicHelperManager { constructor(owner) { - this.capabilities = helperCapabilities('3.23', { + this.capabilities = (0, _manager2.helperCapabilities)('3.23', { hasValue: true, hasDestroyable: true }); - CLASSIC_HELPER_MANAGERS.add(this); var ownerInjection = {}; - (0, _owner.setOwner)(ownerInjection, owner); + (0, _owner2.setOwner)(ownerInjection, owner); this.ownerInjection = ownerInjection; } @@ -5486,7 +6320,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } - (0, _runtime2.setHelperManager)(owner => new ClassicHelperManager(owner), Helper); /////////// + (0, _manager2.setHelperManager)(owner => { + return new ClassicHelperManager(owner); + }, Helper); + var CLASSIC_HELPER_MANAGER = (0, _manager2.getInternalHelperManager)(Helper); /////////// class Wrapper { constructor(compute) { @@ -5505,7 +6342,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim class SimpleClassicHelperManager { constructor() { - this.capabilities = helperCapabilities('3.23', { + this.capabilities = (0, _manager2.helperCapabilities)('3.23', { hasValue: true }); } @@ -5530,8 +6367,8 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return () => compute.call(null, args.positional, args.named); } - getValue(fn) { - return fn(); + getValue(fn$$1) { + return fn$$1(); } getDebugName(definition) { @@ -5541,7 +6378,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } var SIMPLE_CLASSIC_HELPER_MANAGER = new SimpleClassicHelperManager(); - (0, _runtime2.setHelperManager)(() => SIMPLE_CLASSIC_HELPER_MANAGER, Wrapper.prototype); + (0, _manager2.setHelperManager)(() => SIMPLE_CLASSIC_HELPER_MANAGER, Wrapper.prototype); /** In many cases it is not necessary to use the full `Helper` class. The `helper` method create pure-function helpers without instances. @@ -5566,175 +6403,6 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim function helper(helperFn) { return new Wrapper(helperFn); } - /** - @module @ember/template - */ - - - class SafeString { - constructor(string) { - this.string = string; - } - - toString() { - return `${this.string}`; - } - - toHTML() { - return this.toString(); - } - - } - - _exports.SafeString = SafeString; - var escape = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`', - '=': '=' - }; - var possible = /[&<>"'`=]/; - var badChars = /[&<>"'`=]/g; - - function escapeChar(chr) { - return escape[chr]; - } - - function escapeExpression(string) { - if (typeof string !== 'string') { - // don't escape SafeStrings, since they're already safe - if (string && string.toHTML) { - return string.toHTML(); - } else if (string === null || string === undefined) { - return ''; - } else if (!string) { - return String(string); - } // Force a string conversion as this will be done by the append regardless and - // the regex test will do this transparently behind the scenes, causing issues if - // an object's to string has escaped characters in it. - - - string = String(string); - } - - if (!possible.test(string)) { - return string; - } - - return string.replace(badChars, escapeChar); - } - /** - 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 - import { htmlSafe } from '@ember/template'; - - htmlSafe('
    someString
    ') - ``` - - @method htmlSafe - @for @ember/template - @static - @return {SafeString} A string that will not be HTML escaped by Handlebars. - @public - */ - - - function htmlSafe(str) { - if (str === null || str === undefined) { - str = ''; - } else if (typeof str !== 'string') { - str = String(str); - } - - return new SafeString(str); - } - /** - Detects if a string was decorated using `htmlSafe`. - - ```javascript - import { htmlSafe, isHTMLSafe } from '@ember/template'; - - var plainString = 'plain string', - safeString = htmlSafe('
    someValue
    '); - - isHTMLSafe(plainString); // false - isHTMLSafe(safeString); // true - ``` - - @method isHTMLSafe - @for @ember/template - @static - @return {Boolean} `true` if the string was decorated with `htmlSafe`, `false` otherwise. - @public - */ - - - function isHTMLSafe(str) { - return str !== null && typeof str === 'object' && typeof str.toHTML === 'function'; - } - - function isStaticComponentManager(_manager, capabilities) { - return !capabilities.dynamicLayout; - } - - class CompileTimeResolverImpl { - constructor(resolver) { - this.resolver = resolver; - } - - lookupHelper(name, owner) { - return this.resolver.lookupHelper(name, owner); - } - - lookupModifier(name, owner) { - return this.resolver.lookupModifier(name, owner); - } - - lookupComponent(name, owner) { - var definitionHandle = this.resolver.lookupComponentHandle(name, owner); - - if (definitionHandle === null) { - return null; - } - - var { - manager, - state - } = this.resolver.resolve(definitionHandle); - var capabilities = manager.getCapabilities(state); - - if (!isStaticComponentManager(manager, capabilities)) { - return { - handle: definitionHandle, - capabilities, - compilable: null - }; - } - - var template = (0, _util.unwrapTemplate)(manager.getStaticLayout(state)); - var layout = capabilities.wrapped ? template.asWrappedLayout() : template.asLayout(); - return { - handle: definitionHandle, - capabilities, - compilable: layout - }; - } - - lookupPartial(name, owner) { - return this.resolver.lookupPartial(name, owner); - } - - resolve() { - return null; - } - - } function instrumentationPayload(def) { return { @@ -5742,7 +6410,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim }; } - var CAPABILITIES = { + var CAPABILITIES$1 = { dynamicLayout: false, dynamicTag: false, prepareArgs: false, @@ -5754,11 +6422,12 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim updateHook: false, createInstance: true, wrapped: false, - willDestroy: false + willDestroy: false, + hasSubOwner: false }; - class OutletComponentManager extends _runtime2.BaseInternalComponentManager { - create(env, definition, _args, dynamicScope) { + class OutletComponentManager { + create(_owner, definition, _args, env, dynamicScope) { var parentStateRef = dynamicScope.get('outletState'); var currentStateRef = definition.ref; dynamicScope.set('outletState', currentStateRef); @@ -5804,7 +6473,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim bucket: state.outlet, type: 'outlet', name: state.outlet.name, - args: _runtime2.EMPTY_ARGS, + args: _runtime.EMPTY_ARGS, instance: undefined, template: undefined }); @@ -5815,7 +6484,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim bucket: state.engineBucket, type: 'engine', name: state.engineBucket.mountPoint, - args: _runtime2.EMPTY_ARGS, + args: _runtime.EMPTY_ARGS, instance: state.engine, template: undefined }); @@ -5827,20 +6496,13 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim name: definition.name, args: args, instance: definition.controller, - template: definition.template + template: (0, _util.unwrapTemplate)(definition.template).moduleName }); return nodes; } - getStaticLayout({ - template - }) { - // The router has already resolved the template - return template; - } - getCapabilities() { - return CAPABILITIES; + return CAPABILITIES$1; } getSelf({ @@ -5849,10 +6511,16 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return self; } + didCreate() {} + + didUpdate() {} + didRenderLayout(state) { state.finalize(); } + didUpdateLayout() {} + getDestroyable() { return null; } @@ -5864,14 +6532,20 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim class OutletComponentDefinition { constructor(state, manager = OUTLET_MANAGER) { this.state = state; - this.manager = manager; + this.manager = manager; // handle is not used by this custom definition + + this.handle = -1; + var capabilities = manager.getCapabilities(); + this.capabilities = (0, _manager2.capabilityFlagsFrom)(capabilities); + this.compilable = capabilities.wrapped ? (0, _util.unwrapTemplate)(state.template).asWrappedLayout() : (0, _util.unwrapTemplate)(state.template).asLayout(); + this.resolvedName = state.name; } } function createRootOutlet(outletView) { if (_environment2.ENV._APPLICATION_TEMPLATE_WRAPPER) { - var WRAPPED_CAPABILITIES = (0, _polyfills.assign)({}, CAPABILITIES, { + var WRAPPED_CAPABILITIES = (0, _polyfills.assign)({}, CAPABILITIES$1, { dynamicTag: true, elementHook: true, wrapped: true @@ -5881,13 +6555,6 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return 'div'; } - getStaticLayout({ - template - }) { - // The router has already resolved the template - return template; - } - getCapabilities() { return WRAPPED_CAPABILITIES; } @@ -5906,1184 +6573,28 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } } - function NOOP() {} - /** - @module ember - */ - - /** - Represents the internal state of the component. - - @class ComponentStateBucket - @private - */ - - - class ComponentStateBucket { - constructor(environment, component, args, argsTag, finalizer, hasWrappedElement) { - this.environment = environment; - this.component = component; - this.args = args; - this.argsTag = argsTag; - this.finalizer = finalizer; - this.hasWrappedElement = hasWrappedElement; - this.classRef = null; - this.classRef = null; - this.argsRevision = args === null ? 0 : (0, _validator.valueForTag)(argsTag); - this.rootRef = (0, _reference.createConstRef)(component, 'this'); - (0, _runtime2.registerDestructor)(this, () => this.willDestroy(), true); - (0, _runtime2.registerDestructor)(this, () => this.component.destroy()); - } - - willDestroy() { - var { - component, - environment - } = this; - - if (environment.isInteractive) { - (0, _validator.beginUntrackFrame)(); - component.trigger('willDestroyElement'); - component.trigger('willClearRender'); - (0, _validator.endUntrackFrame)(); - var element = (0, _views.getViewElement)(component); - - if (element) { - (0, _views.clearElementView)(element); - (0, _views.clearViewElement)(component); - } - } - - component.renderer.unregister(component); - } - - finalize() { - var { - finalizer - } = this; - finalizer(); - this.finalizer = NOOP; - } - - } - - function isTemplateFactory(template) { - return typeof template === 'function'; - } - - function referenceForParts(rootRef, parts) { - var isAttrs = parts[0] === 'attrs'; // TODO deprecate this - - if (isAttrs) { - parts.shift(); - - if (parts.length === 1) { - return (0, _reference.childRefFor)(rootRef, parts[0]); - } - } - - return (0, _reference.childRefFromParts)(rootRef, parts); - } - - function parseAttributeBinding(microsyntax) { - var colonIndex = microsyntax.indexOf(':'); - - if (colonIndex === -1) { - (true && !(microsyntax !== 'class') && (0, _debug.assert)('You cannot use class as an attributeBinding, use classNameBindings instead.', microsyntax !== 'class')); - return [microsyntax, microsyntax, true]; - } else { - var prop = microsyntax.substring(0, colonIndex); - var attribute = microsyntax.substring(colonIndex + 1); - (true && !(attribute !== 'class') && (0, _debug.assert)('You cannot use class as an attributeBinding, use classNameBindings instead.', attribute !== 'class')); - return [prop, attribute, false]; - } - } - - function installAttributeBinding(component, rootRef, parsed, operations) { - var [prop, attribute, isSimple] = parsed; - - if (attribute === 'id') { - var elementId = (0, _metal.get)(component, prop); - - if (elementId === undefined || elementId === null) { - elementId = component.elementId; - } - - elementId = (0, _reference.createPrimitiveRef)(elementId); - operations.setAttribute('id', elementId, true, null); - return; - } - - var isPath = prop.indexOf('.') > -1; - var reference = isPath ? referenceForParts(rootRef, prop.split('.')) : (0, _reference.childRefFor)(rootRef, prop); - (true && !(!(isSimple && isPath)) && (0, _debug.assert)(`Illegal attributeBinding: '${prop}' is not a valid attribute name.`, !(isSimple && isPath))); - - if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE && attribute === 'style' && createStyleBindingRef !== undefined) { - reference = createStyleBindingRef(reference, (0, _reference.childRefFor)(rootRef, 'isVisible')); - } - - operations.setAttribute(attribute, reference, false, null); - } - - var DISPLAY_NONE = 'display: none;'; - var SAFE_DISPLAY_NONE = htmlSafe(DISPLAY_NONE); - var createStyleBindingRef; - var installIsVisibleBinding; - - if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE) { - createStyleBindingRef = (inner, isVisibleRef) => { - return (0, _reference.createComputeRef)(() => { - var value = (0, _reference.valueForRef)(inner); - var isVisible = (0, _reference.valueForRef)(isVisibleRef); - - if (true - /* DEBUG */ - && isVisible !== undefined) { - (true && !(false) && (0, _debug.deprecate)(`The \`isVisible\` property on classic component classes is deprecated. Was accessed:\n\n${(0, _validator.logTrackingStack)()}`, false, { - id: 'ember-component.is-visible', - until: '4.0.0', - url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-is-visible', - for: 'ember-source', - since: { - enabled: '3.15.0-beta.1' - } - })); - } - - if (isVisible !== false) { - return value; - } else if (!value) { - return SAFE_DISPLAY_NONE; - } else { - var style = value + ' ' + DISPLAY_NONE; - return isHTMLSafe(value) ? htmlSafe(style) : style; - } - }); - }; - - installIsVisibleBinding = (rootRef, operations) => { - operations.setAttribute('style', createStyleBindingRef(_reference.UNDEFINED_REFERENCE, (0, _reference.childRefFor)(rootRef, 'isVisible')), false, null); - }; - } - - function createClassNameBindingRef(rootRef, microsyntax, operations) { - var [prop, truthy, falsy] = microsyntax.split(':'); - var isStatic = prop === ''; - - if (isStatic) { - operations.setAttribute('class', (0, _reference.createPrimitiveRef)(truthy), true, null); - } else { - var isPath = prop.indexOf('.') > -1; - var parts = isPath ? prop.split('.') : []; - var value = isPath ? referenceForParts(rootRef, parts) : (0, _reference.childRefFor)(rootRef, prop); - var ref; - - if (truthy === undefined) { - ref = createSimpleClassNameBindingRef(value, isPath ? parts[parts.length - 1] : prop); - } else { - ref = createColonClassNameBindingRef(value, truthy, falsy); - } - - operations.setAttribute('class', ref, false, null); - } - } - - function createSimpleClassNameBindingRef(inner, path) { - var dasherizedPath; - return (0, _reference.createComputeRef)(() => { - var value = (0, _reference.valueForRef)(inner); - - if (value === true) { - (true && !(path !== undefined) && (0, _debug.assert)('You must pass a path when binding a to a class name using classNameBindings', path !== undefined)); - return dasherizedPath || (dasherizedPath = (0, _string.dasherize)(path)); - } else if (value || value === 0) { - return String(value); - } else { - return null; - } - }); - } - - function createColonClassNameBindingRef(inner, truthy, falsy) { - return (0, _reference.createComputeRef)(() => { - return (0, _reference.valueForRef)(inner) ? truthy : falsy; - }); - } - /** - @module ember - */ - - - var ACTIONS = new _util._WeakSet(); - var INVOKE = (0, _utils.symbol)('INVOKE'); - /** - The `{{action}}` helper provides a way to pass triggers for behavior (usually - just a function) between components, and into components from controllers. - - ### Passing functions with the action helper - - 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 }} -
    - {{! Examples of Handlebars value context }} - {{input on-input=(action "save")}} - {{yield (action "refreshData") andAnotherParam}} - ``` - - In these contexts, - the helper is called a "closure action" helper. Its 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 immediately 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, in the attribute context: - - ```handlebars - {{! An example of attribute context }} -
    - ``` - - The resulting template render logic would be: - - ```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 and still execute in the correct context. - - Here is an example action handler on a component: - - ```app/components/my-component.js - import Component from '@glimmer/component'; - import { action } from '@ember/object'; - - export default class extends Component { - @action - save() { - this.model.save(); - } - } - ``` - - 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`. - 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 targeting 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](/ember/release/classes/Component/methods/sendAction?anchor=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: - - ```app/components/update-name.js - import Component from '@glimmer/component'; - import { action } from '@ember/object'; - - export default class extends Component { - @action - setName(model, name) { - model.set('name', name); - } - } - ``` - - ```app/components/update-name.hbs - {{input on-input=(action (action 'setName' @model) value="target.value")}} - ``` - - The first argument (`@model`) was curried over, and the run-time argument (`event`) - becomes a second argument. Action calls can be nested this way because each simply - returns a function. Any function can be passed to the `{{action}}` helper, including - other actions. - - Actions invoked with `sendAction` have the same currying behavior as demonstrated - with `on-input` above. For example: - - ```app/components/my-input.js - import Component from '@glimmer/component'; - import { action } from '@ember/object'; - - export default class extends Component { - @action - setName(model, name) { - model.set('name', name); - } - } - ``` - - ```handlebars - - ``` - - or - - ```handlebars - {{my-input submit=(action 'setName' @model)}} - ``` - - ```app/components/my-component.js - import Component from '@ember/component'; - - export default Component.extend({ - click() { - // Note that model is not passed, it was curried in the template - this.sendAction('submit', 'bob'); - } - }); - ``` - - ### Attaching actions to DOM elements - - The third context of the `{{action}}` helper can be called "element space". - For example: - - ```handlebars - {{! An example of element space }} -
    - ``` - - Used this way, the `{{action}}` helper provides a useful shortcut for - registering an HTML element in 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. Note - that the closure style actions cannot. - - 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: - - ```handlebars -
    - - -
    - ``` - - To disable bubbling, pass `bubbles=false` to the helper: - - ```handlebars - - ``` - - To disable bubbling with closure style actions you must create your own - wrapper helper that makes use of `event.stopPropagation()`: - - ```handlebars -
    Hello
    - ``` - - ```app/helpers/disable-bubbling.js - import { helper } from '@ember/component/helper'; - - export function disableBubbling([action]) { - return function(event) { - event.stopPropagation(); - return action(event); - }; - } - export default helper(disableBubbling); - ``` - - If you need the default handler to trigger you should either register your - own event handler, or use event methods on your view class. See - ["Responding to Browser Events"](/ember/release/classes/Component) - in the documentation for `Component` 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 -
    - click me -
    - ``` - - See ["Event Names"](/ember/release/classes/Component) 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 events with pressed modifier - keys. You can supply an `allowedKeys` option to specify which keys should not be ignored. - - ```handlebars -
    - click me -
    - ``` - - This way the action will fire when clicking with the alt key pressed down. - Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys. - - ```handlebars -
    - click me with any key pressed -
    - ``` - - ### Specifying a Target - - 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: - - ```app/templates/application.hbs -
    - click me -
    - ``` - - ```app/controllers/application.js - import Controller from '@ember/controller'; - import { inject as service } from '@ember/service'; - - export default class extends Controller { - @service someService; - } - ``` - - @method action - @for Ember.Templates.helpers - @public - */ - - _exports.INVOKE = INVOKE; - - function action(args) { - var { - named, - positional - } = args; - var capturedArgs = positional.capture(); // The first two argument slots are reserved. - // pos[0] is the context (or `this`) - // pos[1] is the action name or function - // Anything else is an action argument. - - var [context, action, ...restArgs] = capturedArgs; - var debugKey = action.debugLabel; - var target = named.has('target') ? named.get('target') : context; - var processArgs = makeArgsProcessor(named.has('value') && named.get('value'), restArgs); - var fn; - - if ((0, _reference.isInvokableRef)(action)) { - fn = makeClosureAction(action, action, invokeRef, processArgs, debugKey); - } else { - fn = makeDynamicClosureAction((0, _reference.valueForRef)(context), target, action, processArgs, debugKey); - } - - ACTIONS.add(fn); - return (0, _reference.createUnboundRef)(fn, '(result of an `action` helper)'); - } - - function NOOP$1(args) { - return args; - } - - function makeArgsProcessor(valuePathRef, actionArgsRef) { - var mergeArgs; - - if (actionArgsRef.length > 0) { - mergeArgs = args => { - return actionArgsRef.map(_reference.valueForRef).concat(args); - }; - } - - var readValue; - - if (valuePathRef) { - readValue = args => { - var valuePath = (0, _reference.valueForRef)(valuePathRef); - - if (valuePath && args.length > 0) { - args[0] = (0, _metal.get)(args[0], valuePath); - } - - return args; - }; - } - - if (mergeArgs && readValue) { - return args => { - return readValue(mergeArgs(args)); - }; - } else { - return mergeArgs || readValue || NOOP$1; - } - } - - function makeDynamicClosureAction(context, targetRef, actionRef, processArgs, debugKey) { - // We don't allow undefined/null values, so this creates a throw-away action to trigger the assertions - if (true - /* DEBUG */ - ) { - makeClosureAction(context, (0, _reference.valueForRef)(targetRef), (0, _reference.valueForRef)(actionRef), processArgs, debugKey); - } - - return (...args) => { - return makeClosureAction(context, (0, _reference.valueForRef)(targetRef), (0, _reference.valueForRef)(actionRef), processArgs, debugKey)(...args); - }; - } - - function makeClosureAction(context, target, action, processArgs, debugKey) { - var self; - var fn; - (true && !(action !== undefined && action !== null) && (0, _debug.assert)(`Action passed is null or undefined in (action) from ${target}.`, action !== undefined && action !== null)); - - if (typeof action[INVOKE] === 'function') { - (true && !(false) && (0, _debug.deprecate)(`Usage of the private INVOKE API to make an object callable via action or fn is no longer supported. Please update to pass in a callback function instead. Received: ${String(action)}`, false, { - until: '3.25.0', - id: 'actions.custom-invoke-invokable', - for: 'ember-source', - since: { - enabled: '3.23.0-beta.1' - } - })); - self = action; - fn = action[INVOKE]; - } else { - var typeofAction = typeof action; - - if (typeofAction === 'string') { - self = target; - fn = target.actions && target.actions[action]; - (true && !(Boolean(fn)) && (0, _debug.assert)(`An action named '${action}' was not found in ${target}`, Boolean(fn))); - } else if (typeofAction === 'function') { - self = context; - fn = action; - } else { - // tslint:disable-next-line:max-line-length - (true && !(false) && (0, _debug.assert)(`An action could not be made for \`${debugKey || action}\` in ${target}. Please confirm that you are using either a quoted action name (i.e. \`(action '${debugKey || 'myAction'}')\`) or a function available in ${target}.`, false)); - } - } - - return (...args) => { - var payload = { - target: self, - args, - label: '@glimmer/closure-action' - }; - return (0, _instrumentation.flaggedInstrument)('interaction.ember-action', payload, () => { - return (0, _runloop.join)(self, fn, ...processArgs(args)); - }); - }; - } // The code above: - // 1. Finds an action function, usually on the `actions` hash - // 2. Calls it with the target as the correct `this` context - // Previously, `UPDATE_REFERENCED_VALUE` was a method on the reference itself, - // so this made a bit more sense. Now, it isn't, and so we need to create a - // function that can have `this` bound to it when called. This allows us to use - // the same codepath to call `updateRef` on the reference. - - - function invokeRef(value) { - (0, _reference.updateRef)(this, value); - } // inputs needed by CurlyComponents (attrs and props, with mutable - // cells, etc). - - - function processComponentArgs(namedArgs) { - var attrs = Object.create(null); - var props = Object.create(null); - props[ARGS] = namedArgs; - - for (var name in namedArgs) { - var ref = namedArgs[name]; - var value = (0, _reference.valueForRef)(ref); - var isAction = typeof value === 'function' && ACTIONS.has(value); - - if ((0, _reference.isUpdatableRef)(ref) && !isAction) { - attrs[name] = new MutableCell(ref, value); - } else { - attrs[name] = value; - } - - props[name] = value; - } - - props.attrs = attrs; - return props; - } - - var REF = (0, _utils.symbol)('REF'); - - class MutableCell { - constructor(ref, value) { - this[_views.MUTABLE_CELL] = true; - this[REF] = ref; - this.value = value; - } - - update(val) { - (0, _reference.updateRef)(this[REF], val); - } - - } - - var __rest = undefined && undefined.__rest || function (s, e) { - var t = {}; - - for (var p in s) { - if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - } - - if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; - } - return t; - }; - - var EMBER_VIEW_REF = (0, _reference.createPrimitiveRef)('ember-view'); - - function aliasIdToElementId(args, props) { - if (args.named.has('id')) { - // tslint:disable-next-line:max-line-length - (true && !(!args.named.has('elementId')) && (0, _debug.assert)(`You cannot invoke a component with both 'id' and 'elementId' at the same time.`, !args.named.has('elementId'))); - props.elementId = props.id; - } - } // We must traverse the attributeBindings in reverse keeping track of - // what has already been applied. This is essentially refining the concatenated - // properties applying right to left. - - - function applyAttributeBindings(attributeBindings, component, rootRef, operations) { - var seen = []; - var i = attributeBindings.length - 1; - - while (i !== -1) { - var binding = attributeBindings[i]; - var parsed = parseAttributeBinding(binding); - var attribute = parsed[1]; - - if (seen.indexOf(attribute) === -1) { - seen.push(attribute); - installAttributeBinding(component, rootRef, parsed, operations); - } - - i--; - } - - if (seen.indexOf('id') === -1) { - var id = component.elementId ? component.elementId : (0, _utils.guidFor)(component); - operations.setAttribute('id', (0, _reference.createPrimitiveRef)(id), false, null); - } - - if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE && installIsVisibleBinding !== undefined && seen.indexOf('style') === -1) { - installIsVisibleBinding(rootRef, operations); - } - } - - var DEFAULT_LAYOUT = (0, _container.privatize)`template:components/-default`; - var EMPTY_POSITIONAL_ARGS = []; - (0, _debug.debugFreeze)(EMPTY_POSITIONAL_ARGS); - - class CurlyComponentManager extends _runtime2.BaseInternalComponentManager { - templateFor(component) { - var { - layout, - layoutName - } = component; - var owner = (0, _owner.getOwner)(component); - var factory; - - if (layout === undefined) { - if (layoutName !== undefined) { - var _factory = owner.lookup(`template:${layoutName}`); - - (true && !(_factory !== undefined) && (0, _debug.assert)(`Layout \`${layoutName}\` not found!`, _factory !== undefined)); - factory = _factory; - } else { - factory = owner.lookup(DEFAULT_LAYOUT); - } - } else if (isTemplateFactory(layout)) { - factory = layout; - } else { - // we were provided an instance already - return layout; - } - - return factory(owner); - } - - getDynamicLayout(bucket) { - return this.templateFor(bucket.component); - } - - getTagName(state) { - var { - component, - hasWrappedElement - } = state; - - if (!hasWrappedElement) { - return null; - } - - return component && component.tagName || 'div'; - } - - getCapabilities(state) { - return state.capabilities; - } - - prepareArgs(state, args) { - if (args.named.has('__ARGS__')) { - var _a = args.named.capture(), - { - __ARGS__ - } = _a, - rest = __rest(_a, ["__ARGS__"]); - - var prepared = { - positional: EMPTY_POSITIONAL_ARGS, - named: (0, _polyfills.assign)((0, _polyfills.assign)({}, rest), (0, _reference.valueForRef)(__ARGS__)) - }; - return prepared; - } - - var { - positionalParams - } = state.ComponentClass.class; // early exits - - if (positionalParams === undefined || positionalParams === null || args.positional.length === 0) { - return null; - } - - var named; - - if (typeof positionalParams === 'string') { - (true && !(!args.named.has(positionalParams)) && (0, _debug.assert)(`You cannot specify positional parameters and the hash argument \`${positionalParams}\`.`, !args.named.has(positionalParams))); - var captured = args.positional.capture(); - named = { - [positionalParams]: (0, _reference.createComputeRef)(() => (0, _runtime2.reifyPositional)(captured)) - }; - (0, _polyfills.assign)(named, args.named.capture()); - } else if (Array.isArray(positionalParams) && positionalParams.length > 0) { - var count = Math.min(positionalParams.length, args.positional.length); - named = {}; - (0, _polyfills.assign)(named, args.named.capture()); - - for (var i = 0; i < count; i++) { - // As of TS 3.7, tsc is giving us the following error on this line without the type annotation - // - // TS7022: 'name' implicitly has type 'any' because it does not have a type annotation and is - // referenced directly or indirectly in its own initializer. - // - // This is almost certainly a TypeScript bug, feel free to try and remove the annotation after - // upgrading if it is not needed anymore. - var name = positionalParams[i]; - (true && !(!args.named.has(name)) && (0, _debug.assert)(`You cannot specify both a positional param (at position ${i}) and the hash argument \`${name}\`.`, !args.named.has(name))); - named[name] = args.positional.at(i); - } - } else { - return null; - } - - return { - positional: _util.EMPTY_ARRAY, - named - }; - } - /* - * This hook is responsible for actually instantiating the component instance. - * It also is where we perform additional bookkeeping to support legacy - * features like exposed by view mixins like ChildViewSupport, ActionSupport, - * etc. - */ - - - create(environment, state, args, dynamicScope, callerSelfRef, hasBlock) { - // Get the nearest concrete component instance from the scope. "Virtual" - // components will be skipped. - var parentView = dynamicScope.view; // Get the Ember.Component subclass to instantiate for this component. - - var factory = state.ComponentClass; // Capture the arguments, which tells Glimmer to give us our own, stable - // copy of the Arguments object that is safe to hold on to between renders. - - var capturedArgs = args.named.capture(); - (0, _validator.beginTrackFrame)(); - var props = processComponentArgs(capturedArgs); - var argsTag = (0, _validator.endTrackFrame)(); // Alias `id` argument to `elementId` property on the component instance. - - aliasIdToElementId(args, props); // Set component instance's parentView property to point to nearest concrete - // component. - - props.parentView = parentView; // Set whether this component was invoked with a block - // (`{{#my-component}}{{/my-component}}`) or without one - // (`{{my-component}}`). - - props[HAS_BLOCK] = hasBlock; // Save the current `this` context of the template as the component's - // `_target`, so bubbled actions are routed to the right place. - - props._target = (0, _reference.valueForRef)(callerSelfRef); // static layout asserts CurriedDefinition - - if (state.template) { - props.layout = state.template; - } // caller: - // - // - // callee: - // - // Now that we've built up all of the properties to set on the component instance, - // actually create it. - - - (0, _validator.beginUntrackFrame)(); - var component = factory.create(props); - var finalizer = (0, _instrumentation._instrumentStart)('render.component', initialRenderInstrumentDetails, component); // We become the new parentView for downstream components, so save our - // component off on the dynamic scope. - - dynamicScope.view = component; // Unless we're the root component, we need to add ourselves to our parent - // component's childViews array. - - if (parentView !== null && parentView !== undefined) { - (0, _views.addChildView)(parentView, component); - } - - component.trigger('didReceiveAttrs'); - var hasWrappedElement = component.tagName !== ''; // We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components - - if (!hasWrappedElement) { - if (environment.isInteractive) { - component.trigger('willRender'); - } - - component._transitionTo('hasElement'); - - if (environment.isInteractive) { - component.trigger('willInsertElement'); - } - } // Track additional lifecycle metadata about this component in a state bucket. - // Essentially we're saving off all the state we'll need in the future. - - - var bucket = new ComponentStateBucket(environment, component, capturedArgs, argsTag, finalizer, hasWrappedElement); - - if (args.named.has('class')) { - bucket.classRef = args.named.get('class'); - } - - if (true - /* DEBUG */ - ) { - processComponentInitializationAssertions(component, props); - } - - if (environment.isInteractive && hasWrappedElement) { - component.trigger('willRender'); - } - - (0, _validator.endUntrackFrame)(); // consume every argument so we always run again - - (0, _validator.consumeTag)(bucket.argsTag); - (0, _validator.consumeTag)(component[DIRTY_TAG]); - return bucket; - } - - getDebugName({ - name - }) { - return name; - } - - getSelf({ - rootRef - }) { - return rootRef; - } - - didCreateElement({ - component, - classRef, - environment, - rootRef - }, element, operations) { - (0, _views.setViewElement)(component, element); - (0, _views.setElementView)(element, component); - var { - attributeBindings, - classNames, - classNameBindings - } = component; - - if (attributeBindings && attributeBindings.length) { - applyAttributeBindings(attributeBindings, component, rootRef, operations); - } else { - var id = component.elementId ? component.elementId : (0, _utils.guidFor)(component); - operations.setAttribute('id', (0, _reference.createPrimitiveRef)(id), false, null); - - if (_deprecatedFeatures.EMBER_COMPONENT_IS_VISIBLE) { - installIsVisibleBinding(rootRef, operations); - } - } - - if (classRef) { - var ref = createSimpleClassNameBindingRef(classRef); - operations.setAttribute('class', ref, false, null); - } - - if (classNames && classNames.length) { - classNames.forEach(name => { - operations.setAttribute('class', (0, _reference.createPrimitiveRef)(name), false, null); - }); - } - - if (classNameBindings && classNameBindings.length) { - classNameBindings.forEach(binding => { - createClassNameBindingRef(rootRef, binding, operations); - }); - } - - operations.setAttribute('class', EMBER_VIEW_REF, false, null); - - if ('ariaRole' in component) { - operations.setAttribute('role', (0, _reference.childRefFor)(rootRef, 'ariaRole'), false, null); - } - - component._transitionTo('hasElement'); - - if (environment.isInteractive) { - (0, _validator.beginUntrackFrame)(); - component.trigger('willInsertElement'); - (0, _validator.endUntrackFrame)(); - } - } - - didRenderLayout(bucket, bounds) { - bucket.component[BOUNDS] = bounds; - bucket.finalize(); - } - - didCreate({ - component, - environment - }) { - if (environment.isInteractive) { - component._transitionTo('inDOM'); - - component.trigger('didInsertElement'); - component.trigger('didRender'); - } - } - - update(bucket) { - var { - component, - args, - argsTag, - argsRevision, - environment - } = bucket; - bucket.finalizer = (0, _instrumentation._instrumentStart)('render.component', rerenderInstrumentDetails, component); - (0, _validator.beginUntrackFrame)(); - - if (args !== null && !(0, _validator.validateTag)(argsTag, argsRevision)) { - (0, _validator.beginTrackFrame)(); - var props = processComponentArgs(args); - argsTag = bucket.argsTag = (0, _validator.endTrackFrame)(); - bucket.argsRevision = (0, _validator.valueForTag)(argsTag); - component[IS_DISPATCHING_ATTRS] = true; - component.setProperties(props); - component[IS_DISPATCHING_ATTRS] = false; - component.trigger('didUpdateAttrs'); - component.trigger('didReceiveAttrs'); - } - - if (environment.isInteractive) { - component.trigger('willUpdate'); - component.trigger('willRender'); - } - - (0, _validator.endUntrackFrame)(); - (0, _validator.consumeTag)(argsTag); - (0, _validator.consumeTag)(component[DIRTY_TAG]); - } - - didUpdateLayout(bucket) { - bucket.finalize(); - } - - didUpdate({ - component, - environment - }) { - if (environment.isInteractive) { - component.trigger('didUpdate'); - component.trigger('didRender'); - } - } - - getDestroyable(bucket) { - return bucket; - } - - } - - function processComponentInitializationAssertions(component, props) { - (true && !((() => { - var { - classNameBindings - } = component; - - for (var i = 0; i < classNameBindings.length; i++) { - var binding = classNameBindings[i]; - - if (typeof binding !== 'string' || binding.length === 0) { - return false; - } - } - - return true; - })()) && (0, _debug.assert)(`classNameBindings must be non-empty strings: ${component}`, (() => { - var { - classNameBindings - } = component; - - for (var i = 0; i < classNameBindings.length; i++) { - var binding = classNameBindings[i]; - - if (typeof binding !== 'string' || binding.length === 0) { - return false; - } - } - - return true; - })())); - (true && !((() => { - var { - classNameBindings - } = component; - - for (var i = 0; i < classNameBindings.length; i++) { - var binding = classNameBindings[i]; - - if (binding.split(' ').length > 1) { - return false; - } - } - - return true; - })()) && (0, _debug.assert)(`classNameBindings must not have spaces in them: ${component}`, (() => { - var { - classNameBindings - } = component; - - for (var i = 0; i < classNameBindings.length; i++) { - var binding = classNameBindings[i]; - - if (binding.split(' ').length > 1) { - return false; - } - } - - return true; - })())); - (true && !(component.tagName !== '' || !component.classNameBindings || component.classNameBindings.length === 0) && (0, _debug.assert)(`You cannot use \`classNameBindings\` on a tag-less component: ${component}`, component.tagName !== '' || !component.classNameBindings || component.classNameBindings.length === 0)); - (true && !(component.tagName !== '' || props.id === component.elementId || !component.elementId && component.elementId !== '') && (0, _debug.assert)(`You cannot use \`elementId\` on a tag-less component: ${component}`, component.tagName !== '' || props.id === component.elementId || !component.elementId && component.elementId !== '')); - (true && !(component.tagName !== '' || !component.attributeBindings || component.attributeBindings.length === 0) && (0, _debug.assert)(`You cannot use \`attributeBindings\` on a tag-less component: ${component}`, component.tagName !== '' || !component.attributeBindings || component.attributeBindings.length === 0)); - } - - function initialRenderInstrumentDetails(component) { - return component.instrumentDetails({ - initialRender: true - }); - } - - function rerenderInstrumentDetails(component) { - return component.instrumentDetails({ - initialRender: false - }); - } - - var CURLY_CAPABILITIES = { - dynamicLayout: true, - dynamicTag: true, - prepareArgs: true, - createArgs: true, - attributeHook: true, - elementHook: true, - createCaller: true, - dynamicScope: true, - updateHook: true, - createInstance: true, - wrapped: true, - willDestroy: true - }; - var CURLY_COMPONENT_MANAGER = new CurlyComponentManager(); - - class CurlyComponentDefinition { - constructor(name, ComponentClass, template, args) { - this.name = name; - this.ComponentClass = ComponentClass; - this.template = template; - this.args = args; - this.manager = CURLY_COMPONENT_MANAGER; - this.state = { - name, - ComponentClass, - template, - capabilities: CURLY_CAPABILITIES - }; - } - - } - class RootComponentManager extends CurlyComponentManager { constructor(component) { super(); this.component = component; } - getStaticLayout() { - return this.templateFor(this.component); - } - - create(environment, _state, _args, dynamicScope) { + create(_owner, _state, _args, { + isInteractive + }, dynamicScope) { var component = this.component; var finalizer = (0, _instrumentation._instrumentStart)('render.component', initialRenderInstrumentDetails, component); dynamicScope.view = component; var hasWrappedElement = component.tagName !== ''; // We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components if (!hasWrappedElement) { - if (environment.isInteractive) { + if (isInteractive) { component.trigger('willRender'); } component._transitionTo('hasElement'); - if (environment.isInteractive) { + if (isInteractive) { component.trigger('willInsertElement'); } } @@ -7094,7 +6605,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim processComponentInitializationAssertions(component, {}); } - var bucket = new ComponentStateBucket(environment, component, null, _validator.CONSTANT_TAG, finalizer, hasWrappedElement); + var bucket = new ComponentStateBucket(component, null, _validator.CONSTANT_TAG, finalizer, hasWrappedElement, isInteractive); (0, _validator.consumeTag)(component[DIRTY_TAG]); return bucket; } @@ -7104,7 +6615,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim var ROOT_CAPABILITIES = { - dynamicLayout: false, + dynamicLayout: true, dynamicTag: true, prepareArgs: false, createArgs: false, @@ -7115,20 +6626,19 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim updateHook: true, createInstance: true, wrapped: true, - willDestroy: false + willDestroy: false, + hasSubOwner: false }; class RootComponentDefinition { constructor(component) { - this.component = component; - var manager = new RootComponentManager(component); - this.manager = manager; - var factory = (0, _container.getFactoryFor)(component); - this.state = { - name: factory.fullName.slice(10), - capabilities: ROOT_CAPABILITIES, - ComponentClass: factory - }; + // handle is not used by this custom definition + this.handle = -1; + this.resolvedName = '-top-level'; + this.capabilities = (0, _manager2.capabilityFlagsFrom)(ROOT_CAPABILITIES); + this.compilable = null; + this.manager = new RootComponentManager(component); + this.state = (0, _container.getFactoryFor)(component); } } @@ -7291,7 +6801,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } - function eachIn(args) { + var eachIn = internalHelper(args => { var inner = args.positional.at(0); return (0, _reference.createComputeRef)(() => { var iterable = (0, _reference.valueForRef)(inner); @@ -7300,12 +6810,12 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim if ((0, _utils.isProxy)(iterable)) { // this is because the each-in doesn't actually get(proxy, 'key') but bypasses it // and the proxy's tag is lazy updated on access - iterable = (0, _runtime._contentFor)(iterable); + iterable = (0, _runtime2._contentFor)(iterable); } return new EachInWrapper(iterable); }); - } + }); function toIterator(iterable) { if (iterable instanceof EachInWrapper) { @@ -7385,9 +6895,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } class ArrayIterator extends BoundedIterator { - constructor(array) { - super(array.length); - this.array = array; + constructor(array$$1) { + super(array$$1.length); + this.array = array$$1; } static from(iterable) { @@ -7395,9 +6905,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } static fromForEachable(object) { - var array = []; - object.forEach(item => array.push(item)); - return this.from(array); + var array$$1 = []; + object.forEach(item => array$$1.push(item)); + return this.from(array$$1); } valueFor(position) { @@ -7407,9 +6917,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } class EmberArrayIterator extends BoundedIterator { - constructor(array) { - super(array.length); - this.array = array; + constructor(array$$1) { + super(array$$1.length); + this.array = array$$1; } static from(iterable) { @@ -7579,13 +7089,15 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return value !== null && (typeof value === 'object' || typeof value === 'function'); } - function toBool$1(predicate) { + function toBool(predicate) { if ((0, _utils.isProxy)(predicate)) { (0, _validator.consumeTag)((0, _metal.tagForProperty)(predicate, 'content')); return Boolean((0, _metal.get)(predicate, 'isTruthy')); - } else if ((0, _runtime.isArray)(predicate)) { + } else if ((0, _runtime2.isArray)(predicate)) { (0, _validator.consumeTag)((0, _metal.tagForProperty)(predicate, '[]')); return predicate.length !== 0; + } else if ((0, _glimmer.isHTMLSafe)(predicate)) { + return Boolean(predicate.toString()); } else { return Boolean(predicate); } @@ -7597,11 +7109,12 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim _runloop.backburner.ensureInstance(); }, - toBool: toBool$1, + toBool, toIterator, getProp: _metal._getProp, - setProp: _metal.set, + setProp: _metal._setProp, getPath: _metal.get, + setPath: _metal.set, scheduleDestroy(destroyable, destructor) { (0, _runloop.schedule)('actions', null, destructor, destroyable); @@ -7613,7 +7126,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim warnIfStyleNotTrusted(value) { (true && (0, _debug.warn)((0, _views.constructStyleDeprecationMessage)(value), (() => { - if (value === null || value === undefined || isHTMLSafe(value)) { + if (value === null || value === undefined || isHTMLSafe$1(value)) { return true; } @@ -7621,6 +7134,36 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim })(), { id: 'ember-htmlbars.style-xss-warning' })); + }, + + assert(test, msg, options) { + var _a; + + if (true + /* DEBUG */ + ) { + var id = options === null || options === void 0 ? void 0 : options.id; + var override = VM_ASSERTION_OVERRIDES.filter(o => o.id === id)[0]; + (true && !(test) && (0, _debug.assert)((_a = override === null || override === void 0 ? void 0 : override.message) !== null && _a !== void 0 ? _a : msg, test)); + } + }, + + deprecate(msg, test, options) { + var _a; + + if (true + /* DEBUG */ + ) { + var { + id + } = options; + var override = VM_DEPRECATION_OVERRIDES.filter(o => o.id === id)[0]; + if (!override) throw new Error(`deprecation override for ${id} not found`); // allow deprecations to be disabled in the VM_DEPRECATION_OVERRIDES array below + + if (!override.disabled) { + (true && !(Boolean(test)) && (0, _debug.deprecate)((_a = override.message) !== null && _a !== void 0 ? _a : msg, Boolean(test), override)); + } + } } }); @@ -7628,32 +7171,37 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim if (true /* DEBUG */ ) { - (0, _validator.setTrackingTransactionEnv)({ - assert(message) { - (true && !(false) && (0, _debug.assert)(message, false)); - }, - - deprecate(message) { - (true && !(false) && (0, _debug.deprecate)(message, false, { - id: 'autotracking.mutation-after-consumption', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.21.0' - } - })); - }, - + _validator.setTrackingTransactionEnv === null || _validator.setTrackingTransactionEnv === void 0 ? void 0 : (0, _validator.setTrackingTransactionEnv)({ debugMessage(obj, keyName) { - var dirtyString = keyName ? `\`${keyName}\` on \`${(0, _utils.getDebugName)(obj)}\`` : `\`${(0, _utils.getDebugName)(obj)}\``; + var dirtyString = keyName ? `\`${keyName}\` on \`${_utils.getDebugName === null || _utils.getDebugName === void 0 ? void 0 : (0, _utils.getDebugName)(obj)}\`` : `\`${_utils.getDebugName === null || _utils.getDebugName === void 0 ? void 0 : (0, _utils.getDebugName)(obj)}\``; return `You attempted to update ${dirtyString}, but it had already been used previously in the same computation. Attempting to update a value after using it in a computation can cause logical errors, infinite revalidation bugs, and performance issues, and is not supported.`; } }); } /////////// - // Define environment delegate + // VM Assertion/Deprecation overrides + var VM_DEPRECATION_OVERRIDES = [{ + id: 'autotracking.mutation-after-consumption', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.21.0' + } + }, { + id: 'this-property-fallback', + disabled: true, + url: 'https://deprecations.emberjs.com/v3.x#toc_this-property-fallback', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.26.0' + } + }]; + var VM_ASSERTION_OVERRIDES = []; /////////// + // Define environment delegate + class EmberEnvironmentDelegate { constructor(owner, isInteractive) { this.owner = owner; @@ -7665,354 +7213,12 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } - var CAPABILITIES$1 = { - dynamicLayout: false, - dynamicTag: false, - prepareArgs: false, - createArgs: true, - attributeHook: false, - elementHook: false, - createCaller: false, - dynamicScope: true, - updateHook: true, - createInstance: true, - wrapped: false, - willDestroy: false - }; - - function capabilities(managerAPI, options = {}) { - (true && !(managerAPI === '3.4' || managerAPI === '3.13') && (0, _debug.assert)('Invalid component manager compatibility specified', managerAPI === '3.4' || managerAPI === '3.13')); - var updateHook = true; - - if (managerAPI === '3.13') { - updateHook = Boolean(options.updateHook); - } - - return (0, _runtime2.buildCapabilities)({ - asyncLifeCycleCallbacks: Boolean(options.asyncLifecycleCallbacks), - destructor: Boolean(options.destructor), - updateHook - }); - } - - function hasAsyncLifeCycleCallbacks(delegate) { - return delegate.capabilities.asyncLifeCycleCallbacks; - } - - function hasUpdateHook(delegate) { - return delegate.capabilities.updateHook; - } - - function hasAsyncUpdateHook(delegate) { - return hasAsyncLifeCycleCallbacks(delegate) && hasUpdateHook(delegate); - } - - function hasDestructors(delegate) { - return delegate.capabilities.destructor; - } - /** - The CustomComponentManager allows addons to provide custom component - implementations that integrate seamlessly into Ember. This is accomplished - through a delegate, registered with the custom component manager, which - implements a set of hooks that determine component behavior. - - To create a custom component manager, instantiate a new CustomComponentManager - class and pass the delegate as the first argument: - - ```js - let manager = new CustomComponentManager({ - // ...delegate implementation... - }); - ``` - - ## Delegate Hooks - - Throughout the lifecycle of a component, the component manager will invoke - delegate hooks that are responsible for surfacing those lifecycle changes to - the end developer. - - * `create()` - invoked when a new instance of a component should be created - * `update()` - invoked when the arguments passed to a component change - * `getContext()` - returns the object that should be - */ - - - class CustomComponentManager extends _runtime2.BaseInternalComponentManager { - create(env, definition, vmArgs) { - var { - delegate - } = definition; - var args = argsProxyFor(vmArgs.capture(), 'component'); - var component; - - if (true - /* DEBUG */ - && _validator.deprecateMutationsInTrackingTransaction !== undefined) { - (0, _validator.deprecateMutationsInTrackingTransaction)(() => { - component = delegate.createComponent(definition.ComponentClass.class, args); - }); - } else { - component = delegate.createComponent(definition.ComponentClass.class, args); - } - - var bucket = new CustomComponentState(delegate, component, args, env); - return bucket; - } - - getDebugName({ - name - }) { - return name; - } - - update(bucket) { - if (hasUpdateHook(bucket.delegate)) { - var { - delegate, - component, - args - } = bucket; - delegate.updateComponent(component, args); - } - } - - didCreate({ - delegate, - component - }) { - if (hasAsyncLifeCycleCallbacks(delegate)) { - delegate.didCreateComponent(component); - } - } - - didUpdate({ - delegate, - component - }) { - if (hasAsyncUpdateHook(delegate)) { - delegate.didUpdateComponent(component); - } - } - - didRenderLayout() {} - - didUpdateLayout() {} - - getSelf({ - delegate, - component - }) { - return (0, _reference.createConstRef)(delegate.getContext(component), 'this'); - } - - getDestroyable(bucket) { - return bucket; - } - - getCapabilities() { - return CAPABILITIES$1; - } - - getStaticLayout(state) { - return state.template; - } - - } - - var CUSTOM_COMPONENT_MANAGER = new CustomComponentManager(); - /** - * Stores internal state about a component instance after it's been created. - */ - - class CustomComponentState { - constructor(delegate, component, args, env) { - this.delegate = delegate; - this.component = component; - this.args = args; - this.env = env; - - if (hasDestructors(delegate)) { - (0, _runtime2.registerDestructor)(this, () => delegate.destroyComponent(component)); - } - } - - } - - class CustomManagerDefinition { - constructor(name, ComponentClass, delegate, template) { - this.name = name; - this.ComponentClass = ComponentClass; - this.delegate = delegate; - this.template = template; - this.manager = CUSTOM_COMPONENT_MANAGER; - this.state = { - name, - ComponentClass, - template, - delegate - }; - } - - } - - var CAPABILITIES$2 = { - dynamicLayout: false, - dynamicTag: false, - prepareArgs: false, - createArgs: true, - attributeHook: false, - elementHook: false, - createCaller: true, - dynamicScope: false, - updateHook: false, - createInstance: true, - wrapped: false, - willDestroy: false - }; - - class InternalComponentDefinition { - constructor(manager, ComponentClass, layout) { - this.manager = manager; - this.state = { - ComponentClass, - layout - }; - } - - } - - class InternalManager extends _runtime2.BaseInternalComponentManager { - constructor(owner, name) { - super(); - this.owner = owner; - this.name = name; - } - - static for(name) { - return owner => new InternalManager(owner, name); - } - - getCapabilities() { - return CAPABILITIES$2; - } - - create(env, { - ComponentClass - }, args, _dynamicScope, caller) { - (true && !((0, _reference.isConstRef)(caller)) && (0, _debug.assert)('caller must be const', (0, _reference.isConstRef)(caller))); - (true && !(args.positional.length === 0) && (0, _debug.assert)(`The ${this.name} component does not take any positional arguments`, args.positional.length === 0)); - var instance = new ComponentClass(this.owner, args.named.capture(), (0, _reference.valueForRef)(caller)); - var state = { - env, - instance - }; - return state; - } - - getDebugName() { - return this.name; - } - - getSelf({ - instance - }) { - return (0, _reference.createConstRef)(instance, 'this'); - } - - getDestroyable(state) { - return state.instance; - } - - getStaticLayout({ - layout: template - }) { - return template; - } - - } - - var CAPABILITIES$3 = { - dynamicLayout: false, - dynamicTag: false, - prepareArgs: false, - createArgs: false, - attributeHook: false, - elementHook: false, - createCaller: false, - dynamicScope: false, - updateHook: false, - createInstance: false, - wrapped: false, - willDestroy: false - }; - - class TemplateOnlyComponentManager { - getStaticLayout({ - template - }) { - return template; - } - - getCapabilities() { - return CAPABILITIES$3; - } - - getDebugName({ - name - }) { - return name; - } - - getSelf() { - return _reference.NULL_REFERENCE; - } - - getDestroyable() { - return null; - } - - } - - var MANAGER = new TemplateOnlyComponentManager(); - - class TemplateOnlyComponentDefinition { - constructor(name, template) { - this.name = name; - this.template = template; - this.manager = MANAGER; - } - - get state() { - return this; - } - - } - var helper$1; if (true /* DEBUG */ ) { helper$1 = args => { - var inner = args.positional.at(0); - var messageRef = args.positional.at(1); - return (0, _reference.createComputeRef)(() => { - var value = (0, _reference.valueForRef)(inner); - (true && !(typeof value !== 'string') && (0, _debug.assert)((0, _reference.valueForRef)(messageRef), typeof value !== 'string')); - return value; - }); - }; - } else { - helper$1 = args => args.positional.at(0); - } - - var componentAssertionHelper = helper$1; - var helper$2; - - if (true - /* DEBUG */ - ) { - helper$2 = args => { var inner = args.positional.at(0); return (0, _reference.createComputeRef)(() => { var value = (0, _reference.valueForRef)(inner); @@ -8021,12 +7227,11 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim }); }; } else { - helper$2 = args => args.positional.at(0); + helper$1 = args => args.positional.at(0); } - var inElementNullCheckHelper = helper$2; - - function normalizeClassHelper(args) { + var inElementNullCheckHelper = internalHelper(helper$1); + var normalizeClassHelper = internalHelper(args => { var positional = args.positional.capture(); return (0, _reference.createComputeRef)(() => { var classNameParts = (0, _reference.valueForRef)(positional[0]).split('.'); @@ -8041,7 +7246,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return String(value); } }); - } + }); /** @module ember */ @@ -8052,8 +7257,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim transform at build time, similar to the (-each-in) helper */ - - function trackArray(args) { + var trackArray = internalHelper(args => { var inner = args.positional.at(0); return (0, _reference.createComputeRef)(() => { var iterable = (0, _reference.valueForRef)(inner); @@ -8064,631 +7268,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return iterable; }); - } - /** - @module ember - */ - - /** - Use the `{{array}}` helper to create an array to pass as an option to your - components. - - ```handlebars - - ``` - or - ```handlebars - {{my-component people=(array - 'Tom Dale' - 'Yehuda Katz' - this.myOtherPerson) - }} - ``` - - Would result in an object such as: - - ```js - ['Tom Dale', 'Yehuda Katz', this.get('myOtherPerson')] - ``` - - Where the 3rd item in the array is bound to updates of the `myOtherPerson` property. - - @method array - @for Ember.Templates.helpers - @param {Array} options - @return {Array} Array - @since 3.8.0 - @public - */ - - - function array(args) { - var captured = args.positional.capture(); - return (0, _reference.createComputeRef)(() => (0, _runtime2.reifyPositional)(captured), null, 'array'); - } - - var isEmpty = value => { - return value === null || value === undefined || typeof value.toString !== 'function'; - }; - - var normalizeTextValue = value => { - if (isEmpty(value)) { - return ''; - } - - return String(value); - }; - /** - @module ember - */ - - /** - Concatenates the given arguments into a string. - - Example: - - ```handlebars - {{some-component name=(concat firstName " " lastName)}} - - {{! would pass name=" " to the component}} - ``` - - or for angle bracket invocation, you actually don't need concat at all. - - ```handlebars - - ``` - - @public - @method concat - @for Ember.Templates.helpers - @since 1.13.0 - */ - - - function concat(args) { - var captured = args.positional.capture(); - return (0, _reference.createComputeRef)(() => (0, _runtime2.reifyPositional)(captured).map(normalizeTextValue).join(''), null, 'concat'); - } - - function buildUntouchableThis(source) { - var context = null; - - if (true - /* DEBUG */ - && _utils.HAS_NATIVE_PROXY) { - var assertOnProperty = property => { - (true && !(false) && (0, _debug.assert)(`You accessed \`this.${String(property)}\` from a function passed to the ${source}, but the function itself was not bound to a valid \`this\` context. Consider updating to usage of \`@action\`.`)); - }; - - context = new Proxy({}, { - get(_target, property) { - assertOnProperty(property); - }, - - set(_target, property) { - assertOnProperty(property); - return false; - }, - - has(_target, property) { - assertOnProperty(property); - return false; - } - - }); - } - - return context; - } - - var context = buildUntouchableThis('`fn` helper'); - /** - @module ember - */ - - /** - The `fn` helper allows you to ensure a function that you are passing off - to another component, helper, or modifier has access to arguments that are - available in the template. - - For example, if you have an `each` helper looping over a number of items, you - may need to pass a function that expects to receive the item as an argument - to a component invoked within the loop. Here's how you could use the `fn` - helper to pass both the function and its arguments together: - - ```app/templates/components/items-listing.hbs - {{#each @items as |item|}} - - {{/each}} - ``` - - ```app/components/items-list.js - import Component from '@glimmer/component'; - import { action } from '@ember/object'; - - export default class ItemsList extends Component { - @action - handleSelected(item) { - // ...snip... - } - } - ``` - - In this case the `display-item` component will receive a normal function - that it can invoke. When it invokes the function, the `handleSelected` - function will receive the `item` and any arguments passed, thanks to the - `fn` helper. - - Let's take look at what that means in a couple circumstances: - - - When invoked as `this.args.select()` the `handleSelected` function will - receive the `item` from the loop as its first and only argument. - - When invoked as `this.args.select('foo')` the `handleSelected` function - will receive the `item` from the loop as its first argument and the - string `'foo'` as its second argument. - - In the example above, we used `@action` to ensure that `handleSelected` is - properly bound to the `items-list`, but let's explore what happens if we - left out `@action`: - - ```app/components/items-list.js - import Component from '@glimmer/component'; - - export default class ItemsList extends Component { - handleSelected(item) { - // ...snip... - } - } - ``` - - In this example, when `handleSelected` is invoked inside the `display-item` - component, it will **not** have access to the component instance. In other - words, it will have no `this` context, so please make sure your functions - are bound (via `@action` or other means) before passing into `fn`! - - See also [partial application](https://en.wikipedia.org/wiki/Partial_application). - - @method fn - @for Ember.Templates.helpers - @public - @since 3.11.0 - */ - - function fn(args) { - var positional = args.positional.capture(); - var callbackRef = positional[0]; - if (true - /* DEBUG */ - ) assertCallbackIsFn(callbackRef); - return (0, _reference.createComputeRef)(() => { - return (...invocationArgs) => { - var [fn, ...args] = (0, _runtime2.reifyPositional)(positional); - if (true - /* DEBUG */ - ) assertCallbackIsFn(callbackRef); - - if ((0, _reference.isInvokableRef)(callbackRef)) { - var value = args.length > 0 ? args[0] : invocationArgs[0]; - return (0, _reference.updateRef)(callbackRef, value); - } else { - return fn.call(context, ...args, ...invocationArgs); - } - }; - }, null, 'fn'); - } - - function assertCallbackIsFn(callbackRef) { - (true && !(callbackRef && ((0, _reference.isInvokableRef)(callbackRef) || typeof (0, _reference.valueForRef)(callbackRef) === 'function')) && (0, _debug.assert)(`You must pass a function as the \`fn\` helpers first argument, you passed ${callbackRef ? (0, _reference.valueForRef)(callbackRef) : callbackRef}. While rendering:\n\n${callbackRef === null || callbackRef === void 0 ? void 0 : callbackRef.debugLabel}`, callbackRef && ((0, _reference.isInvokableRef)(callbackRef) || typeof (0, _reference.valueForRef)(callbackRef) === 'function'))); - } - /** - @module ember - */ - - /** - Dynamically look up a property on an object. The second argument to `{{get}}` - should have a string value, although it can be bound. - - For example, these two usages are equivalent: - - ```app/components/developer-detail.js - import Component from '@glimmer/component'; - import { tracked } from '@glimmer/tracking'; - - export default class extends Component { - @tracked developer = { - name: "Sandi Metz", - language: "Ruby" - } - } - ``` - - ```handlebars - {{this.developer.name}} - {{get this.developer "name"}} - ``` - - If there were several facts about a person, the `{{get}}` helper can dynamically - pick one: - - ```app/templates/application.hbs - - ``` - - ```handlebars - {{get this.developer @factName}} - ``` - - For a more complex example, this template would allow the user to switch - between showing the user's height and weight with a click: - - ```app/components/developer-detail.js - import Component from '@glimmer/component'; - import { tracked } from '@glimmer/tracking'; - - export default class extends Component { - @tracked developer = { - name: "Sandi Metz", - language: "Ruby" - } - - @tracked currentFact = 'name' - - @action - showFact(fact) { - this.currentFact = fact; - } - } - ``` - - ```app/components/developer-detail.js - {{get this.developer this.currentFact}} - - - - ``` - - The `{{get}}` helper can also respect mutable values itself. For example: - - ```app/components/developer-detail.js - - - - - ``` - - Would allow the user to swap what fact is being displayed, and also edit - that fact via a two-way mutable binding. - - @public - @method get - @for Ember.Templates.helpers - @since 2.1.0 - */ - - - function get$1(args) { - var sourceRef = args.positional.at(0); - var pathRef = args.positional.at(1); - - if ((0, _reference.isConstRef)(pathRef)) { - // Since the path is constant, we can create a normal chain of property - // references. The source reference will update like normal, and all of the - // child references will update accordingly. - var path = (0, _reference.valueForRef)(pathRef); - - if (path === undefined || path === null || path === '') { - return _reference.NULL_REFERENCE; - } else if (typeof path === 'string' && path.indexOf('.') > -1) { - return (0, _reference.childRefFromParts)(sourceRef, path.split('.')); - } else { - return (0, _reference.childRefFor)(sourceRef, String(path)); - } - } else { - return (0, _reference.createComputeRef)(() => { - var source = (0, _reference.valueForRef)(sourceRef); - - if ((0, _utils.isObject)(source)) { - return (0, _metal.get)(source, String((0, _reference.valueForRef)(pathRef))); - } - }, value => { - var source = (0, _reference.valueForRef)(sourceRef); - - if ((0, _utils.isObject)(source)) { - return (0, _metal.set)(source, String((0, _reference.valueForRef)(pathRef)), value); - } - }, 'get'); - } - } - /** - @module ember - */ - - /** - Use the `{{hash}}` helper to create a hash to pass as an option to your - components. This is specially useful for contextual components where you can - just yield a hash: - - ```handlebars - {{yield (hash - name='Sarah' - title=office - )}} - ``` - - Would result in an object such as: - - ```js - { name: 'Sarah', title: this.get('office') } - ``` - - Where the `title` is bound to updates of the `office` property. - - Note that the hash is an empty object with no prototype chain, therefore - common methods like `toString` are not available in the resulting hash. - If you need to use such a method, you can use the `call` or `apply` - approach: - - ```js - function toString(obj) { - return Object.prototype.toString.apply(obj); - } - ``` - - @method hash - @for Ember.Templates.helpers - @param {Object} options - @return {Object} Hash - @since 2.3.0 - @public - */ - - - function hash(args) { - var positional = args.named.capture(); - return (0, _reference.createComputeRef)(() => (0, _runtime2.reifyNamed)(positional), null, 'hash'); - } - /** - @module ember - */ - - /** - The `if` helper allows you to conditionally render one of two branches, - depending on the "truthiness" of a property. - For example the following values are all falsey: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array. - - This helper has two forms, block and inline. - - ## Block form - - You can use the block form of `if` to conditionally render a section of the template. - - To use it, pass the conditional value to the `if` helper, - using the block form to wrap the section of template you want to conditionally render. - Like so: - - ```app/templates/application.hbs - - ``` - - ```app/components/weather.hbs - {{! will not render because greeting is undefined}} - {{#if @isRaining}} - Yes, grab an umbrella! - {{/if}} - ``` - - You can also define what to show if the property is falsey by using - the `else` helper. - - ```app/components/weather.hbs - {{#if @isRaining}} - Yes, grab an umbrella! - {{else}} - No, it's lovely outside! - {{/if}} - ``` - - You are also able to combine `else` and `if` helpers to create more complex - conditional logic. - - For the following template: - - ```app/components/weather.hbs - {{#if @isRaining}} - Yes, grab an umbrella! - {{else if @isCold}} - Grab a coat, it's chilly! - {{else}} - No, it's lovely outside! - {{/if}} - ``` - - If you call it by saying `isCold` is true: - - ```app/templates/application.hbs - - ``` - - Then `Grab a coat, it's chilly!` will be rendered. - - ## Inline form - - The inline `if` helper conditionally renders a single property or string. - - In this form, the `if` helper receives three arguments, the conditional value, - the value to render when truthy, and the value to render when falsey. - - For example, if `useLongGreeting` is truthy, the following: - - ```app/templates/application.hbs - - ``` - - ```app/components/greeting.hbs - {{if @useLongGreeting "Hello" "Hi"}} Alex - ``` - - Will render: - - ```html - Hello Alex - ``` - - One detail to keep in mind is that both branches of the `if` helper will be evaluated, - so if you have `{{if condition "foo" (expensive-operation "bar")`, - `expensive-operation` will always calculate. - - @method if - @for Ember.Templates.helpers - @public - */ - - - function inlineIf(args) { - var positional = args.positional.capture(); - return (0, _reference.createComputeRef)(() => { - (true && !(positional.length === 3 || positional.length === 2) && (0, _debug.assert)('The inline form of the `if` helper expects two or three arguments, e.g. `{{if trialExpired "Expired" expiryDate}}`.', positional.length === 3 || positional.length === 2)); - var [condition, truthyValue, falsyValue] = positional; - - if ((0, _globalContext.toBool)((0, _reference.valueForRef)(condition)) === true) { - return (0, _reference.valueForRef)(truthyValue); - } else { - return falsyValue !== undefined ? (0, _reference.valueForRef)(falsyValue) : undefined; - } - }, null, 'if'); - } - /** - The `unless` helper is the inverse of the `if` helper. It displays if a value - is falsey ("not true" or "is false"). Example values that will display with - `unless`: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array. - - ## Inline form - - The inline `unless` helper conditionally renders a single property or string. - This helper acts like a ternary operator. If the first property is falsy, - the second argument will be displayed, otherwise, the third argument will be - displayed - - For example, if you pass a falsey `useLongGreeting` to the `Greeting` component: - - ```app/templates/application.hbs - - ``` - - ```app/components/greeting.hbs - {{unless @useLongGreeting "Hi" "Hello"}} Ben - ``` - - Then it will display: - - ```html - Hi Ben - ``` - - ## Block form - - Like the `if` helper, the `unless` helper also has a block form. - - The following will not render anything: - - ```app/templates/application.hbs - - ``` - - ```app/components/greeting.hbs - {{#unless @greeting}} - No greeting was found. Why not set one? - {{/unless}} - ``` - - You can also use an `else` helper with the `unless` block. The - `else` will display if the value is truthy. - - If you have the following component: - - ```app/components/logged-in.hbs - {{#unless @userData}} - Please login. - {{else}} - Welcome back! - {{/unless}} - ``` - - Calling it with a truthy `userData`: - - ```app/templates/application.hbs - - ``` - - Will render: - - ```html - Welcome back! - ``` - - and calling it with a falsey `userData`: - - ```app/templates/application.hbs - - ``` - - Will render: - - ```html - Please login. - ``` - - @method unless - @for Ember.Templates.helpers - @public - */ - - - function inlineUnless(args) { - var positional = args.positional.capture(); - return (0, _reference.createComputeRef)(() => { - (true && !(positional.length === 3 || positional.length === 2) && (0, _debug.assert)('The inline form of the `unless` helper expects two or three arguments, e.g. `{{unless isFirstLogin "Welcome back!"}}`.', positional.length === 3 || positional.length === 2)); - var [condition, falsyValue, truthyValue] = positional; - - if ((0, _globalContext.toBool)((0, _reference.valueForRef)(condition)) === true) { - return truthyValue !== undefined ? (0, _reference.valueForRef)(truthyValue) : undefined; - } else { - return (0, _reference.valueForRef)(falsyValue); - } - }, null, 'unless'); - } - /** - @module ember - */ - - /** - `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.Templates.helpers - @param {Array} params - @public - */ - - - function log(args) { - var positional = args.positional.capture(); - return (0, _reference.createComputeRef)(() => { - /* eslint-disable no-console */ - console.log(...(0, _runtime2.reifyPositional)(positional)); - /* eslint-enable no-console */ - }); - } + }); /** @module ember */ @@ -8767,8 +7347,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @public */ - - function mut(args) { + var mut = internalHelper(args => { var ref = args.positional.at(0); // TODO: Improve this error message. This covers at least two distinct // cases: // @@ -8784,7 +7363,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim (true && !((0, _reference.isUpdatableRef)(ref)) && (0, _debug.assert)('You can only pass a path to mut', (0, _reference.isUpdatableRef)(ref))); return (0, _reference.createInvokableRef)(ref); - } + }); /** @module ember */ @@ -8811,17 +7390,16 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @public */ - - function queryParams(args) { + var queryParams = internalHelper(args => { var { positional, named } = args.capture(); return (0, _reference.createComputeRef)(() => { (true && !(positional.length === 0) && (0, _debug.assert)("The `query-params` helper only accepts hash parameters, e.g. (query-params queryParamPropertyName='foo') as opposed to just (query-params 'foo')", positional.length === 0)); - return new _routing.QueryParams((0, _polyfills.assign)({}, (0, _runtime2.reifyNamed)(named))); + return new _routing.QueryParams((0, _polyfills.assign)({}, (0, _runtime.reifyNamed)(named))); }); - } + }); /** The `readonly` helper let's you specify that a binding is one-way only, instead of two-way. @@ -8938,10 +7516,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @private */ - - function readonly(args) { + var readonly = internalHelper(args => { return (0, _reference.createReadOnlyRef)(args.positional.at(0)); - } + }); /** @module ember */ @@ -8974,12 +7551,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @public */ - - function unbound(args) { + var unbound = internalHelper(args => { (true && !(args.positional.length === 1 && args.named.length === 0) && (0, _debug.assert)('unbound helper cannot be called with multiple params or hash params', args.positional.length === 1 && args.named.length === 0)); return (0, _reference.createUnboundRef)((0, _reference.valueForRef)(args.positional.at(0)), '(resurt of an `unbound` helper)'); - } - + }); var MODIFIERS = ['alt', 'shift', 'meta', 'ctrl']; var POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/; @@ -9037,14 +7612,14 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim this.positional = positionalArgs; this.dom = dom; this.eventName = this.getEventName(); - (0, _runtime2.registerDestructor)(this, () => ActionHelper.unregisterAction(this)); + (0, _destroyable.registerDestructor)(this, () => ActionHelper.unregisterAction(this)); } getEventName() { var { - on + on: on$$1 } = this.namedArgs; - return on !== undefined ? (0, _reference.valueForRef)(on) : 'click'; + return on$$1 !== undefined ? (0, _reference.valueForRef)(on$$1) : 'click'; } getActionArgs() { @@ -9149,11 +7724,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return shouldBubble; } - } // implements ModifierManager - + } class ActionModifierManager { - create(element, _state, args, _dynamicScope, dom) { + create(_owner, element, _state, args, _dynamicScope, dom) { var { named, positional @@ -9244,566 +7818,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } - function capabilities$1(managerAPI, optionalFeatures = {}) { - (true && !(managerAPI === '3.13' || managerAPI === '3.22') && (0, _debug.assert)('Invalid modifier manager compatibility specified', managerAPI === '3.13' || managerAPI === '3.22')); - return (0, _runtime2.buildCapabilities)({ - disableAutoTracking: Boolean(optionalFeatures.disableAutoTracking), - useArgsProxy: managerAPI === '3.13' ? false : true, - passFactoryToCreate: managerAPI === '3.13' - }); - } - - class CustomModifierDefinition { - constructor(name, ModifierClass, delegate, isInteractive) { - this.name = name; - this.ModifierClass = ModifierClass; - this.delegate = delegate; - this.state = { - ModifierClass, - name, - delegate - }; - this.manager = isInteractive ? CUSTOM_INTERACTIVE_MODIFIER_MANAGER : CUSTOM_NON_INTERACTIVE_MODIFIER_MANAGER; - } - - } - /** - The CustomModifierManager allows addons to provide custom modifier - implementations that integrate seamlessly into Ember. This is accomplished - through a delegate, registered with the custom modifier manager, which - implements a set of hooks that determine modifier behavior. - To create a custom modifier manager, instantiate a new CustomModifierManager - class and pass the delegate as the first argument: - - ```js - let manager = new CustomModifierManager({ - // ...delegate implementation... - }); - ``` - - ## Delegate Hooks - - Throughout the lifecycle of a modifier, the modifier manager will invoke - delegate hooks that are responsible for surfacing those lifecycle changes to - the end developer. - * `createModifier()` - invoked when a new instance of a modifier should be created - * `installModifier()` - invoked when the modifier is installed on the element - * `updateModifier()` - invoked when the arguments passed to a modifier change - * `destroyModifier()` - invoked when the modifier is about to be destroyed - */ - - - class InteractiveCustomModifierManager { - create(element, definition, vmArgs) { - var { - delegate, - ModifierClass - } = definition; - var capturedArgs = vmArgs.capture(); - var { - useArgsProxy, - passFactoryToCreate - } = delegate.capabilities; - var args = useArgsProxy ? argsProxyFor(capturedArgs, 'modifier') : (0, _runtime2.reifyArgs)(capturedArgs); - var instance; - - if (true - /* DEBUG */ - && _validator.deprecateMutationsInTrackingTransaction !== undefined) { - (0, _validator.deprecateMutationsInTrackingTransaction)(() => { - instance = delegate.createModifier(passFactoryToCreate ? ModifierClass : ModifierClass.class, args); - }); - } else { - instance = delegate.createModifier(passFactoryToCreate ? ModifierClass : ModifierClass.class, args); - } - - var tag = (0, _validator.createUpdatableTag)(); - var state; - - if (useArgsProxy) { - state = { - tag, - element, - delegate, - args, - modifier: instance - }; - } else { - state = { - tag, - element, - delegate, - modifier: instance, - - get args() { - return (0, _runtime2.reifyArgs)(capturedArgs); - } - - }; - } - - if (true - /* DEBUG */ - ) { - state.debugName = definition.name; - } - - (0, _runtime2.registerDestructor)(state, () => delegate.destroyModifier(instance, state.args)); - return state; - } - - getDebugName({ - debugName - }) { - return debugName; - } - - getTag({ - tag - }) { - return tag; - } - - install(state) { - var { - element, - args, - delegate, - modifier - } = state; - var { - capabilities - } = delegate; - - if (capabilities.disableAutoTracking === true) { - (0, _validator.untrack)(() => delegate.installModifier(modifier, element, args)); - } else { - delegate.installModifier(modifier, element, args); - } - } - - update(state) { - var { - args, - delegate, - modifier - } = state; - var { - capabilities - } = delegate; - - if (capabilities.disableAutoTracking === true) { - (0, _validator.untrack)(() => delegate.updateModifier(modifier, args)); - } else { - delegate.updateModifier(modifier, args); - } - } - - getDestroyable(state) { - return state; - } - - } - - class NonInteractiveCustomModifierManager { - create() { - return null; - } - - getDebugName() { - return ''; - } - - getTag() { - return null; - } - - install() {} - - update() {} - - getDestroyable() { - return null; - } - - } - - var CUSTOM_INTERACTIVE_MODIFIER_MANAGER = new InteractiveCustomModifierManager(); - var CUSTOM_NON_INTERACTIVE_MODIFIER_MANAGER = new NonInteractiveCustomModifierManager(); - var untouchableContext = buildUntouchableThis('`on` modifier'); - /** - @module ember - */ - - /* - Internet Explorer 11 does not support `once` and also does not support - passing `eventOptions`. In some situations it then throws a weird script - error, like: - - ``` - Could not complete the operation due to error 80020101 - ``` - - This flag determines, whether `{ once: true }` and thus also event options in - general are supported. - */ - - var SUPPORTS_EVENT_OPTIONS = (() => { - try { - var div = document.createElement('div'); - var counter = 0; - div.addEventListener('click', () => counter++, { - once: true - }); - var event; - - if (typeof Event === 'function') { - event = new Event('click'); - } else { - event = document.createEvent('Event'); - event.initEvent('click', true, true); - } - - div.dispatchEvent(event); - div.dispatchEvent(event); - return counter === 1; - } catch (error) { - return false; - } - })(); - - class OnModifierState { - constructor(owner, element, args) { - this.tag = (0, _validator.createUpdatableTag)(); - this.shouldUpdate = true; - this.owner = owner; - this.element = element; - this.args = args; - } - - updateFromArgs() { - var { - args - } = this; - var { - once, - passive, - capture - } = (0, _runtime2.reifyNamed)(args.named); - - if (once !== this.once) { - this.once = once; - this.shouldUpdate = true; - } - - if (passive !== this.passive) { - this.passive = passive; - this.shouldUpdate = true; - } - - if (capture !== this.capture) { - this.capture = capture; - this.shouldUpdate = true; - } - - var options; - - if (once || passive || capture) { - options = this.options = { - once, - passive, - capture - }; - } else { - this.options = undefined; - } - - (true && !(args.positional[0] !== undefined && typeof (0, _reference.valueForRef)(args.positional[0]) === 'string') && (0, _debug.assert)('You must pass a valid DOM event name as the first argument to the `on` modifier', args.positional[0] !== undefined && typeof (0, _reference.valueForRef)(args.positional[0]) === 'string')); - var eventName = (0, _reference.valueForRef)(args.positional[0]); - - if (eventName !== this.eventName) { - this.eventName = eventName; - this.shouldUpdate = true; - } - - var userProvidedCallbackReference = args.positional[1]; - - if (true - /* DEBUG */ - ) { - (true && !(args.positional[1] !== undefined) && (0, _debug.assert)(`You must pass a function as the second argument to the \`on\` modifier.`, args.positional[1] !== undefined)); - var value = (0, _reference.valueForRef)(userProvidedCallbackReference); - (true && !(typeof value === 'function') && (0, _debug.assert)(`You must pass a function as the second argument to the \`on\` modifier, you passed ${value === null ? 'null' : typeof value}. While rendering:\n\n${userProvidedCallbackReference.debugLabel}`, typeof value === 'function')); - } - - var userProvidedCallback = (0, _reference.valueForRef)(userProvidedCallbackReference); - - if (userProvidedCallback !== this.userProvidedCallback) { - this.userProvidedCallback = userProvidedCallback; - this.shouldUpdate = true; - } - - (true && !(args.positional.length === 2) && (0, _debug.assert)(`You can only pass two positional arguments (event name and callback) to the \`on\` modifier, but you provided ${args.positional.length}. Consider using the \`fn\` helper to provide additional arguments to the \`on\` callback.`, args.positional.length === 2)); - var needsCustomCallback = SUPPORTS_EVENT_OPTIONS === false && once || - /* needs manual once implementation */ - true - /* DEBUG */ - && passive; - /* needs passive enforcement */ - - if (this.shouldUpdate) { - if (needsCustomCallback) { - var callback = this.callback = function (event) { - if (true - /* DEBUG */ - && passive) { - event.preventDefault = () => { - (true && !(false) && (0, _debug.assert)(`You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()': \n\n${userProvidedCallback}`)); - }; - } - - if (!SUPPORTS_EVENT_OPTIONS && once) { - removeEventListener(this, eventName, callback, options); - } - - return userProvidedCallback.call(untouchableContext, event); - }; - } else if (true - /* DEBUG */ - ) { - // prevent the callback from being bound to the element - this.callback = userProvidedCallback.bind(untouchableContext); - } else { - this.callback = userProvidedCallback; - } - } - } - - } - - var adds = 0; - var removes = 0; - - function removeEventListener(element, eventName, callback, options) { - removes++; - - if (SUPPORTS_EVENT_OPTIONS) { - // when options are supported, use them across the board - element.removeEventListener(eventName, callback, options); - } else if (options !== undefined && options.capture) { - // used only in the following case: - // - // `{ once: true | false, passive: true | false, capture: true } - // - // `once` is handled via a custom callback that removes after first - // invocation so we only care about capture here as a boolean - element.removeEventListener(eventName, callback, true); - } else { - // used only in the following cases: - // - // * where there is no options - // * `{ once: true | false, passive: true | false, capture: false } - element.removeEventListener(eventName, callback); - } - } - - function addEventListener(element, eventName, callback, options) { - adds++; - - if (SUPPORTS_EVENT_OPTIONS) { - // when options are supported, use them across the board - element.addEventListener(eventName, callback, options); - } else if (options !== undefined && options.capture) { - // used only in the following case: - // - // `{ once: true | false, passive: true | false, capture: true } - // - // `once` is handled via a custom callback that removes after first - // invocation so we only care about capture here as a boolean - element.addEventListener(eventName, callback, true); - } else { - // used only in the following cases: - // - // * where there is no options - // * `{ once: true | false, passive: true | false, capture: false } - element.addEventListener(eventName, callback); - } - } - /** - The `{{on}}` modifier lets you easily add event listeners (it uses - [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) - internally). - - For example, if you'd like to run a function on your component when a ` - ``` - - ```app/components/like-post.js - import Component from '@glimmer/component'; - import { action } from '@ember/object'; - - export default class LikePostComponent extends Component { - @action - saveLike() { - // someone likes your post! - // better send a request off to your server... - } - } - ``` - - ### Arguments - - `{{on}}` accepts two positional arguments, and a few named arguments. - - The positional arguments are: - - - `event` -- the name to use when calling `addEventListener` - - `callback` -- the function to be passed to `addEventListener` - - The named arguments are: - - - capture -- a `true` value indicates that events of this type will be dispatched - to the registered listener before being dispatched to any EventTarget beneath it - in the DOM tree. - - once -- indicates that the listener should be invoked at most once after being - added. If true, the listener would be automatically removed when invoked. - - passive -- if `true`, indicates that the function specified by listener will never - call preventDefault(). If a passive listener does call preventDefault(), the user - agent will do nothing other than generate a console warning. See - [Improving scrolling performance with passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners) - to learn more. - - The callback function passed to `{{on}}` will receive any arguments that are passed - to the event handler. Most commonly this would be the `event` itself. - - If you would like to pass additional arguments to the function you should use - the `{{fn}}` helper. - - For example, in our example case above if you'd like to pass in the post that - was being liked when the button is clicked you could do something like: - - ```app/components/like-post.hbs - - ``` - - In this case, the `saveLike` function will receive two arguments: the click event - and the value of `@post`. - - ### Function Context - - In the example above, we used `@action` to ensure that `likePost` is - properly bound to the `items-list`, but let's explore what happens if we - left out `@action`: - - ```app/components/like-post.js - import Component from '@glimmer/component'; - - export default class LikePostComponent extends Component { - saveLike() { - // ...snip... - } - } - ``` - - In this example, when the button is clicked `saveLike` will be invoked, - it will **not** have access to the component instance. In other - words, it will have no `this` context, so please make sure your functions - are bound (via `@action` or other means) before passing into `on`! - - @method on - @for Ember.Templates.helpers - @public - @since 3.11.0 - */ - - - class OnModifierManager { - constructor(owner, isInteractive) { - this.SUPPORTS_EVENT_OPTIONS = SUPPORTS_EVENT_OPTIONS; - this.isInteractive = isInteractive; - this.owner = owner; - } - - getDebugName() { - return 'on'; - } - - get counters() { - return { - adds, - removes - }; - } - - create(element, _state, args) { - if (!this.isInteractive) { - return null; - } - - var capturedArgs = args.capture(); - return new OnModifierState(this.owner, element, capturedArgs); - } - - getTag(state) { - if (state === null) { - return null; - } - - return state.tag; - } - - install(state) { - if (state === null) { - return; - } - - state.updateFromArgs(); - var { - element, - eventName, - callback, - options - } = state; - addEventListener(element, eventName, callback, options); - (0, _runtime2.registerDestructor)(state, () => removeEventListener(element, eventName, callback, options)); - state.shouldUpdate = false; - } - - update(state) { - if (state === null) { - return; - } // stash prior state for el.removeEventListener - - - var { - element, - eventName, - callback, - options - } = state; - state.updateFromArgs(); - - if (!state.shouldUpdate) { - return; - } // use prior state values for removal - - - removeEventListener(element, eventName, callback, options); // read updated values from the state object - - addEventListener(state.element, state.eventName, state.callback, state.options); - state.shouldUpdate = false; - } - - getDestroyable(state) { - return state; - } - - } - - var CAPABILITIES$4 = { + var ACTION_MODIFIER_MANAGER = new ActionModifierManager(); + var actionModifier = (0, _manager2.setInternalModifierManager)(ACTION_MODIFIER_MANAGER, {}); + var CAPABILITIES$2 = { dynamicLayout: true, dynamicTag: false, prepareArgs: false, @@ -9815,27 +7832,32 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim updateHook: true, createInstance: true, wrapped: false, - willDestroy: false + willDestroy: false, + hasSubOwner: true }; - class MountManager extends _runtime2.BaseInternalComponentManager { + class MountManager { getDynamicLayout(state) { var templateFactory$$1 = state.engine.lookup('template:application'); - return templateFactory$$1(state.engine); + return (0, _util.unwrapTemplate)(templateFactory$$1(state.engine)).asLayout(); } getCapabilities() { - return CAPABILITIES$4; + return CAPABILITIES$2; } - create(env, { + getOwner(state) { + return state.engine; + } + + create(owner, { name - }, args) { + }, args, env) { // TODO // mount is a runtime helper, this shouldn't use dynamic layout // we should resolve the engine app template in the helper // it also should use the owner that looked up the mount helper. - var engine = env.owner.buildChildEngineInstance(name); + var engine = owner.buildChildEngineInstance(name); engine.boot(); var applicationFactory = engine.factoryFor(`controller:application`); var controllerFactory = applicationFactory || (0, _routing.generateControllerFactory)(engine, 'application'); @@ -9872,7 +7894,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } if (env.debugRenderTree) { - (0, _runtime2.associateDestroyableChild)(engine, controller); + (0, _destroyable.associateDestroyableChild)(engine, controller); } return bucket; @@ -9884,7 +7906,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return name; } - getDebugCustomRenderTree(definition, state, args, template) { + getDebugCustomRenderTree(definition, state, args, templateModuleName) { return [{ bucket: state.engine, instance: state.engine, @@ -9897,7 +7919,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim type: 'route-template', name: 'application', args, - template + template: templateModuleName }]; } @@ -9911,8 +7933,14 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return bucket.engine; } + didCreate() {} + + didUpdate() {} + didRenderLayout() {} + didUpdateLayout() {} + update(bucket) { var { controller, @@ -9924,17 +7952,20 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim } } - didUpdateLayout() {} - } var MOUNT_MANAGER = new MountManager(); class MountDefinition { - constructor(name) { + constructor(resolvedName) { + this.resolvedName = resolvedName; // handle is not used by this custom definition + + this.handle = -1; this.manager = MOUNT_MANAGER; + this.compilable = null; + this.capabilities = (0, _manager2.capabilityFlagsFrom)(CAPABILITIES$2); this.state = { - name + name: resolvedName }; } @@ -9981,8 +8012,8 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim */ - function mountHelper(args, vm) { - var env = vm.env; + var mountHelper = internalHelper((args, vm) => { + var owner = vm.getOwner(); var nameRef = args.positional.at(0); var captured = null; (true && !(args.positional.length === 1) && (0, _debug.assert)('You can only pass a single positional argument to the {{mount}} helper, e.g. {{mount "chat-engine"}}.', args.positional.length === 1)); @@ -9999,9 +8030,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim if (args.named.has('model')) { - (true && !(args.named.length === 1) && (0, _debug.assert)('[BUG] this should already be checked by the macro', args.named.length === 1)); + (true && !(args.named.length === 1) && (0, _debug.assert)('[BUG] this should already be checked by the template transform', args.named.length === 1)); var named = args.named.capture(); - captured = (0, _runtime2.createCapturedArgs)(named, _runtime2.EMPTY_POSITIONAL); + captured = (0, _runtime.createCapturedArgs)(named, _runtime.EMPTY_POSITIONAL); } var lastName, lastDef; @@ -10013,14 +8044,11 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return lastDef; } - (true && !(env.owner.hasRegistration(`engine:${name}`)) && (0, _debug.assert)(`You used \`{{mount '${name}'}}\`, but the engine '${name}' can not be found.`, env.owner.hasRegistration(`engine:${name}`))); - - if (!env.owner.hasRegistration(`engine:${name}`)) { - return null; - } - + (true && !(owner.hasRegistration(`engine:${name}`)) && (0, _debug.assert)(`You used \`{{mount '${name}'}}\`, but the engine '${name}' can not be found.`, owner.hasRegistration(`engine:${name}`))); lastName = name; - lastDef = (0, _runtime2.curry)(new MountDefinition(name), captured); + lastDef = (0, _runtime.curry)(0 + /* Component */ + , new MountDefinition(name), owner, captured, true); return lastDef; } else { (true && !(name === null || name === undefined) && (0, _debug.assert)(`Invalid engine name '${name}' specified, engine name must be either a string, null or undefined.`, name === null || name === undefined)); @@ -10029,7 +8057,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return null; } }); - } + }); /** The `{{outlet}}` helper lets you specify where a child route will render in your template. An important use of the `{{outlet}}` helper is in your @@ -10078,8 +8106,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim @public */ - - function outletHelper(args, vm) { + var outletHelper = internalHelper((args, vm) => { var scope = vm.dynamicScope(); var nameRef; @@ -10097,7 +8124,10 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim var lastState = null; var definition = null; return (0, _reference.createComputeRef)(() => { - var state = stateFor(outletRef); + var _a, _b; + + var outletState = (0, _reference.valueForRef)(outletRef); + var state = stateFor(outletRef, outletState); if (!validate(state, lastState)) { lastState = state; @@ -10112,9 +8142,13 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim named.model = (0, _reference.createDebugAliasRef)('@model', named.model); } - var _args2 = (0, _runtime2.createCapturedArgs)(named, _runtime2.EMPTY_POSITIONAL); + var owner = (_b = (_a = outletState === null || outletState === void 0 ? void 0 : outletState.render) === null || _a === void 0 ? void 0 : _a.owner) !== null && _b !== void 0 ? _b : vm.getOwner(); - definition = (0, _runtime2.curry)(new OutletComponentDefinition(state), _args2); + var _args2 = (0, _runtime.createCapturedArgs)(named, _runtime.EMPTY_POSITIONAL); + + definition = (0, _runtime.curry)(0 + /* Component */ + , new OutletComponentDefinition(state), owner, _args2, true); } else { definition = null; } @@ -10122,10 +8156,9 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim return definition; }); - } + }); - function stateFor(ref) { - var outlet = (0, _reference.valueForRef)(ref); + function stateFor(ref, outlet) { if (outlet === undefined) return null; var render = outlet.render; if (render === undefined) return null; @@ -10179,7 +8212,7 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim var component = componentFor(name, owner, options); if (component !== null && component.class !== undefined) { - var _layout = (0, _runtime2.getComponentTemplate)(component.class); + var _layout = (0, _manager2.getComponentTemplate)(component.class); if (_layout !== undefined) { return { @@ -10250,223 +8283,134 @@ define("@ember/-internals/glimmer/index", ["exports", "@ember/polyfills", "@glim }; } - var BUILTINS_HELPERS = { - if: inlineIf, + var BUILTIN_KEYWORD_HELPERS = { action, - array, - concat, - fn, - get: get$1, - hash, - log, mut, - 'query-params': queryParams, readonly, unbound, - unless: inlineUnless, - '-hash': hash, + 'query-params': queryParams, + '-hash': _runtime.hash, '-each-in': eachIn, '-normalize-class': normalizeClassHelper, '-track-array': trackArray, - '-get-dynamic-var': _runtime2.getDynamicVar, '-mount': mountHelper, '-outlet': outletHelper, - '-assert-implicit-component-helper-argument': componentAssertionHelper, '-in-el-null': inElementNullCheckHelper }; + var BUILTIN_HELPERS = (0, _polyfills.assign)((0, _polyfills.assign)({}, BUILTIN_KEYWORD_HELPERS), { + array: _runtime.array, + concat: _runtime.concat, + fn: _runtime.fn, + get: _runtime.get, + hash: _runtime.hash + }); + var BUILTIN_KEYWORD_MODIFIERS = { + action: actionModifier + }; + var BUILTIN_MODIFIERS = (0, _polyfills.assign)((0, _polyfills.assign)({}, BUILTIN_KEYWORD_MODIFIERS), { + on: _runtime.on + }); + var CLASSIC_HELPER_MANAGER_ASSOCIATED = new _util._WeakSet(); - class RuntimeResolverImpl { - constructor(owner, isInteractive) { - this.handles = [undefined]; - this.objToHandle = new WeakMap(); - this.builtInHelpers = BUILTINS_HELPERS; + class ResolverImpl { + constructor() { this.componentDefinitionCache = new Map(); - this.componentDefinitionCount = 0; - this.helperDefinitionCount = 0; - this.isInteractive = isInteractive; - this.builtInModifiers = { - action: { - manager: new ActionModifierManager(), - state: null - }, - on: { - manager: new OnModifierManager(owner, isInteractive), - state: null - } - }; } - /*** IRuntimeResolver ***/ - - /** - * public componentDefHandleCount = 0; - * Called while executing Append Op.PushDynamicComponentManager if string - */ - - - lookupComponent(name, owner) { - var handle = this.lookupComponentHandle(name, owner); - - if (handle === null) { - (true && !(false) && (0, _debug.assert)(`Could not find component named "${name}" (no component or template with that name was found)`)); - return null; - } - - return this.resolve(handle); - } - - lookupComponentHandle(name, owner) { - var nextHandle = this.handles.length; - var handle = this.handle(this._lookupComponentDefinition(name, owner)); - (true && !(!(name === 'text-area' && handle === null)) && (0, _debug.assert)('Could not find component `