@remote-dom/polyfill 1.0.6 → 1.2.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 (82) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/cjs/Attr.cjs +55 -0
  3. package/build/cjs/CharacterData.cjs +30 -0
  4. package/build/cjs/ChildNode.cjs +47 -0
  5. package/build/cjs/Comment.cjs +13 -0
  6. package/build/cjs/CustomElementRegistry.cjs +43 -0
  7. package/build/cjs/CustomEvent.cjs +30 -0
  8. package/build/cjs/Document.cjs +107 -0
  9. package/build/cjs/DocumentFragment.cjs +14 -0
  10. package/build/cjs/Element.cjs +99 -0
  11. package/build/cjs/Event.cjs +115 -0
  12. package/build/cjs/EventTarget.cjs +108 -0
  13. package/build/cjs/HTMLBodyElement.cjs +9 -0
  14. package/build/cjs/HTMLElement.cjs +9 -0
  15. package/build/cjs/HTMLHeadElement.cjs +9 -0
  16. package/build/cjs/HTMLHtmlElement.cjs +9 -0
  17. package/build/cjs/HTMLTemplateElement.cjs +28 -0
  18. package/build/cjs/MutationObserver.cjs +9 -0
  19. package/build/cjs/NamedNodeMap.cjs +123 -0
  20. package/build/cjs/Node.cjs +116 -0
  21. package/build/cjs/NodeList.cjs +11 -0
  22. package/build/cjs/ParentNode.cjs +131 -0
  23. package/build/cjs/SVGElement.cjs +21 -0
  24. package/build/cjs/Text.cjs +13 -0
  25. package/build/cjs/Window.cjs +78 -0
  26. package/build/cjs/constants.cjs +61 -0
  27. package/build/cjs/index.cjs +13 -0
  28. package/build/cjs/selectors.cjs +203 -0
  29. package/build/cjs/serialization.cjs +99 -0
  30. package/build/cjs/shared.cjs +65 -0
  31. package/build/esm/Attr.mjs +2 -3
  32. package/build/esm/CharacterData.mjs +3 -4
  33. package/build/esm/Document.mjs +2 -3
  34. package/build/esm/EventTarget.mjs +8 -4
  35. package/build/esm/NamedNodeMap.mjs +3 -4
  36. package/build/esm/Node.mjs +4 -1
  37. package/build/esm/ParentNode.mjs +3 -4
  38. package/build/esm/Window.mjs +2 -0
  39. package/build/esm/constants.mjs +2 -1
  40. package/build/esm/index.mjs +2 -1
  41. package/build/esnext/Attr.esnext +2 -3
  42. package/build/esnext/CharacterData.esnext +3 -4
  43. package/build/esnext/Document.esnext +2 -3
  44. package/build/esnext/EventTarget.esnext +18 -4
  45. package/build/esnext/NamedNodeMap.esnext +7 -4
  46. package/build/esnext/Node.esnext +4 -1
  47. package/build/esnext/ParentNode.esnext +3 -4
  48. package/build/esnext/Window.esnext +2 -0
  49. package/build/esnext/constants.esnext +2 -1
  50. package/build/esnext/index.esnext +2 -1
  51. package/build/tsconfig.tsbuildinfo +1 -1
  52. package/build/typescript/Attr.d.ts.map +1 -1
  53. package/build/typescript/CharacterData.d.ts.map +1 -1
  54. package/build/typescript/Document.d.ts.map +1 -1
  55. package/build/typescript/EventTarget.d.ts +7 -1
  56. package/build/typescript/EventTarget.d.ts.map +1 -1
  57. package/build/typescript/NamedNodeMap.d.ts.map +1 -1
  58. package/build/typescript/Node.d.ts +2 -1
  59. package/build/typescript/Node.d.ts.map +1 -1
  60. package/build/typescript/Window.d.ts +3 -0
  61. package/build/typescript/Window.d.ts.map +1 -1
  62. package/build/typescript/constants.d.ts +1 -0
  63. package/build/typescript/constants.d.ts.map +1 -1
  64. package/build/typescript/hooks.d.ts +0 -1
  65. package/build/typescript/hooks.d.ts.map +1 -1
  66. package/build/typescript/index.d.ts +3 -1
  67. package/build/typescript/index.d.ts.map +1 -1
  68. package/package.json +3 -2
  69. package/rollup.config.js +1 -1
  70. package/source/Attr.ts +2 -2
  71. package/source/CharacterData.ts +3 -4
  72. package/source/Document.ts +9 -3
  73. package/source/EventTarget.ts +19 -4
  74. package/source/NamedNodeMap.ts +14 -4
  75. package/source/Node.ts +5 -0
  76. package/source/ParentNode.ts +3 -3
  77. package/source/Window.ts +3 -0
  78. package/source/constants.ts +1 -0
  79. package/source/hooks.ts +0 -2
  80. package/source/index.ts +3 -1
  81. package/build/esm/hooks.mjs +0 -3
  82. package/build/esnext/hooks.esnext +0 -3
