@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
1,717 lines (1,378 loc) • 783 kB
JavaScript
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