UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

121 lines (104 loc) 13.6 kB
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==