UNPKG

ember-source

Version:

A JavaScript framework for creating ambitious web applications

112 lines (96 loc) 3.4 kB
import { a as createComputeRef, v as valueForRef, N as NULL_REFERENCE } from './reference-BoPB2LfI.js'; import { s as setInternalComponentManager } from './api-BawZUDYD.js'; import '../@ember/debug/index.js'; import { i as internalHelper } from './internal-helper-Ez7zbEIa.js'; import { assert } from '../@ember/debug/lib/assert.js'; /** @module @ember/helper */ // ============ Element Component (for string tag names) ============ // Renders content wrapped in the specified HTML element, or just renders // content without a wrapper for empty string. const ELEMENT_CAPABILITIES = { createInstance: true, wrapped: true }; class ElementComponentManager { getCapabilities() { return ELEMENT_CAPABILITIES; } getDebugName(state) { return `(element "${state.tagName}")`; } getSelf() { return NULL_REFERENCE; } getDestroyable() { return null; } didCreateElement() {} create(_owner, state) { // For empty string, return null so getTagName returns null (no wrapper element) return state.tagName || null; } getTagName(state) { return state; } didRenderLayout() {} didUpdateLayout() {} didCreate() {} didUpdate() {} } const ELEMENT_COMPONENT_MANAGER = new ElementComponentManager(); class ElementComponentDefinition { constructor(tagName) { this.tagName = tagName; } toString() { return `(element "${this.tagName}")`; } } setInternalComponentManager(ELEMENT_COMPONENT_MANAGER, ElementComponentDefinition.prototype); // Cache component definitions per tag name to avoid creating duplicate definitions const ELEMENT_DEFINITIONS = new Map(); function getElementDefinition(tagName) { let definition = ELEMENT_DEFINITIONS.get(tagName); if (definition === undefined) { definition = new ElementComponentDefinition(tagName); ELEMENT_DEFINITIONS.set(tagName, definition); } return definition; } // ============ Element Helper ============ /** The `element` helper lets you dynamically set the tag name of an element. ```handlebars {{#let (element @tagName) as |Tag|}} <Tag class="my-element">Hello</Tag> {{/let}} ``` When `@tagName` is `"h1"`, this renders `<h1 class="my-element">Hello</h1>`. When `@tagName` is an empty string `""`, the block content is rendered without a wrapping element. Passing `null`, `undefined`, or non-string values will throw an assertion error. Changing the tag name will tear down and recreate the element and its contents. The `element` helper is built-in and does not need to be imported. @method element @for Ember.Templates.helpers @public */ const element = internalHelper(({ positional, named }) => { return createComputeRef(() => { { (!(positional.length === 1) && assert('The `element` helper takes a single positional argument', positional.length === 1)); (!(Object.keys(named).length === 0) && assert('The `element` helper does not take any named arguments', Object.keys(named).length === 0)); } let tagName = valueForRef(positional[0]); { (!(typeof tagName === 'string') && assert(`The argument passed to the \`element\` helper must be a string${tagName === null || tagName === undefined || typeof tagName === 'object' ? '' : ` (you passed \`${tagName}\`)`}`, typeof tagName === 'string')); } return getElementDefinition(tagName); }, null, 'element'); }); export { element as e };