@@ -0,0 +1,203 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const constants = require('./constants.cjs');
6
+ const shared = require('./shared.cjs');
7
+
8
+ var Combinator = /*#__PURE__*/function (Combinator) {
9
+ Combinator[Combinator["Descendant"] = 0] = "Descendant";
10
+ Combinator[Combinator["Child"] = 1] = "Child";
11
+ Combinator[Combinator["Sibling"] = 2] = "Sibling";
12
+ Combinator[Combinator["Adjacent"] = 3] = "Adjacent";
13
+ Combinator[Combinator["Inner"] = 4] = "Inner";
14
+ return Combinator;
15
+ }(Combinator || {});
16
+ var MatcherType = /*#__PURE__*/function (MatcherType) {
17
+ MatcherType[MatcherType["Unknown"] = 0] = "Unknown";
18
+ MatcherType[MatcherType["Element"] = 1] = "Element";
19
+ MatcherType[MatcherType["Id"] = 2] = "Id";
20
+ MatcherType[MatcherType["Class"] = 3] = "Class";
21
+ MatcherType[MatcherType["Attribute"] = 4] = "Attribute";
22
+ MatcherType[MatcherType["Pseudo"] = 5] = "Pseudo";
23
+ MatcherType[MatcherType["Function"] = 6] = "Function";
24
+ return MatcherType;
25
+ }(MatcherType || {});
26
+ const ELEMENT_SELECTOR_TEST = /[a-z]/;
27
+ function querySelector(within, selector) {
28
+ const parts = parseSelector(selector);
29
+ let result = null;
30
+ const child = within[constants.CHILD];
31
+ if (child && parts[0].matchers.length) {
32
+ walkNodesForSelector(child, parts, node => {
33
+ result = node;
34
+ return false;
35
+ });
36
+ }
37
+ return result;
38
+ }
39
+ function querySelectorAll(within, selector) {
40
+ const parts = parseSelector(selector);
41
+ const results = [];
42
+ const child = within[constants.CHILD];
43
+ if (child && parts[0].matchers.length) {
44
+ walkNodesForSelector(child, parts, node => {
45
+ results.push(node);
46
+ });
47
+ }
48
+ return results;
49
+ }
50
+ function parseSelector(selector) {
51
+ let part = {
52
+ combinator: Combinator.Inner,
53
+ matchers: []
54
+ };
55
+ const parts = [part];
56
+ const tokenizer = /\s*?([>\s+~]?)\s*?(?:(?:\[\s*([^\]=]+)(?:=(['"])(.*?)\3)?\s*\])|([#.]?)([^\s#.[>:]+)|:(\w+)(?:\((.*?)\))?)/gi;
57
+ let token;
58
+ while (token = tokenizer.exec(selector)) {
59
+ // [1]: ancestor/parent/sibling/adjacent
60
+ // [2]: attribute name
61
+ // [4]: attribute value
62
+ // [5]: id/class sigil
63
+ // [6]: id/class name
64
+ // [7]: :pseudo/:function() name
65
+ // [8]: :function(argument) value
66
+ if (token[1]) {
67
+ // Update the combinator on the (now parent) Part:
68
+ if (token[1] === '>') part.combinator = Combinator.Child;else if (token[1] === '+') part.combinator = Combinator.Adjacent;else if (token[1] === '~') part.combinator = Combinator.Sibling;else part.combinator = Combinator.Descendant;
69
+ // Add a new Part for the next selector parts:
70
+ part = {
71
+ combinator: Combinator.Inner,
72
+ matchers: []
73
+ };
74
+ parts.push(part);
75
+ }
76
+ let type = MatcherType.Unknown;
77
+ if (token[2]) {
78
+ type = MatcherType.Attribute;
79
+ } else if (token[5]) {
80
+ type = token[5] === '#' ? MatcherType.Id : MatcherType.Class;
81
+ } else if (token[7]) {
82
+ type = token[8] == null ? MatcherType.Pseudo : MatcherType.Function;
83
+ } else if (token[6] && ELEMENT_SELECTOR_TEST.test(token[6])) {
84
+ type = MatcherType.Element;
85
+ }
86
+ part.matchers.push({
87
+ type,
88
+ name: token[2] || token[6] || token[7],
89
+ value: token[4] ?? token[6] ?? token[8]
90
+ });
91
+ }
92
+ return parts;
93
+ }
94
+ function matchesSelector(element, selector) {
95
+ const parsed = parseSelector(selector);
96
+ let part;
97
+ while (part = parsed.pop()) {
98
+ if (!matchesSelectorPart(element, part)) return false;
99
+ }
100
+ return true;
101
+ }
102
+ function walkNodesForSelector(node, parts, callback) {
103
+ if (shared.isElementNode(node)) {
104
+ if (matchesSelectorRecursive(node, parts)) {
105
+ if (callback(node) === false) return false;
106
+ }
107
+ const child = node[constants.CHILD];
108
+ if (child && walkNodesForSelector(child, parts, callback) === false) {
109
+ return false;
110
+ }
111
+ }
112
+ const next = node[constants.NEXT];
113
+ if (next && walkNodesForSelector(next, parts, callback) === false) {
114
+ return false;
115
+ }
116
+ return true;
117
+ }
118
+ function matchesSelectorRecursive(element, parts) {
119
+ const {
120
+ combinator,
121
+ matchers
122
+ } = parts[parts.length - 1];
123
+ if (combinator === Combinator.Inner) {
124
+ if (!matchesSelectorMatcher(element, matchers)) return false;
125
+ const pp = parts.slice(0, -1);
126
+ return pp.length === 0 || matchesSelectorRecursive(element, pp);
127
+ }
128
+ const link = combinator === Combinator.Child || combinator === Combinator.Descendant ? constants.PARENT : constants.PREV;
129
+ let ref = element[link];
130
+ if (!ref || !matchesSelectorMatcher(ref, matchers)) {
131
+ return false;
132
+ }
133
+ if (combinator === Combinator.Descendant || combinator === Combinator.Sibling) {
134
+ while (ref = ref[link]) {
135
+ if (matchesSelectorMatcher(ref, matchers)) {
136
+ const pp = parts.slice(0, -1);
137
+ if (pp.length === 0) return true;
138
+ if (matchesSelectorRecursive(element, pp)) return true;
139
+ }
140
+ }
141
+ }
142
+ return false;
143
+ }
144
+ function matchesSelectorPart(element, {
145
+ combinator,
146
+ matchers
147
+ }) {
148
+ if (combinator === Combinator.Inner) {
149
+ return matchesSelectorMatcher(element, matchers);
150
+ }
151
+ const link = combinator === Combinator.Child || combinator === Combinator.Descendant ? constants.PARENT : constants.PREV;
152
+ let ref = element[link];
153
+ if (!ref || !matchesSelectorMatcher(ref, matchers)) {
154
+ return false;
155
+ }
156
+ if (combinator === Combinator.Descendant || combinator === Combinator.Sibling) {
157
+ while (ref = ref[link]) {
158
+ if (matchesSelectorMatcher(ref, matchers)) return true;
159
+ }
160
+ }
161
+ return false;
162
+ }
163
+ function matchesSelectorMatcher(element, matcher) {
164
+ if (!element) return false;
165
+ if (Array.isArray(matcher)) {
166
+ for (const single of matcher) {
167
+ if (matchesSelectorMatcher(element, single) === false) return false;
168
+ }
169
+ return true;
170
+ }
171
+ const {
172
+ type,
173
+ name,
174
+ value
175
+ } = matcher;
176
+ switch (type) {
177
+ case MatcherType.Element:
178
+ return element.localName === name;
179
+ case MatcherType.Id:
180
+ return element.getAttribute('id') === name;
181
+ case MatcherType.Class:
182
+ return element.getAttribute('class') === name;
183
+ case MatcherType.Attribute:
184
+ return value == null ? element.hasAttribute(name) : element.getAttribute(name) === value;
185
+ case MatcherType.Pseudo:
186
+ switch (name) {
187
+ default:
188
+ throw Error(`Pseudo :${name} not implemented`);
189
+ }
190
+ case MatcherType.Function:
191
+ switch (name) {
192
+ case 'has':
193
+ return matchesSelector(element, value || '');
194
+ default:
195
+ throw Error(`Function :${name}(${value}) not implemented`);
196
+ }
197
+ }
198
+ return false;
199
+ }
200
+
201
+ exports.parseSelector = parseSelector;
202
+ exports.querySelector = querySelector;
203
+ exports.querySelectorAll = querySelectorAll;
@@ -0,0 +1,99 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const constants = require('./constants.cjs');
6
+
7
+ // const voidElements = {
8
+ // img: true,
9
+ // image: true,
10
+ // };
11
+ // const elementTokenizer =
12
+ // /(?:<([a-z][a-z0-9-:]*)( [^<>'"\n=\s]+=(['"])[^>'"\n]*\3)*\s*(\/?)\s*>|<\/([a-z][a-z0-9-:]*)>|([^&<>]+))/gi;
13
+ // const attributeTokenizer = / ([^<>'"\n=\s]+)=(['"])([^>'"\n]*)\2/g;
14
+
15
+ const elementTokenizer = /(?:<([a-z][a-z0-9-:]*)((?:\s[^<>'"=\n\s]+(?:=(['"])[^\n]*?\3|=[^>'"\n\s]*|))*)\s*(\/?)\s*>|<\/([a-z][a-z0-9-:]*)>|<!--(.*?)-->|([^&<>]+))/gi;
16
+ const attributeTokenizer = /\s([^<>'"=\n\s]+)(?:=(['"])([^\n]*?)\2|=([^>'"\n\s]*)|)/g;
17
+ function parseHtml(html, contextNode) {
18
+ const document = contextNode.ownerDocument;
19
+ const root = document.createDocumentFragment();
20
+ const stack = [root];
21
+ let parent = root;
22
+ let token;
23
+ elementTokenizer.lastIndex = 0;
24
+ while (token = elementTokenizer.exec(html)) {
25
+ const tag = token[1];
26
+ if (tag) {
27
+ const node = document.createElement(tag);
28
+ const attrs = token[2];
29
+ attributeTokenizer.lastIndex = 0;
30
+ let t;
31
+ while (t = attributeTokenizer.exec(attrs)) {
32
+ node.setAttribute(t[1], t[3] || t[4] || '');
33
+ }
34
+ parent.append(node);
35
+ // if (voidElements[tag] === true) continue;
36
+ stack.push(parent);
37
+ parent = node;
38
+ } else if (token[5]) {
39
+ parent = stack.pop() || root;
40
+ } else if (token[6]) {
41
+ parent.append(document.createComment(token[6]));
42
+ } else {
43
+ parent.append(token[7]);
44
+ }
45
+ }
46
+ return root;
47
+ }
48
+ function serializeChildren(parentNode) {
49
+ let out = '';
50
+ let child = parentNode[constants.CHILD];
51
+ while (child) {
52
+ out += serializeNode(child);
53
+ child = child[constants.NEXT];
54
+ }
55
+ return out;
56
+ }
57
+ function serializeNode(node) {
58
+ switch (node.nodeType) {
59
+ case constants.NodeType.ELEMENT_NODE:
60
+ {
61
+ const el = node;
62
+ let out = `<${el[constants.NAME]}`;
63
+ let attr = el[constants.ATTRIBUTES]?.[constants.CHILD];
64
+ while (attr) {
65
+ out += ` ${attr[constants.NAME]}`;
66
+ let value = attr[constants.VALUE];
67
+ if (value !== '') {
68
+ value = String(value).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
69
+ out += `="${value}"`;
70
+ }
71
+ attr = attr[constants.NEXT];
72
+ }
73
+ out += '>';
74
+ out += serializeChildren(el);
75
+ // let child = el[CHILD];
76
+ // while (child) {
77
+ // out += serialize(child);
78
+ // child = child[NEXT];
79
+ // }
80
+ out += `</${el[constants.NAME]}>`;
81
+ return out;
82
+ }
83
+ case constants.NodeType.TEXT_NODE:
84
+ {
85
+ const text = node;
86
+ return text[constants.DATA].replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
87
+ }
88
+ case constants.NodeType.COMMENT_NODE:
89
+ {
90
+ const text = node;
91
+ return `<!--${text[constants.DATA]}-->`;
92
+ }
93
+ }
94
+ return '';
95
+ }
96
+
97
+ exports.parseHtml = parseHtml;
98
+ exports.serializeChildren = serializeChildren;
99
+ exports.serializeNode = serializeNode;
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const constants = require('./constants.cjs');
6
+
7
+ function isCharacterData(node) {
8
+ return constants.DATA in node;
9
+ }
10
+ function isTextNode(node) {
11
+ return node.nodeType === constants.NodeType.TEXT_NODE;
12
+ }
13
+ function isCommentNode(node) {
14
+ return node.nodeType === constants.NodeType.COMMENT_NODE;
15
+ }
16
+ function isElementNode(node) {
17
+ return node.nodeType === constants.NodeType.ELEMENT_NODE;
18
+ }
19
+ function isDocumentFragmentNode(node) {
20
+ return node.nodeType === constants.NodeType.DOCUMENT_FRAGMENT_NODE;
21
+ }
22
+ function isParentNode(node) {
23
+ return 'appendChild' in node;
24
+ }
25
+ function cloneNode(node, deep, document = node.ownerDocument) {
26
+ if (isTextNode(node)) {
27
+ return document.createTextNode(node.data);
28
+ } else if (isCommentNode(node)) {
29
+ return document.createComment(node.data);
30
+ } else if (isElementNode(node)) {
31
+ const cloned = document.createElement(node.localName);
32
+ if (node[constants.ATTRIBUTES]) {
33
+ for (let i = 0; i < node[constants.ATTRIBUTES].length; i++) {
34
+ const attribute = node[constants.ATTRIBUTES].item(i);
35
+ cloned.setAttributeNS(attribute.namespaceURI, attribute.name, attribute.value);
36
+ }
37
+ }
38
+ if (deep) {
39
+ for (const child of node.childNodes) {
40
+ cloned.appendChild(cloneNode(child, true, document));
41
+ }
42
+ }
43
+ return cloned;
44
+ } else if (isDocumentFragmentNode(node)) {
45
+ const fragment = document.createDocumentFragment();
46
+ if (deep) {
47
+ for (const child of node.childNodes) {
48
+ fragment.appendChild(cloneNode(child, true, document));
49
+ }
50
+ }
51
+ return fragment;
52
+ } else {
53
+ const cloned = new node.constructor();
54
+ cloned[constants.OWNER_DOCUMENT] = document;
55
+ return cloned;
56
+ }
57
+ }
58
+
59
+ exports.cloneNode = cloneNode;
60
+ exports.isCharacterData = isCharacterData;
61
+ exports.isCommentNode = isCommentNode;
62
+ exports.isDocumentFragmentNode = isDocumentFragmentNode;
63
+ exports.isElementNode = isElementNode;
64
+ exports.isParentNode = isParentNode;
65
+ exports.isTextNode = isTextNode;
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.mjs';
2
- import { NodeType, NS, NEXT, OWNER_ELEMENT, NAME, VALUE } from './constants.mjs';
1
+ import { NodeType, NS, NEXT, OWNER_ELEMENT, NAME, VALUE, HOOKS } from './constants.mjs';
3
2
  import { Node } from './Node.mjs';
4
3
 
5
4
  class Attr extends Node {
@@ -30,7 +29,7 @@ class Attr extends Node {
30
29
  this[VALUE] = str;
31
30
  const ownerElement = this[OWNER_ELEMENT];
32
31
  if (!ownerElement) return;
33
- hooks.setAttribute?.(ownerElement, this[NAME], str, this[NS]);
32
+ this[HOOKS].setAttribute?.(ownerElement, this[NAME], str, this[NS]);
34
33
  }
35
34
  get nodeValue() {
36
35
  return this.value;
@@ -1,12 +1,11 @@
1
- import { hooks } from './hooks.mjs';
2
- import { DATA } from './constants.mjs';
1
+ import { DATA, HOOKS } from './constants.mjs';
3
2
  import { ChildNode } from './ChildNode.mjs';
4
3
 
5
4
  class CharacterData extends ChildNode {
6
5
  [DATA] = '';
7
6
  constructor(data) {
8
7
  super();
9
- this.setData(data);
8
+ this[DATA] = data == null ? '' : String(data);
10
9
  }
11
10
  setData(data) {
12
11
  let str = '';
@@ -14,7 +13,7 @@ class CharacterData extends ChildNode {
14
13
  str = typeof data === 'string' ? data : String(data);
15
14
  }
16
15
  this[DATA] = str;
17
- hooks.setText?.(this, str);
16
+ this[HOOKS].setText?.(this, str);
18
17
  }
19
18
  get data() {
20
19
  return this[DATA];
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.mjs';
2
- import { NodeType, NAME, OWNER_DOCUMENT, NamespaceURI, NS } from './constants.mjs';
1
+ import { NodeType, NAME, OWNER_DOCUMENT, NamespaceURI, NS, HOOKS } from './constants.mjs';
3
2
  import { Event } from './Event.mjs';
4
3
  import { ParentNode } from './ParentNode.mjs';
5
4
  import { Element } from './Element.mjs';
@@ -85,7 +84,7 @@ function setupElement(element, ownerDocument, name, namespace) {
85
84
  value: namespace
86
85
  });
87
86
  }
88
- hooks.createElement?.(element, namespace);
87
+ ownerDocument[HOOKS].createElement?.(element, namespace);
89
88
  return element;
90
89
  }
91
90
  function adoptNode(node, document) {
@@ -1,9 +1,13 @@
1
- import { hooks } from './hooks.mjs';
2
- import { LISTENERS } from './constants.mjs';
1
+ import { LISTENERS, OWNER_DOCUMENT, HOOKS } from './constants.mjs';
3
2
  import { fireEvent, CAPTURE_MARKER, EventPhase } from './Event.mjs';
4
3
 
5
4
  const ONCE_LISTENERS = Symbol('onceListeners');
6
5
  class EventTarget {
6
+ /**
7
+ * Property set by entities that extend this class that are part of the DOM tree.
8
+ * @internal
9
+ */
10
+
7
11
  addEventListener(type, listener, options) {
8
12
  if (listener == null) return;
9
13
  const capture = options === true || options && options.capture === true;
@@ -40,7 +44,7 @@ class EventTarget {
40
44
  once: true
41
45
  });
42
46
  list.add(normalizedListener);
43
- hooks.addEventListener?.(this, type, listener, options);
47
+ this[OWNER_DOCUMENT]?.defaultView[HOOKS].addEventListener?.(this, type, listener, options);
44
48
  }
45
49
  removeEventListener(type, listener, options) {
46
50
  return removeEventListener.call(this, type, listener, options);
@@ -92,7 +96,7 @@ function removeEventListener(type, listener, options) {
92
96
  if (list) {
93
97
  const deleted = list.delete(normalizedListener);
94
98
  if (deleted) {
95
- hooks.removeEventListener?.(this, type, listener, options);
99
+ this[OWNER_DOCUMENT]?.defaultView[HOOKS].removeEventListener?.(this, type, listener, options);
96
100
  }
97
101
  }
98
102
  }
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.mjs';
2
- import { CHILD, OWNER_ELEMENT, NS, NEXT } from './constants.mjs';
1
+ import { CHILD, OWNER_ELEMENT, NS, NEXT, HOOKS } from './constants.mjs';
3
2
 
4
3
  class NamedNodeMap {
5
4
  [CHILD] = null;
@@ -49,7 +48,7 @@ class NamedNodeMap {
49
48
  if (prev) prev[NEXT] = attr[NEXT];
50
49
  if (this[CHILD] === attr) this[CHILD] = attr[NEXT];
51
50
  updateElementAttribute(ownerElement, attr.name, attr.value, null);
52
- hooks.removeAttribute?.(ownerElement, name, namespaceURI);
51
+ ownerElement[HOOKS].removeAttribute?.(ownerElement, name, namespaceURI);
53
52
  return attr;
54
53
  }
55
54
  prev = attr;
@@ -86,7 +85,7 @@ class NamedNodeMap {
86
85
  // only invoke the protocol if the value changed
87
86
  if (!old || old.value !== attr.value) {
88
87
  updateElementAttribute(ownerElement, attr.name, old?.value ?? null, attr.value);
89
- hooks.setAttribute?.(ownerElement, attr.name, attr.value, attr[NS]);
88
+ ownerElement[HOOKS].setAttribute?.(ownerElement, attr.name, attr.value, attr[NS]);
90
89
  }
91
90
  return old;
92
91
  }
@@ -1,4 +1,4 @@
1
- import { NodeType, NAME, PARENT, CHILD, PREV, NEXT, OWNER_DOCUMENT, NamespaceURI } from './constants.mjs';
1
+ import { NodeType, NAME, PARENT, CHILD, PREV, NEXT, HOOKS, OWNER_DOCUMENT, NamespaceURI } from './constants.mjs';
2
2
  import { EventTarget } from './EventTarget.mjs';
3
3
  import { isCharacterData, isParentNode, cloneNode, isTextNode } from './shared.mjs';
4
4
 
@@ -9,6 +9,9 @@ class Node extends EventTarget {
9
9
  [CHILD] = null;
10
10
  [PREV] = null;
11
11
  [NEXT] = null;
12
+ get [HOOKS]() {
13
+ return this[OWNER_DOCUMENT].defaultView[HOOKS];
14
+ }
12
15
  get localName() {
13
16
  return this[NAME];
14
17
  }
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.mjs';
2
- import { PREV, NEXT, CHILD, NodeType, OWNER_DOCUMENT, PARENT } from './constants.mjs';
1
+ import { PREV, NEXT, CHILD, HOOKS, NodeType, OWNER_DOCUMENT, PARENT } from './constants.mjs';
3
2
  import { ChildNode, toNode } from './ChildNode.mjs';
4
3
  import { NodeList } from './NodeList.mjs';
5
4
  import { querySelectorAll, querySelector } from './selectors.mjs';
@@ -46,7 +45,7 @@ class ParentNode extends ChildNode {
46
45
  const children = this.children;
47
46
  children.splice(children.indexOf(child), 1);
48
47
  }
49
- hooks.removeChild?.(this, child, childNodesIndex);
48
+ this[HOOKS].removeChild?.(this, child, childNodesIndex);
50
49
  }
51
50
  replaceChild(newChild, oldChild) {
52
51
  if (oldChild.parentNode !== this) {
@@ -121,7 +120,7 @@ class ParentNode extends ChildNode {
121
120
  childNodes.push(child);
122
121
  if (isElement) this.children.push(child);
123
122
  }
124
- hooks.insertChild?.(this, child, insertIndex);
123
+ this[HOOKS].insertChild?.(this, child, insertIndex);
125
124
  }
126
125
  }
127
126
 
@@ -15,8 +15,10 @@ import { DocumentFragment } from './DocumentFragment.mjs';
15
15
  import { HTMLTemplateElement } from './HTMLTemplateElement.mjs';
16
16
  import { CustomElementRegistryImplementation } from './CustomElementRegistry.mjs';
17
17
  import { MutationObserver } from './MutationObserver.mjs';
18
+ import { HOOKS } from './constants.mjs';
18
19
 
19
20
  class Window extends EventTarget {
21
+ [HOOKS] = {};
20
22
  name = '';
21
23
  parent = this;
22
24
  self = this;
@@ -13,6 +13,7 @@ const LISTENERS = Symbol('listeners');
13
13
  const IS_TRUSTED = Symbol('isTrusted');
14
14
  const CONTENT = Symbol('content');
15
15
  const SLOT = Symbol('slot');
16
+ const HOOKS = Symbol('hooks');
16
17
 
17
18
  // @TODO remove explicit values
18
19
  let NodeType = /*#__PURE__*/function (NodeType) {
@@ -36,4 +37,4 @@ let NamespaceURI = /*#__PURE__*/function (NamespaceURI) {
36
37
  return NamespaceURI;
37
38
  }({});
38
39
 
39
- export { ATTRIBUTES, CHILD, CONTENT, DATA, IS_TRUSTED, LISTENERS, NAME, NEXT, NS, NamespaceURI, NodeType, OWNER_DOCUMENT, OWNER_ELEMENT, PARENT, PREV, SLOT, VALUE };
40
+ export { ATTRIBUTES, CHILD, CONTENT, DATA, HOOKS, IS_TRUSTED, LISTENERS, NAME, NEXT, NS, NamespaceURI, NodeType, OWNER_DOCUMENT, OWNER_ELEMENT, PARENT, PREV, SLOT, VALUE };
@@ -1,2 +1,3 @@
1
- export { hooks } from './hooks.mjs';
1
+ export { HOOKS } from './constants.mjs';
2
2
  export { Window } from './Window.mjs';
3
+ export { HTMLElement } from './HTMLElement.mjs';
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.esnext';
2
- import { NodeType, NS, NEXT, VALUE, OWNER_ELEMENT, NAME } from './constants.esnext';
1
+ import { NodeType, NS, NEXT, VALUE, OWNER_ELEMENT, NAME, HOOKS } from './constants.esnext';
3
2
  import { Node } from './Node.esnext';
4
3
 
5
4
  class Attr extends Node {
@@ -33,7 +32,7 @@ class Attr extends Node {
33
32
  this[VALUE] = str;
34
33
  const ownerElement = this[OWNER_ELEMENT];
35
34
  if (!ownerElement) return;
36
- hooks.setAttribute?.(ownerElement, this[NAME], str, this[NS]);
35
+ this[HOOKS].setAttribute?.(ownerElement, this[NAME], str, this[NS]);
37
36
  }
38
37
  get nodeValue() {
39
38
  return this.value;
@@ -1,12 +1,11 @@
1
- import { hooks } from './hooks.esnext';
2
- import { DATA } from './constants.esnext';
1
+ import { DATA, HOOKS } from './constants.esnext';
3
2
  import { ChildNode } from './ChildNode.esnext';
4
3
 
5
4
  class CharacterData extends ChildNode {
6
5
  [DATA] = "";
7
6
  constructor(data) {
8
7
  super();
9
- this.setData(data);
8
+ this[DATA] = data == null ? "" : String(data);
10
9
  }
11
10
  setData(data) {
12
11
  let str = "";
@@ -14,7 +13,7 @@ class CharacterData extends ChildNode {
14
13
  str = typeof data === "string" ? data : String(data);
15
14
  }
16
15
  this[DATA] = str;
17
- hooks.setText?.(this, str);
16
+ this[HOOKS].setText?.(this, str);
18
17
  }
19
18
  get data() {
20
19
  return this[DATA];
@@ -1,5 +1,4 @@
1
- import { hooks } from './hooks.esnext';
2
- import { NodeType, NAME, OWNER_DOCUMENT, NamespaceURI, NS } from './constants.esnext';
1
+ import { NodeType, NAME, OWNER_DOCUMENT, NamespaceURI, NS, HOOKS } from './constants.esnext';
3
2
  import { Event } from './Event.esnext';
4
3
  import { ParentNode } from './ParentNode.esnext';
5
4
  import { Element } from './Element.esnext';
@@ -85,7 +84,7 @@ function setupElement(element, ownerDocument, name, namespace) {
85
84
  if (namespace) {
86
85
  Object.defineProperty(element, NS, { value: namespace });
87
86
  }
88
- hooks.createElement?.(element, namespace);
87
+ ownerDocument[HOOKS].createElement?.(element, namespace);
89
88
  return element;
90
89
  }
91
90
  function adoptNode(node, document) {
@@ -1,11 +1,15 @@
1
- import { hooks } from './hooks.esnext';
2
- import { LISTENERS } from './constants.esnext';
1
+ import { LISTENERS, OWNER_DOCUMENT, HOOKS } from './constants.esnext';
3
2
  import { fireEvent, EventPhase, CAPTURE_MARKER } from './Event.esnext';
4
3
 
5
4
  const ONCE_LISTENERS = Symbol("onceListeners");
6
5
  class EventTarget {
7
6
  [LISTENERS];
8
7
  [ONCE_LISTENERS];
8
+ /**
9
+ * Property set by entities that extend this class that are part of the DOM tree.
10
+ * @internal
11
+ */
12
+ [OWNER_DOCUMENT];
9
13
  addEventListener(type, listener, options) {
10
14
  if (listener == null) return;
11
15
  const capture = options === true || options && options.capture === true;
@@ -44,7 +48,12 @@ class EventTarget {
44
48
  { once: true }
45
49
  );
46
50
  list.add(normalizedListener);
47
- hooks.addEventListener?.(this, type, listener, options);
51
+ this[OWNER_DOCUMENT]?.defaultView[HOOKS].addEventListener?.(
52
+ this,
53
+ type,
54
+ listener,
55
+ options
56
+ );
48
57
  }
49
58
  removeEventListener(type, listener, options) {
50
59
  return removeEventListener.call(this, type, listener, options);
@@ -90,7 +99,12 @@ function removeEventListener(type, listener, options) {
90
99
  if (list) {
91
100
  const deleted = list.delete(normalizedListener);
92
101
  if (deleted) {
93
- hooks.removeEventListener?.(this, type, listener, options);
102
+ this[OWNER_DOCUMENT]?.defaultView[HOOKS].removeEventListener?.(
103
+ this,
104
+ type,
105
+ listener,
106
+ options
107
+ );
94
108
  }
95
109
  }
96
110
  }