@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
121 lines (104 loc) • 13.6 kB
JavaScript
import { ConcreteBounds } from '../bounds';
// http://www.w3.org/TR/html/syntax.html#html-integration-point
const SVG_INTEGRATION_POINTS = {
foreignObject: 1,
desc: 1,
title: 1
}; // http://www.w3.org/TR/html/syntax.html#adjust-svg-attributes
// TODO: Adjust SVG attributes
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
// TODO: Adjust SVG elements
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
export const BLACKLIST_TABLE = Object.create(null);
export class DOMOperations {
constructor(document) {
this.document = document;
this.setupUselessElement();
} // split into separate method so that NodeDOMTreeConstruction
// can override it.
setupUselessElement() {
this.uselessElement = this.document.createElement('div');
}
createElement(tag, context) {
let isElementInSVGNamespace, isHTMLIntegrationPoint;
if (context) {
isElementInSVGNamespace = context.namespaceURI === "http://www.w3.org/2000/svg"
/* SVG */
|| tag === 'svg';
isHTMLIntegrationPoint = !!SVG_INTEGRATION_POINTS[context.tagName];
} else {
isElementInSVGNamespace = tag === 'svg';
isHTMLIntegrationPoint = false;
}
if (isElementInSVGNamespace && !isHTMLIntegrationPoint) {
// FIXME: This does not properly handle <font> with color, face, or
// size attributes, which is also disallowed by the spec. We should fix
// this.
if (BLACKLIST_TABLE[tag]) {
throw new Error(`Cannot create a ${tag} inside an SVG context`);
}
return this.document.createElementNS("http://www.w3.org/2000/svg"
/* SVG */
, tag);
} else {
return this.document.createElement(tag);
}
}
insertBefore(parent, node, reference) {
parent.insertBefore(node, reference);
}
insertHTMLBefore(parent, nextSibling, html) {
if (html === '') {
let comment = this.createComment('');
parent.insertBefore(comment, nextSibling);
return new ConcreteBounds(parent, comment, comment);
}
let prev = nextSibling ? nextSibling.previousSibling : parent.lastChild;
let last;
if (nextSibling === null) {
parent.insertAdjacentHTML("beforeend"
/* beforeend */
, html);
last = parent.lastChild;
} else if (nextSibling instanceof HTMLElement) {
nextSibling.insertAdjacentHTML('beforebegin', html);
last = nextSibling.previousSibling;
} else {
// Non-element nodes do not support insertAdjacentHTML, so add an
// element and call it on that element. Then remove the element.
//
// This also protects Edge, IE and Firefox w/o the inspector open
// from merging adjacent text nodes. See ./compat/text-node-merging-fix.ts
let {
uselessElement
} = this;
parent.insertBefore(uselessElement, nextSibling);
uselessElement.insertAdjacentHTML("beforebegin"
/* beforebegin */
, html);
last = uselessElement.previousSibling;
parent.removeChild(uselessElement);
}
let first = prev ? prev.nextSibling : parent.firstChild;
return new ConcreteBounds(parent, first, last);
}
createTextNode(text) {
return this.document.createTextNode(text);
}
createComment(data) {
return this.document.createComment(data);
}
}
export function moveNodesBefore(source, target, nextSibling) {
let first = source.firstChild;
let last = first;
let current = first;
while (current) {
let next = current.nextSibling;
target.insertBefore(current, nextSibling);
last = current;
current = next;
}
return new ConcreteBounds(target, first, last);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RvbS9vcGVyYXRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVVBLFNBQVMsY0FBVCxRQUErQixXQUEvQjtBQUdBO0FBQ0EsTUFBTSxzQkFBc0IsR0FBRztBQUFFLEVBQUEsYUFBYSxFQUFFLENBQWpCO0FBQW9CLEVBQUEsSUFBSSxFQUFFLENBQTFCO0FBQTZCLEVBQUEsS0FBSyxFQUFFO0FBQXBDLENBQS9CLEMsQ0FFQTtBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUNBLE9BQU8sTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLE1BQVAsQ0FBYyxJQUFkLENBQXhCO0FBRVAsT0FBTSxNQUFPLGFBQVAsQ0FBb0I7QUFHeEIsRUFBQSxXQUFBLENBQXNCLFFBQXRCLEVBQThDO0FBQXhCLFNBQUEsUUFBQSxHQUFBLFFBQUE7QUFDcEIsU0FBSyxtQkFBTDtBQUNELEdBTHVCLENBT3hCO0FBQ0E7OztBQUNVLEVBQUEsbUJBQW1CLEdBQUE7QUFDM0IsU0FBSyxjQUFMLEdBQXNCLEtBQUssUUFBTCxDQUFjLGFBQWQsQ0FBNEIsS0FBNUIsQ0FBdEI7QUFDRDs7QUFFRCxFQUFBLGFBQWEsQ0FBQyxHQUFELEVBQWMsT0FBZCxFQUFxQztBQUNoRCxRQUFJLHVCQUFKLEVBQXNDLHNCQUF0Qzs7QUFFQSxRQUFJLE9BQUosRUFBYTtBQUNYLE1BQUEsdUJBQXVCLEdBQUcsT0FBTyxDQUFDLFlBQVIsS0FBb0I7QUFBQTtBQUFwQixTQUEwQyxHQUFHLEtBQUssS0FBNUU7QUFDQSxNQUFBLHNCQUFzQixHQUFHLENBQUMsQ0FBRSxzQkFBdUMsQ0FBQyxPQUFPLENBQUMsT0FBVCxDQUFuRTtBQUNELEtBSEQsTUFHTztBQUNMLE1BQUEsdUJBQXVCLEdBQUcsR0FBRyxLQUFLLEtBQWxDO0FBQ0EsTUFBQSxzQkFBc0IsR0FBRyxLQUF6QjtBQUNEOztBQUVELFFBQUksdUJBQXVCLElBQUksQ0FBQyxz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RyxPQUFQO0FBQ0EsSUFBQSxPQUFPLEdBQUcsSUFBVjtBQUNEOztBQUVELFNBQU8sSUFBSSxjQUFKLENBQW1CLE1BQW5CLEVBQTJCLEtBQTNCLEVBQWtDLElBQWxDLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFNpbXBsZUVsZW1lbnQsXG4gIFNpbXBsZURvY3VtZW50LFxuICBOYW1lc3BhY2UsXG4gIFNpbXBsZU5vZGUsXG4gIEluc2VydFBvc2l0aW9uLFxuICBTaW1wbGVUZXh0LFxuICBTaW1wbGVDb21tZW50LFxufSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRGljdCwgT3B0aW9uLCBCb3VuZHMgfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IENvbmNyZXRlQm91bmRzIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IGV4cGVjdCB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG4vLyBodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sL3N5bnRheC5odG1sI2h0bWwtaW50ZWdyYXRpb24tcG9pbnRcbmNvbnN0IFNWR19JTlRFR1JBVElPTl9QT0lOVFMgPSB7IGZvcmVpZ25PYmplY3Q6IDEsIGRlc2M6IDEsIHRpdGxlOiAxIH07XG5cbi8vIGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWwvc3ludGF4Lmh0bWwjYWRqdXN0LXN2Zy1hdHRyaWJ1dGVzXG4vLyBUT0RPOiBBZGp1c3QgU1ZHIGF0dHJpYnV0ZXNcblxuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5mb3JlaWduXG4vLyBUT0RPOiBBZGp1c3QgU1ZHIGVsZW1lbnRzXG5cbi8vIGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWwvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluZm9yZWlnblxuZXhwb3J0IGNvbnN0IEJMQUNLTElTVF9UQUJMRSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmV4cG9ydCBjbGFzcyBET01PcGVyYXRpb25zIHtcbiAgcHJvdGVjdGVkIHVzZWxlc3NFbGVtZW50ITogU2ltcGxlRWxlbWVudDsgLy8gU2V0IGJ5IHRoaXMuc2V0dXBVc2VsZXNzRWxlbWVudCgpIGluIGNvbnN0cnVjdG9yXG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIGRvY3VtZW50OiBTaW1wbGVEb2N1bWVudCkge1xuICAgIHRoaXMuc2V0dXBVc2VsZXNzRWxlbWVudCgpO1xuICB9XG5cbiAgLy8gc3BsaXQgaW50byBzZXBhcmF0ZSBtZXRob2Qgc28gdGhhdCBOb2RlRE9NVHJlZUNvbnN0cnVjdGlvblxuICAvLyBjYW4gb3ZlcnJpZGUgaXQuXG4gIHByb3RlY3RlZCBzZXR1cFVzZWxlc3NFbGVtZW50KCkge1xuICAgIHRoaXMudXNlbGVzc0VsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICB9XG5cbiAgY3JlYXRlRWxlbWVudCh0YWc6IHN0cmluZywgY29udGV4dD86IFNpbXBsZUVsZW1lbnQpOiBTaW1wbGVFbGVtZW50IHtcbiAgICBsZXQgaXNFbGVtZW50SW5TVkdOYW1lc3BhY2U6IGJvb2xlYW4sIGlzSFRNTEludGVncmF0aW9uUG9pbnQ6IGJvb2xlYW47XG5cbiAgICBpZiAoY29udGV4dCkge1xuICAgICAgaXNFbGVtZW50SW5TVkdOYW1lc3BhY2UgPSBjb250ZXh0Lm5hbWVzcGFjZVVSSSA9PT0gTmFtZXNwYWNlLlNWRyB8fCB0YWcgPT09ICdzdmcnO1xuICAgICAgaXNIVE1MSW50ZWdyYXRpb25Qb2ludCA9ICEhKFNWR19JTlRFR1JBVElPTl9QT0lOVFMgYXMgRGljdDxudW1iZXI+KVtjb250ZXh0LnRhZ05hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpc0VsZW1lbnRJblNWR05hbWVzcGFjZSA9IHRhZyA9PT0gJ3N2Zyc7XG4gICAgICBpc0hUTUxJbnRlZ3JhdGlvblBvaW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGlzRWxlbWVudEluU1ZHTmFtZXNwYWNlICYmICFpc0hUTUxJbnRlZ3JhdGlvblBvaW50KSB7XG4gICAgICAvLyBGSVhNRTogVGhpcyBkb2VzIG5vdCBwcm9wZXJseSBoYW5kbGUgPGZvbnQ+IHdpdGggY29sb3IsIGZhY2UsIG9yXG4gICAgICAvLyBzaXplIGF0dHJpYnV0ZXMsIHdoaWNoIGlzIGFsc28gZGlzYWxsb3dlZCBieSB0aGUgc3BlYy4gV2Ugc2hvdWxkIGZpeFxuICAgICAgLy8gdGhpcy5cbiAgICAgIGlmIChCTEFDS0xJU1RfVEFCTEVbdGFnXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjcmVhdGUgYSAke3RhZ30gaW5zaWRlIGFuIFNWRyBjb250ZXh0YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhOYW1lc3BhY2UuU1ZHLCB0YWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7XG4gICAgfVxuICB9XG5cbiAgaW5zZXJ0QmVmb3JlKHBhcmVudDogU2ltcGxlRWxlbWVudCwgbm9kZTogU2ltcGxlTm9kZSwgcmVmZXJlbmNlOiBPcHRpb248U2ltcGxlTm9kZT4pIHtcbiAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5vZGUsIHJlZmVyZW5jZSk7XG4gIH1cblxuICBpbnNlcnRIVE1MQmVmb3JlKHBhcmVudDogU2ltcGxlRWxlbWVudCwgbmV4dFNpYmxpbmc6IE9wdGlvbjxTaW1wbGVOb2RlPiwgaHRtbDogc3RyaW5nKTogQm91bmRzIHtcbiAgICBpZiAoaHRtbCA9PT0gJycpIHtcbiAgICAgIGxldCBjb21tZW50ID0gdGhpcy5jcmVhdGVDb21tZW50KCcnKTtcbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY29tbWVudCwgbmV4dFNpYmxpbmcpO1xuICAgICAgcmV0dXJuIG5ldyBDb25jcmV0ZUJvdW5kcyhwYXJlbnQsIGNvbW1lbnQsIGNvbW1lbnQpO1xuICAgIH1cblxuICAgIGxldCBwcmV2ID0gbmV4dFNpYmxpbmcgPyBuZXh0U2libGluZy5wcmV2aW91c1NpYmxpbmcgOiBwYXJlbnQubGFzdENoaWxkO1xuICAgIGxldCBsYXN0OiBTaW1wbGVOb2RlO1xuXG4gICAgaWYgKG5leHRTaWJsaW5nID09PSBudWxsKSB7XG4gICAgICBwYXJlbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKEluc2VydFBvc2l0aW9uLmJlZm9yZWVuZCwgaHRtbCk7XG4gICAgICBsYXN0ID0gZXhwZWN0KHBhcmVudC5sYXN0Q2hpbGQsICdidWcgaW4gaW5zZXJ0QWRqYWNlbnRIVE1MPycpO1xuICAgIH0gZWxzZSBpZiAobmV4dFNpYmxpbmcgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgbmV4dFNpYmxpbmcuaW5zZXJ0QWRqYWNlbnRIVE1MKCdiZWZvcmViZWdpbicsIGh0bWwpO1xuICAgICAgbGFzdCA9IGV4cGVjdChuZXh0U2libGluZy5wcmV2aW91c1NpYmxpbmcsICdidWcgaW4gaW5zZXJ0QWRqYWNlbnRIVE1MPycpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOb24tZWxlbWVudCBub2RlcyBkbyBub3Qgc3VwcG9ydCBpbnNlcnRBZGphY2VudEhUTUwsIHNvIGFkZCBhblxuICAgICAgLy8gZWxlbWVudCBhbmQgY2FsbCBpdCBvbiB0aGF0IGVsZW1lbnQuIFRoZW4gcmVtb3ZlIHRoZSBlbGVtZW50LlxuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgYWxzbyBwcm90ZWN0cyBFZGdlLCBJRSBhbmQgRmlyZWZveCB3L28gdGhlIGluc3BlY3RvciBvcGVuXG4gICAgICAvLyBmcm9tIG1lcmdpbmcgYWRqYWNlbnQgdGV4dCBub2Rlcy4gU2VlIC4vY29tcGF0L3RleHQtbm9kZS1tZXJnaW5nLWZpeC50c1xuICAgICAgbGV0IHsgdXNlbGVzc0VsZW1lbnQgfSA9IHRoaXM7XG5cbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUodXNlbGVzc0VsZW1lbnQsIG5leHRTaWJsaW5nKTtcbiAgICAgIHVzZWxlc3NFbGVtZW50Lmluc2VydEFkamFjZW50SFRNTChJbnNlcnRQb3NpdGlvbi5iZWZvcmViZWdpbiwgaHRtbCk7XG4gICAgICBsYXN0ID0gZXhwZWN0KHVzZWxlc3NFbGVtZW50LnByZXZpb3VzU2libGluZywgJ2J1ZyBpbiBpbnNlcnRBZGphY2VudEhUTUw/Jyk7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodXNlbGVzc0VsZW1lbnQpO1xuICAgIH1cblxuICAgIGxldCBmaXJzdCA9IGV4cGVjdChwcmV2ID8gcHJldi5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkLCAnYnVnIGluIGluc2VydEFkamFjZW50SFRNTD8nKTtcbiAgICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHBhcmVudCwgZmlyc3QsIGxhc3QpO1xuICB9XG5cbiAgY3JlYXRlVGV4dE5vZGUodGV4dDogc3RyaW5nKTogU2ltcGxlVGV4dCB7XG4gICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCk7XG4gIH1cblxuICBjcmVhdGVDb21tZW50KGRhdGE6IHN0cmluZyk6IFNpbXBsZUNvbW1lbnQge1xuICAgIHJldHVybiB0aGlzLmRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoZGF0YSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1vdmVOb2Rlc0JlZm9yZShcbiAgc291cmNlOiBTaW1wbGVOb2RlLFxuICB0YXJnZXQ6IFNpbXBsZUVsZW1lbnQsXG4gIG5leHRTaWJsaW5nOiBPcHRpb248U2ltcGxlTm9kZT5cbik6IEJvdW5kcyB7XG4gIGxldCBmaXJzdCA9IGV4cGVjdChzb3VyY2UuZmlyc3RDaGlsZCwgJ3NvdXJjZSBpcyBlbXB0eScpO1xuICBsZXQgbGFzdDogU2ltcGxlTm9kZSA9IGZpcnN0O1xuICBsZXQgY3VycmVudDogT3B0aW9uPFNpbXBsZU5vZGU+ID0gZmlyc3Q7XG5cbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBsZXQgbmV4dDogT3B0aW9uPFNpbXBsZU5vZGU+ID0gY3VycmVudC5uZXh0U2libGluZztcblxuICAgIHRhcmdldC5pbnNlcnRCZWZvcmUoY3VycmVudCwgbmV4dFNpYmxpbmcpO1xuXG4gICAgbGFzdCA9IGN1cnJlbnQ7XG4gICAgY3VycmVudCA9IG5leHQ7XG4gIH1cblxuICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHRhcmdldCwgZmlyc3QsIGxhc3QpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==