@tkeron/html-parser 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.github/workflows/npm_deploy.yml +14 -4
  2. package/README.md +6 -6
  3. package/bun.lock +6 -8
  4. package/check-versions.ts +147 -0
  5. package/index.ts +4 -8
  6. package/package.json +5 -6
  7. package/src/dom-simulator/append-child.ts +130 -0
  8. package/src/dom-simulator/append.ts +18 -0
  9. package/src/dom-simulator/attributes.ts +23 -0
  10. package/src/dom-simulator/clone-node.ts +51 -0
  11. package/src/dom-simulator/convert-ast-node-to-dom.ts +37 -0
  12. package/src/dom-simulator/create-cdata.ts +18 -0
  13. package/src/dom-simulator/create-comment.ts +23 -0
  14. package/src/dom-simulator/create-doctype.ts +24 -0
  15. package/src/dom-simulator/create-document.ts +81 -0
  16. package/src/dom-simulator/create-element.ts +195 -0
  17. package/src/dom-simulator/create-processing-instruction.ts +19 -0
  18. package/src/dom-simulator/create-temp-parent.ts +9 -0
  19. package/src/dom-simulator/create-text-node.ts +23 -0
  20. package/src/dom-simulator/escape-text-content.ts +6 -0
  21. package/src/dom-simulator/find-special-elements.ts +14 -0
  22. package/src/dom-simulator/get-text-content.ts +18 -0
  23. package/src/dom-simulator/index.ts +36 -0
  24. package/src/dom-simulator/inner-outer-html.ts +182 -0
  25. package/src/dom-simulator/insert-after.ts +20 -0
  26. package/src/dom-simulator/insert-before.ts +108 -0
  27. package/src/dom-simulator/matches.ts +26 -0
  28. package/src/dom-simulator/node-types.ts +26 -0
  29. package/src/dom-simulator/prepend.ts +24 -0
  30. package/src/dom-simulator/remove-child.ts +68 -0
  31. package/src/dom-simulator/remove.ts +7 -0
  32. package/src/dom-simulator/replace-child.ts +152 -0
  33. package/src/dom-simulator/set-text-content.ts +33 -0
  34. package/src/dom-simulator/update-element-content.ts +56 -0
  35. package/src/dom-simulator.ts +12 -1126
  36. package/src/encoding/constants.ts +8 -0
  37. package/src/encoding/detect-encoding.ts +21 -0
  38. package/src/encoding/index.ts +1 -0
  39. package/src/encoding/normalize-encoding.ts +6 -0
  40. package/src/html-entities.ts +2127 -0
  41. package/src/index.ts +5 -5
  42. package/src/parser/adoption-agency-helpers.ts +145 -0
  43. package/src/parser/constants.ts +137 -0
  44. package/src/parser/dom-to-ast.ts +79 -0
  45. package/src/parser/index.ts +9 -0
  46. package/src/parser/parse.ts +772 -0
  47. package/src/parser/types.ts +56 -0
  48. package/src/selectors/find-elements-descendant.ts +47 -0
  49. package/src/selectors/index.ts +2 -0
  50. package/src/selectors/matches-selector.ts +12 -0
  51. package/src/selectors/matches-token.ts +27 -0
  52. package/src/selectors/parse-selector.ts +48 -0
  53. package/src/selectors/query-selector-all.ts +43 -0
  54. package/src/selectors/query-selector.ts +6 -0
  55. package/src/selectors/types.ts +10 -0
  56. package/src/serializer/attributes.ts +74 -0
  57. package/src/serializer/escape.ts +13 -0
  58. package/src/serializer/index.ts +1 -0
  59. package/src/serializer/serialize-tokens.ts +511 -0
  60. package/src/tokenizer/calculate-position.ts +10 -0
  61. package/src/tokenizer/constants.ts +11 -0
  62. package/src/tokenizer/decode-entities.ts +64 -0
  63. package/src/tokenizer/index.ts +2 -0
  64. package/src/tokenizer/parse-attributes.ts +74 -0
  65. package/src/tokenizer/tokenize.ts +165 -0
  66. package/src/tokenizer/types.ts +25 -0
  67. package/tests/adoption-agency-helpers.test.ts +304 -0
  68. package/tests/advanced.test.ts +242 -221
  69. package/tests/cloneNode.test.ts +19 -66
  70. package/tests/custom-elements-head.test.ts +54 -55
  71. package/tests/dom-extended.test.ts +77 -64
  72. package/tests/dom-manipulation.test.ts +51 -24
  73. package/tests/dom.test.ts +15 -13
  74. package/tests/encoding/detect-encoding.test.ts +33 -0
  75. package/tests/google-dom.test.ts +2 -2
  76. package/tests/helpers/tokenizer-adapter.test.ts +29 -43
  77. package/tests/helpers/tokenizer-adapter.ts +36 -33
  78. package/tests/helpers/tree-adapter.test.ts +20 -20
  79. package/tests/helpers/tree-adapter.ts +34 -24
  80. package/tests/html-entities-text.test.ts +6 -2
  81. package/tests/innerhtml-void-elements.test.ts +52 -36
  82. package/tests/outerHTML-replacement.test.ts +37 -65
  83. package/tests/parser/dom-to-ast.test.ts +109 -0
  84. package/tests/parser/parse.test.ts +139 -0
  85. package/tests/parser.test.ts +281 -217
  86. package/tests/selectors/query-selector-all.test.ts +39 -0
  87. package/tests/selectors/query-selector.test.ts +42 -0
  88. package/tests/serializer/attributes.test.ts +132 -0
  89. package/tests/serializer/escape.test.ts +51 -0
  90. package/tests/serializer/serialize-tokens.test.ts +80 -0
  91. package/tests/serializer-core.test.ts +6 -6
  92. package/tests/serializer-injectmeta.test.ts +6 -6
  93. package/tests/serializer-optionaltags.test.ts +9 -6
  94. package/tests/serializer-options.test.ts +6 -6
  95. package/tests/serializer-whitespace.test.ts +6 -6
  96. package/tests/tokenizer/calculate-position.test.ts +34 -0
  97. package/tests/tokenizer/decode-entities.test.ts +31 -0
  98. package/tests/tokenizer/parse-attributes.test.ts +44 -0
  99. package/tests/tokenizer/tokenize.test.ts +757 -0
  100. package/tests/tokenizer-namedEntities.test.ts +10 -7
  101. package/tests/tokenizer-pendingSpecChanges.test.ts +10 -7
  102. package/tests/tokenizer.test.ts +268 -256
  103. package/tests/tree-construction-adoption01.test.ts +25 -16
  104. package/tests/tree-construction-adoption02.test.ts +30 -19
  105. package/tests/tree-construction-domjs-unsafe.test.ts +6 -4
  106. package/tests/tree-construction-entities02.test.ts +18 -16
  107. package/tests/tree-construction-html5test-com.test.ts +16 -10
  108. package/tests/tree-construction-math.test.ts +11 -9
  109. package/tests/tree-construction-namespace-sensitivity.test.ts +11 -9
  110. package/tests/tree-construction-noscript01.test.ts +11 -9
  111. package/tests/tree-construction-ruby.test.ts +6 -4
  112. package/tests/tree-construction-scriptdata01.test.ts +6 -4
  113. package/tests/tree-construction-svg.test.ts +6 -4
  114. package/tests/tree-construction-template.test.ts +6 -4
  115. package/tests/tree-construction-tests10.test.ts +6 -4
  116. package/tests/tree-construction-tests11.test.ts +6 -4
  117. package/tests/tree-construction-tests20.test.ts +7 -4
  118. package/tests/tree-construction-tests21.test.ts +7 -4
  119. package/tests/tree-construction-tests23.test.ts +7 -4
  120. package/tests/tree-construction-tests24.test.ts +7 -4
  121. package/tests/tree-construction-tests5.test.ts +6 -5
  122. package/tests/tree-construction-tests6.test.ts +6 -5
  123. package/tests/tree-construction-tests_innerHTML_1.test.ts +6 -5
  124. package/tests/void-elements.test.ts +85 -40
  125. package/tsconfig.json +1 -1
  126. package/src/css-selector.ts +0 -185
  127. package/src/encoding.ts +0 -39
  128. package/src/parser.ts +0 -682
  129. package/src/serializer.ts +0 -450
  130. package/src/tokenizer.ts +0 -325
  131. package/tests/selectors.test.ts +0 -128
