@remote-dom/polyfill 0.0.1

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 (168) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +45 -0
  3. package/build/cjs/Attr.cjs +54 -0
  4. package/build/cjs/CharacterData.cjs +29 -0
  5. package/build/cjs/ChildNode.cjs +45 -0
  6. package/build/cjs/Comment.cjs +11 -0
  7. package/build/cjs/CustomElementRegistry.cjs +35 -0
  8. package/build/cjs/CustomEvent.cjs +28 -0
  9. package/build/cjs/Document.cjs +94 -0
  10. package/build/cjs/DocumentFragment.cjs +12 -0
  11. package/build/cjs/Element.cjs +81 -0
  12. package/build/cjs/Event.cjs +113 -0
  13. package/build/cjs/EventTarget.cjs +101 -0
  14. package/build/cjs/HTMLElement.cjs +7 -0
  15. package/build/cjs/HTMLTemplateElement.cjs +26 -0
  16. package/build/cjs/MutationObserver.cjs +7 -0
  17. package/build/cjs/NamedNodeMap.cjs +115 -0
  18. package/build/cjs/Node.cjs +102 -0
  19. package/build/cjs/NodeList.cjs +9 -0
  20. package/build/cjs/ParentNode.cjs +130 -0
  21. package/build/cjs/SVGElement.cjs +19 -0
  22. package/build/cjs/Text.cjs +11 -0
  23. package/build/cjs/Window.cjs +69 -0
  24. package/build/cjs/constants.cjs +57 -0
  25. package/build/cjs/hooks.cjs +5 -0
  26. package/build/cjs/index.cjs +10 -0
  27. package/build/cjs/selectors.cjs +203 -0
  28. package/build/cjs/serialization.cjs +96 -0
  29. package/build/cjs/shared.cjs +63 -0
  30. package/build/esm/Attr.mjs +52 -0
  31. package/build/esm/CharacterData.mjs +27 -0
  32. package/build/esm/ChildNode.mjs +42 -0
  33. package/build/esm/Comment.mjs +9 -0
  34. package/build/esm/CustomElementRegistry.mjs +33 -0
  35. package/build/esm/CustomEvent.mjs +26 -0
  36. package/build/esm/Document.mjs +89 -0
  37. package/build/esm/DocumentFragment.mjs +10 -0
  38. package/build/esm/Element.mjs +95 -0
  39. package/build/esm/Event.mjs +108 -0
  40. package/build/esm/EventTarget.mjs +99 -0
  41. package/build/esm/HTMLElement.mjs +5 -0
  42. package/build/esm/HTMLTemplateElement.mjs +24 -0
  43. package/build/esm/MutationObserver.mjs +5 -0
  44. package/build/esm/NamedNodeMap.mjs +121 -0
  45. package/build/esm/Node.mjs +100 -0
  46. package/build/esm/NodeList.mjs +7 -0
  47. package/build/esm/ParentNode.mjs +128 -0
  48. package/build/esm/SVGElement.mjs +17 -0
  49. package/build/esm/Text.mjs +9 -0
  50. package/build/esm/Window.mjs +66 -0
  51. package/build/esm/constants.mjs +39 -0
  52. package/build/esm/hooks.mjs +3 -0
  53. package/build/esm/index.mjs +2 -0
  54. package/build/esm/selectors.mjs +197 -0
  55. package/build/esm/serialization.mjs +92 -0
  56. package/build/esm/shared.mjs +55 -0
  57. package/build/esnext/Attr.esnext +57 -0
  58. package/build/esnext/CharacterData.esnext +27 -0
  59. package/build/esnext/ChildNode.esnext +47 -0
  60. package/build/esnext/Comment.esnext +9 -0
  61. package/build/esnext/CustomElementRegistry.esnext +34 -0
  62. package/build/esnext/CustomEvent.esnext +25 -0
  63. package/build/esnext/Document.esnext +86 -0
  64. package/build/esnext/DocumentFragment.esnext +10 -0
  65. package/build/esnext/Element.esnext +99 -0
  66. package/build/esnext/Event.esnext +109 -0
  67. package/build/esnext/EventTarget.esnext +99 -0
  68. package/build/esnext/HTMLElement.esnext +6 -0
  69. package/build/esnext/HTMLTemplateElement.esnext +26 -0
  70. package/build/esnext/MutationObserver.esnext +5 -0
  71. package/build/esnext/NamedNodeMap.esnext +131 -0
  72. package/build/esnext/Node.esnext +116 -0
  73. package/build/esnext/NodeList.esnext +7 -0
  74. package/build/esnext/ParentNode.esnext +138 -0
  75. package/build/esnext/SVGElement.esnext +17 -0
  76. package/build/esnext/Text.esnext +9 -0
  77. package/build/esnext/Window.esnext +59 -0
  78. package/build/esnext/constants.esnext +37 -0
  79. package/build/esnext/hooks.esnext +3 -0
  80. package/build/esnext/index.esnext +2 -0
  81. package/build/esnext/selectors.esnext +169 -0
  82. package/build/esnext/serialization.esnext +76 -0
  83. package/build/esnext/shared.esnext +59 -0
  84. package/build/tsconfig.tsbuildinfo +1 -0
  85. package/build/typescript/Attr.d.ts +24 -0
  86. package/build/typescript/Attr.d.ts.map +1 -0
  87. package/build/typescript/CharacterData.d.ts +10 -0
  88. package/build/typescript/CharacterData.d.ts.map +1 -0
  89. package/build/typescript/ChildNode.d.ts +10 -0
  90. package/build/typescript/ChildNode.d.ts.map +1 -0
  91. package/build/typescript/Comment.d.ts +7 -0
  92. package/build/typescript/Comment.d.ts.map +1 -0
  93. package/build/typescript/CustomElementRegistry.d.ts +9 -0
  94. package/build/typescript/CustomElementRegistry.d.ts.map +1 -0
  95. package/build/typescript/CustomEvent.d.ts +17 -0
  96. package/build/typescript/CustomEvent.d.ts.map +1 -0
  97. package/build/typescript/Document.d.ts +27 -0
  98. package/build/typescript/Document.d.ts.map +1 -0
  99. package/build/typescript/DocumentFragment.d.ts +8 -0
  100. package/build/typescript/DocumentFragment.d.ts.map +1 -0
  101. package/build/typescript/Element.d.ts +32 -0
  102. package/build/typescript/Element.d.ts.map +1 -0
  103. package/build/typescript/Event.d.ts +47 -0
  104. package/build/typescript/Event.d.ts.map +1 -0
  105. package/build/typescript/EventTarget.d.ts +12 -0
  106. package/build/typescript/EventTarget.d.ts.map +1 -0
  107. package/build/typescript/HTMLElement.d.ts +4 -0
  108. package/build/typescript/HTMLElement.d.ts.map +1 -0
  109. package/build/typescript/HTMLTemplateElement.d.ts +11 -0
  110. package/build/typescript/HTMLTemplateElement.d.ts.map +1 -0
  111. package/build/typescript/MutationObserver.d.ts +3 -0
  112. package/build/typescript/MutationObserver.d.ts.map +1 -0
  113. package/build/typescript/NamedNodeMap.d.ts +18 -0
  114. package/build/typescript/NamedNodeMap.d.ts.map +1 -0
  115. package/build/typescript/Node.d.ts +37 -0
  116. package/build/typescript/Node.d.ts.map +1 -0
  117. package/build/typescript/NodeList.d.ts +4 -0
  118. package/build/typescript/NodeList.d.ts.map +1 -0
  119. package/build/typescript/ParentNode.d.ts +18 -0
  120. package/build/typescript/ParentNode.d.ts.map +1 -0
  121. package/build/typescript/SVGElement.d.ts +7 -0
  122. package/build/typescript/SVGElement.d.ts.map +1 -0
  123. package/build/typescript/Text.d.ts +7 -0
  124. package/build/typescript/Text.d.ts.map +1 -0
  125. package/build/typescript/Window.d.ts +45 -0
  126. package/build/typescript/Window.d.ts.map +1 -0
  127. package/build/typescript/constants.d.ts +35 -0
  128. package/build/typescript/constants.d.ts.map +1 -0
  129. package/build/typescript/hooks.d.ts +13 -0
  130. package/build/typescript/hooks.d.ts.map +1 -0
  131. package/build/typescript/index.d.ts +3 -0
  132. package/build/typescript/index.d.ts.map +1 -0
  133. package/build/typescript/selectors.d.ts +32 -0
  134. package/build/typescript/selectors.d.ts.map +1 -0
  135. package/build/typescript/serialization.d.ts +6 -0
  136. package/build/typescript/serialization.d.ts.map +1 -0
  137. package/build/typescript/shared.d.ts +16 -0
  138. package/build/typescript/shared.d.ts.map +1 -0
  139. package/package.json +35 -0
  140. package/rollup.config.js +3 -0
  141. package/source/Attr.ts +70 -0
  142. package/source/CharacterData.ts +29 -0
  143. package/source/ChildNode.ts +45 -0
  144. package/source/Comment.ts +7 -0
  145. package/source/CustomElementRegistry.ts +52 -0
  146. package/source/CustomEvent.ts +30 -0
  147. package/source/Document.ts +112 -0
  148. package/source/DocumentFragment.ts +8 -0
  149. package/source/Element.ts +119 -0
  150. package/source/Event.ts +142 -0
  151. package/source/EventTarget.ts +139 -0
  152. package/source/HTMLElement.ts +3 -0
  153. package/source/HTMLTemplateElement.ts +28 -0
  154. package/source/MutationObserver.ts +3 -0
  155. package/source/NamedNodeMap.ts +156 -0
  156. package/source/Node.ts +139 -0
  157. package/source/NodeList.ts +5 -0
  158. package/source/ParentNode.ts +158 -0
  159. package/source/SVGElement.ts +16 -0
  160. package/source/Text.ts +7 -0
  161. package/source/Window.ts +64 -0
  162. package/source/constants.ts +37 -0
  163. package/source/hooks.ts +28 -0
  164. package/source/index.ts +2 -0
  165. package/source/selectors.ts +230 -0
  166. package/source/serialization.ts +110 -0
  167. package/source/shared.ts +80 -0
  168. package/tsconfig.json +10 -0
