Skip to content

Commit

Permalink
fix: fallback document impl in old safari
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Dec 8, 2022
1 parent 2f9506e commit 242470c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ An alternative API is also available to use in case legacy browsers not implemen

The following is a version of the previous example implemented using the alternative API.


```js
import writableDOM from "writable-dom";

Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 33 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,37 @@ type Writable = {
close(): Promise<void>;
};

const createHTMLDocument = () => document.implementation.createHTMLDocument("");
let createDocument = (
target: ParentNode,
nextSibling: ChildNode | null
): Document => {
const testDoc = createHTMLDocument();
testDoc.write("<script>");
/**
* Safari and potentially other browsers strip script tags from detached documents.
* If that's the case we'll fallback to an iframe implementation.
*/
createDocument = testDoc.scripts.length
? createHTMLDocument
: (target, nextSibling) => {
const frame = document.createElement("iframe");
frame.src = "";
frame.style.display = "none";
target.insertBefore(frame, nextSibling);
const doc = frame.contentDocument!;
const { close } = doc;
doc.close = () => {
target.removeChild(frame);
close.call(doc);
};

return doc;
};

return createDocument(target, nextSibling);
};

export = function writableDOM(
this: unknown,
target: ParentNode,
Expand All @@ -13,12 +44,12 @@ export = function writableDOM(
return new WritableStream(writableDOM(target, previousSibling));
}

const doc = document.implementation.createHTMLDocument("");
const nextSibling = previousSibling ? previousSibling.nextSibling : null;
const doc = createDocument(target, nextSibling);
doc.write("<!DOCTYPE html><body><template>");
const root = (doc.body.firstChild as HTMLTemplateElement).content;
const walker = doc.createTreeWalker(root);
const targetNodes = new WeakMap<Node, Node>([[root, target]]);
const nextSibling = previousSibling ? previousSibling.nextSibling : null;
let pendingText: Text | null = null;
let scanNode: Node | null = null;
let resolve: void | (() => void);
Expand Down

0 comments on commit 242470c

Please sign in to comment.