]> Lady’s Gitweb - Lemon/blob - window/mod.js
5e97d4f2af8e289dc45496f943192f12056db703
[Lemon] / window / mod.js
1 // 🍋🏷 Lemon ∷ window/mod.js
2 // ====================================================================
3 //
4 // Copyright © 2022 Lady [@ Lady’s Computer].
5 //
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
9
10 import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
11
12 { // Polyfill document.
13 globalThis.document = new DOMImplementation().createDocument(
14 xhtmlNamespace,
15 "html",
16 null,
17 );
18 const { documentElement } = document;
19 documentElement.appendChild(
20 document.createElementNS(xhtmlNamespace, "head"),
21 );
22 documentElement.appendChild(
23 document.createElementNS(xhtmlNamespace, "body"),
24 );
25 }
26
27 { // Polyfill `element.append`.
28 Object.getPrototypeOf(
29 globalThis.document.documentElement,
30 ).append = function (...children) {
31 for (const child of children) {
32 this.appendChild(
33 typeof child === "string"
34 ? this.ownerDocument.createTextNode(child)
35 : child,
36 );
37 }
38 };
39 }
40
41 { // Apply patches to `Node.nodeType` and `Node.normalize`.
42 const { TEXT_NODE, prototype: nodePrototype } = Node;
43 const originalNodeTypeGetter = Object.getOwnPropertyDescriptor(
44 nodePrototype,
45 "nodeType",
46 )?.get ?? (() => {
47 const originalNodeTypeValue = nodePrototype.nodeType;
48 return () => originalNodeTypeValue;
49 })();
50 Object.defineProperty(nodePrototype, "nodeType", {
51 configurable: true,
52 enumerable: true,
53 /**
54 * To simulate restrictions on calling `nodeType` only on actual
55 * Nodes, check for inheritance first.
56 */
57 get() {
58 if (!(this instanceof Node)) {
59 // This is not a Node.
60 throw new TypeError("nodeType requires this be a Node.");
61 } else {
62 // This is a Node; walk the prototype chain and attempt to get
63 // the node type.
64 for (
65 //deno-lint-ignore no-this-alias
66 let target = this;
67 target != null && target != nodePrototype;
68 target = Object.getPrototypeOf(target)
69 ) {
70 if (Object.hasOwn(target, "nodeType")) {
71 return Reflect.get(target, "nodeType", this);
72 } else {
73 continue;
74 }
75 }
76 return originalNodeTypeGetter.call(this);
77 }
78 },
79 set: undefined,
80 });
81 nodePrototype.normalize = function () {
82 let child = this.firstChild;
83 while (child) {
84 const next = child.nextSibling;
85 if (
86 next && next.nodeType == TEXT_NODE &&
87 child.nodeType == TEXT_NODE
88 ) {
89 this.removeChild(next);
90 child.appendData(next.data);
91 } else {
92 if (child.nodeType == TEXT_NODE && !child.data) {
93 this.removeChild(child);
94 } else {
95 child.normalize();
96 }
97 child = next;
98 }
99 }
100 };
101 }
This page took 0.046109 seconds and 3 git commands to generate.