@embroider/core 3.3.1-unstable.cb4e47b → 3.3.1-unstable.cd8d1be

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embroider/core",
3
- "version": "3.3.1-unstable.cb4e47b",
3
+ "version": "3.3.1-unstable.cd8d1be",
4
4
  "private": false,
5
5
  "description": "A build system for EmberJS applications.",
6
6
  "repository": {
@@ -23,8 +23,8 @@
23
23
  "@babel/core": "^7.14.5",
24
24
  "@babel/parser": "^7.14.5",
25
25
  "@babel/traverse": "^7.14.5",
26
- "@embroider/macros": "1.13.3-unstable.cb4e47b",
27
- "@embroider/shared-internals": "2.5.1-unstable.cb4e47b",
26
+ "@embroider/macros": "1.13.3-unstable.cd8d1be",
27
+ "@embroider/shared-internals": "2.5.1-unstable.cd8d1be",
28
28
  "assert-never": "^1.2.1",
29
29
  "babel-plugin-ember-template-compilation": "^2.1.1",
30
30
  "broccoli-node-api": "^1.7.0",
@@ -9,31 +9,35 @@ export interface EmberHTML {
9
9
  implicitTestScripts?: Node;
10
10
  implicitTestStyles?: Node;
11
11
  }
12
- declare class NodeRange {
13
- end: Node;
14
- start: Node;
15
- constructor(initial: Node);
12
+ declare class Placeholder {
13
+ readonly start: Node;
14
+ readonly end: Node;
15
+ readonly reference: Node;
16
+ static replacing(node: Node): Placeholder;
17
+ static immediatelyAfter(node: Node): Placeholder;
18
+ readonly parent: HTMLElement;
19
+ constructor(start: Node, end: Node, reference: Node);
16
20
  clear(): void;
17
21
  insert(node: Node): void;
18
22
  }
19
23
  export declare class PreparedEmberHTML {
20
24
  private asset;
21
25
  dom: JSDOM;
22
- javascript: NodeRange;
23
- styles: NodeRange;
24
- implicitScripts: NodeRange;
25
- implicitStyles: NodeRange;
26
- testJavascript: NodeRange;
27
- implicitTestScripts: NodeRange;
28
- implicitTestStyles: NodeRange;
26
+ javascript: Placeholder;
27
+ styles: Placeholder;
28
+ implicitScripts: Placeholder;
29
+ implicitStyles: Placeholder;
30
+ testJavascript: Placeholder;
31
+ implicitTestScripts: Placeholder;
32
+ implicitTestStyles: Placeholder;
29
33
  constructor(asset: EmberAsset);
30
- private allRanges;
34
+ private placeholders;
31
35
  clear(): void;
32
- insertScriptTag(location: NodeRange, relativeSrc: string, opts?: {
36
+ insertScriptTag(placeholder: Placeholder, relativeSrc: string, { type, tag }?: {
33
37
  type?: string;
34
38
  tag?: string;
35
39
  }): void;
36
- insertStyleLink(location: NodeRange, relativeHref: string): void;
40
+ insertStyleLink(placeholder: Placeholder, relativeHref: string): void;
37
41
  }
38
42
  export declare function insertNewline(at: Node): void;
39
43
  export {};
package/src/ember-html.js CHANGED
@@ -3,44 +3,69 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.insertNewline = exports.PreparedEmberHTML = void 0;
4
4
  const jsdom_1 = require("jsdom");
5
5
  const fs_1 = require("fs");
6
- class NodeRange {
7
- constructor(initial) {
8
- this.start = initial.ownerDocument.createTextNode('');
9
- initial.parentElement.insertBefore(this.start, initial);
10
- this.end = initial;
6
+ const html_placeholder_1 = require("./html-placeholder");
7
+ class Placeholder {
8
+ static replacing(node) {
9
+ let placeholder = this.immediatelyAfter(node);
10
+ node.parentElement.removeChild(node);
11
+ return placeholder;
12
+ }
13
+ static immediatelyAfter(node) {
14
+ let document = node.ownerDocument;
15
+ let parent = node.parentElement;
16
+ if (!document || !parent) {
17
+ throw new Error('Cannot make Placeholder out of detached node');
18
+ }
19
+ let nextSibling = node.nextSibling;
20
+ let start = document.createTextNode('');
21
+ let end = document.createTextNode('');
22
+ parent.insertBefore(start, nextSibling);
23
+ parent.insertBefore(end, nextSibling);
24
+ return new Placeholder(start, end, node);
25
+ }
26
+ constructor(start, end, reference) {
27
+ this.start = start;
28
+ this.end = end;
29
+ this.reference = reference;
30
+ if (start.parentElement && start.parentElement === end.parentElement) {
31
+ this.parent = start.parentElement;
32
+ }
33
+ else {
34
+ throw new Error('Cannot make Placeholder out of detached node');
35
+ }
11
36
  }
12
37
  clear() {
13
- while (this.start.nextSibling !== this.end) {
14
- this.start.parentElement.removeChild(this.start.nextSibling);
38
+ let { start, end, parent } = this;
39
+ let target = start.nextSibling;
40
+ while (target && target !== end) {
41
+ parent.removeChild(target);
42
+ target = target.nextSibling;
15
43
  }
16
44
  }
17
45
  insert(node) {
18
- this.end.parentElement.insertBefore(node, this.end);
46
+ this.parent.insertBefore(node, this.end);
19
47
  }
20
48
  }
21
- function immediatelyAfter(node) {
22
- let newMarker = node.ownerDocument.createTextNode('');
23
- node.parentElement.insertBefore(newMarker, node.nextSibling);
24
- return new NodeRange(newMarker);
25
- }
26
49
  class PreparedEmberHTML {
27
50
  constructor(asset) {
28
51
  this.asset = asset;
29
52
  this.dom = new jsdom_1.JSDOM((0, fs_1.readFileSync)(asset.sourcePath, 'utf8'));
30
53
  let html = asset.prepare(this.dom);
31
- this.javascript = new NodeRange(html.javascript);
32
- this.styles = new NodeRange(html.styles);
33
- this.implicitScripts = new NodeRange(html.implicitScripts);
34
- this.implicitStyles = new NodeRange(html.implicitStyles);
35
- this.testJavascript = html.testJavascript ? new NodeRange(html.testJavascript) : immediatelyAfter(html.javascript);
54
+ this.javascript = Placeholder.replacing(html.javascript);
55
+ this.styles = Placeholder.replacing(html.styles);
56
+ this.implicitScripts = Placeholder.replacing(html.implicitScripts);
57
+ this.implicitStyles = Placeholder.replacing(html.implicitStyles);
58
+ this.testJavascript = html.testJavascript
59
+ ? Placeholder.replacing(html.testJavascript)
60
+ : Placeholder.immediatelyAfter(this.javascript.end);
36
61
  this.implicitTestScripts = html.implicitTestScripts
37
- ? new NodeRange(html.implicitTestScripts)
38
- : immediatelyAfter(html.implicitScripts);
62
+ ? Placeholder.replacing(html.implicitTestScripts)
63
+ : Placeholder.immediatelyAfter(this.implicitScripts.end);
39
64
  this.implicitTestStyles = html.implicitTestStyles
40
- ? new NodeRange(html.implicitTestStyles)
41
- : immediatelyAfter(html.implicitStyles);
65
+ ? Placeholder.replacing(html.implicitTestStyles)
66
+ : Placeholder.immediatelyAfter(this.implicitStyles.end);
42
67
  }
43
- allRanges() {
68
+ placeholders() {
44
69
  return [
45
70
  this.javascript,
46
71
  this.styles,
@@ -52,29 +77,31 @@ class PreparedEmberHTML {
52
77
  ];
53
78
  }
54
79
  clear() {
55
- for (let range of this.allRanges()) {
80
+ for (let range of this.placeholders()) {
56
81
  range.clear();
57
82
  }
58
83
  }
59
84
  // this takes the src relative to the application root, we adjust it so it's
60
85
  // root-relative via the configured rootURL
61
- insertScriptTag(location, relativeSrc, opts) {
62
- let newTag = this.dom.window.document.createElement(opts && opts.tag ? opts.tag : 'script');
63
- newTag.setAttribute('src', this.asset.rootURL + relativeSrc);
64
- if (opts && opts.type) {
65
- newTag.setAttribute('type', opts.type);
66
- }
67
- location.insert(this.dom.window.document.createTextNode('\n'));
68
- location.insert(newTag);
86
+ insertScriptTag(placeholder, relativeSrc, { type, tag = 'script' } = {}) {
87
+ let document = this.dom.window.document;
88
+ let from = placeholder.reference.nodeType === 1 ? placeholder.reference : undefined;
89
+ let src = this.asset.rootURL + relativeSrc;
90
+ let attributes = type ? { src, type } : { src };
91
+ let newTag = (0, html_placeholder_1.makeTag)(document, { from, tag, attributes });
92
+ placeholder.insert(this.dom.window.document.createTextNode('\n'));
93
+ placeholder.insert(newTag);
69
94
  }
70
95
  // this takes the href relative to the application root, we adjust it so it's
71
96
  // root-relative via the configured rootURL
72
- insertStyleLink(location, relativeHref) {
73
- let newTag = this.dom.window.document.createElement('link');
74
- newTag.rel = 'stylesheet';
75
- newTag.href = this.asset.rootURL + relativeHref;
76
- location.insert(this.dom.window.document.createTextNode('\n'));
77
- location.insert(newTag);
97
+ insertStyleLink(placeholder, relativeHref) {
98
+ let document = this.dom.window.document;
99
+ let from = placeholder.reference.nodeType === 1 ? placeholder.reference : undefined;
100
+ let href = this.asset.rootURL + relativeHref;
101
+ let newTag = (0, html_placeholder_1.makeTag)(document, { from, tag: 'link', attributes: { href } });
102
+ (0, html_placeholder_1.normalizeStyleLink)(newTag);
103
+ placeholder.insert(this.dom.window.document.createTextNode('\n'));
104
+ placeholder.insert(newTag);
78
105
  }
79
106
  }
80
107
  exports.PreparedEmberHTML = PreparedEmberHTML;
@@ -1 +1 @@
1
- {"version":3,"file":"ember-html.js","sourceRoot":"","sources":["ember-html.ts"],"names":[],"mappings":"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","sourcesContent":["import { JSDOM } from 'jsdom';\nimport { readFileSync } from 'fs';\nimport type { EmberAsset } from './asset';\n\nexport interface EmberHTML {\n // each of the Nodes in here points at where we should insert the\n // corresponding parts of the ember app. The Nodes themselves will be\n // replaced, so provide placeholders.\n\n // these are mandatory, the Ember app may need to put things into them.\n javascript: Node;\n styles: Node;\n implicitScripts: Node;\n implicitStyles: Node;\n\n // these are optional because you *may* choose to stick your implicit test\n // things into specific locations (which we need for backward-compat). But you\n // can leave these off and we will simply put them in the same places as the\n // non-test things.\n //\n // Do not confuse these with controlling whether or not we will insert tests.\n // That is separately controlled via `includeTests`.\n testJavascript?: Node;\n implicitTestScripts?: Node;\n implicitTestStyles?: Node;\n}\n\nclass NodeRange {\n end: Node;\n start: Node;\n constructor(initial: Node) {\n this.start = initial.ownerDocument!.createTextNode('');\n initial.parentElement!.insertBefore(this.start, initial);\n this.end = initial;\n }\n clear() {\n while (this.start.nextSibling !== this.end) {\n this.start.parentElement!.removeChild(this.start.nextSibling!);\n }\n }\n insert(node: Node) {\n this.end.parentElement!.insertBefore(node, this.end);\n }\n}\n\nfunction immediatelyAfter(node: Node) {\n let newMarker = node.ownerDocument!.createTextNode('');\n node.parentElement!.insertBefore(newMarker, node.nextSibling);\n return new NodeRange(newMarker);\n}\n\nexport class PreparedEmberHTML {\n dom: JSDOM;\n javascript: NodeRange;\n styles: NodeRange;\n implicitScripts: NodeRange;\n implicitStyles: NodeRange;\n testJavascript: NodeRange;\n implicitTestScripts: NodeRange;\n implicitTestStyles: NodeRange;\n\n constructor(private asset: EmberAsset) {\n this.dom = new JSDOM(readFileSync(asset.sourcePath, 'utf8'));\n let html = asset.prepare(this.dom);\n this.javascript = new NodeRange(html.javascript);\n this.styles = new NodeRange(html.styles);\n this.implicitScripts = new NodeRange(html.implicitScripts);\n this.implicitStyles = new NodeRange(html.implicitStyles);\n this.testJavascript = html.testJavascript ? new NodeRange(html.testJavascript) : immediatelyAfter(html.javascript);\n this.implicitTestScripts = html.implicitTestScripts\n ? new NodeRange(html.implicitTestScripts)\n : immediatelyAfter(html.implicitScripts);\n this.implicitTestStyles = html.implicitTestStyles\n ? new NodeRange(html.implicitTestStyles)\n : immediatelyAfter(html.implicitStyles);\n }\n\n private allRanges(): NodeRange[] {\n return [\n this.javascript,\n this.styles,\n this.implicitScripts,\n this.implicitStyles,\n this.implicitTestScripts,\n this.implicitTestStyles,\n this.testJavascript,\n ];\n }\n\n clear() {\n for (let range of this.allRanges()) {\n range.clear();\n }\n }\n\n // this takes the src relative to the application root, we adjust it so it's\n // root-relative via the configured rootURL\n insertScriptTag(location: NodeRange, relativeSrc: string, opts?: { type?: string; tag?: string }) {\n let newTag = this.dom.window.document.createElement(opts && opts.tag ? opts.tag : 'script');\n newTag.setAttribute('src', this.asset.rootURL + relativeSrc);\n if (opts && opts.type) {\n newTag.setAttribute('type', opts.type);\n }\n location.insert(this.dom.window.document.createTextNode('\\n'));\n location.insert(newTag);\n }\n\n // this takes the href relative to the application root, we adjust it so it's\n // root-relative via the configured rootURL\n insertStyleLink(location: NodeRange, relativeHref: string) {\n let newTag = this.dom.window.document.createElement('link');\n newTag.rel = 'stylesheet';\n newTag.href = this.asset.rootURL + relativeHref;\n location.insert(this.dom.window.document.createTextNode('\\n'));\n location.insert(newTag);\n }\n}\n\nexport function insertNewline(at: Node) {\n at.parentElement!.insertBefore(at.ownerDocument!.createTextNode('\\n'), at);\n}\n"]}
1
+ {"version":3,"file":"ember-html.js","sourceRoot":"","sources":["ember-html.ts"],"names":[],"mappings":"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","sourcesContent":["import { JSDOM } from 'jsdom';\nimport { readFileSync } from 'fs';\nimport type { EmberAsset } from './asset';\nimport { makeTag, normalizeStyleLink } from './html-placeholder';\n\nexport interface EmberHTML {\n // each of the Nodes in here points at where we should insert the\n // corresponding parts of the ember app. The Nodes themselves will be\n // replaced, so provide placeholders.\n\n // these are mandatory, the Ember app may need to put things into them.\n javascript: Node;\n styles: Node;\n implicitScripts: Node;\n implicitStyles: Node;\n\n // these are optional because you *may* choose to stick your implicit test\n // things into specific locations (which we need for backward-compat). But you\n // can leave these off and we will simply put them in the same places as the\n // non-test things.\n //\n // Do not confuse these with controlling whether or not we will insert tests.\n // That is separately controlled via `includeTests`.\n testJavascript?: Node;\n implicitTestScripts?: Node;\n implicitTestStyles?: Node;\n}\n\nclass Placeholder {\n static replacing(node: Node): Placeholder {\n let placeholder = this.immediatelyAfter(node);\n node.parentElement!.removeChild(node);\n return placeholder;\n }\n\n static immediatelyAfter(node: Node): Placeholder {\n let document = node.ownerDocument;\n let parent = node.parentElement;\n\n if (!document || !parent) {\n throw new Error('Cannot make Placeholder out of detached node');\n }\n\n let nextSibling = node.nextSibling;\n let start = document.createTextNode('');\n let end = document.createTextNode('');\n\n parent.insertBefore(start, nextSibling);\n parent.insertBefore(end, nextSibling);\n return new Placeholder(start, end, node);\n }\n\n readonly parent: HTMLElement;\n\n constructor(readonly start: Node, readonly end: Node, readonly reference: Node) {\n if (start.parentElement && start.parentElement === end.parentElement) {\n this.parent = start.parentElement;\n } else {\n throw new Error('Cannot make Placeholder out of detached node');\n }\n }\n\n clear() {\n let { start, end, parent } = this;\n let target = start.nextSibling;\n\n while (target && target !== end) {\n parent.removeChild(target);\n target = target.nextSibling;\n }\n }\n\n insert(node: Node) {\n this.parent.insertBefore(node, this.end);\n }\n}\n\nexport class PreparedEmberHTML {\n dom: JSDOM;\n javascript: Placeholder;\n styles: Placeholder;\n implicitScripts: Placeholder;\n implicitStyles: Placeholder;\n testJavascript: Placeholder;\n implicitTestScripts: Placeholder;\n implicitTestStyles: Placeholder;\n\n constructor(private asset: EmberAsset) {\n this.dom = new JSDOM(readFileSync(asset.sourcePath, 'utf8'));\n let html = asset.prepare(this.dom);\n this.javascript = Placeholder.replacing(html.javascript);\n this.styles = Placeholder.replacing(html.styles);\n this.implicitScripts = Placeholder.replacing(html.implicitScripts);\n this.implicitStyles = Placeholder.replacing(html.implicitStyles);\n this.testJavascript = html.testJavascript\n ? Placeholder.replacing(html.testJavascript)\n : Placeholder.immediatelyAfter(this.javascript.end);\n this.implicitTestScripts = html.implicitTestScripts\n ? Placeholder.replacing(html.implicitTestScripts)\n : Placeholder.immediatelyAfter(this.implicitScripts.end);\n this.implicitTestStyles = html.implicitTestStyles\n ? Placeholder.replacing(html.implicitTestStyles)\n : Placeholder.immediatelyAfter(this.implicitStyles.end);\n }\n\n private placeholders(): Placeholder[] {\n return [\n this.javascript,\n this.styles,\n this.implicitScripts,\n this.implicitStyles,\n this.implicitTestScripts,\n this.implicitTestStyles,\n this.testJavascript,\n ];\n }\n\n clear() {\n for (let range of this.placeholders()) {\n range.clear();\n }\n }\n\n // this takes the src relative to the application root, we adjust it so it's\n // root-relative via the configured rootURL\n insertScriptTag(\n placeholder: Placeholder,\n relativeSrc: string,\n { type, tag = 'script' }: { type?: string; tag?: string } = {}\n ) {\n let document = this.dom.window.document;\n let from = placeholder.reference.nodeType === 1 ? (placeholder.reference as HTMLElement) : undefined;\n let src = this.asset.rootURL + relativeSrc;\n let attributes: Record<string, string> = type ? { src, type } : { src };\n let newTag = makeTag(document, { from, tag, attributes });\n placeholder.insert(this.dom.window.document.createTextNode('\\n'));\n placeholder.insert(newTag);\n }\n\n // this takes the href relative to the application root, we adjust it so it's\n // root-relative via the configured rootURL\n insertStyleLink(placeholder: Placeholder, relativeHref: string) {\n let document = this.dom.window.document;\n let from = placeholder.reference.nodeType === 1 ? (placeholder.reference as HTMLElement) : undefined;\n let href = this.asset.rootURL + relativeHref;\n let newTag = makeTag(document, { from, tag: 'link', attributes: { href } });\n normalizeStyleLink(newTag);\n placeholder.insert(this.dom.window.document.createTextNode('\\n'));\n placeholder.insert(newTag);\n }\n}\n\nexport function insertNewline(at: Node) {\n at.parentElement!.insertBefore(at.ownerDocument!.createTextNode('\\n'), at);\n}\n"]}
@@ -61,7 +61,7 @@ class HTMLEntrypoint {
61
61
  return handledScriptTags;
62
62
  }
63
63
  handledStyles() {
64
- let styleTags = [...this.dom.window.document.querySelectorAll('link[rel="stylesheet"]')];
64
+ let styleTags = [...this.dom.window.document.querySelectorAll('link[rel*="stylesheet"]')];
65
65
  let [ignoredStyleTags, handledStyleTags] = (0, partition_1.default)(styleTags, styleTag => {
66
66
  return !styleTag.href || styleTag.hasAttribute('data-embroider-ignore') || isAbsoluteURL(styleTag.href);
67
67
  });
@@ -1 +1 @@
1
- {"version":3,"file":"html-entrypoint.js","sourceRoot":"","sources":["html-entrypoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { getOrCreate } from '@embroider/shared-internals';\nimport { readFileSync } from 'fs-extra';\nimport { join } from 'path';\nimport { JSDOM } from 'jsdom';\nimport partition from 'lodash/partition';\nimport zip from 'lodash/zip';\nimport Placeholder from './html-placeholder';\nimport type { Variant } from './packager';\n\nexport class HTMLEntrypoint {\n private dom: JSDOM;\n private placeholders: Map<string, Placeholder[]> = new Map();\n modules: string[] = [];\n scripts: string[] = [];\n styles: string[] = [];\n\n constructor(\n private pathToVanillaApp: string,\n private rootURL: string,\n private publicAssetURL: string,\n public filename: string\n ) {\n this.dom = new JSDOM(readFileSync(join(this.pathToVanillaApp, this.filename), 'utf8'));\n\n for (let tag of this.handledStyles()) {\n let styleTag = tag as HTMLLinkElement;\n let href = styleTag.href;\n if (!isAbsoluteURL(href)) {\n let url = this.relativeToApp(href);\n this.styles.push(url);\n let placeholder = new Placeholder(styleTag);\n let list = getOrCreate(this.placeholders, url, () => []);\n list.push(placeholder);\n }\n }\n\n for (let scriptTag of this.handledScripts()) {\n // scriptTag.src include rootURL. Convert it to be relative to the app.\n let src = this.relativeToApp(scriptTag.src);\n\n if (scriptTag.type === 'module') {\n this.modules.push(src);\n } else {\n this.scripts.push(src);\n }\n\n let placeholder = new Placeholder(scriptTag);\n let list = getOrCreate(this.placeholders, src, () => []);\n list.push(placeholder);\n }\n }\n\n private relativeToApp(rootRelativeURL: string) {\n return rootRelativeURL.replace(this.rootURL, '');\n }\n\n private handledScripts() {\n let scriptTags = [...this.dom.window.document.querySelectorAll('script')] as HTMLScriptElement[];\n let [ignoredScriptTags, handledScriptTags] = partition(scriptTags, scriptTag => {\n return !scriptTag.src || scriptTag.hasAttribute('data-embroider-ignore') || isAbsoluteURL(scriptTag.src);\n });\n for (let scriptTag of ignoredScriptTags) {\n scriptTag.removeAttribute('data-embroider-ignore');\n }\n return handledScriptTags;\n }\n\n private handledStyles() {\n let styleTags = [...this.dom.window.document.querySelectorAll('link[rel=\"stylesheet\"]')] as HTMLLinkElement[];\n let [ignoredStyleTags, handledStyleTags] = partition(styleTags, styleTag => {\n return !styleTag.href || styleTag.hasAttribute('data-embroider-ignore') || isAbsoluteURL(styleTag.href);\n });\n for (let styleTag of ignoredStyleTags) {\n styleTag.removeAttribute('data-embroider-ignore');\n }\n return handledStyleTags;\n }\n\n // bundles maps from input asset to a per-variant map of output assets\n render(stats: BundleSummary): string {\n let insertedLazy = new Set<string>();\n let fastbootVariant = stats.variants.findIndex(v => Boolean(v.runtime === 'fastboot'));\n let supportsFastboot = stats.variants.some(v => v.runtime === 'fastboot' || v.runtime === 'all');\n\n for (let [src, placeholders] of this.placeholders) {\n let match = stats.entrypoints.get(src);\n if (match) {\n let firstVariant = stats.variants.findIndex((_, index) => Boolean(match!.get(index)));\n let matchingBundles = match.get(firstVariant)!;\n let matchingFastbootBundles = fastbootVariant >= 0 ? match.get(fastbootVariant) || [] : [];\n\n for (let placeholder of placeholders) {\n placeholder.clear();\n if (supportsFastboot && placeholder.isScript()) {\n // if there is any fastboot involved, we will emit the lazy bundles\n // right before our first script.\n\n let lazyMatch = stats.lazyBundles.get(src);\n if (lazyMatch && !insertedLazy.has(src)) {\n insertLazyJavascript(lazyMatch, placeholder, this.rootURL);\n insertLazyStyles(lazyMatch, placeholder, this.publicAssetURL);\n insertedLazy.add(src);\n }\n }\n for (let [base, fastboot] of zip(matchingBundles, matchingFastbootBundles)) {\n if (supportsFastboot) {\n // the fastboot version gets prefixed with the rootURL, which\n // points to our local build directory, because that's where\n // fastboot always loads scripts from. If there's no\n // fastboot-specific variant, fastboot loads the base variant, but\n // still from rootURL rather than publicAssetURL.\n fastboot = this.rootURL + (fastboot ?? base);\n }\n\n if (base) {\n // the browser version gets prefixed with the publicAssetURL\n // because that's where browsers will load it from\n base = this.publicAssetURL + base;\n }\n\n if (!base) {\n // this bundle only exists in the fastboot variant\n let element = placeholder.start.ownerDocument.createElement('fastboot-script');\n element.setAttribute('src', fastboot!);\n placeholder.insert(element);\n placeholder.insertNewline();\n } else if (!fastboot) {\n // no fastboot variant\n placeholder.insertURL(base);\n } else if (fastboot === base) {\n // fastboot variant happens to be exactly the same bundle as base\n // (and publicAssetURL===rootURL), so a plain script tag covers\n // both\n placeholder.insertURL(base);\n } else {\n // we have both and they differ\n let element = placeholder.insertURL(base);\n if (element) {\n element.setAttribute('data-fastboot-src', fastboot);\n }\n }\n }\n }\n } else {\n // no match means keep the original HTML content for this placeholder.\n // (If we really wanted it empty instead, there would be matchingBundles\n // and it would be an empty list.)\n for (let placeholder of placeholders) {\n placeholder.reset();\n }\n }\n }\n return this.dom.serialize();\n }\n}\n\nexport interface BundleSummary {\n // entrypoints.get(inputAsset).get(variantIndex) === outputAssets\n //\n // these are the output assets that are needed eagerly to boot the given input\n // asset\n entrypoints: Map<string, Map<number, string[]>>;\n\n // lazyBundles.get(inputAsset) === lazyOutputAssets\n //\n // these are the output assets that might be loaded lazyily at runtime by the\n // given input asset.\n //\n // These are tracked specifically for the fastboot variant, because that's\n // where we need to be responsble for them.\n lazyBundles: Map<string, string[]>;\n\n variants: Variant[];\n}\n\nfunction isAbsoluteURL(url: string) {\n return /^(?:[a-z]+:)?\\/\\//i.test(url);\n}\n\n// we (somewhat arbitrarily) decide to put the lazy javascript bundles before\n// the very first <script> that we have rewritten\nfunction insertLazyJavascript(lazyBundles: string[], placeholder: Placeholder, rootURL: string) {\n for (let bundle of lazyBundles) {\n if (bundle.endsWith('.js')) {\n let element = placeholder.start.ownerDocument.createElement('fastboot-script');\n // we're using rootURL instead of publicAssetURL here because\n // <fastboot-script> is executed by fastboot, which always loads them from\n // the local build directory. NOT from the publicAssetURL that browsers\n // will use, which could be a CDN.\n element.setAttribute('src', rootURL + bundle);\n placeholder.insert(element);\n placeholder.insertNewline();\n }\n }\n}\n\nfunction insertLazyStyles(lazyBundles: string[], placeholder: Placeholder, publicAssetURL: string) {\n for (let bundle of lazyBundles) {\n if (bundle.endsWith('.css')) {\n let element = placeholder.start.ownerDocument.createElement('link');\n element.setAttribute('href', publicAssetURL + bundle);\n element.setAttribute('rel', 'stylesheet');\n placeholder.insert(element);\n placeholder.insertNewline();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"html-entrypoint.js","sourceRoot":"","sources":["html-entrypoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { getOrCreate } from '@embroider/shared-internals';\nimport { readFileSync } from 'fs-extra';\nimport { join } from 'path';\nimport { JSDOM } from 'jsdom';\nimport partition from 'lodash/partition';\nimport zip from 'lodash/zip';\nimport Placeholder from './html-placeholder';\nimport type { Variant } from './packager';\n\nexport class HTMLEntrypoint {\n private dom: JSDOM;\n private placeholders: Map<string, Placeholder[]> = new Map();\n modules: string[] = [];\n scripts: string[] = [];\n styles: string[] = [];\n\n constructor(\n private pathToVanillaApp: string,\n private rootURL: string,\n private publicAssetURL: string,\n public filename: string\n ) {\n this.dom = new JSDOM(readFileSync(join(this.pathToVanillaApp, this.filename), 'utf8'));\n\n for (let tag of this.handledStyles()) {\n let styleTag = tag as HTMLLinkElement;\n let href = styleTag.href;\n if (!isAbsoluteURL(href)) {\n let url = this.relativeToApp(href);\n this.styles.push(url);\n let placeholder = new Placeholder(styleTag);\n let list = getOrCreate(this.placeholders, url, () => []);\n list.push(placeholder);\n }\n }\n\n for (let scriptTag of this.handledScripts()) {\n // scriptTag.src include rootURL. Convert it to be relative to the app.\n let src = this.relativeToApp(scriptTag.src);\n\n if (scriptTag.type === 'module') {\n this.modules.push(src);\n } else {\n this.scripts.push(src);\n }\n\n let placeholder = new Placeholder(scriptTag);\n let list = getOrCreate(this.placeholders, src, () => []);\n list.push(placeholder);\n }\n }\n\n private relativeToApp(rootRelativeURL: string) {\n return rootRelativeURL.replace(this.rootURL, '');\n }\n\n private handledScripts() {\n let scriptTags = [...this.dom.window.document.querySelectorAll('script')] as HTMLScriptElement[];\n let [ignoredScriptTags, handledScriptTags] = partition(scriptTags, scriptTag => {\n return !scriptTag.src || scriptTag.hasAttribute('data-embroider-ignore') || isAbsoluteURL(scriptTag.src);\n });\n for (let scriptTag of ignoredScriptTags) {\n scriptTag.removeAttribute('data-embroider-ignore');\n }\n return handledScriptTags;\n }\n\n private handledStyles() {\n let styleTags = [...this.dom.window.document.querySelectorAll('link[rel*=\"stylesheet\"]')] as HTMLLinkElement[];\n let [ignoredStyleTags, handledStyleTags] = partition(styleTags, styleTag => {\n return !styleTag.href || styleTag.hasAttribute('data-embroider-ignore') || isAbsoluteURL(styleTag.href);\n });\n for (let styleTag of ignoredStyleTags) {\n styleTag.removeAttribute('data-embroider-ignore');\n }\n return handledStyleTags;\n }\n\n // bundles maps from input asset to a per-variant map of output assets\n render(stats: BundleSummary): string {\n let insertedLazy = new Set<string>();\n let fastbootVariant = stats.variants.findIndex(v => Boolean(v.runtime === 'fastboot'));\n let supportsFastboot = stats.variants.some(v => v.runtime === 'fastboot' || v.runtime === 'all');\n\n for (let [src, placeholders] of this.placeholders) {\n let match = stats.entrypoints.get(src);\n if (match) {\n let firstVariant = stats.variants.findIndex((_, index) => Boolean(match!.get(index)));\n let matchingBundles = match.get(firstVariant)!;\n let matchingFastbootBundles = fastbootVariant >= 0 ? match.get(fastbootVariant) || [] : [];\n\n for (let placeholder of placeholders) {\n placeholder.clear();\n if (supportsFastboot && placeholder.isScript()) {\n // if there is any fastboot involved, we will emit the lazy bundles\n // right before our first script.\n\n let lazyMatch = stats.lazyBundles.get(src);\n if (lazyMatch && !insertedLazy.has(src)) {\n insertLazyJavascript(lazyMatch, placeholder, this.rootURL);\n insertLazyStyles(lazyMatch, placeholder, this.publicAssetURL);\n insertedLazy.add(src);\n }\n }\n for (let [base, fastboot] of zip(matchingBundles, matchingFastbootBundles)) {\n if (supportsFastboot) {\n // the fastboot version gets prefixed with the rootURL, which\n // points to our local build directory, because that's where\n // fastboot always loads scripts from. If there's no\n // fastboot-specific variant, fastboot loads the base variant, but\n // still from rootURL rather than publicAssetURL.\n fastboot = this.rootURL + (fastboot ?? base);\n }\n\n if (base) {\n // the browser version gets prefixed with the publicAssetURL\n // because that's where browsers will load it from\n base = this.publicAssetURL + base;\n }\n\n if (!base) {\n // this bundle only exists in the fastboot variant\n let element = placeholder.start.ownerDocument.createElement('fastboot-script');\n element.setAttribute('src', fastboot!);\n placeholder.insert(element);\n placeholder.insertNewline();\n } else if (!fastboot) {\n // no fastboot variant\n placeholder.insertURL(base);\n } else if (fastboot === base) {\n // fastboot variant happens to be exactly the same bundle as base\n // (and publicAssetURL===rootURL), so a plain script tag covers\n // both\n placeholder.insertURL(base);\n } else {\n // we have both and they differ\n let element = placeholder.insertURL(base);\n if (element) {\n element.setAttribute('data-fastboot-src', fastboot);\n }\n }\n }\n }\n } else {\n // no match means keep the original HTML content for this placeholder.\n // (If we really wanted it empty instead, there would be matchingBundles\n // and it would be an empty list.)\n for (let placeholder of placeholders) {\n placeholder.reset();\n }\n }\n }\n return this.dom.serialize();\n }\n}\n\nexport interface BundleSummary {\n // entrypoints.get(inputAsset).get(variantIndex) === outputAssets\n //\n // these are the output assets that are needed eagerly to boot the given input\n // asset\n entrypoints: Map<string, Map<number, string[]>>;\n\n // lazyBundles.get(inputAsset) === lazyOutputAssets\n //\n // these are the output assets that might be loaded lazyily at runtime by the\n // given input asset.\n //\n // These are tracked specifically for the fastboot variant, because that's\n // where we need to be responsble for them.\n lazyBundles: Map<string, string[]>;\n\n variants: Variant[];\n}\n\nfunction isAbsoluteURL(url: string) {\n return /^(?:[a-z]+:)?\\/\\//i.test(url);\n}\n\n// we (somewhat arbitrarily) decide to put the lazy javascript bundles before\n// the very first <script> that we have rewritten\nfunction insertLazyJavascript(lazyBundles: string[], placeholder: Placeholder, rootURL: string) {\n for (let bundle of lazyBundles) {\n if (bundle.endsWith('.js')) {\n let element = placeholder.start.ownerDocument.createElement('fastboot-script');\n // we're using rootURL instead of publicAssetURL here because\n // <fastboot-script> is executed by fastboot, which always loads them from\n // the local build directory. NOT from the publicAssetURL that browsers\n // will use, which could be a CDN.\n element.setAttribute('src', rootURL + bundle);\n placeholder.insert(element);\n placeholder.insertNewline();\n }\n }\n}\n\nfunction insertLazyStyles(lazyBundles: string[], placeholder: Placeholder, publicAssetURL: string) {\n for (let bundle of lazyBundles) {\n if (bundle.endsWith('.css')) {\n let element = placeholder.start.ownerDocument.createElement('link');\n element.setAttribute('href', publicAssetURL + bundle);\n element.setAttribute('rel', 'stylesheet');\n placeholder.insert(element);\n placeholder.insertNewline();\n }\n }\n}\n"]}
@@ -1,3 +1,19 @@
1
+ export declare function makeTag(document: Document, options: {
2
+ from: HTMLElement;
3
+ tag?: string;
4
+ attributes?: {
5
+ [name: string]: string | null;
6
+ };
7
+ }): HTMLElement;
8
+ export declare function makeTag(document: Document, options: {
9
+ from?: HTMLElement;
10
+ tag: string;
11
+ attributes?: {
12
+ [name: string]: string | null;
13
+ };
14
+ }): HTMLElement;
15
+ export declare function normalizeScriptTag(tag: HTMLElement): void;
16
+ export declare function normalizeStyleLink(tag: HTMLElement): void;
1
17
  export default class Placeholder {
2
18
  private target;
3
19
  end: InDOMNode;
@@ -8,8 +24,8 @@ export default class Placeholder {
8
24
  insert(node: Node): void;
9
25
  appendToHead(node: Node): void;
10
26
  isScript(): boolean;
11
- insertURL(url: string): void | HTMLScriptElement;
12
- insertScriptTag(src: string): HTMLScriptElement;
27
+ insertURL(url: string): void | HTMLElement;
28
+ insertScriptTag(src: string): HTMLElement;
13
29
  insertStyleLink(href: string): void;
14
30
  insertNewline(node?: InDOMNode): void;
15
31
  }
@@ -1,5 +1,52 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeStyleLink = exports.normalizeScriptTag = exports.makeTag = void 0;
4
+ function makeTag(document, { from, tag, attributes } = {}) {
5
+ if (!tag && from) {
6
+ tag = from.tagName;
7
+ }
8
+ if (!tag) {
9
+ throw new Error('Must supply one of `options.from` or `options.tag`');
10
+ }
11
+ let cloned = document.createElement(tag);
12
+ let overrides = new Map(Object.entries(attributes !== null && attributes !== void 0 ? attributes : {}));
13
+ if (from) {
14
+ for (let { name, value: originalValue } of from.attributes) {
15
+ let value = overrides.has(name) ? overrides.get(name) : originalValue;
16
+ overrides.delete(name);
17
+ if (value === null) {
18
+ continue;
19
+ }
20
+ else {
21
+ cloned.setAttribute(name, value);
22
+ }
23
+ }
24
+ }
25
+ for (let [name, value] of overrides) {
26
+ if (value !== null) {
27
+ cloned.setAttribute(name, value);
28
+ }
29
+ }
30
+ return cloned;
31
+ }
32
+ exports.makeTag = makeTag;
33
+ function normalizeScriptTag(tag) {
34
+ if (tag.getAttribute('type') === 'module') {
35
+ // we always convert modules to scripts, dropping
36
+ tag.removeAttribute('type');
37
+ }
38
+ }
39
+ exports.normalizeScriptTag = normalizeScriptTag;
40
+ function normalizeStyleLink(tag) {
41
+ let rel = tag.getAttribute('rel');
42
+ if (rel === null) {
43
+ tag.setAttribute('rel', 'stylesheet');
44
+ }
45
+ else if (!rel.includes('stylesheet')) {
46
+ tag.setAttribute('rel', `${rel} stylesheet`);
47
+ }
48
+ }
49
+ exports.normalizeStyleLink = normalizeStyleLink;
3
50
  class Placeholder {
4
51
  // remove the target Element from the DOM, and track where it was so we can
5
52
  // update that location later.
@@ -46,31 +93,29 @@ class Placeholder {
46
93
  throw new Error(`don't know how to insertURL ${url}`);
47
94
  }
48
95
  insertScriptTag(src) {
49
- let newTag = this.end.ownerDocument.createElement('script');
50
- for (let { name, value } of [...this.target.attributes]) {
51
- if (name === 'type' && value === 'module') {
52
- // we always convert modules to scripts
53
- continue;
54
- }
55
- // all other attributes are copied forward unchanged
56
- newTag.setAttribute(name, value);
57
- }
58
- newTag.src = src;
96
+ let newTag = makeTag(this.end.ownerDocument, { from: this.target, attributes: { src } });
97
+ normalizeScriptTag(newTag);
59
98
  this.insert(newTag);
60
99
  this.insertNewline();
61
100
  return newTag;
62
101
  }
63
102
  insertStyleLink(href) {
64
- let newTag = this.end.ownerDocument.createElement('link');
65
- newTag.href = href;
66
- newTag.rel = 'stylesheet';
103
+ let newTag;
67
104
  if (this.isScript()) {
68
105
  // Add dynamic styles from scripts to the bottom of the head, and not to where the script was,
69
106
  // to prevent FOUC when pre-rendering (FastBoot)
107
+ newTag = makeTag(this.end.ownerDocument, {
108
+ from: this.target,
109
+ tag: 'link',
110
+ attributes: { href, type: null, src: null },
111
+ });
112
+ normalizeStyleLink(newTag);
70
113
  this.appendToHead(newTag);
71
114
  }
72
115
  else {
73
116
  // Keep the new style in the same place as the original one
117
+ newTag = makeTag(this.end.ownerDocument, { from: this.target, attributes: { href } });
118
+ normalizeStyleLink(newTag);
74
119
  this.insert(newTag);
75
120
  }
76
121
  this.insertNewline(newTag);
@@ -1 +1 @@
1
- {"version":3,"file":"html-placeholder.js","sourceRoot":"","sources":["html-placeholder.ts"],"names":[],"mappings":"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","sourcesContent":["export default class Placeholder {\n end: InDOMNode;\n start: StartNode;\n\n // remove the target Element from the DOM, and track where it was so we can\n // update that location later.\n constructor(private target: HTMLElement) {\n if (!target.ownerDocument || !target.parentElement) {\n throw new Error('can only construct a placeholder for an element that is in DOM');\n }\n let start = target.ownerDocument.createTextNode('');\n target.parentElement.insertBefore(start, target);\n let endNode = target.ownerDocument.createTextNode('');\n target.replaceWith(endNode);\n\n // Type cast is justified because start always has a nextSibling (it's\n // \"end\") and because we know we already inserted the node.\n this.start = start as StartNode;\n\n // Type cast is justified because we know we already inserted the node.\n this.end = endNode as InDOMNode;\n }\n\n reset() {\n this.clear();\n this.insert(this.target);\n }\n\n clear() {\n while (this.start.nextSibling !== this.end) {\n this.start.parentElement.removeChild(this.start.nextSibling);\n }\n }\n\n insert(node: Node): void {\n this.end.parentElement.insertBefore(node, this.end);\n }\n\n appendToHead(node: Node): void {\n this.end.ownerDocument.head.appendChild(node);\n }\n\n isScript(): boolean {\n return this.target.tagName === 'SCRIPT';\n }\n\n insertURL(url: string) {\n if (url.endsWith('.js')) {\n return this.insertScriptTag(url);\n }\n if (url.endsWith('.css')) {\n return this.insertStyleLink(url);\n }\n throw new Error(`don't know how to insertURL ${url}`);\n }\n\n insertScriptTag(src: string) {\n let newTag = this.end.ownerDocument.createElement('script');\n for (let { name, value } of [...this.target.attributes]) {\n if (name === 'type' && value === 'module') {\n // we always convert modules to scripts\n continue;\n }\n // all other attributes are copied forward unchanged\n newTag.setAttribute(name, value);\n }\n newTag.src = src;\n this.insert(newTag);\n this.insertNewline();\n return newTag;\n }\n\n insertStyleLink(href: string) {\n let newTag = this.end.ownerDocument.createElement('link');\n newTag.href = href;\n newTag.rel = 'stylesheet';\n\n if (this.isScript()) {\n // Add dynamic styles from scripts to the bottom of the head, and not to where the script was,\n // to prevent FOUC when pre-rendering (FastBoot)\n this.appendToHead(newTag);\n } else {\n // Keep the new style in the same place as the original one\n this.insert(newTag);\n }\n this.insertNewline(newTag as InDOMNode);\n }\n\n insertNewline(node: InDOMNode = this.end): void {\n node.parentElement.insertBefore(node.ownerDocument.createTextNode('\\n'), node);\n }\n}\n\n// an html node that's definitely inserted into the DOM\ninterface InDOMNode extends Node {\n parentElement: HTMLElement;\n ownerDocument: Document;\n}\n\n// an html node that definitely has a next sibling.\ninterface StartNode extends InDOMNode {\n nextSibling: InDOMNode & ChildNode;\n}\n"]}
1
+ {"version":3,"file":"html-placeholder.js","sourceRoot":"","sources":["html-placeholder.ts"],"names":[],"mappings":"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","sourcesContent":["export function makeTag(\n document: Document,\n options: { from: HTMLElement; tag?: string; attributes?: { [name: string]: string | null } }\n): HTMLElement;\nexport function makeTag(\n document: Document,\n options: { from?: HTMLElement; tag: string; attributes?: { [name: string]: string | null } }\n): HTMLElement;\nexport function makeTag(\n document: Document,\n { from, tag, attributes }: { from?: HTMLElement; tag?: string; attributes?: { [name: string]: string | null } } = {}\n): HTMLElement {\n if (!tag && from) {\n tag = from.tagName;\n }\n\n if (!tag) {\n throw new Error('Must supply one of `options.from` or `options.tag`');\n }\n\n let cloned = document.createElement(tag);\n let overrides = new Map(Object.entries(attributes ?? {}));\n\n if (from) {\n for (let { name, value: originalValue } of from.attributes) {\n let value = overrides.has(name) ? overrides.get(name)! : originalValue;\n overrides.delete(name);\n\n if (value === null) {\n continue;\n } else {\n cloned.setAttribute(name, value);\n }\n }\n }\n\n for (let [name, value] of overrides) {\n if (value !== null) {\n cloned.setAttribute(name, value);\n }\n }\n\n return cloned;\n}\n\nexport function normalizeScriptTag(tag: HTMLElement): void {\n if (tag.getAttribute('type') === 'module') {\n // we always convert modules to scripts, dropping\n tag.removeAttribute('type');\n }\n}\n\nexport function normalizeStyleLink(tag: HTMLElement): void {\n let rel = tag.getAttribute('rel');\n\n if (rel === null) {\n tag.setAttribute('rel', 'stylesheet');\n } else if (!rel.includes('stylesheet')) {\n tag.setAttribute('rel', `${rel} stylesheet`);\n }\n}\n\nexport default class Placeholder {\n end: InDOMNode;\n start: StartNode;\n\n // remove the target Element from the DOM, and track where it was so we can\n // update that location later.\n constructor(private target: HTMLElement) {\n if (!target.ownerDocument || !target.parentElement) {\n throw new Error('can only construct a placeholder for an element that is in DOM');\n }\n let start = target.ownerDocument.createTextNode('');\n target.parentElement.insertBefore(start, target);\n let endNode = target.ownerDocument.createTextNode('');\n target.replaceWith(endNode);\n\n // Type cast is justified because start always has a nextSibling (it's\n // \"end\") and because we know we already inserted the node.\n this.start = start as StartNode;\n\n // Type cast is justified because we know we already inserted the node.\n this.end = endNode as InDOMNode;\n }\n\n reset() {\n this.clear();\n this.insert(this.target);\n }\n\n clear() {\n while (this.start.nextSibling !== this.end) {\n this.start.parentElement.removeChild(this.start.nextSibling);\n }\n }\n\n insert(node: Node): void {\n this.end.parentElement.insertBefore(node, this.end);\n }\n\n appendToHead(node: Node): void {\n this.end.ownerDocument.head.appendChild(node);\n }\n\n isScript(): boolean {\n return this.target.tagName === 'SCRIPT';\n }\n\n insertURL(url: string) {\n if (url.endsWith('.js')) {\n return this.insertScriptTag(url);\n }\n if (url.endsWith('.css')) {\n return this.insertStyleLink(url);\n }\n throw new Error(`don't know how to insertURL ${url}`);\n }\n\n insertScriptTag(src: string) {\n let newTag = makeTag(this.end.ownerDocument, { from: this.target, attributes: { src } });\n normalizeScriptTag(newTag);\n\n this.insert(newTag);\n this.insertNewline();\n return newTag;\n }\n\n insertStyleLink(href: string) {\n let newTag: HTMLElement;\n\n if (this.isScript()) {\n // Add dynamic styles from scripts to the bottom of the head, and not to where the script was,\n // to prevent FOUC when pre-rendering (FastBoot)\n newTag = makeTag(this.end.ownerDocument, {\n from: this.target,\n tag: 'link',\n attributes: { href, type: null, src: null },\n });\n normalizeStyleLink(newTag);\n this.appendToHead(newTag);\n } else {\n // Keep the new style in the same place as the original one\n newTag = makeTag(this.end.ownerDocument, { from: this.target, attributes: { href } });\n normalizeStyleLink(newTag);\n this.insert(newTag);\n }\n this.insertNewline(newTag as InDOMNode);\n }\n\n insertNewline(node: InDOMNode = this.end): void {\n node.parentElement.insertBefore(node.ownerDocument.createTextNode('\\n'), node);\n }\n}\n\n// an html node that's definitely inserted into the DOM\ninterface InDOMNode extends Node {\n parentElement: HTMLElement;\n ownerDocument: Document;\n}\n\n// an html node that definitely has a next sibling.\ninterface StartNode extends InDOMNode {\n nextSibling: InDOMNode & ChildNode;\n}\n"]}