UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

198 lines (168 loc) 16.7 kB
import { DEBUG } from '@glimmer/env'; import { assign, Stack } from '@glimmer/util'; import { reifyArgs } from './vm/arguments'; let GUID = 0; export class Ref { constructor(value) { this.id = GUID++; this.value = value; } get() { return this.value; } release() { if (DEBUG && this.value === null) { throw new Error('BUG: double release?'); } this.value = null; } toString() { let label = `Ref ${this.id}`; if (this.value === null) { return `${label} (released)`; } else { try { return `${label}: ${this.value}`; } catch (_a) { return label; } } } } export default class DebugRenderTreeImpl { constructor() { this.stack = new Stack(); this.refs = new WeakMap(); this.roots = new Set(); this.nodes = new WeakMap(); } begin() { this.reset(); } create(state, node) { let internalNode = assign({}, node, { bounds: null, refs: new Set() }); this.nodes.set(state, internalNode); this.appendChild(internalNode, state); this.enter(state); } update(state) { this.enter(state); } didRender(state, bounds) { if (DEBUG && this.stack.current !== state) { throw new Error(`BUG: expecting ${this.stack.current}, got ${state}`); } this.nodeFor(state).bounds = bounds; this.exit(); } willDestroy(state) { this.refs.get(state).release(); } commit() { this.reset(); } capture() { return this.captureRefs(this.roots); } reset() { if (this.stack.size !== 0) { // We probably encountered an error during the rendering loop. This will // likely trigger undefined behavior and memory leaks as the error left // things in an inconsistent state. It is recommended that the user // refresh the page. // TODO: We could warn here? But this happens all the time in our tests? // Clean up the root reference to prevent errors from happening if we // attempt to capture the render tree (Ember Inspector may do this) let root = this.stack.toArray()[0]; let ref = this.refs.get(root); if (ref !== undefined) { this.roots.delete(ref); } while (!this.stack.isEmpty()) { this.stack.pop(); } } } enter(state) { this.stack.push(state); } exit() { if (DEBUG && this.stack.size === 0) { throw new Error('BUG: unbalanced pop'); } this.stack.pop(); } nodeFor(state) { return this.nodes.get(state); } appendChild(node, state) { if (DEBUG && this.refs.has(state)) { throw new Error('BUG: child already appended'); } let parent = this.stack.current; let ref = new Ref(state); this.refs.set(state, ref); if (parent) { let parentNode = this.nodeFor(parent); parentNode.refs.add(ref); node.parent = parentNode; } else { this.roots.add(ref); } } captureRefs(refs) { let captured = []; refs.forEach(ref => { let state = ref.get(); if (state) { captured.push(this.captureNode(`render-node:${ref.id}`, state)); } else { refs.delete(ref); } }); return captured; } captureNode(id, state) { let node = this.nodeFor(state); let { type, name, args, instance, refs } = node; let template = this.captureTemplate(node); let bounds = this.captureBounds(node); let children = this.captureRefs(refs); return { id, type, name, args: reifyArgs(args), instance, template, bounds, children }; } captureTemplate({ template }) { return template || null; } captureBounds(node) { let bounds = node.bounds; let parentElement = bounds.parentElement(); let firstNode = bounds.firstNode(); let lastNode = bounds.lastNode(); return { parentElement, firstNode, lastNode }; } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RlYnVnLXJlbmRlci10cmVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFNBQVMsS0FBVCxRQUFzQixjQUF0QjtBQVFBLFNBQWlCLE1BQWpCLEVBQXlCLEtBQXpCLFFBQXNDLGVBQXRDO0FBQ0EsU0FBUyxTQUFULFFBQTBCLGdCQUExQjtBQVFBLElBQUksSUFBSSxHQUFHLENBQVg7QUFFQSxPQUFNLE1BQU8sR0FBUCxDQUFVO0FBSWQsRUFBQSxXQUFBLENBQVksS0FBWixFQUFvQjtBQUhYLFNBQUEsRUFBQSxHQUFhLElBQUksRUFBakI7QUFJUCxTQUFLLEtBQUwsR0FBYSxLQUFiO0FBQ0Q7O0FBRUQsRUFBQSxHQUFHLEdBQUE7QUFDRCxXQUFPLEtBQUssS0FBWjtBQUNEOztBQUVELEVBQUEsT0FBTyxHQUFBO0FBQ0wsUUFBSSxLQUFLLElBQUksS0FBSyxLQUFMLEtBQWUsSUFBNUIsRUFBa0M7QUFDaEMsWUFBTSxJQUFJLEtBQUosQ0FBVSxzQkFBVixDQUFOO0FBQ0Q7O0FBRUQsU0FBSyxLQUFMLEdBQWEsSUFBYjtBQUNEOztBQUVELEVBQUEsUUFBUSxHQUFBO0FBQ04sUUFBSSxLQUFLLEdBQUcsT0FBTyxLQUFLLEVBQUUsRUFBMUI7O0FBRUEsUUFBSSxLQUFLLEtBQUwsS0FBZSxJQUFuQixFQUF5QjtBQUN2QixhQUFPLEdBQUcsS0FBSyxhQUFmO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsVUFBSTtBQUNGLGVBQU8sR0FBRyxLQUFLLEtBQUssS0FBSyxLQUFLLEVBQTlCO0FBQ0QsT0FGRCxDQUVFLE9BQUEsRUFBQSxFQUFNO0FBQ04sZUFBTyxLQUFQO0FBQ0Q7QUFDRjtBQUNGOztBQWhDYTtBQW1DaEIsZUFBYyxNQUFPLG1CQUFQLENBQTBCO0FBQXhDLEVBQUEsV0FBQSxHQUFBO0FBRVUsU0FBQSxLQUFBLEdBQVEsSUFBSSxLQUFKLEVBQVI7QUFFQSxTQUFBLElBQUEsR0FB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QU0sR0FBRyxLQUFLLGFBQUwsQ0FBbUIsSUFBbkIsQ0FBYjtBQUNBLFFBQUksUUFBUSxHQUFHLEtBQUssV0FBTCxDQUFpQixJQUFqQixDQUFmO0FBQ0EsV0FBTztBQUFFLE1BQUEsRUFBRjtBQUFNLE1BQUEsSUFBTjtBQUFZLE1BQUEsSUFBWjtBQUFrQixNQUFBLElBQUksRUFBRSxTQUFTLENBQUMsSUFBRCxDQUFqQztBQUF5QyxNQUFBLFFBQXpDO0FBQW1ELE1BQUEsUUFBbkQ7QUFBNkQsTUFBQSxNQUE3RDtBQUFxRSxNQUFBO0FBQXJFLEtBQVA7QUFDRDs7QUFFTyxFQUFBLGVBQWUsQ0FBQztBQUFFLElBQUE7QUFBRixHQUFELEVBQTBDO0FBQy9ELFdBQU8sUUFBUSxJQUFJLElBQW5CO0FBQ0Q7O0FBRU8sRUFBQSxhQUFhLENBQUMsSUFBRCxFQUFrQztBQUNyRCxRQUFJLE1BQU0sR0FBVSxJQUFJLENBQUMsTUFBekI7QUFDQSxRQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsYUFBUCxFQUFwQjtBQUNBLFFBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFQLEVBQWhCO0FBQ0EsUUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVAsRUFBZjtBQUNBLFdBQU87QUFBRSxNQUFBLGFBQUY7QUFBaUIsTUFBQSxTQUFqQjtBQUE0QixNQUFBO0FBQTVCLEtBQVA7QUFDRDs7QUE3SXFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREVCVUcgfSBmcm9tICdAZ2xpbW1lci9lbnYnO1xuaW1wb3J0IHtcbiAgQm91bmRzLFxuICBDYXB0dXJlZFJlbmRlck5vZGUsXG4gIERlYnVnUmVuZGVyVHJlZSxcbiAgT3B0aW9uLFxuICBSZW5kZXJOb2RlLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IGV4cGVjdCwgYXNzaWduLCBTdGFjayB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgcmVpZnlBcmdzIH0gZnJvbSAnLi92bS9hcmd1bWVudHMnO1xuXG5pbnRlcmZhY2UgSW50ZXJuYWxSZW5kZXJOb2RlPFQgZXh0ZW5kcyBvYmplY3Q+IGV4dGVuZHMgUmVuZGVyTm9kZSB7XG4gIGJvdW5kczogT3B0aW9uPEJvdW5kcz47XG4gIHJlZnM6IFNldDxSZWY8VD4+O1xuICBwYXJlbnQ/OiBJbnRlcm5hbFJlbmRlck5vZGU8VD47XG59XG5cbmxldCBHVUlEID0gMDtcblxuZXhwb3J0IGNsYXNzIFJlZjxUIGV4dGVuZHMgb2JqZWN0PiB7XG4gIHJlYWRvbmx5IGlkOiBudW1iZXIgPSBHVUlEKys7XG4gIHByaXZhdGUgdmFsdWU6IE9wdGlvbjxUPjtcblxuICBjb25zdHJ1Y3Rvcih2YWx1ZTogVCkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCgpOiBPcHRpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICB9XG5cbiAgcmVsZWFzZSgpOiB2b2lkIHtcbiAgICBpZiAoREVCVUcgJiYgdGhpcy52YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCVUc6IGRvdWJsZSByZWxlYXNlPycpO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWUgPSBudWxsO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogU3RyaW5nIHtcbiAgICBsZXQgbGFiZWwgPSBgUmVmICR7dGhpcy5pZH1gO1xuXG4gICAgaWYgKHRoaXMudmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBgJHtsYWJlbH0gKHJlbGVhc2VkKWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBgJHtsYWJlbH06ICR7dGhpcy52YWx1ZX1gO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBsYWJlbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGVidWdSZW5kZXJUcmVlSW1wbDxUQnVja2V0IGV4dGVuZHMgb2JqZWN0PlxuICBpbXBsZW1lbnRzIERlYnVnUmVuZGVyVHJlZTxUQnVja2V0PiB7XG4gIHByaXZhdGUgc3RhY2sgPSBuZXcgU3RhY2s8VEJ1Y2tldD4oKTtcblxuICBwcml2YXRlIHJlZnMgPSBuZXcgV2Vha01hcDxUQnVja2V0LCBSZWY8VEJ1Y2tldD4+KCk7XG4gIHByaXZhdGUgcm9vdHMgPSBuZXcgU2V0PFJlZjxUQnVja2V0Pj4oKTtcbiAgcHJpdmF0ZSBub2RlcyA9IG5ldyBXZWFrTWFwPFRCdWNrZXQsIEludGVybmFsUmVuZGVyTm9kZTxUQnVja2V0Pj4oKTtcblxuICBiZWdpbigpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cblxuICBjcmVhdGUoc3RhdGU6IFRCdWNrZXQsIG5vZGU6IFJlbmRlck5vZGUpOiB2b2lkIHtcbiAgICBsZXQgaW50ZXJuYWxOb2RlOiBJbnRlcm5hbFJlbmRlck5vZGU8VEJ1Y2tldD4gPSBhc3NpZ24oe30sIG5vZGUsIHtcbiAgICAgIGJvdW5kczogbnVsbCxcbiAgICAgIHJlZnM6IG5ldyBTZXQ8UmVmPFRCdWNrZXQ+PigpLFxuICAgIH0pO1xuICAgIHRoaXMubm9kZXMuc2V0KHN0YXRlLCBpbnRlcm5hbE5vZGUpO1xuICAgIHRoaXMuYXBwZW5kQ2hpbGQoaW50ZXJuYWxOb2RlLCBzdGF0ZSk7XG4gICAgdGhpcy5lbnRlcihzdGF0ZSk7XG4gIH1cblxuICB1cGRhdGUoc3RhdGU6IFRCdWNrZXQpOiB2b2lkIHtcbiAgICB0aGlzLmVudGVyKHN0YXRlKTtcbiAgfVxuXG4gIGRpZFJlbmRlcihzdGF0ZTogVEJ1Y2tldCwgYm91bmRzOiBCb3VuZHMpOiB2b2lkIHtcbiAgICBpZiAoREVCVUcgJiYgdGhpcy5zdGFjay5jdXJyZW50ICE9PSBzdGF0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBCVUc6IGV4cGVjdGluZyAke3RoaXMuc3RhY2suY3VycmVudH0sIGdvdCAke3N0YXRlfWApO1xuICAgIH1cblxuICAgIHRoaXMubm9kZUZvcihzdGF0ZSkuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMuZXhpdCgpO1xuICB9XG5cbiAgd2lsbERlc3Ryb3koc3RhdGU6IFRCdWNrZXQpOiB2b2lkIHtcbiAgICBleHBlY3QodGhpcy5yZWZzLmdldChzdGF0ZSksICdCVUc6IG1pc3NpbmcgcmVmJykucmVsZWFzZSgpO1xuICB9XG5cbiAgY29tbWl0KCk6IHZvaWQge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG4gIGNhcHR1cmUoKTogQ2FwdHVyZWRSZW5kZXJOb2RlW10ge1xuICAgIHJldHVybiB0aGlzLmNhcHR1cmVSZWZzKHRoaXMucm9vdHMpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNldCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdGFjay5zaXplICE9PSAwKSB7XG4gICAgICAvLyBXZSBwcm9iYWJseSBlbmNvdW50ZXJlZCBhbiBlcnJvciBkdXJpbmcgdGhlIHJlbmRlcmluZyBsb29wLiBUaGlzIHdpbGxcbiAgICAgIC8vIGxpa2VseSB0cmlnZ2VyIHVuZGVmaW5lZCBiZWhhdmlvciBhbmQgbWVtb3J5IGxlYWtzIGFzIHRoZSBlcnJvciBsZWZ0XG4gICAgICAvLyB0aGluZ3MgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBJdCBpcyByZWNvbW1lbmRlZCB0aGF0IHRoZSB1c2VyXG4gICAgICAvLyByZWZyZXNoIHRoZSBwYWdlLlxuXG4gICAgICAvLyBUT0RPOiBXZSBjb3VsZCB3YXJuIGhlcmU/IEJ1dCB0aGlzIGhhcHBlbnMgYWxsIHRoZSB0aW1lIGluIG91ciB0ZXN0cz9cblxuICAgICAgLy8gQ2xlYW4gdXAgdGhlIHJvb3QgcmVmZXJlbmNlIHRvIHByZXZlbnQgZXJyb3JzIGZyb20gaGFwcGVuaW5nIGlmIHdlXG4gICAgICAvLyBhdHRlbXB0IHRvIGNhcHR1cmUgdGhlIHJlbmRlciB0cmVlIChFbWJlciBJbnNwZWN0b3IgbWF5IGRvIHRoaXMpXG4gICAgICBsZXQgcm9vdCA9IGV4cGVjdCh0aGlzLnN0YWNrLnRvQXJyYXkoKVswXSwgJ2V4cGVjdGVkIHJvb3Qgc3RhdGUgd2hlbiByZXNldHRpbmcgcmVuZGVyIHRyZWUnKTtcbiAgICAgIGxldCByZWYgPSB0aGlzLnJlZnMuZ2V0KHJvb3QpO1xuXG4gICAgICBpZiAocmVmICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5yb290cy5kZWxldGUocmVmKTtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKCF0aGlzLnN0YWNrLmlzRW1wdHkoKSkge1xuICAgICAgICB0aGlzLnN0YWNrLnBvcCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW50ZXIoc3RhdGU6IFRCdWNrZXQpOiB2b2lkIHtcbiAgICB0aGlzLnN0YWNrLnB1c2goc3RhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBleGl0KCk6IHZvaWQge1xuICAgIGlmIChERUJVRyAmJiB0aGlzLnN0YWNrLnNpemUgPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQlVHOiB1bmJhbGFuY2VkIHBvcCcpO1xuICAgIH1cblxuICAgIHRoaXMuc3RhY2sucG9wKCk7XG4gIH1cblxuICBwcml2YXRlIG5vZGVGb3Ioc3RhdGU6IFRCdWNrZXQpOiBJbnRlcm5hbFJlbmRlck5vZGU8VEJ1Y2tldD4ge1xuICAgIHJldHVybiBleHBlY3QodGhpcy5ub2Rlcy5nZXQoc3RhdGUpLCAnQlVHOiBtaXNzaW5nIG5vZGUnKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwZW5kQ2hpbGQobm9kZTogSW50ZXJuYWxSZW5kZXJOb2RlPFRCdWNrZXQ+LCBzdGF0ZTogVEJ1Y2tldCk6IHZvaWQge1xuICAgIGlmIChERUJVRyAmJiB0aGlzLnJlZnMuaGFzKHN0YXRlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCVUc6IGNoaWxkIGFscmVhZHkgYXBwZW5kZWQnKTtcbiAgICB9XG5cbiAgICBsZXQgcGFyZW50ID0gdGhpcy5zdGFjay5jdXJyZW50O1xuICAgIGxldCByZWYgPSBuZXcgUmVmKHN0YXRlKTtcblxuICAgIHRoaXMucmVmcy5zZXQoc3RhdGUsIHJlZik7XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICBsZXQgcGFyZW50Tm9kZSA9IHRoaXMubm9kZUZvcihwYXJlbnQpO1xuICAgICAgcGFyZW50Tm9kZS5yZWZzLmFkZChyZWYpO1xuICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnROb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvb3RzLmFkZChyZWYpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FwdHVyZVJlZnMocmVmczogU2V0PFJlZjxUQnVja2V0Pj4pOiBDYXB0dXJlZFJlbmRlck5vZGVbXSB7XG4gICAgbGV0IGNhcHR1cmVkOiBDYXB0dXJlZFJlbmRlck5vZGVbXSA9IFtdO1xuXG4gICAgcmVmcy5mb3JFYWNoKChyZWYpID0+IHtcbiAgICAgIGxldCBzdGF0ZSA9IHJlZi5nZXQoKTtcblxuICAgICAgaWYgKHN0YXRlKSB7XG4gICAgICAgIGNhcHR1cmVkLnB1c2godGhpcy5jYXB0dXJlTm9kZShgcmVuZGVyLW5vZGU6JHtyZWYuaWR9YCwgc3RhdGUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlZnMuZGVsZXRlKHJlZik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FwdHVyZWQ7XG4gIH1cblxuICBwcml2YXRlIGNhcHR1cmVOb2RlKGlkOiBzdHJpbmcsIHN0YXRlOiBUQnVja2V0KTogQ2FwdHVyZWRSZW5kZXJOb2RlIHtcbiAgICBsZXQgbm9kZSA9IHRoaXMubm9kZUZvcihzdGF0ZSk7XG4gICAgbGV0IHsgdHlwZSwgbmFtZSwgYXJncywgaW5zdGFuY2UsIHJlZnMgfSA9IG5vZGU7XG4gICAgbGV0IHRlbXBsYXRlID0gdGhpcy5jYXB0dXJlVGVtcGxhdGUobm9kZSk7XG4gICAgbGV0IGJvdW5kcyA9IHRoaXMuY2FwdHVyZUJvdW5kcyhub2RlKTtcbiAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLmNhcHR1cmVSZWZzKHJlZnMpO1xuICAgIHJldHVybiB7IGlkLCB0eXBlLCBuYW1lLCBhcmdzOiByZWlmeUFyZ3MoYXJncyksIGluc3RhbmNlLCB0ZW1wbGF0ZSwgYm91bmRzLCBjaGlsZHJlbiB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjYXB0dXJlVGVtcGxhdGUoeyB0ZW1wbGF0ZSB9OiBJbnRlcm5hbFJlbmRlck5vZGU8VEJ1Y2tldD4pOiBPcHRpb248c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRlbXBsYXRlIHx8IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGNhcHR1cmVCb3VuZHMobm9kZTogSW50ZXJuYWxSZW5kZXJOb2RlPFRCdWNrZXQ+KTogQ2FwdHVyZWRSZW5kZXJOb2RlWydib3VuZHMnXSB7XG4gICAgbGV0IGJvdW5kcyA9IGV4cGVjdChub2RlLmJvdW5kcywgJ0JVRzogbWlzc2luZyBib3VuZHMnKTtcbiAgICBsZXQgcGFyZW50RWxlbWVudCA9IGJvdW5kcy5wYXJlbnRFbGVtZW50KCk7XG4gICAgbGV0IGZpcnN0Tm9kZSA9IGJvdW5kcy5maXJzdE5vZGUoKTtcbiAgICBsZXQgbGFzdE5vZGUgPSBib3VuZHMubGFzdE5vZGUoKTtcbiAgICByZXR1cm4geyBwYXJlbnRFbGVtZW50LCBmaXJzdE5vZGUsIGxhc3ROb2RlIH07XG4gIH1cbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=