Skip to content

Commit

Permalink
fix: fix inline scripts and styles potentially breaking
Browse files Browse the repository at this point in the history
fix the issue which breaks scripts split in different chunks in the input stream
by applying them only after the scripts has been fully visited

also fix the same issue for embeded styles, even though there everything works
fine it is better to apply all the styles together and avoid potential flashes
of unexpected style combinations

resolves #1
  • Loading branch information
dario-piotrowicz committed Sep 15, 2022
1 parent 51650e1 commit 9d58c8f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Embedded App.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Embedded App.
<script></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Embedded App.
<script>
scriptValues = ["a", "b"];
</script>
After Script.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Embedded App.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Embedded App. <style></style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Embedded App.
<style>
h1 {
color: red;
}
</style>
After Styles.
26 changes: 26 additions & 0 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,29 @@ After blocking.`,
},
])
);

it(
"inline-scripts",
fixture([
"Embedded App.",
'<script>scriptValues = ["a',
'", "b"];</script>',
"After Script.",
async (page) => {
assert.deepStrictEqual(await page.evaluate(() => scriptValues), [
"a",
"b",
]);
},
])
);

it(
"inline-styles",
fixture([
"Embedded App. ",
"<style> h1 { colo",
"r: red; } </style>",
" After Styles.",
])
);
40 changes: 36 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 && isInlineHost(pendingText.parentElement)) {
// 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;
Expand All @@ -42,6 +43,8 @@ export = function writableDOM(
}
},
close() {
appendInlineTextIfNeeded(pendingText, inlineHostNode);

return isBlocked
? new Promise<void>((_) => (resolve = _))
: Promise.resolve();
Expand All @@ -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 {
Expand All @@ -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.
Expand Down Expand Up @@ -178,3 +189,24 @@ function getPreloadLink(node: any) {

return link;
}

function appendInlineTextIfNeeded(
pendingText: Text | null,
inlineTextHostNode: Node | null
) {
if (pendingText && inlineTextHostNode) {
inlineTextHostNode.appendChild(pendingText);
}
}

function isInlineHost(node: Node) {
if (node.nodeType !== Node.ELEMENT_NODE) {
return false;
}

const { tagName } = node as Element;
return (
(tagName === "SCRIPT" && !(node as HTMLScriptElement).src) ||
tagName === "STYLE"
);
}

0 comments on commit 9d58c8f

Please sign in to comment.