UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

1,717 lines (1,378 loc) 783 kB
define('@glimmer/runtime', ['exports', '@glimmer/reference', '@glimmer/util', '@glimmer/vm', '@glimmer/destroyable', '@glimmer/global-context', '@glimmer/env', '@glimmer/validator', '@glimmer/manager', '@glimmer/program', '@glimmer/owner', '@glimmer/runtime'], function (exports, reference, util, vm, destroyable, globalContext, env, validator, manager, program, owner, runtime) { 'use strict'; var DynamicScopeImpl = /*#__PURE__*/function () { function DynamicScopeImpl(bucket) { if (bucket) { this.bucket = util.assign({}, bucket); } else { this.bucket = {}; } } var _proto = DynamicScopeImpl.prototype; _proto.get = function get(key) { return this.bucket[key]; }; _proto.set = function set(key, reference) { return this.bucket[key] = reference; }; _proto.child = function child() { return new DynamicScopeImpl(this.bucket); }; return DynamicScopeImpl; }(); var PartialScopeImpl = /*#__PURE__*/function () { function PartialScopeImpl( // the 0th slot is `self` slots, owner, callerScope, // named arguments and blocks passed to a layout that uses eval evalScope, // locals in scope when the partial was invoked partialMap) { this.slots = slots; this.owner = owner; this.callerScope = callerScope; this.evalScope = evalScope; this.partialMap = partialMap; } PartialScopeImpl.root = function root(self, size, owner) { if (size === void 0) { size = 0; } var refs = new Array(size + 1); for (var i = 0; i <= size; i++) { refs[i] = reference.UNDEFINED_REFERENCE; } return new PartialScopeImpl(refs, owner, null, null, null).init({ self: self }); }; PartialScopeImpl.sized = function sized(size, owner) { if (size === void 0) { size = 0; } var refs = new Array(size + 1); for (var i = 0; i <= size; i++) { refs[i] = reference.UNDEFINED_REFERENCE; } return new PartialScopeImpl(refs, owner, null, null, null); }; var _proto2 = PartialScopeImpl.prototype; _proto2.init = function init(_ref) { var self = _ref.self; this.slots[0] = self; return this; }; _proto2.getSelf = function getSelf() { return this.get(0); }; _proto2.getSymbol = function getSymbol(symbol) { return this.get(symbol); }; _proto2.getBlock = function getBlock(symbol) { var block = this.get(symbol); return block === reference.UNDEFINED_REFERENCE ? null : block; }; _proto2.getEvalScope = function getEvalScope() { return this.evalScope; }; _proto2.getPartialMap = function getPartialMap() { return this.partialMap; }; _proto2.bind = function bind(symbol, value) { this.set(symbol, value); }; _proto2.bindSelf = function bindSelf(self) { this.set(0, self); }; _proto2.bindSymbol = function bindSymbol(symbol, value) { this.set(symbol, value); }; _proto2.bindBlock = function bindBlock(symbol, value) { this.set(symbol, value); }; _proto2.bindEvalScope = function bindEvalScope(map) { this.evalScope = map; }; _proto2.bindPartialMap = function bindPartialMap(map) { this.partialMap = map; }; _proto2.bindCallerScope = function bindCallerScope(scope) { this.callerScope = scope; }; _proto2.getCallerScope = function getCallerScope() { return this.callerScope; }; _proto2.child = function child() { return new PartialScopeImpl(this.slots.slice(), this.owner, this.callerScope, this.evalScope, this.partialMap); }; _proto2.get = function get(index) { if (index >= this.slots.length) { throw new RangeError("BUG: cannot get $" + index + " from scope; length=" + this.slots.length); } return this.slots[index]; }; _proto2.set = function set(index, value) { if (index >= this.slots.length) { throw new RangeError("BUG: cannot get $" + index + " from scope; length=" + this.slots.length); } this.slots[index] = value; }; return PartialScopeImpl; }(); // the VM in other classes, but are not intended to be a part of // Glimmer's API. var INNER_VM = util.symbol('INNER_VM'); var DESTROYABLE_STACK = util.symbol('DESTROYABLE_STACK'); var STACKS = util.symbol('STACKS'); var REGISTERS = util.symbol('REGISTERS'); var HEAP = util.symbol('HEAP'); var CONSTANTS = util.symbol('CONSTANTS'); var ARGS = util.symbol('ARGS'); var PC = util.symbol('PC'); var CursorImpl = function CursorImpl(element, nextSibling) { this.element = element; this.nextSibling = nextSibling; }; var ConcreteBounds = /*#__PURE__*/function () { function ConcreteBounds(parentNode, first, last) { this.parentNode = parentNode; this.first = first; this.last = last; } var _proto = ConcreteBounds.prototype; _proto.parentElement = function parentElement() { return this.parentNode; }; _proto.firstNode = function firstNode() { return this.first; }; _proto.lastNode = function lastNode() { return this.last; }; return ConcreteBounds; }(); var SingleNodeBounds = /*#__PURE__*/function () { function SingleNodeBounds(parentNode, node) { this.parentNode = parentNode; this.node = node; } var _proto2 = SingleNodeBounds.prototype; _proto2.parentElement = function parentElement() { return this.parentNode; }; _proto2.firstNode = function firstNode() { return this.node; }; _proto2.lastNode = function lastNode() { return this.node; }; return SingleNodeBounds; }(); function move(bounds, reference) { var parent = bounds.parentElement(); var first = bounds.firstNode(); var last = bounds.lastNode(); var current = first; while (true) { var next = current.nextSibling; parent.insertBefore(current, reference); if (current === last) { return next; } current = next; } } function clear(bounds) { var parent = bounds.parentElement(); var first = bounds.firstNode(); var last = bounds.lastNode(); var current = first; while (true) { var next = current.nextSibling; parent.removeChild(current); if (current === last) { return next; } current = next; } } function normalizeStringValue(value) { if (isEmpty(value)) { return ''; } return String(value); } function shouldCoerce(value) { return isString(value) || isEmpty(value) || typeof value === 'boolean' || typeof value === 'number'; } function isEmpty(value) { return value === null || value === undefined || typeof value.toString !== 'function'; } function isSafeString(value) { return typeof value === 'object' && value !== null && typeof value.toHTML === 'function'; } function isNode(value) { return typeof value === 'object' && value !== null && typeof value.nodeType === 'number'; } function isFragment(value) { return isNode(value) && value.nodeType === 11; } function isString(value) { return typeof value === 'string'; } /* * @method normalizeProperty * @param element {HTMLElement} * @param slotName {String} * @returns {Object} { name, type } */ function normalizeProperty(element, slotName) { var type, normalized; if (slotName in element) { normalized = slotName; type = 'prop'; } else { var lower = slotName.toLowerCase(); if (lower in element) { type = 'prop'; normalized = lower; } else { type = 'attr'; normalized = slotName; } } if (type === 'prop' && (normalized.toLowerCase() === 'style' || preferAttr(element.tagName, normalized))) { type = 'attr'; } return { normalized: normalized, type: type }; } // * browser bug // * strange spec outlier var ATTR_OVERRIDES = { INPUT: { form: true, // Chrome 46.0.2464.0: 'autocorrect' in document.createElement('input') === false // Safari 8.0.7: 'autocorrect' in document.createElement('input') === false // Mobile Safari (iOS 8.4 simulator): 'autocorrect' in document.createElement('input') === true autocorrect: true, // Chrome 54.0.2840.98: 'list' in document.createElement('input') === true // Safari 9.1.3: 'list' in document.createElement('input') === false list: true }, // element.form is actually a legitimate readOnly property, that is to be // mutated, but must be mutated by setAttribute... SELECT: { form: true }, OPTION: { form: true }, TEXTAREA: { form: true }, LABEL: { form: true }, FIELDSET: { form: true }, LEGEND: { form: true }, OBJECT: { form: true }, OUTPUT: { form: true }, BUTTON: { form: true } }; function preferAttr(tagName, propName) { var tag = ATTR_OVERRIDES[tagName.toUpperCase()]; return tag && tag[propName.toLowerCase()] || false; } var badProtocols = ['javascript:', 'vbscript:']; var badTags = ['A', 'BODY', 'LINK', 'IMG', 'IFRAME', 'BASE', 'FORM']; var badTagsForDataURI = ['EMBED']; var badAttributes = ['href', 'src', 'background', 'action']; var badAttributesForDataURI = ['src']; function has(array, item) { return array.indexOf(item) !== -1; } function checkURI(tagName, attribute) { return (tagName === null || has(badTags, tagName)) && has(badAttributes, attribute); } function checkDataURI(tagName, attribute) { if (tagName === null) return false; return has(badTagsForDataURI, tagName) && has(badAttributesForDataURI, attribute); } function requiresSanitization(tagName, attribute) { return checkURI(tagName, attribute) || checkDataURI(tagName, attribute); } var protocolForUrl; if (typeof URL === 'object' && URL !== null && // this is super annoying, TS thinks that URL **must** be a function so `URL.parse` check // thinks it is `never` without this `as unknown as any` typeof URL.parse === 'function') { // In Ember-land the `fastboot` package sets the `URL` global to `require('url')` // ultimately, this should be changed (so that we can either rely on the natural `URL` global // that exists) but for now we have to detect the specific `FastBoot` case first // // a future version of `fastboot` will detect if this legacy URL setup is required (by // inspecting Ember version) and if new enough, it will avoid shadowing the `URL` global // constructor with `require('url')`. var nodeURL = URL; protocolForUrl = function protocolForUrl(url) { var protocol = null; if (typeof url === 'string') { protocol = nodeURL.parse(url).protocol; } return protocol === null ? ':' : protocol; }; } else if (typeof URL === 'function') { protocolForUrl = function protocolForUrl(_url) { try { var url = new URL(_url); return url.protocol; } catch (error) { // any non-fully qualified url string will trigger an error (because there is no // baseURI that we can provide; in that case we **know** that the protocol is // "safe" because it isn't specifically one of the `badProtocols` listed above // (and those protocols can never be the default baseURI) return ':'; } }; } else { // fallback for IE11 support var parsingNode = document.createElement('a'); protocolForUrl = function protocolForUrl(url) { parsingNode.href = url; return parsingNode.protocol; }; } function sanitizeAttributeValue(element, attribute, value) { var tagName = null; if (value === null || value === undefined) { return value; } if (isSafeString(value)) { return value.toHTML(); } if (!element) { tagName = null; } else { tagName = element.tagName.toUpperCase(); } var str = normalizeStringValue(value); if (checkURI(tagName, attribute)) { var protocol = protocolForUrl(str); if (has(badProtocols, protocol)) { return "unsafe:" + str; } } if (checkDataURI(tagName, attribute)) { return "unsafe:" + str; } return str; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } function dynamicAttribute(element, attr, namespace, isTrusting) { if (isTrusting === void 0) { isTrusting = false; } var tagName = element.tagName, namespaceURI = element.namespaceURI; var attribute = { element: element, name: attr, namespace: namespace }; if (env.DEBUG && attr === 'style' && !isTrusting) { return new DebugStyleAttributeManager(attribute); } if (namespaceURI === "http://www.w3.org/2000/svg" /* SVG */ ) { return buildDynamicAttribute(tagName, attr, attribute); } var _normalizeProperty = normalizeProperty(element, attr), type = _normalizeProperty.type, normalized = _normalizeProperty.normalized; if (type === 'attr') { return buildDynamicAttribute(tagName, normalized, attribute); } else { return buildDynamicProperty(tagName, normalized, attribute); } } function buildDynamicAttribute(tagName, name, attribute) { if (requiresSanitization(tagName, name)) { return new SafeDynamicAttribute(attribute); } else { return new SimpleDynamicAttribute(attribute); } } function buildDynamicProperty(tagName, name, attribute) { if (requiresSanitization(tagName, name)) { return new SafeDynamicProperty(name, attribute); } if (isUserInputValue(tagName, name)) { return new InputValueDynamicAttribute(name, attribute); } if (isOptionSelected(tagName, name)) { return new OptionSelectedDynamicAttribute(name, attribute); } return new DefaultDynamicProperty(name, attribute); } var DynamicAttribute = function DynamicAttribute(attribute) { this.attribute = attribute; }; var SimpleDynamicAttribute = /*#__PURE__*/function (_DynamicAttribute) { _inheritsLoose(SimpleDynamicAttribute, _DynamicAttribute); function SimpleDynamicAttribute() { return _DynamicAttribute.apply(this, arguments) || this; } var _proto = SimpleDynamicAttribute.prototype; _proto.set = function set(dom, value, _env) { var normalizedValue = normalizeValue(value); if (normalizedValue !== null) { var _this$attribute = this.attribute, name = _this$attribute.name, namespace = _this$attribute.namespace; dom.__setAttribute(name, normalizedValue, namespace); } }; _proto.update = function update(value, _env) { var normalizedValue = normalizeValue(value); var _this$attribute2 = this.attribute, element = _this$attribute2.element, name = _this$attribute2.name; if (normalizedValue === null) { element.removeAttribute(name); } else { element.setAttribute(name, normalizedValue); } }; return SimpleDynamicAttribute; }(DynamicAttribute); var DefaultDynamicProperty = /*#__PURE__*/function (_DynamicAttribute2) { _inheritsLoose(DefaultDynamicProperty, _DynamicAttribute2); function DefaultDynamicProperty(normalizedName, attribute) { var _this; _this = _DynamicAttribute2.call(this, attribute) || this; _this.normalizedName = normalizedName; return _this; } var _proto2 = DefaultDynamicProperty.prototype; _proto2.set = function set(dom, value, _env) { if (value !== null && value !== undefined) { this.value = value; dom.__setProperty(this.normalizedName, value); } }; _proto2.update = function update(value, _env) { var element = this.attribute.element; if (this.value !== value) { element[this.normalizedName] = this.value = value; if (value === null || value === undefined) { this.removeAttribute(); } } }; _proto2.removeAttribute = function removeAttribute() { // TODO this sucks but to preserve properties first and to meet current // semantics we must do this. var _this$attribute3 = this.attribute, element = _this$attribute3.element, namespace = _this$attribute3.namespace; if (namespace) { element.removeAttributeNS(namespace, this.normalizedName); } else { element.removeAttribute(this.normalizedName); } }; return DefaultDynamicProperty; }(DynamicAttribute); var SafeDynamicProperty = /*#__PURE__*/function (_DefaultDynamicProper) { _inheritsLoose(SafeDynamicProperty, _DefaultDynamicProper); function SafeDynamicProperty() { return _DefaultDynamicProper.apply(this, arguments) || this; } var _proto3 = SafeDynamicProperty.prototype; _proto3.set = function set(dom, value, env) { var _this$attribute4 = this.attribute, element = _this$attribute4.element, name = _this$attribute4.name; var sanitized = sanitizeAttributeValue(element, name, value); _DefaultDynamicProper.prototype.set.call(this, dom, sanitized, env); }; _proto3.update = function update(value, env) { var _this$attribute5 = this.attribute, element = _this$attribute5.element, name = _this$attribute5.name; var sanitized = sanitizeAttributeValue(element, name, value); _DefaultDynamicProper.prototype.update.call(this, sanitized, env); }; return SafeDynamicProperty; }(DefaultDynamicProperty); var SafeDynamicAttribute = /*#__PURE__*/function (_SimpleDynamicAttribu) { _inheritsLoose(SafeDynamicAttribute, _SimpleDynamicAttribu); function SafeDynamicAttribute() { return _SimpleDynamicAttribu.apply(this, arguments) || this; } var _proto4 = SafeDynamicAttribute.prototype; _proto4.set = function set(dom, value, env) { var _this$attribute6 = this.attribute, element = _this$attribute6.element, name = _this$attribute6.name; var sanitized = sanitizeAttributeValue(element, name, value); _SimpleDynamicAttribu.prototype.set.call(this, dom, sanitized, env); }; _proto4.update = function update(value, env) { var _this$attribute7 = this.attribute, element = _this$attribute7.element, name = _this$attribute7.name; var sanitized = sanitizeAttributeValue(element, name, value); _SimpleDynamicAttribu.prototype.update.call(this, sanitized, env); }; return SafeDynamicAttribute; }(SimpleDynamicAttribute); var InputValueDynamicAttribute = /*#__PURE__*/function (_DefaultDynamicProper2) { _inheritsLoose(InputValueDynamicAttribute, _DefaultDynamicProper2); function InputValueDynamicAttribute() { return _DefaultDynamicProper2.apply(this, arguments) || this; } var _proto5 = InputValueDynamicAttribute.prototype; _proto5.set = function set(dom, value) { dom.__setProperty('value', normalizeStringValue(value)); }; _proto5.update = function update(value) { var input = this.attribute.element; var currentValue = input.value; var normalizedValue = normalizeStringValue(value); if (currentValue !== normalizedValue) { input.value = normalizedValue; } }; return InputValueDynamicAttribute; }(DefaultDynamicProperty); var OptionSelectedDynamicAttribute = /*#__PURE__*/function (_DefaultDynamicProper3) { _inheritsLoose(OptionSelectedDynamicAttribute, _DefaultDynamicProper3); function OptionSelectedDynamicAttribute() { return _DefaultDynamicProper3.apply(this, arguments) || this; } var _proto6 = OptionSelectedDynamicAttribute.prototype; _proto6.set = function set(dom, value) { if (value !== null && value !== undefined && value !== false) { dom.__setProperty('selected', true); } }; _proto6.update = function update(value) { var option = this.attribute.element; if (value) { option.selected = true; } else { option.selected = false; } }; return OptionSelectedDynamicAttribute; }(DefaultDynamicProperty); function isOptionSelected(tagName, attribute) { return tagName === 'OPTION' && attribute === 'selected'; } function isUserInputValue(tagName, attribute) { return (tagName === 'INPUT' || tagName === 'TEXTAREA') && attribute === 'value'; } function normalizeValue(value) { if (value === false || value === undefined || value === null || typeof value.toString === 'undefined') { return null; } if (value === true) { return ''; } // onclick function etc in SSR if (typeof value === 'function') { return null; } return String(value); } var DebugStyleAttributeManager; if (env.DEBUG) { DebugStyleAttributeManager = /*#__PURE__*/function (_SimpleDynamicAttribu2) { _inheritsLoose(DebugStyleAttributeManager, _SimpleDynamicAttribu2); function DebugStyleAttributeManager() { return _SimpleDynamicAttribu2.apply(this, arguments) || this; } var _proto7 = DebugStyleAttributeManager.prototype; _proto7.set = function set(dom, value, env) { globalContext.warnIfStyleNotTrusted(value); _SimpleDynamicAttribu2.prototype.set.call(this, dom, value, env); }; _proto7.update = function update(value, env) { globalContext.warnIfStyleNotTrusted(value); _SimpleDynamicAttribu2.prototype.update.call(this, value, env); }; return DebugStyleAttributeManager; }(SimpleDynamicAttribute); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inheritsLoose$1(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var _a; var First = /*#__PURE__*/function () { function First(node) { this.node = node; } var _proto = First.prototype; _proto.firstNode = function firstNode() { return this.node; }; return First; }(); var Last = /*#__PURE__*/function () { function Last(node) { this.node = node; } var _proto2 = Last.prototype; _proto2.lastNode = function lastNode() { return this.node; }; return Last; }(); var CURSOR_STACK = util.symbol('CURSOR_STACK'); var NewElementBuilder = /*#__PURE__*/function () { function NewElementBuilder(env, parentNode, nextSibling) { this.constructing = null; this.operations = null; this[_a] = new util.Stack(); this.modifierStack = new util.Stack(); this.blockStack = new util.Stack(); this.pushElement(parentNode, nextSibling); this.env = env; this.dom = env.getAppendOperations(); this.updateOperations = env.getDOM(); } NewElementBuilder.forInitialRender = function forInitialRender(env, cursor) { return new this(env, cursor.element, cursor.nextSibling).initialize(); }; NewElementBuilder.resume = function resume(env, block) { var parentNode = block.parentElement(); var nextSibling = block.reset(env); var stack = new this(env, parentNode, nextSibling).initialize(); stack.pushLiveBlock(block); return stack; }; var _proto4 = NewElementBuilder.prototype; _proto4.initialize = function initialize() { this.pushSimpleBlock(); return this; }; _proto4.debugBlocks = function debugBlocks() { return this.blockStack.toArray(); }; _proto4.block = function block() { return this.blockStack.current; }; _proto4.popElement = function popElement() { this[CURSOR_STACK].pop(); this[CURSOR_STACK].current; }; _proto4.pushSimpleBlock = function pushSimpleBlock() { return this.pushLiveBlock(new SimpleLiveBlock(this.element)); }; _proto4.pushUpdatableBlock = function pushUpdatableBlock() { return this.pushLiveBlock(new UpdatableBlockImpl(this.element)); }; _proto4.pushBlockList = function pushBlockList(list) { return this.pushLiveBlock(new LiveBlockList(this.element, list)); }; _proto4.pushLiveBlock = function pushLiveBlock(block, isRemote) { if (isRemote === void 0) { isRemote = false; } var current = this.blockStack.current; if (current !== null) { if (!isRemote) { current.didAppendBounds(block); } } this.__openBlock(); this.blockStack.push(block); return block; }; _proto4.popBlock = function popBlock() { this.block().finalize(this); this.__closeBlock(); return this.blockStack.pop(); }; _proto4.__openBlock = function __openBlock() {}; _proto4.__closeBlock = function __closeBlock() {} // todo return seems unused ; _proto4.openElement = function openElement(tag) { var element = this.__openElement(tag); this.constructing = element; return element; }; _proto4.__openElement = function __openElement(tag) { return this.dom.createElement(tag, this.element); }; _proto4.flushElement = function flushElement(modifiers) { var parent = this.element; var element = this.constructing; this.__flushElement(parent, element); this.constructing = null; this.operations = null; this.pushModifiers(modifiers); this.pushElement(element, null); this.didOpenElement(element); }; _proto4.__flushElement = function __flushElement(parent, constructing) { this.dom.insertBefore(parent, constructing, this.nextSibling); }; _proto4.closeElement = function closeElement() { this.willCloseElement(); this.popElement(); return this.popModifiers(); }; _proto4.pushRemoteElement = function pushRemoteElement(element, guid, insertBefore) { return this.__pushRemoteElement(element, guid, insertBefore); }; _proto4.__pushRemoteElement = function __pushRemoteElement(element, _guid, insertBefore) { this.pushElement(element, insertBefore); if (insertBefore === undefined) { while (element.lastChild) { element.removeChild(element.lastChild); } } var block = new RemoteLiveBlock(element); return this.pushLiveBlock(block, true); }; _proto4.popRemoteElement = function popRemoteElement() { this.popBlock(); this.popElement(); }; _proto4.pushElement = function pushElement(element, nextSibling) { if (nextSibling === void 0) { nextSibling = null; } this[CURSOR_STACK].push(new CursorImpl(element, nextSibling)); }; _proto4.pushModifiers = function pushModifiers(modifiers) { this.modifierStack.push(modifiers); }; _proto4.popModifiers = function popModifiers() { return this.modifierStack.pop(); }; _proto4.didAppendBounds = function didAppendBounds(bounds) { this.block().didAppendBounds(bounds); return bounds; }; _proto4.didAppendNode = function didAppendNode(node) { this.block().didAppendNode(node); return node; }; _proto4.didOpenElement = function didOpenElement(element) { this.block().openElement(element); return element; }; _proto4.willCloseElement = function willCloseElement() { this.block().closeElement(); }; _proto4.appendText = function appendText(string) { return this.didAppendNode(this.__appendText(string)); }; _proto4.__appendText = function __appendText(text) { var dom = this.dom, element = this.element, nextSibling = this.nextSibling; var node = dom.createTextNode(text); dom.insertBefore(element, node, nextSibling); return node; }; _proto4.__appendNode = function __appendNode(node) { this.dom.insertBefore(this.element, node, this.nextSibling); return node; }; _proto4.__appendFragment = function __appendFragment(fragment) { var first = fragment.firstChild; if (first) { var ret = new ConcreteBounds(this.element, first, fragment.lastChild); this.dom.insertBefore(this.element, fragment, this.nextSibling); return ret; } else { return new SingleNodeBounds(this.element, this.__appendComment('')); } }; _proto4.__appendHTML = function __appendHTML(html) { return this.dom.insertHTMLBefore(this.element, this.nextSibling, html); }; _proto4.appendDynamicHTML = function appendDynamicHTML(value) { var bounds = this.trustedContent(value); this.didAppendBounds(bounds); }; _proto4.appendDynamicText = function appendDynamicText(value) { var node = this.untrustedContent(value); this.didAppendNode(node); return node; }; _proto4.appendDynamicFragment = function appendDynamicFragment(value) { var bounds = this.__appendFragment(value); this.didAppendBounds(bounds); }; _proto4.appendDynamicNode = function appendDynamicNode(value) { var node = this.__appendNode(value); var bounds = new SingleNodeBounds(this.element, node); this.didAppendBounds(bounds); }; _proto4.trustedContent = function trustedContent(value) { return this.__appendHTML(value); }; _proto4.untrustedContent = function untrustedContent(value) { return this.__appendText(value); }; _proto4.appendComment = function appendComment(string) { return this.didAppendNode(this.__appendComment(string)); }; _proto4.__appendComment = function __appendComment(string) { var dom = this.dom, element = this.element, nextSibling = this.nextSibling; var node = dom.createComment(string); dom.insertBefore(element, node, nextSibling); return node; }; _proto4.__setAttribute = function __setAttribute(name, value, namespace) { this.dom.setAttribute(this.constructing, name, value, namespace); }; _proto4.__setProperty = function __setProperty(name, value) { this.constructing[name] = value; }; _proto4.setStaticAttribute = function setStaticAttribute(name, value, namespace) { this.__setAttribute(name, value, namespace); }; _proto4.setDynamicAttribute = function setDynamicAttribute(name, value, trusting, namespace) { var element = this.constructing; var attribute = dynamicAttribute(element, name, namespace, trusting); attribute.set(this, value, this.env); return attribute; }; _createClass(NewElementBuilder, [{ key: "element", get: function get() { return this[CURSOR_STACK].current.element; } }, { key: "nextSibling", get: function get() { return this[CURSOR_STACK].current.nextSibling; } }, { key: "hasBlocks", get: function get() { return this.blockStack.size > 0; } }]); return NewElementBuilder; }(); _a = CURSOR_STACK; var SimpleLiveBlock = /*#__PURE__*/function () { function SimpleLiveBlock(parent) { this.parent = parent; this.first = null; this.last = null; this.nesting = 0; } var _proto5 = SimpleLiveBlock.prototype; _proto5.parentElement = function parentElement() { return this.parent; }; _proto5.firstNode = function firstNode() { var first = this.first; return first.firstNode(); }; _proto5.lastNode = function lastNode() { var last = this.last; return last.lastNode(); }; _proto5.openElement = function openElement(element) { this.didAppendNode(element); this.nesting++; }; _proto5.closeElement = function closeElement() { this.nesting--; }; _proto5.didAppendNode = function didAppendNode(node) { if (this.nesting !== 0) return; if (!this.first) { this.first = new First(node); } this.last = new Last(node); }; _proto5.didAppendBounds = function didAppendBounds(bounds) { if (this.nesting !== 0) return; if (!this.first) { this.first = bounds; } this.last = bounds; }; _proto5.finalize = function finalize(stack) { if (this.first === null) { stack.appendComment(''); } }; return SimpleLiveBlock; }(); var RemoteLiveBlock = /*#__PURE__*/function (_SimpleLiveBlock) { _inheritsLoose$1(RemoteLiveBlock, _SimpleLiveBlock); function RemoteLiveBlock(parent) { var _this; _this = _SimpleLiveBlock.call(this, parent) || this; destroyable.registerDestructor(_assertThisInitialized(_this), function () { // In general, you only need to clear the root of a hierarchy, and should never // need to clear any child nodes. This is an important constraint that gives us // a strong guarantee that clearing a subtree is a single DOM operation. // // Because remote blocks are not normally physically nested inside of the tree // that they are logically nested inside, we manually clear remote blocks when // a logical parent is cleared. // // HOWEVER, it is currently possible for a remote block to be physically nested // inside of the block it is logically contained inside of. This happens when // the remote block is appended to the end of the application's entire element. // // The problem with that scenario is that Glimmer believes that it owns more of // the DOM than it actually does. The code is attempting to write past the end // of the Glimmer-managed root, but Glimmer isn't aware of that. // // The correct solution to that problem is for Glimmer to be aware of the end // of the bounds that it owns, and once we make that change, this check could // be removed. // // For now, a more targeted fix is to check whether the node was already removed // and avoid clearing the node if it was. In most cases this shouldn't happen, // so this might hide bugs where the code clears nested nodes unnecessarily, // so we should eventually try to do the correct fix. if (_this.parentElement() === _this.firstNode().parentNode) { clear(_assertThisInitialized(_this)); } }); return _this; } return RemoteLiveBlock; }(SimpleLiveBlock); var UpdatableBlockImpl = /*#__PURE__*/function (_SimpleLiveBlock2) { _inheritsLoose$1(UpdatableBlockImpl, _SimpleLiveBlock2); function UpdatableBlockImpl() { return _SimpleLiveBlock2.apply(this, arguments) || this; } var _proto6 = UpdatableBlockImpl.prototype; _proto6.reset = function reset() { destroyable.destroy(this); var nextSibling = clear(this); this.first = null; this.last = null; this.nesting = 0; return nextSibling; }; return UpdatableBlockImpl; }(SimpleLiveBlock); // FIXME: All the noops in here indicate a modelling problem var LiveBlockList = /*#__PURE__*/function () { function LiveBlockList(parent, boundList) { this.parent = parent; this.boundList = boundList; this.parent = parent; this.boundList = boundList; } var _proto7 = LiveBlockList.prototype; _proto7.parentElement = function parentElement() { return this.parent; }; _proto7.firstNode = function firstNode() { var head = this.boundList[0]; return head.firstNode(); }; _proto7.lastNode = function lastNode() { var boundList = this.boundList; var tail = boundList[boundList.length - 1]; return tail.lastNode(); }; _proto7.openElement = function openElement(_element) { }; _proto7.closeElement = function closeElement() { }; _proto7.didAppendNode = function didAppendNode(_node) { }; _proto7.didAppendBounds = function didAppendBounds(_bounds) {}; _proto7.finalize = function finalize(_stack) { }; return LiveBlockList; }(); function clientBuilder(env, cursor) { return NewElementBuilder.forInitialRender(env, cursor); } var AppendOpcodes = /*#__PURE__*/function () { function AppendOpcodes() { this.evaluateOpcode = util.fillNulls(104 /* Size */ ).slice(); } var _proto = AppendOpcodes.prototype; _proto.add = function add(name, evaluate, kind) { if (kind === void 0) { kind = 'syscall'; } this.evaluateOpcode[name] = { syscall: kind !== 'machine', evaluate: evaluate }; }; _proto.debugBefore = function debugBefore(vm$1, opcode) { var params = undefined; var opName = undefined; var sp; return { sp: sp, pc: vm$1.fetchValue(vm.$pc), name: opName, params: params, type: opcode.type, isMachine: opcode.isMachine, size: opcode.size, state: undefined }; }; _proto.debugAfter = function debugAfter(vm$1, pre) { var sp = pre.sp, type = pre.type, isMachine = pre.isMachine, pc = pre.pc; }; _proto.evaluate = function evaluate(vm, opcode, type) { var operation = this.evaluateOpcode[type]; if (operation.syscall) { operation.evaluate(vm, opcode); } else { operation.evaluate(vm[INNER_VM], opcode); } }; return AppendOpcodes; }(); var APPEND_OPCODES = new AppendOpcodes(); function createConcatRef(partsRefs) { return reference.createComputeRef(function () { var parts = new Array(); for (var i = 0; i < partsRefs.length; i++) { var value = reference.valueForRef(partsRefs[i]); if (value !== null && value !== undefined) { parts[i] = castToString(value); } } if (parts.length > 0) { return parts.join(''); } return null; }); } function castToString(value) { if (typeof value.toString !== 'function') { return ''; } return String(value); } var TYPE = util.symbol('TYPE'); var INNER = util.symbol('INNER'); var OWNER = util.symbol('OWNER'); var ARGS$1 = util.symbol('ARGS'); var RESOLVED = util.symbol('RESOLVED'); var CURRIED_VALUES = new util._WeakSet(); function isCurriedValue(value) { return CURRIED_VALUES.has(value); } function isCurriedType(value, type) { return isCurriedValue(value) && value[TYPE] === type; } var CurriedValue = /** @internal */ function CurriedValue(type, inner, owner, args, resolved) { if (resolved === void 0) { resolved = false; } CURRIED_VALUES.add(this); this[TYPE] = type; this[INNER] = inner; this[OWNER] = owner; this[ARGS$1] = args; this[RESOLVED] = resolved; }; function resolveCurriedValue(curriedValue) { var currentWrapper = curriedValue; var positional; var named; var definition, owner, resolved; while (true) { var _currentWrapper = currentWrapper, curriedArgs = _currentWrapper[ARGS$1], inner = _currentWrapper[INNER]; if (curriedArgs !== null) { var curriedNamed = curriedArgs.named, curriedPositional = curriedArgs.positional; if (curriedPositional.length > 0) { positional = positional === undefined ? curriedPositional : curriedPositional.concat(positional); } if (named === undefined) { named = []; } named.unshift(curriedNamed); } if (!isCurriedValue(inner)) { // Save off the owner that this helper was curried with. Later on, // we'll fetch the value of this register and set it as the owner on the // new root scope. definition = inner; owner = currentWrapper[OWNER]; resolved = currentWrapper[RESOLVED]; break; } currentWrapper = inner; } return { definition: definition, owner: owner, resolved: resolved, positional: positional, named: named }; } function curry(type, spec, owner, args, resolved) { if (resolved === void 0) { resolved = false; } return new CurriedValue(type, spec, owner, args, resolved); } function createCurryRef(type, inner, owner, args, resolver, isStrict) { var lastValue, curriedDefinition; return reference.createComputeRef(function () { var value = reference.valueForRef(inner); if (value === lastValue) { return curriedDefinition; } if (isCurriedType(value, type)) { curriedDefinition = args ? curry(type, value, owner, args) : args; } else if (type === 0 /* Component */ && typeof value === 'string' && value) { // Only components should enter this path, as helpers and modifiers do not // support string based resolution if (env.DEBUG) { if (isStrict) { throw new Error("Attempted to resolve a dynamic component with a string definition, `" + value + "` in a strict mode template. In strict mode, using strings to resolve component definitions is prohibited. You can instead import the component definition and use it directly."); } var resolvedDefinition = resolver.lookupComponent(value, owner); if (!resolvedDefinition) { throw new Error("Attempted to resolve `" + value + "`, which was expected to be a component, but nothing was found."); } } curriedDefinition = curry(type, value, owner, args); } else if (util.isObject(value)) { curriedDefinition = curry(type, value, owner, args); } else { curriedDefinition = null; } lastValue = value; return curriedDefinition; }); } function _defineProperties$1(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass$1(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties$1(Constructor.prototype, protoProps); if (staticProps) _defineProperties$1(Constructor, staticProps); return Constructor; } /* The calling convention is: * 0-N block arguments at the bottom * 0-N positional arguments next (left-to-right) * 0-N named arguments next */ var VMArgumentsImpl = /*#__PURE__*/function () { function VMArgumentsImpl() { this.stack = null; this.positional = new PositionalArgumentsImpl(); this.named = new NamedArgumentsImpl(); this.blocks = new BlockArgumentsImpl(); } var _proto = VMArgumentsImpl.prototype; _proto.empty = function empty(stack) { var base = stack[REGISTERS][vm.$sp] + 1; this.named.empty(stack, base); this.positional.empty(stack, base); this.blocks.empty(stack, base); return this; }; _proto.setup = function setup(stack, names, blockNames, positionalCount, atNames) { this.stack = stack; /* | ... | blocks | positional | named | | ... | b0 b1 | p0 p1 p2 p3 | n0 n1 | index | ... | 4/5/6 7/8/9 | 10 11 12 13 | 14 15 | ^ ^ ^ ^ bbase pbase nbase sp */ var named = this.named; var namedCount = names.length; var namedBase = stack[REGISTERS][vm.$sp] - namedCount + 1; named.setup(stack, namedBase, namedCount, names, atNames); var positional = this.positional; var positionalBase = namedBase - positionalCount; positional.setup(stack, positionalBase, positionalCount); var blocks = this.blocks; var blocksCount = blockNames.length; var blocksBase = positionalBase - blocksCount * 3; blocks.setup(stack, blocksBase, blocksCount, blockNames); }; _proto.at = function at(pos) { return this.positional.at(pos); }; _proto.realloc = function realloc(offset) { var stack = this.stack; if (offset > 0 && stack !== null) { var positional = this.positional, named = this.named; var newBase = positional.base + offset; var length = positional.length + named.length; for (var i = length - 1; i >= 0; i--) { stack.copy(i + positional.base, i + newBase); } positional.base += offset; named.base += offset; stack[REGISTERS][vm.$sp] += offset; } }; _proto.capture = function capture() { var positional = this.positional.length === 0 ? EMPTY_POSITIONAL : this.positional.capture(); var named = this.named.length === 0 ? EMPTY_NAMED : this.named.capture(); return { named: named, positional: positional }; }; _proto.clear = function clear() { var stack = this.stack, length = this.length; if (length > 0 && stack !== null) stack.pop(length); }; _createClass$1(VMArgumentsImpl, [{ key: "base", get: function get() { return this.blocks.base; } }, { key: "length", get: function get() { return this.positional.length + this.named.length + this.blocks.length * 3; } }]); return VMArgumentsImpl; }(); var EMPTY_REFERENCES = util.emptyArray(); var PositionalArgumentsImpl = /*#__PURE__*/function () { function PositionalArgumentsImpl() { this.base = 0; this.length = 0; this.stack = null; this._references = null; } var _proto2 = PositionalArgumentsImpl.prototype; _proto2.empty = function empty(stack, base) { this.stack = stack; this.base = base; this.length = 0; this._references = EMPTY_REFERENCES; }; _proto2.setup = function setup(stack, base, length) { this.stack = stack; this.base = base; this.length = length; if (length === 0) { this._references = EMPTY_REFERENCES; } else { this._references = null; } }; _proto2.at = function at(position) { var base = this.base, length = this.length, stack = this.stack; if (position < 0 || position >= length) { return reference.UNDEFINED_REFERENCE; } return stack.get(position, base); }; _proto2.capture = function capture() { return this.references; }; _proto2.prepend = function prepend(other) { var additions = other.length; if (additions > 0) { var base = this.base, length = this.length, stack = this.stack; this.base = base = base - additions; this.length = length + additions; for (var i = 0; i < additions; i++) { stack.set(other[i], i, base); } this._references = null; } }; _createClass$1(PositionalArgumentsImpl, [{ key: "references", get: function get() { var references = this._references; if (!references) { var stack = this.stack, base = this.base, length = this.length; references = this._references = stack.slice(base, base + length); } return references; } }]); return PositionalArgumentsImpl; }(); var NamedArgumentsImpl = /*#__PURE__*/function () { function NamedArgumentsImpl() { this.base = 0; this.length = 0; this._references = null; this._names = util.EMPTY_STRING_ARRAY; this._atNames = util.EMPTY_STRING_ARRAY; } var _proto3 = NamedArgumentsImpl.prototype; _proto3.empty = function empty(stack, base) { this.stack = stack; this.base = base; this.length = 0; this._references = EMPTY_REFERENCES; this._names = util.EMPTY_STRING_ARRAY; this._atNames = util.EMPTY_STRING_ARRAY; }; _proto3.setup = function setup(stack, base, length, names, atNames) { this.stack = stack; this.base = base; this.length = length; if (length === 0) { this._references = EMPTY_REFERENCES; this._names = util.EMPTY_STRING_ARRAY; this._atNames = util.EMPTY_STRING_ARRAY; } else { this._references = null; if (atNames) { this._names = null; this._atNames = names; } else { this._names = names; this._atNames = null; } } }; _proto3.has = function has(name) { return this.names.indexOf(name) !== -1; }; _proto3.get = function get(name, atNames) { if (atNames