]> Lady’s Gitweb - Lemon/blobdiff - window/mod.js
[window] Polyfill top‐level D·O·M interfaces
[Lemon] / window / mod.js
index 5e97d4f2af8e289dc45496f943192f12056db703..82be590858b07bd660ac3708f0ae49a08551bde6 100644 (file)
@@ -7,7 +7,20 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
 
-import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
+import {
+  DOMImplementation,
+  DOMParser,
+  xhtmlNamespace,
+  XMLSerializer,
+} from "./deps.js";
+
+{ // Polyfill global interfaces.
+  Object.assign(globalThis, {
+    DOMImplementation,
+    DOMParser,
+    XMLSerializer,
+  });
+}
 
 { // Polyfill document.
   globalThis.document = new DOMImplementation().createDocument(
@@ -24,7 +37,7 @@ import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
   );
 }
 
-{ // Polyfill `element.append`.
+{ // Polyfill Element::append.
   Object.getPrototypeOf(
     globalThis.document.documentElement,
   ).append = function (...children) {
@@ -38,13 +51,15 @@ import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
   };
 }
 
-{ // Apply patches to `Node.nodeType` and `Node.normalize`.
-  const { TEXT_NODE, prototype: nodePrototype } = Node;
+{ // Apply patches to Node::nodeType and Node::normalize.
+  const nodePrototype = Object.getPrototypeOf(
+    Object.getPrototypeOf(document.createDocumentFragment()),
+  );
   const originalNodeTypeGetter = Object.getOwnPropertyDescriptor(
     nodePrototype,
     "nodeType",
   )?.get ?? (() => {
-    const originalNodeTypeValue = nodePrototype.nodeType;
+    const { nodeType: originalNodeTypeValue } = nodePrototype;
     return () => originalNodeTypeValue;
   })();
   Object.defineProperty(nodePrototype, "nodeType", {
@@ -55,7 +70,28 @@ import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
      * Nodes, check for inheritance first.
      */
     get() {
-      if (!(this instanceof Node)) {
+      if (
+        !(() => {
+          // Test whether this object has the node prototype in its
+          // prototype chain.
+          for (
+            let prototype = this === Object(this)
+              ? Object.getPrototypeOf(this)
+              : null;
+            prototype != null;
+            prototype = Object.getPrototypeOf(prototype)
+          ) {
+            if (prototype === nodePrototype) {
+              // This object inherits from the Node prototype.
+              return true;
+            } else {
+              // This object is not yet known to inherits from the Node
+              // prototype.
+              continue;
+            }
+          }
+        })()
+      ) {
         // This is not a Node.
         throw new TypeError("nodeType requires this be a Node.");
       } else {
@@ -82,14 +118,11 @@ import { DOMImplementation, Node, xhtmlNamespace } from "./deps.js";
     let child = this.firstChild;
     while (child) {
       const next = child.nextSibling;
-      if (
-        next && next.nodeType == TEXT_NODE &&
-        child.nodeType == TEXT_NODE
-      ) {
+      if (next && next.nodeType == 3 && child.nodeType == 3) {
         this.removeChild(next);
         child.appendData(next.data);
       } else {
-        if (child.nodeType == TEXT_NODE && !child.data) {
+        if (child.nodeType == 3 && !child.data) {
           this.removeChild(child);
         } else {
           child.normalize();
This page took 0.024041 seconds and 4 git commands to generate.