@@ -0,0 +1,142 @@
1
+ import {IS_TRUSTED, LISTENERS} from './constants.ts';
2
+ import type {EventTarget} from './EventTarget.ts';
3
+
4
+ export const enum EventPhase {
5
+ NONE = 0,
6
+ CAPTURING_PHASE = 1,
7
+ AT_TARGET = 2,
8
+ BUBBLING_PHASE = 3,
9
+ }
10
+
11
+ export const CAPTURE_MARKER = '@';
12
+
13
+ export interface EventInit {
14
+ bubbles?: boolean;
15
+ cancelable?: boolean;
16
+ composed?: boolean;
17
+ }
18
+
19
+ const now =
20
+ typeof performance === 'undefined'
21
+ ? Date.now
22
+ : performance.now.bind(performance);
23
+
24
+ export class Event {
25
+ static NONE = EventPhase.NONE;
26
+ static CAPTURING_PHASE = EventPhase.CAPTURING_PHASE;
27
+ static AT_TARGET = EventPhase.AT_TARGET;
28
+ static BUBBLING_PHASE = EventPhase.BUBBLING_PHASE;
29
+
30
+ // NONE = EventPhase.NONE;
31
+ // CAPTURING_PHASE = EventPhase.CAPTURING_PHASE;
32
+ // AT_TARGET = EventPhase.AT_TARGET;
33
+ // BUBBLING_PHASE = EventPhase.BUBBLING_PHASE;
34
+
35
+ timeStamp = now();
36
+ target: EventTarget | null = null;
37
+ currentTarget: EventTarget | null = null;
38
+ srcElement: EventTarget | null = null;
39
+ bubbles = false;
40
+ cancelable = false;
41
+ composed = false;
42
+ defaultPrevented = false;
43
+ cancelBubble = false;
44
+ immediatePropagationStopped = false;
45
+ eventPhase: EventPhase = 0;
46
+ path: EventTarget[] = [];
47
+ // private inPassiveListener = false;
48
+ data?: any;
49
+ [IS_TRUSTED]!: boolean;
50
+
51
+ constructor(
52
+ public type: string,
53
+ options?: EventInit,
54
+ ) {
55
+ Object.defineProperty(this, IS_TRUSTED, {writable: true, value: false});
56
+ if (options) {
57
+ if (options.bubbles) this.bubbles = options.bubbles;
58
+ if (options.cancelable) this.cancelable = options.cancelable;
59
+ if (options.composed) this.composed = options.composed;
60
+ }
61
+ }
62
+
63
+ get composedPath() {
64
+ return this.path;
65
+ }
66
+
67
+ get isTrusted() {
68
+ return this[IS_TRUSTED];
69
+ }
70
+
71
+ stopPropagation() {
72
+ this.cancelBubble = true;
73
+ }
74
+
75
+ stopImmediatePropagation() {
76
+ this.immediatePropagationStopped = true;
77
+ }
78
+
79
+ preventDefault() {
80
+ this.defaultPrevented = true;
81
+ }
82
+
83
+ set returnValue(value) {
84
+ this.defaultPrevented = value;
85
+ }
86
+
87
+ get returnValue() {
88
+ return this.defaultPrevented;
89
+ }
90
+
91
+ /** @deprecated */
92
+ initEvent(type: string, bubbles?: boolean, cancelable?: boolean) {
93
+ this.type = type;
94
+ this.bubbles = Boolean(bubbles);
95
+ this.cancelable = Boolean(cancelable);
96
+ }
97
+ }
98
+
99
+ export function fireEvent(
100
+ event: Event,
101
+ target: EventTarget,
102
+ phase: EventPhase,
103
+ ) {
104
+ const listeners = target[LISTENERS];
105
+ const list = listeners?.get(
106
+ `${event.type}${
107
+ phase === EventPhase.CAPTURING_PHASE ? CAPTURE_MARKER : ''
108
+ }`,
109
+ );
110
+ if (!list) return false;
111
+
112
+ let defaultPrevented = false;
113
+
114
+ for (const listener of list) {
115
+ event.eventPhase = phase;
116
+ event.currentTarget = target;
117
+
118
+ try {
119
+ if (typeof listener === 'object') {
120
+ listener.handleEvent(event as any);
121
+ } else {
122
+ listener.call(target, event as any);
123
+ }
124
+ } catch (err) {
125
+ setTimeout(thrower, 0, err);
126
+ }
127
+
128
+ if (event.defaultPrevented === true) {
129
+ defaultPrevented = true;
130
+ }
131
+
132
+ if (event.immediatePropagationStopped) {
133
+ break;
134
+ }
135
+ }
136
+
137
+ return defaultPrevented;
138
+ }
139
+
140
+ function thrower(error: any) {
141
+ throw error;
142
+ }
@@ -0,0 +1,139 @@
1
+ import {hooks} from './hooks.ts';
2
+ import {LISTENERS} from './constants.ts';
3
+ import {fireEvent, EventPhase} from './Event.ts';
4
+ import {CAPTURE_MARKER, type Event} from './Event.ts';
5
+ import type {ChildNode} from './ChildNode.ts';
6
+
7
+ const ONCE_LISTENERS = Symbol('onceListeners');
8
+
9
+ export class EventTarget {
10
+ [LISTENERS]?: Map<string, Set<EventListenerOrEventListenerObject>>;
11
+ [ONCE_LISTENERS]?: WeakMap<EventListenerOrEventListenerObject, EventListener>;
12
+
13
+ addEventListener(
14
+ type: string,
15
+ listener: EventListenerOrEventListenerObject | null,
16
+ options?: boolean | AddEventListenerOptions,
17
+ ) {
18
+ if (listener == null) return;
19
+
20
+ const capture = options === true || (options && options.capture === true);
21
+ const once = typeof options === 'object' && options.once === true;
22
+ const signal = typeof options === 'object' ? options.signal : undefined;
23
+ const key = `${type}${capture ? CAPTURE_MARKER : ''}`;
24
+ let normalizedListener = listener;
25
+
26
+ if (once) {
27
+ normalizedListener = function normalizedListener(
28
+ this: EventTarget,
29
+ ...args: Parameters<EventListener>
30
+ ) {
31
+ this.removeEventListener(type, listener, options);
32
+
33
+ return typeof listener === 'object'
34
+ ? listener.handleEvent(...args)
35
+ : listener.call(this, ...args);
36
+ };
37
+
38
+ let onceListeners = this[ONCE_LISTENERS];
39
+ if (!onceListeners) {
40
+ onceListeners = new WeakMap();
41
+ this[ONCE_LISTENERS] = onceListeners;
42
+ }
43
+
44
+ onceListeners.set(listener, normalizedListener);
45
+ }
46
+
47
+ let listeners = this[LISTENERS];
48
+ if (!listeners) {
49
+ listeners = new Map();
50
+ this[LISTENERS] = listeners;
51
+ }
52
+
53
+ let list = listeners.get(key);
54
+ if (!list) {
55
+ list = new Set();
56
+ listeners.set(key, list);
57
+ }
58
+
59
+ list.add(normalizedListener);
60
+
61
+ signal?.addEventListener(
62
+ 'abort',
63
+ () => {
64
+ removeEventListener.call(this, type, listener, options);
65
+ },
66
+ {once: true},
67
+ );
68
+
69
+ hooks.addEventListener?.(this as any, type, listener, options);
70
+ }
71
+
72
+ removeEventListener(
73
+ type: string,
74
+ listener: EventListenerOrEventListenerObject | null,
75
+ options?: boolean | EventListenerOptions,
76
+ ) {
77
+ return removeEventListener.call(this, type, listener, options);
78
+ }
79
+
80
+ // function isChildNode(node: EventTarget): node is ChildNode {
81
+ // return PARENT in node;
82
+ // }
83
+
84
+ dispatchEvent(event: Event) {
85
+ const path: EventTarget[] = [];
86
+ // instanceof here is just to keep TypeScript happy
87
+ let target = this as unknown as ChildNode | null;
88
+ while (target != null) {
89
+ path.push(target);
90
+ target = target.parentNode;
91
+ }
92
+ // while (target instanceof Node && (target = target.parentNode)) {
93
+ // path.push(target);
94
+ // }
95
+ event.target = this;
96
+ event.srcElement = this;
97
+ event.path = path;
98
+ let defaultPrevented = false;
99
+ for (let i = path.length; --i; ) {
100
+ if (fireEvent(event, path[i]!, EventPhase.CAPTURING_PHASE)) {
101
+ defaultPrevented = true;
102
+ }
103
+ }
104
+ if (fireEvent(event, this, EventPhase.AT_TARGET)) {
105
+ defaultPrevented = true;
106
+ }
107
+ for (let i = 1; i < path.length; i++) {
108
+ if (fireEvent(event, path[i]!, EventPhase.BUBBLING_PHASE)) {
109
+ defaultPrevented = true;
110
+ }
111
+ }
112
+ return !defaultPrevented;
113
+ }
114
+ }
115
+
116
+ function removeEventListener(
117
+ this: EventTarget,
118
+ type: string,
119
+ listener: EventListenerOrEventListenerObject | null,
120
+ options?: boolean | EventListenerOptions,
121
+ ) {
122
+ if (listener == null) return;
123
+
124
+ const onceListeners = this[ONCE_LISTENERS];
125
+ const normalizedListener = onceListeners?.get(listener) ?? listener;
126
+
127
+ onceListeners?.delete(listener);
128
+
129
+ const capture = options === true || (options && options.capture === true);
130
+ const key = `${type}${capture ? CAPTURE_MARKER : ''}`;
131
+ const list = this[LISTENERS]?.get(key);
132
+
133
+ if (list) {
134
+ const deleted = list.delete(normalizedListener);
135
+ if (deleted) {
136
+ hooks.removeEventListener?.(this as any, type, listener, options);
137
+ }
138
+ }
139
+ }
@@ -0,0 +1,3 @@
1
+ import {Element} from './Element.ts';
2
+
3
+ export class HTMLElement extends Element {}
@@ -0,0 +1,28 @@
1
+ import {CONTENT} from './constants.ts';
2
+ import {DocumentFragment} from './DocumentFragment.ts';
3
+ import {Element} from './Element.ts';
4
+ import {parseHtml, serializeChildren} from './serialization.ts';
5
+
6
+ export class HTMLTemplateElement extends Element {
7
+ [CONTENT]?: DocumentFragment;
8
+
9
+ get content() {
10
+ let content = this[CONTENT];
11
+ if (!content) {
12
+ content = this.ownerDocument.createDocumentFragment();
13
+ this[CONTENT] = content;
14
+ }
15
+ return content;
16
+ }
17
+
18
+ set content(_) {}
19
+
20
+ set innerHTML(html) {
21
+ this.content.replaceChildren(parseHtml(String(html), this));
22
+ }
23
+
24
+ get innerHTML() {
25
+ const content = this[CONTENT];
26
+ return content ? serializeChildren(content) : '';
27
+ }
28
+ }
@@ -0,0 +1,3 @@
1
+ export class MutationObserver {
2
+ // stub implementation
3
+ }
@@ -0,0 +1,156 @@
1
+ import {hooks} from './hooks.ts';
2
+ import {CHILD, OWNER_ELEMENT, NS, NEXT, NamespaceURI} from './constants.ts';
3
+ import type {Attr} from './Attr.ts';
4
+ import type {Element} from './Element.ts';
5
+
6
+ export class NamedNodeMap {
7
+ [CHILD]: Attr | null = null;
8
+ [OWNER_ELEMENT]: Element;
9
+
10
+ constructor(ownerElement: Element) {
11
+ this[OWNER_ELEMENT] = ownerElement;
12
+ }
13
+
14
+ getNamedItem(name: string) {
15
+ return this.getNamedItemNS(null, name);
16
+ }
17
+
18
+ getNamedItemNS(namespaceURI: NamespaceURI | null, name: string) {
19
+ let attr = this[CHILD];
20
+ while (attr) {
21
+ if (attr.name === name && attr[NS] == namespaceURI) {
22
+ return attr;
23
+ }
24
+ attr = attr[NEXT];
25
+ }
26
+ return null;
27
+ }
28
+
29
+ item(index: number) {
30
+ let attr = this[CHILD];
31
+ let i = 0;
32
+ while (attr) {
33
+ if (i++ === index) return attr;
34
+ attr = attr[NEXT];
35
+ }
36
+ return null;
37
+ }
38
+
39
+ get length() {
40
+ let index = 0;
41
+ let attr = this[CHILD];
42
+ while (attr) {
43
+ index++;
44
+ attr = attr[NEXT];
45
+ }
46
+ return index;
47
+ }
48
+
49
+ removeNamedItem(name: string) {
50
+ return this.removeNamedItemNS(null, name);
51
+ }
52
+
53
+ removeNamedItemNS(namespaceURI: NamespaceURI | null, name: string) {
54
+ const ownerElement = this[OWNER_ELEMENT];
55
+ let attr = this[CHILD];
56
+ let prev: typeof attr | null = null;
57
+
58
+ while (attr != null) {
59
+ if (attr.name === name && attr[NS] == namespaceURI) {
60
+ if (prev) prev[NEXT] = attr[NEXT];
61
+ if (this[CHILD] === attr) this[CHILD] = attr[NEXT];
62
+ updateElementAttribute(ownerElement, attr.name, attr.value, null);
63
+ hooks.removeAttribute?.(ownerElement as any, name, namespaceURI);
64
+ return attr;
65
+ }
66
+
67
+ prev = attr;
68
+ attr = attr[NEXT];
69
+ }
70
+
71
+ return null;
72
+ }
73
+
74
+ setNamedItem(attr: Attr) {
75
+ const ownerElement = this[OWNER_ELEMENT];
76
+ let old = null;
77
+ let child = this[CHILD];
78
+ attr[OWNER_ELEMENT] = ownerElement;
79
+ if (child == null) {
80
+ this[CHILD] = attr;
81
+ // return null;
82
+ } else {
83
+ let prev;
84
+ while (child) {
85
+ if (child.name === attr.name && child[NS] == attr[NS]) {
86
+ if (prev) prev[NEXT] = attr;
87
+ else this[CHILD] = attr;
88
+ attr[NEXT] = child[NEXT];
89
+ child[NEXT] = null;
90
+ old = child;
91
+ break;
92
+ // return child;
93
+ }
94
+ prev = child;
95
+ child = child[NEXT];
96
+ }
97
+ if (prev) prev[NEXT] = attr;
98
+ else this[CHILD] = attr;
99
+ // return null;
100
+ }
101
+
102
+ // only invoke the protocol if the value changed
103
+ if (!old || old.value !== attr.value) {
104
+ updateElementAttribute(
105
+ ownerElement,
106
+ attr.name,
107
+ old?.value ?? null,
108
+ attr.value,
109
+ );
110
+
111
+ hooks.setAttribute?.(
112
+ ownerElement as any,
113
+ attr.name,
114
+ attr.value,
115
+ attr[NS],
116
+ );
117
+ }
118
+ return old;
119
+ }
120
+
121
+ setNamedItemNS(attr: Attr) {
122
+ return this.setNamedItem(attr);
123
+ }
124
+
125
+ *[Symbol.iterator]() {
126
+ let attr = this[CHILD];
127
+ while (attr) {
128
+ yield attr;
129
+ attr = attr[NEXT];
130
+ }
131
+ }
132
+ }
133
+
134
+ function updateElementAttribute(
135
+ element: Element,
136
+ name: string,
137
+ oldValue: string | null,
138
+ newValue: string | null,
139
+ ) {
140
+ const {observedAttributes} = element.constructor as typeof Element;
141
+ const {attributeChangedCallback} = element;
142
+
143
+ if (name === 'slot' && element.slot !== newValue) {
144
+ element.slot = newValue ?? '';
145
+ }
146
+
147
+ if (
148
+ attributeChangedCallback == null ||
149
+ observedAttributes == null ||
150
+ !observedAttributes.includes(name)
151
+ ) {
152
+ return;
153
+ }
154
+
155
+ return attributeChangedCallback.call(element, name, oldValue, newValue);
156
+ }
package/source/Node.ts ADDED
@@ -0,0 +1,139 @@
1
+ import {
2
+ OWNER_DOCUMENT,
3
+ NAME,
4
+ PARENT,
5
+ CHILD,
6
+ PREV,
7
+ NEXT,
8
+ NamespaceURI,
9
+ NodeType,
10
+ } from './constants.ts';
11
+ import type {Document} from './Document.ts';
12
+ import type {ParentNode} from './ParentNode.ts';
13
+ import {EventTarget} from './EventTarget.ts';
14
+ import {
15
+ isCharacterData,
16
+ isParentNode,
17
+ isTextNode,
18
+ cloneNode,
19
+ } from './shared.ts';
20
+
21
+ export class Node extends EventTarget {
22
+ nodeType = NodeType.NODE;
23
+
24
+ [OWNER_DOCUMENT]!: Document;
25
+ [NAME] = '';
26
+ [PARENT]: ParentNode | null = null;
27
+ [CHILD]: Node | null = null;
28
+ [PREV]: Node | null = null;
29
+ [NEXT]: Node | null = null;
30
+
31
+ get localName() {
32
+ return this[NAME];
33
+ }
34
+
35
+ get nodeName() {
36
+ return this[NAME].toUpperCase();
37
+ }
38
+
39
+ get ownerDocument() {
40
+ return this[OWNER_DOCUMENT];
41
+ }
42
+
43
+ isDefaultNamespace(namespace: string) {
44
+ return namespace === NamespaceURI.XHTML;
45
+ }
46
+
47
+ get parentNode() {
48
+ return this[PARENT];
49
+ }
50
+
51
+ set parentNode(_readonly) {}
52
+
53
+ get previousSibling() {
54
+ return this[PREV];
55
+ }
56
+
57
+ set previousSibling(_readonly) {}
58
+
59
+ get nextSibling() {
60
+ return this[NEXT];
61
+ }
62
+
63
+ set nextSibling(_readonly) {}
64
+
65
+ get previousElementSibling() {
66
+ let sib = this[PREV];
67
+ while (sib && sib.nodeType !== 1) sib = sib[PREV];
68
+ return sib;
69
+ }
70
+
71
+ set previousElementSibling(_readonly) {}
72
+
73
+ get nextElementSibling() {
74
+ let sib = this[NEXT];
75
+ while (sib && sib.nodeType !== 1) sib = sib[NEXT];
76
+ return sib;
77
+ }
78
+
79
+ set nextElementSibling(_readonly) {}
80
+
81
+ get firstChild() {
82
+ return this[CHILD];
83
+ }
84
+
85
+ set firstChild(_readonly) {}
86
+
87
+ get lastChild() {
88
+ let child = this[CHILD];
89
+ while (child) {
90
+ const next = child[NEXT];
91
+ if (next == null) break;
92
+ child = next;
93
+ }
94
+ return child;
95
+ }
96
+
97
+ set lastChild(_readonly) {}
98
+
99
+ get nodeValue(): string | null {
100
+ if (isCharacterData(this)) return this.data;
101
+ return null;
102
+ }
103
+
104
+ set nodeValue(data: string | null | undefined) {
105
+ if (isCharacterData(this)) this.data = data;
106
+ }
107
+
108
+ get textContent(): string | null {
109
+ if (isCharacterData(this)) return this.data;
110
+ let text = '';
111
+ function walk(node: Node) {
112
+ if (isTextNode(node)) {
113
+ text += node.data;
114
+ }
115
+ const child = node[CHILD];
116
+ if (child) walk(child);
117
+ const sibling = node[NEXT];
118
+ if (sibling) walk(sibling);
119
+ }
120
+ walk(this);
121
+ return text;
122
+ }
123
+
124
+ set textContent(data: any) {
125
+ if (isCharacterData(this)) {
126
+ this.data = data;
127
+ } else if (isParentNode(this)) {
128
+ let child;
129
+ while ((child = this[CHILD])) {
130
+ this.removeChild(child);
131
+ }
132
+ this.append(data);
133
+ }
134
+ }
135
+
136
+ cloneNode(deep?: boolean) {
137
+ return cloneNode(this, deep);
138
+ }
139
+ }
@@ -0,0 +1,5 @@
1
+ export class NodeList extends Array {
2
+ item(index: number) {
3
+ return this[index];
4
+ }
5
+ }