Skip to content

Commit 242e990

Browse files
committed
fix: trailing script/style issue, improve support for iframes
1 parent 87f0398 commit 242e990

File tree

4 files changed

+37
-19
lines changed

4 files changed

+37
-19
lines changed

.changeset/big-snakes-begin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"writable-dom": patch
3+
---
4+
5+
Support blocking=render attribute.

.changeset/old-rivers-visit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"writable-dom": patch
3+
---
4+
5+
Prefer importing new nodes into the target document (better support for writable dom into an iframe).

.changeset/purple-jokes-decide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"writable-dom": patch
3+
---
4+
5+
Fix issue with script/style text not inserted if it was the last child of the document.

src/index.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export = function writableDOM(
5050
}
5151

5252
const nextSibling = previousSibling ? previousSibling.nextSibling : null;
53+
const owner = target.ownerDocument!;
5354
const doc = createDocument(target, nextSibling);
5455
doc.write("<!DOCTYPE html><body><template>");
5556
const root = (doc.body.firstChild as HTMLTemplateElement).content;
@@ -72,9 +73,10 @@ export = function writableDOM(
7273
}
7374
},
7475
close() {
75-
return isBlocked
76-
? new Promise<void>((_) => (resolve = _))
77-
: Promise.resolve();
76+
return new Promise((_) => {
77+
resolve = _;
78+
if (!isBlocked) walk();
79+
});
7880
},
7981
};
8082

@@ -87,7 +89,7 @@ export = function writableDOM(
8789
if (scanNode) walker.currentNode = scanNode;
8890

8991
while ((node = walker.nextNode())) {
90-
const link = getPreloadLink((scanNode = node));
92+
const link = getPreloadLink((scanNode = node), owner);
9193
if (link) {
9294
link.onload = link.onerror = () => target.removeChild(link);
9395
target.insertBefore(link, nextSibling);
@@ -101,7 +103,7 @@ export = function writableDOM(
101103
if (resolve || walker.nextNode()) {
102104
targetNodes
103105
.get(startNode.parentNode!)!
104-
.appendChild(document.importNode(startNode, false));
106+
.appendChild(owner.importNode(startNode, false));
105107
walker.currentNode = startNode;
106108
}
107109
} else {
@@ -123,7 +125,7 @@ export = function writableDOM(
123125
}
124126

125127
const parentNode = targetNodes.get(node.parentNode!) as ParentNode;
126-
const clone = document.importNode(node, false);
128+
const clone = owner.importNode(node, false);
127129
let insertParent: ParentNode = parentNode;
128130
targetNodes.set(node, clone);
129131

@@ -132,7 +134,7 @@ export = function writableDOM(
132134
(insertParent = targetFragments.get(parentNode)!) ||
133135
targetFragments.set(
134136
parentNode,
135-
(insertParent = new DocumentFragment()),
137+
(insertParent = owner.createDocumentFragment()),
136138
);
137139
}
138140

@@ -177,27 +179,28 @@ export = function writableDOM(
177179
function isBlocking(node: any): node is HTMLElement {
178180
return (
179181
node.nodeType === NodeType.ELEMENT_NODE &&
180-
((node.tagName === "SCRIPT" &&
181-
node.src &&
182-
!(
183-
node.noModule ||
184-
node.type === "module" ||
185-
node.hasAttribute("async") ||
186-
node.hasAttribute("defer")
187-
)) ||
182+
(node.blocking === "render" ||
183+
(node.tagName === "SCRIPT" &&
184+
node.src &&
185+
!(
186+
node.noModule ||
187+
node.type === "module" ||
188+
node.hasAttribute("async") ||
189+
node.hasAttribute("defer")
190+
)) ||
188191
(node.tagName === "LINK" &&
189192
node.rel === "stylesheet" &&
190193
(!node.media || matchMedia(node.media).matches)))
191194
);
192195
}
193196

194-
function getPreloadLink(node: any) {
197+
function getPreloadLink(node: any, owner: Document) {
195198
let link: HTMLLinkElement | undefined;
196199
if (node.nodeType === NodeType.ELEMENT_NODE) {
197200
switch (node.tagName) {
198201
case "SCRIPT":
199202
if (node.src && !node.noModule) {
200-
link = document.createElement("link");
203+
link = owner.createElement("link");
201204
link.href = node.src;
202205
if (node.getAttribute("type") === "module") {
203206
link.rel = "modulepreload";
@@ -212,14 +215,14 @@ function getPreloadLink(node: any) {
212215
node.rel === "stylesheet" &&
213216
(!node.media || matchMedia(node.media).matches)
214217
) {
215-
link = document.createElement("link");
218+
link = owner.createElement("link");
216219
link.href = node.href;
217220
link.rel = "preload";
218221
link.as = "style";
219222
}
220223
break;
221224
case "IMG":
222-
link = document.createElement("link");
225+
link = owner.createElement("link");
223226
link.rel = "preload";
224227
link.as = "image";
225228
if (node.srcset) {

0 commit comments

Comments
 (0)