@@ -0,0 +1,108 @@
1
+ import { NodeType } from "./node-types.js";
2
+ import { appendChild } from "./append-child.js";
3
+ import { removeChild } from "./remove-child.js";
4
+ import { updateElementContent } from "./update-element-content.js";
5
+
6
+ export const insertBefore = (
7
+ parent: any,
8
+ newNode: any,
9
+ referenceNode: any,
10
+ ): any => {
11
+ if (referenceNode === null) {
12
+ appendChild(parent, newNode);
13
+ return newNode;
14
+ }
15
+
16
+ const refIndex = parent.childNodes.indexOf(referenceNode);
17
+ if (refIndex === -1) {
18
+ throw new Error("Reference node is not a child of this node");
19
+ }
20
+
21
+ if (
22
+ newNode.nodeType === NodeType.ELEMENT_NODE ||
23
+ newNode.nodeType === NodeType.DOCUMENT_NODE
24
+ ) {
25
+ let ancestor = parent;
26
+ while (ancestor) {
27
+ if (ancestor === newNode) {
28
+ throw new Error(
29
+ "HierarchyRequestError: Cannot insert a node as a descendant of itself",
30
+ );
31
+ }
32
+ ancestor = ancestor.parentNode;
33
+ }
34
+ }
35
+
36
+ if (newNode.parentNode) {
37
+ removeChild(newNode.parentNode, newNode);
38
+ }
39
+
40
+ parent.childNodes.splice(refIndex, 0, newNode);
41
+ newNode.parentNode = parent;
42
+
43
+ newNode.previousSibling = referenceNode.previousSibling;
44
+ newNode.nextSibling = referenceNode;
45
+
46
+ if (referenceNode.previousSibling) {
47
+ referenceNode.previousSibling.nextSibling = newNode;
48
+ }
49
+ referenceNode.previousSibling = newNode;
50
+
51
+ if (parent.firstChild === referenceNode) {
52
+ parent.firstChild = newNode;
53
+ }
54
+
55
+ if (
56
+ parent.nodeType === NodeType.ELEMENT_NODE &&
57
+ newNode.nodeType === NodeType.ELEMENT_NODE
58
+ ) {
59
+ const parentElement = parent;
60
+ const newElement = newNode;
61
+
62
+ newElement.parentElement = parentElement;
63
+
64
+ let refElementIndex = -1;
65
+ if (referenceNode.nodeType === NodeType.ELEMENT_NODE) {
66
+ refElementIndex = parentElement.children.indexOf(referenceNode);
67
+ } else {
68
+ let nextElement = referenceNode.nextSibling;
69
+ while (nextElement && nextElement.nodeType !== NodeType.ELEMENT_NODE) {
70
+ nextElement = nextElement.nextSibling;
71
+ }
72
+ if (nextElement) {
73
+ refElementIndex = parentElement.children.indexOf(nextElement);
74
+ }
75
+ }
76
+
77
+ if (refElementIndex === -1) {
78
+ parentElement.children.push(newElement);
79
+ } else {
80
+ parentElement.children.splice(refElementIndex, 0, newElement);
81
+ }
82
+
83
+ const newElemIndex = parentElement.children.indexOf(newElement);
84
+ newElement.previousElementSibling =
85
+ newElemIndex > 0 ? parentElement.children[newElemIndex - 1] : null;
86
+ newElement.nextElementSibling =
87
+ newElemIndex < parentElement.children.length - 1
88
+ ? parentElement.children[newElemIndex + 1]
89
+ : null;
90
+
91
+ if (newElement.previousElementSibling) {
92
+ newElement.previousElementSibling.nextElementSibling = newElement;
93
+ }
94
+ if (newElement.nextElementSibling) {
95
+ newElement.nextElementSibling.previousElementSibling = newElement;
96
+ }
97
+
98
+ if (newElemIndex === 0) {
99
+ parentElement.firstElementChild = newElement;
100
+ }
101
+ }
102
+
103
+ if (parent.nodeType === NodeType.ELEMENT_NODE) {
104
+ updateElementContent(parent);
105
+ }
106
+
107
+ return newNode;
108
+ };
@@ -0,0 +1,26 @@
1
+ import { NodeType } from "./node-types.js";
2
+ import { querySelectorAll as querySelectorAllFunction } from "../selectors";
3
+ import { createTempParent } from "./create-temp-parent.js";
4
+
5
+ export const matches = (element: any, selector: string): boolean => {
6
+ if (!selector || element.nodeType !== NodeType.ELEMENT_NODE) {
7
+ return false;
8
+ }
9
+
10
+ try {
11
+ if (selector.includes(" ") || selector.includes(">")) {
12
+ let root = element;
13
+ while (root.parentNode) {
14
+ root = root.parentNode;
15
+ }
16
+ const results = querySelectorAllFunction(root, selector);
17
+ return results.includes(element);
18
+ }
19
+
20
+ const parent = element.parentNode || createTempParent(element);
21
+ const results = querySelectorAllFunction(parent, selector);
22
+ return results.includes(element);
23
+ } catch (error) {
24
+ return false;
25
+ }
26
+ };
@@ -0,0 +1,26 @@
1
+ export const enum NodeType {
2
+ ELEMENT_NODE = 1,
3
+ TEXT_NODE = 3,
4
+ COMMENT_NODE = 8,
5
+ DOCUMENT_NODE = 9,
6
+ DOCUMENT_TYPE_NODE = 10,
7
+ PROCESSING_INSTRUCTION_NODE = 7,
8
+ CDATA_SECTION_NODE = 4,
9
+ }
10
+
11
+ export const VOID_ELEMENTS = new Set([
12
+ "area",
13
+ "base",
14
+ "br",
15
+ "col",
16
+ "embed",
17
+ "hr",
18
+ "img",
19
+ "input",
20
+ "link",
21
+ "meta",
22
+ "param",
23
+ "source",
24
+ "track",
25
+ "wbr",
26
+ ]);
@@ -0,0 +1,24 @@
1
+ import { createTextNode } from "./create-text-node.js";
2
+ import { insertBefore } from "./insert-before.js";
3
+ import { appendChild } from "./append-child.js";
4
+
5
+ export const prepend = (parent: any, ...nodes: any[]): void => {
6
+ if (nodes.length === 0) return;
7
+
8
+ for (let i = nodes.length - 1; i >= 0; i--) {
9
+ const node = nodes[i];
10
+ let childNode: any;
11
+
12
+ if (typeof node === "string") {
13
+ childNode = createTextNode(node);
14
+ } else {
15
+ childNode = node;
16
+ }
17
+
18
+ if (parent.firstChild) {
19
+ insertBefore(parent, childNode, parent.firstChild);
20
+ } else {
21
+ appendChild(parent, childNode);
22
+ }
23
+ }
24
+ };
@@ -0,0 +1,68 @@
1
+ import { NodeType } from "./node-types.js";
2
+ import { updateElementContent } from "./update-element-content.js";
3
+
4
+ export const removeChild = (parent: any, child: any): any => {
5
+ const index = parent.childNodes.indexOf(child);
6
+ if (index === -1) {
7
+ throw new Error("Child not found");
8
+ }
9
+
10
+ parent.childNodes.splice(index, 1);
11
+
12
+ if (child.previousSibling) {
13
+ child.previousSibling.nextSibling = child.nextSibling;
14
+ }
15
+ if (child.nextSibling) {
16
+ child.nextSibling.previousSibling = child.previousSibling;
17
+ }
18
+
19
+ if (parent.firstChild === child) {
20
+ parent.firstChild = child.nextSibling;
21
+ }
22
+ if (parent.lastChild === child) {
23
+ parent.lastChild = child.previousSibling;
24
+ }
25
+
26
+ if (
27
+ parent.nodeType === NodeType.ELEMENT_NODE &&
28
+ child.nodeType === NodeType.ELEMENT_NODE
29
+ ) {
30
+ const childElement = child;
31
+ const elemIndex = parent.children.indexOf(childElement);
32
+ if (elemIndex !== -1) {
33
+ parent.children.splice(elemIndex, 1);
34
+
35
+ if (childElement.previousElementSibling) {
36
+ childElement.previousElementSibling.nextElementSibling =
37
+ childElement.nextElementSibling;
38
+ }
39
+ if (childElement.nextElementSibling) {
40
+ childElement.nextElementSibling.previousElementSibling =
41
+ childElement.previousElementSibling;
42
+ }
43
+
44
+ if (parent.firstElementChild === childElement) {
45
+ parent.firstElementChild = childElement.nextElementSibling;
46
+ }
47
+ if (parent.lastElementChild === childElement) {
48
+ parent.lastElementChild = childElement.previousElementSibling;
49
+ }
50
+ }
51
+ }
52
+
53
+ child.parentNode = null;
54
+ if (child.nodeType === NodeType.ELEMENT_NODE) {
55
+ child.parentElement = null;
56
+ }
57
+ child.previousSibling = null;
58
+ child.nextSibling = null;
59
+ if (child.nodeType === NodeType.ELEMENT_NODE) {
60
+ child.previousElementSibling = null;
61
+ child.nextElementSibling = null;
62
+ }
63
+
64
+ if (parent.nodeType === NodeType.ELEMENT_NODE) {
65
+ updateElementContent(parent);
66
+ }
67
+ return child;
68
+ };
@@ -0,0 +1,7 @@
1
+ import { removeChild } from "./remove-child.js";
2
+
3
+ export const remove = (node: any): void => {
4
+ if (node.parentNode) {
5
+ removeChild(node.parentNode, node);
6
+ }
7
+ };
@@ -0,0 +1,152 @@
1
+ import { NodeType } from "./node-types.js";
2
+ import { removeChild } from "./remove-child.js";
3
+ import { updateElementContent } from "./update-element-content.js";
4
+
5
+ export const replaceChild = (
6
+ parent: any,
7
+ newChild: any,
8
+ oldChild: any,
9
+ ): any => {
10
+ const oldIndex = parent.childNodes.indexOf(oldChild);
11
+ if (oldIndex === -1) {
12
+ throw new Error("Old child is not a child of this node");
13
+ }
14
+
15
+ if (
16
+ newChild.nodeType === NodeType.ELEMENT_NODE ||
17
+ newChild.nodeType === NodeType.DOCUMENT_NODE
18
+ ) {
19
+ let ancestor = parent;
20
+ while (ancestor) {
21
+ if (ancestor === newChild) {
22
+ throw new Error(
23
+ "HierarchyRequestError: Cannot insert a node as a descendant of itself",
24
+ );
25
+ }
26
+ ancestor = ancestor.parentNode;
27
+ }
28
+ }
29
+
30
+ if (newChild.parentNode) {
31
+ removeChild(newChild.parentNode, newChild);
32
+ }
33
+
34
+ parent.childNodes[oldIndex] = newChild;
35
+ newChild.parentNode = parent;
36
+
37
+ newChild.previousSibling = oldChild.previousSibling;
38
+ newChild.nextSibling = oldChild.nextSibling;
39
+
40
+ if (oldChild.previousSibling) {
41
+ oldChild.previousSibling.nextSibling = newChild;
42
+ }
43
+ if (oldChild.nextSibling) {
44
+ oldChild.nextSibling.previousSibling = newChild;
45
+ }
46
+
47
+ if (parent.firstChild === oldChild) {
48
+ parent.firstChild = newChild;
49
+ }
50
+ if (parent.lastChild === oldChild) {
51
+ parent.lastChild = newChild;
52
+ }
53
+
54
+ if (parent.nodeType === NodeType.ELEMENT_NODE) {
55
+ const parentElement = parent;
56
+
57
+ if (oldChild.nodeType === NodeType.ELEMENT_NODE) {
58
+ const oldElemIndex = parentElement.children.indexOf(oldChild);
59
+ if (oldElemIndex !== -1) {
60
+ if (newChild.nodeType === NodeType.ELEMENT_NODE) {
61
+ parentElement.children[oldElemIndex] = newChild;
62
+ newChild.parentElement = parentElement;
63
+
64
+ newChild.previousElementSibling = oldChild.previousElementSibling;
65
+ newChild.nextElementSibling = oldChild.nextElementSibling;
66
+
67
+ if (oldChild.previousElementSibling) {
68
+ oldChild.previousElementSibling.nextElementSibling = newChild;
69
+ }
70
+ if (oldChild.nextElementSibling) {
71
+ oldChild.nextElementSibling.previousElementSibling = newChild;
72
+ }
73
+
74
+ if (parentElement.firstElementChild === oldChild) {
75
+ parentElement.firstElementChild = newChild;
76
+ }
77
+ if (parentElement.lastElementChild === oldChild) {
78
+ parentElement.lastElementChild = newChild;
79
+ }
80
+ } else {
81
+ parentElement.children.splice(oldElemIndex, 1);
82
+
83
+ if (oldChild.previousElementSibling) {
84
+ oldChild.previousElementSibling.nextElementSibling =
85
+ oldChild.nextElementSibling;
86
+ }
87
+ if (oldChild.nextElementSibling) {
88
+ oldChild.nextElementSibling.previousElementSibling =
89
+ oldChild.previousElementSibling;
90
+ }
91
+
92
+ if (parentElement.firstElementChild === oldChild) {
93
+ parentElement.firstElementChild = oldChild.nextElementSibling;
94
+ }
95
+ if (parentElement.lastElementChild === oldChild) {
96
+ parentElement.lastElementChild = oldChild.previousElementSibling;
97
+ }
98
+ }
99
+ }
100
+ } else if (newChild.nodeType === NodeType.ELEMENT_NODE) {
101
+ const newElement = newChild;
102
+ newElement.parentElement = parentElement;
103
+
104
+ let insertIndex = 0;
105
+ for (let i = 0; i < oldIndex; i++) {
106
+ if (parent.childNodes[i].nodeType === NodeType.ELEMENT_NODE) {
107
+ insertIndex++;
108
+ }
109
+ }
110
+
111
+ parentElement.children.splice(insertIndex, 0, newElement);
112
+
113
+ newElement.previousElementSibling =
114
+ insertIndex > 0 ? parentElement.children[insertIndex - 1] : null;
115
+ newElement.nextElementSibling =
116
+ insertIndex < parentElement.children.length - 1
117
+ ? parentElement.children[insertIndex + 1]
118
+ : null;
119
+
120
+ if (newElement.previousElementSibling) {
121
+ newElement.previousElementSibling.nextElementSibling = newElement;
122
+ }
123
+ if (newElement.nextElementSibling) {
124
+ newElement.nextElementSibling.previousElementSibling = newElement;
125
+ }
126
+
127
+ if (insertIndex === 0) {
128
+ parentElement.firstElementChild = newElement;
129
+ }
130
+ if (insertIndex === parentElement.children.length - 1) {
131
+ parentElement.lastElementChild = newElement;
132
+ }
133
+ }
134
+ }
135
+
136
+ oldChild.parentNode = null;
137
+ if (oldChild.nodeType === NodeType.ELEMENT_NODE) {
138
+ oldChild.parentElement = null;
139
+ }
140
+ oldChild.previousSibling = null;
141
+ oldChild.nextSibling = null;
142
+ if (oldChild.nodeType === NodeType.ELEMENT_NODE) {
143
+ oldChild.previousElementSibling = null;
144
+ oldChild.nextElementSibling = null;
145
+ }
146
+
147
+ if (parent.nodeType === NodeType.ELEMENT_NODE) {
148
+ updateElementContent(parent);
149
+ }
150
+
151
+ return oldChild;
152
+ };
@@ -0,0 +1,33 @@
1
+ import { NodeType } from "./node-types.js";
2
+ import { updateElementContent } from "./update-element-content.js";
3
+
4
+ export const setTextContent = (element: any, text: string): void => {
5
+ element.childNodes = [];
6
+ element.children = [];
7
+ element.firstChild = null;
8
+ element.lastChild = null;
9
+ element.firstElementChild = null;
10
+ element.lastElementChild = null;
11
+
12
+ if (text) {
13
+ const textNode: any = {
14
+ nodeType: NodeType.TEXT_NODE,
15
+ nodeName: "#text",
16
+ nodeValue: text,
17
+ textContent: text,
18
+ data: text,
19
+ childNodes: [],
20
+ parentNode: element,
21
+ firstChild: null,
22
+ lastChild: null,
23
+ nextSibling: null,
24
+ previousSibling: null,
25
+ };
26
+
27
+ element.childNodes.push(textNode);
28
+ element.firstChild = textNode;
29
+ element.lastChild = textNode;
30
+ }
31
+
32
+ updateElementContent(element);
33
+ };
@@ -0,0 +1,56 @@
1
+ import { NodeType, VOID_ELEMENTS } from "./node-types.js";
2
+ import { getTextContent } from "./get-text-content.js";
3
+ import { escapeTextContent } from "./escape-text-content.js";
4
+
5
+ export const updateElementContent = (element: any): void => {
6
+ const innerHTML = element.childNodes
7
+ .map((child: any) => {
8
+ if (child.nodeType === NodeType.TEXT_NODE) {
9
+ return escapeTextContent(child.textContent || "");
10
+ } else if (child.nodeType === NodeType.ELEMENT_NODE) {
11
+ return child.outerHTML;
12
+ } else if (child.nodeType === NodeType.COMMENT_NODE) {
13
+ return `<!--${child.data}-->`;
14
+ }
15
+ return "";
16
+ })
17
+ .join("");
18
+
19
+ Object.defineProperty(element, "_internalInnerHTML", {
20
+ value: innerHTML,
21
+ writable: true,
22
+ enumerable: false,
23
+ configurable: true,
24
+ });
25
+
26
+ const attrs = Object.entries(element.attributes)
27
+ .map(([k, v]) => ` ${k}="${v}"`)
28
+ .join("");
29
+ const tagNameLower = element.tagName.toLowerCase();
30
+ const isVoid = VOID_ELEMENTS.has(tagNameLower);
31
+
32
+ const outerHTML = isVoid
33
+ ? `<${tagNameLower}${attrs}>`
34
+ : `<${tagNameLower}${attrs}>${innerHTML}</${tagNameLower}>`;
35
+
36
+ Object.defineProperty(element, "_internalOuterHTML", {
37
+ value: outerHTML,
38
+ writable: true,
39
+ enumerable: false,
40
+ configurable: true,
41
+ });
42
+
43
+ const computedTextContent = getTextContent(element);
44
+ Object.defineProperty(element, "_internalTextContent", {
45
+ value: computedTextContent,
46
+ writable: true,
47
+ enumerable: false,
48
+ configurable: true,
49
+ });
50
+
51
+ if (element.parentElement) {
52
+ element.parentElement._internalOuterHTML = undefined;
53
+ element.parentElement._internalInnerHTML = undefined;
54
+ element.parentElement._internalTextContent = undefined;
55
+ }
56
+ };