diff --git a/src/__tests__/__snapshots__/inline-scripts.expected/step-0.html b/src/__tests__/__snapshots__/inline-scripts.expected/step-0.html
new file mode 100644
index 0000000..2eed606
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-scripts.expected/step-0.html
@@ -0,0 +1 @@
+Embedded App.
diff --git a/src/__tests__/__snapshots__/inline-scripts.expected/step-1.html b/src/__tests__/__snapshots__/inline-scripts.expected/step-1.html
new file mode 100644
index 0000000..dd4d2da
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-scripts.expected/step-1.html
@@ -0,0 +1,2 @@
+Embedded App.
+
diff --git a/src/__tests__/__snapshots__/inline-scripts.expected/step-3.html b/src/__tests__/__snapshots__/inline-scripts.expected/step-3.html
new file mode 100644
index 0000000..c4e2acf
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-scripts.expected/step-3.html
@@ -0,0 +1,5 @@
+Embedded App.
+
+After Script.
diff --git a/src/__tests__/__snapshots__/inline-styles.expected/step-0.html b/src/__tests__/__snapshots__/inline-styles.expected/step-0.html
new file mode 100644
index 0000000..2eed606
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-styles.expected/step-0.html
@@ -0,0 +1 @@
+Embedded App.
diff --git a/src/__tests__/__snapshots__/inline-styles.expected/step-1.html b/src/__tests__/__snapshots__/inline-styles.expected/step-1.html
new file mode 100644
index 0000000..a6dd68f
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-styles.expected/step-1.html
@@ -0,0 +1 @@
+Embedded App.
diff --git a/src/__tests__/__snapshots__/inline-styles.expected/step-3.html b/src/__tests__/__snapshots__/inline-styles.expected/step-3.html
new file mode 100644
index 0000000..de9c359
--- /dev/null
+++ b/src/__tests__/__snapshots__/inline-styles.expected/step-3.html
@@ -0,0 +1,7 @@
+Embedded App.
+
+After Styles.
diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts
index 18b9b31..fe04578 100644
--- a/src/__tests__/index.test.ts
+++ b/src/__tests__/index.test.ts
@@ -118,3 +118,29 @@ After blocking.`,
},
])
);
+
+it(
+ "inline-scripts",
+ fixture([
+ "Embedded App.",
+ '',
+ "After Script.",
+ async (page) => {
+ assert.deepStrictEqual(await page.evaluate(() => scriptValues), [
+ "a",
+ "b",
+ ]);
+ },
+ ])
+);
+
+it(
+ "inline-styles",
+ fixture([
+ "Embedded App. ",
+ "",
+ " After Styles.",
+ ])
+);
diff --git a/src/index.ts b/src/index.ts
index c42f3b2..2eaa2ae 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -23,12 +23,13 @@ export = function writableDOM(
let scanNode: Node | null = null;
let resolve: void | (() => void);
let isBlocked = false;
+ let inlineHostNode: Node | null = null;
return {
write(chunk: string) {
doc.write(chunk);
- if (pendingText) {
+ if (pendingText && !inlineHostNode) {
// When we left on text, it's possible more text was written to the same node.
// here we copy in the final text content from the detached dom to the live dom.
(targetNodes.get(pendingText) as Text).data = pendingText.data;
@@ -42,6 +43,8 @@ export = function writableDOM(
}
},
close() {
+ appendInlineTextIfNeeded(pendingText, inlineHostNode);
+
return isBlocked
? new Promise((_) => (resolve = _))
: Promise.resolve();
@@ -68,6 +71,7 @@ export = function writableDOM(
} else {
while ((node = walker.nextNode())) {
const clone = document.importNode(node, false);
+ const previousPendingText = pendingText;
if (node.nodeType === Node.TEXT_NODE) {
pendingText = node as Text;
} else {
@@ -86,10 +90,17 @@ export = function writableDOM(
const parentNode = targetNodes.get(node.parentNode!)!;
targetNodes.set(node, clone);
- if (parentNode === target) {
- target.insertBefore(clone, nextSibling);
+ if (isInlineHost(parentNode!)) {
+ inlineHostNode = parentNode;
} else {
- parentNode.appendChild(clone);
+ appendInlineTextIfNeeded(previousPendingText, inlineHostNode);
+ inlineHostNode = null;
+
+ if (parentNode === target) {
+ target.insertBefore(clone, nextSibling);
+ } else {
+ parentNode.appendChild(clone);
+ }
}
// Start walking for preloads.
@@ -178,3 +189,20 @@ function getPreloadLink(node: any) {
return link;
}
+
+function appendInlineTextIfNeeded(
+ pendingText: Text | null,
+ inlineTextHostNode: Node | null
+) {
+ if (pendingText && inlineTextHostNode) {
+ inlineTextHostNode.appendChild(pendingText);
+ }
+}
+
+function isInlineHost(node: Node) {
+ const { tagName } = node as Element;
+ return (
+ (tagName === "SCRIPT" && !(node as HTMLScriptElement).src) ||
+ tagName === "STYLE"
+ );
+}