-
Notifications
You must be signed in to change notification settings - Fork 43
/
dom-parser.ts
67 lines (55 loc) · 1.63 KB
/
dom-parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { getLock, setLock } from "../constructor-lock.ts";
import { nodesFromString } from "../deserialize.ts";
import { HTMLDocument, DocumentType } from "./document.ts";
import type { Element } from "./element.ts";
export type DOMParserMimeType =
"text/html"
| "text/xml"
| "application/xml"
| "application/xhtml+xml"
| "image/svg+xml";
export class DOMParser {
parseFromString(source: string, mimeType: DOMParserMimeType): HTMLDocument | null {
if (mimeType !== "text/html") {
throw new Error(`DOMParser: "${ mimeType }" unimplemented`); // TODO
}
setLock(false);
const doc = new HTMLDocument();
setLock(false);
const fakeDoc = nodesFromString(source);
let htmlNode: Element | null = null;
let hasDoctype = false;
for (const child of [...fakeDoc.childNodes]) {
doc.appendChild(child);
if (child instanceof DocumentType) {
hasDoctype = true;
} else if (child.nodeName === "HTML") {
htmlNode = <Element> child;
}
}
if (!hasDoctype) {
setLock(false);
const docType = new DocumentType("html", "", "");
// doc.insertBefore(docType, doc.firstChild);
if (doc.childNodes.length === 0) {
doc.appendChild(docType);
} else {
doc.childNodes[0].before(docType);
}
}
setLock(true);
if (htmlNode) {
for (const child of htmlNode.childNodes) {
switch ((<Element> child).tagName) {
case "HEAD":
doc.head = <Element> child;
break;
case "BODY":
doc.body = <Element> child;
break;
}
}
}
return doc;
}
}