@fluixi/dom 1.0.0-alpha.83 → 1.0.0-alpha.85
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.
- package/dist/cdn/dom-client.cjs +1427 -1
- package/dist/cdn/dom-client.d.ts +2 -2
- package/dist/cdn/dom-client.global.js +2 -1
- package/dist/cdn/dom-client.js +3 -3
- package/dist/cdn/dom-client.mjs +1430 -1
- package/dist/cdn/dom.cjs +3127 -1
- package/dist/cdn/dom.d.ts +2 -2
- package/dist/cdn/dom.global.js +2 -1
- package/dist/cdn/dom.js +4 -4
- package/dist/cdn/dom.mjs +3133 -1
- package/dist/index.cjs +3155 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +3149 -1
- package/dist/lib/component/index.cjs +128 -1
- package/dist/lib/component/index.mjs +105 -1
- package/dist/lib/component/modifiers.cjs +126 -1
- package/dist/lib/component/modifiers.d.ts +12 -0
- package/dist/lib/component/modifiers.d.ts.map +1 -1
- package/dist/lib/component/modifiers.js +12 -84
- package/dist/lib/component/modifiers.mjs +105 -1
- package/dist/lib/dom/delegate.cjs +60 -1
- package/dist/lib/dom/delegate.js +1 -1
- package/dist/lib/dom/delegate.mjs +39 -1
- package/dist/lib/dom/dynamic-element.cjs +949 -1
- package/dist/lib/dom/dynamic-element.d.ts +3 -3
- package/dist/lib/dom/dynamic-element.js +2 -2
- package/dist/lib/dom/dynamic-element.mjs +928 -1
- package/dist/lib/dom/hydration-state.cjs +93 -1
- package/dist/lib/dom/hydration-state.d.ts +1 -1
- package/dist/lib/dom/hydration-state.js +1 -1
- package/dist/lib/dom/hydration-state.mjs +72 -1
- package/dist/lib/dom/hydration.cjs +685 -1
- package/dist/lib/dom/hydration.js +8 -8
- package/dist/lib/dom/hydration.mjs +664 -1
- package/dist/lib/dom/index.cjs +2040 -1
- package/dist/lib/dom/index.js +1 -1
- package/dist/lib/dom/index.mjs +2020 -1
- package/dist/lib/dom/integration.cjs +71 -1
- package/dist/lib/dom/integration.js +3 -3
- package/dist/lib/dom/integration.mjs +51 -1
- package/dist/lib/dom/island.cjs +790 -1
- package/dist/lib/dom/island.d.ts +1 -1
- package/dist/lib/dom/island.js +11 -11
- package/dist/lib/dom/island.mjs +769 -1
- package/dist/lib/dom/runtime.cjs +1432 -1
- package/dist/lib/dom/runtime.d.ts +60 -17
- package/dist/lib/dom/runtime.d.ts.map +1 -1
- package/dist/lib/dom/runtime.js +122 -79
- package/dist/lib/dom/runtime.mjs +1414 -1
- package/dist/lib/dom/server/fx-data.cjs +53 -1
- package/dist/lib/dom/server/fx-data.d.ts +5 -5
- package/dist/lib/dom/server/fx-data.js +6 -6
- package/dist/lib/dom/server/fx-data.mjs +32 -1
- package/dist/lib/dom/server/host.cjs +66 -1
- package/dist/lib/dom/server/host.d.ts +6 -0
- package/dist/lib/dom/server/host.d.ts.map +1 -1
- package/dist/lib/dom/server/host.js +7 -1
- package/dist/lib/dom/server/host.mjs +45 -1
- package/dist/lib/dom/server/index.cjs +759 -1
- package/dist/lib/dom/server/index.d.ts +1 -1
- package/dist/lib/dom/server/index.js +1 -1
- package/dist/lib/dom/server/index.mjs +743 -1
- package/dist/lib/dom/server/nodes.cjs +302 -1
- package/dist/lib/dom/server/nodes.d.ts +2 -2
- package/dist/lib/dom/server/nodes.d.ts.map +1 -1
- package/dist/lib/dom/server/nodes.js +4 -4
- package/dist/lib/dom/server/nodes.mjs +279 -1
- package/dist/lib/dom/server/parse-template.cjs +395 -1
- package/dist/lib/dom/server/parse-template.d.ts +1 -1
- package/dist/lib/dom/server/parse-template.js +4 -4
- package/dist/lib/dom/server/parse-template.mjs +372 -1
- package/dist/lib/dom/server/render.cjs +691 -1
- package/dist/lib/dom/server/render.d.ts +9 -1
- package/dist/lib/dom/server/render.d.ts.map +1 -1
- package/dist/lib/dom/server/render.js +23 -15
- package/dist/lib/dom/server/render.mjs +677 -1
- package/dist/lib/dom/server/request-context.cjs +110 -1
- package/dist/lib/dom/server/request-context.d.ts +29 -9
- package/dist/lib/dom/server/request-context.d.ts.map +1 -1
- package/dist/lib/dom/server/request-context.js +28 -8
- package/dist/lib/dom/server/request-context.mjs +89 -1
- package/dist/lib/dom/server/serialize.cjs +187 -1
- package/dist/lib/dom/server/serialize.js +3 -3
- package/dist/lib/dom/server/serialize.mjs +164 -1
- package/dist/lib/dom/server-renderer.cjs +760 -1
- package/dist/lib/dom/server-renderer.js +1 -1
- package/dist/lib/dom/server-renderer.mjs +745 -1
- package/dist/lib/dom/types.cjs +18 -1
- package/dist/lib/dom/utils.cjs +381 -1
- package/dist/lib/dom/utils.d.ts +1 -88
- package/dist/lib/dom/utils.d.ts.map +1 -1
- package/dist/lib/dom/utils.js +2 -99
- package/dist/lib/dom/utils.mjs +361 -1
- package/dist/lib/dom/versions.cjs +60 -1
- package/dist/lib/dom/versions.d.ts +3 -3
- package/dist/lib/dom/versions.d.ts.map +1 -1
- package/dist/lib/dom/versions.js +17 -5
- package/dist/lib/dom/versions.mjs +37 -1
- package/dist/lib/element/attributes.cjs +19 -1
- package/dist/lib/element/attributes.d.ts +7 -7
- package/dist/lib/element/attributes.js +1 -1
- package/dist/lib/element/attributes.mjs +1 -0
- package/dist/lib/element/index.cjs +19 -1
- package/dist/lib/element/index.mjs +1 -0
- package/dist/lib/element/types.cjs +18 -1
- package/dist/lib/element/types.d.ts +4 -5
- package/dist/lib/element/types.d.ts.map +1 -1
- package/dist/lib/element/types.js +0 -1
- package/dist/lib/flow/class-map.cjs +38 -1
- package/dist/lib/flow/class-map.d.ts +3 -3
- package/dist/lib/flow/class-map.js +2 -2
- package/dist/lib/flow/class-map.mjs +17 -1
- package/dist/lib/flow/client-only.cjs +57 -1
- package/dist/lib/flow/client-only.d.ts +4 -4
- package/dist/lib/flow/client-only.js +3 -3
- package/dist/lib/flow/client-only.mjs +36 -1
- package/dist/lib/flow/dynamic.cjs +53 -1
- package/dist/lib/flow/dynamic.d.ts +2 -2
- package/dist/lib/flow/dynamic.js +3 -3
- package/dist/lib/flow/dynamic.mjs +32 -1
- package/dist/lib/flow/error-boundary.cjs +43 -1
- package/dist/lib/flow/error-boundary.d.ts +2 -2
- package/dist/lib/flow/error-boundary.js +3 -3
- package/dist/lib/flow/error-boundary.mjs +22 -1
- package/dist/lib/flow/for.cjs +66 -1
- package/dist/lib/flow/for.d.ts +9 -9
- package/dist/lib/flow/for.d.ts.map +1 -1
- package/dist/lib/flow/for.js +2 -2
- package/dist/lib/flow/for.mjs +45 -1
- package/dist/lib/flow/index-flow.cjs +67 -1
- package/dist/lib/flow/index-flow.d.ts +5 -5
- package/dist/lib/flow/index-flow.js +4 -4
- package/dist/lib/flow/index-flow.mjs +46 -1
- package/dist/lib/flow/index.cjs +805 -1
- package/dist/lib/flow/index.mjs +792 -1
- package/dist/lib/flow/portal.cjs +538 -1
- package/dist/lib/flow/portal.mjs +519 -1
- package/dist/lib/flow/show.cjs +81 -1
- package/dist/lib/flow/show.d.ts +1 -1
- package/dist/lib/flow/show.d.ts.map +1 -1
- package/dist/lib/flow/show.js +4 -115
- package/dist/lib/flow/show.mjs +67 -1
- package/dist/lib/flow/style-map.cjs +43 -1
- package/dist/lib/flow/style-map.d.ts +3 -3
- package/dist/lib/flow/style-map.js +3 -3
- package/dist/lib/flow/style-map.mjs +22 -1
- package/dist/lib/flow/switch.cjs +91 -1
- package/dist/lib/flow/switch.d.ts +3 -3
- package/dist/lib/flow/switch.d.ts.map +1 -1
- package/dist/lib/flow/switch.js +6 -6
- package/dist/lib/flow/switch.mjs +70 -1
- package/dist/lib/flow/utils.cjs +44 -1
- package/dist/lib/flow/utils.d.ts +1 -1
- package/dist/lib/flow/utils.js +1 -1
- package/dist/lib/flow/utils.mjs +23 -1
- package/dist/lib/html.cjs +32 -1
- package/dist/lib/html.d.ts +6 -6
- package/dist/lib/html.js +5 -5
- package/dist/lib/html.mjs +11 -1
- package/dist/lib/index.cjs +3104 -1
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -3
- package/dist/lib/index.mjs +3097 -1
- package/dist/lib/shared/types.cjs +18 -1
- package/dist/lib/shared/types.d.ts +8 -8
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/version.generated.cjs +26 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +2 -2
- package/dist/version.generated.mjs +5 -1
- package/package.json +7 -6
- package/dist/lib/jsx/control-flow/flow.cjs +0 -1
- package/dist/lib/jsx/control-flow/flow.d.ts +0 -2
- package/dist/lib/jsx/control-flow/flow.d.ts.map +0 -1
- package/dist/lib/jsx/control-flow/flow.js +0 -627
- package/dist/lib/jsx/control-flow/flow.mjs +0 -0
- package/dist/lib/jsx/control-flow/for-flow.cjs +0 -1
- package/dist/lib/jsx/control-flow/for-flow.d.ts +0 -2
- package/dist/lib/jsx/control-flow/for-flow.d.ts.map +0 -1
- package/dist/lib/jsx/control-flow/for-flow.js +0 -1
- package/dist/lib/jsx/control-flow/for-flow.mjs +0 -0
|
@@ -1 +1,372 @@
|
|
|
1
|
-
|
|
1
|
+
// src/lib/dom/server/host.ts
|
|
2
|
+
var SERVER_NODE = /* @__PURE__ */ Symbol.for("fluixi.server-node");
|
|
3
|
+
var STATE = /* @__PURE__ */ Symbol.for("fluixi.dom.server-host");
|
|
4
|
+
var realm = globalThis;
|
|
5
|
+
var state = realm[STATE] ??= {
|
|
6
|
+
server: typeof document === "undefined",
|
|
7
|
+
nodes: null
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// src/lib/dom/server/nodes.ts
|
|
11
|
+
var NODE_ELEMENT = 1;
|
|
12
|
+
var NODE_TEXT = 3;
|
|
13
|
+
var NODE_COMMENT = 8;
|
|
14
|
+
var _a;
|
|
15
|
+
_a = SERVER_NODE;
|
|
16
|
+
var ServerNode = class {
|
|
17
|
+
constructor() {
|
|
18
|
+
// Brand the host.ts guards check for (lets them skip an instanceof on these classes).
|
|
19
|
+
this[_a] = true;
|
|
20
|
+
this.parentNode = null;
|
|
21
|
+
this.childNodes = [];
|
|
22
|
+
}
|
|
23
|
+
get firstChild() {
|
|
24
|
+
return this.childNodes[0] ?? null;
|
|
25
|
+
}
|
|
26
|
+
get lastChild() {
|
|
27
|
+
return this.childNodes[this.childNodes.length - 1] ?? null;
|
|
28
|
+
}
|
|
29
|
+
get nextSibling() {
|
|
30
|
+
const p = this.parentNode;
|
|
31
|
+
if (!p) return null;
|
|
32
|
+
const i = p.childNodes.indexOf(this);
|
|
33
|
+
return i >= 0 ? p.childNodes[i + 1] ?? null : null;
|
|
34
|
+
}
|
|
35
|
+
get previousSibling() {
|
|
36
|
+
const p = this.parentNode;
|
|
37
|
+
if (!p) return null;
|
|
38
|
+
const i = p.childNodes.indexOf(this);
|
|
39
|
+
return i > 0 ? p.childNodes[i - 1] ?? null : null;
|
|
40
|
+
}
|
|
41
|
+
get parentElement() {
|
|
42
|
+
return this.parentNode;
|
|
43
|
+
}
|
|
44
|
+
appendChild(child) {
|
|
45
|
+
if (child.parentNode) child.parentNode.removeChild(child);
|
|
46
|
+
child.parentNode = this;
|
|
47
|
+
this.childNodes.push(child);
|
|
48
|
+
return child;
|
|
49
|
+
}
|
|
50
|
+
insertBefore(child, ref) {
|
|
51
|
+
if (ref == null) return this.appendChild(child);
|
|
52
|
+
if (child.parentNode) child.parentNode.removeChild(child);
|
|
53
|
+
const i = this.childNodes.indexOf(ref);
|
|
54
|
+
child.parentNode = this;
|
|
55
|
+
if (i < 0) this.childNodes.push(child);
|
|
56
|
+
else this.childNodes.splice(i, 0, child);
|
|
57
|
+
return child;
|
|
58
|
+
}
|
|
59
|
+
removeChild(child) {
|
|
60
|
+
const i = this.childNodes.indexOf(child);
|
|
61
|
+
if (i >= 0) this.childNodes.splice(i, 1);
|
|
62
|
+
child.parentNode = null;
|
|
63
|
+
return child;
|
|
64
|
+
}
|
|
65
|
+
replaceChild(next, old) {
|
|
66
|
+
const i = this.childNodes.indexOf(old);
|
|
67
|
+
if (i >= 0) {
|
|
68
|
+
if (next.parentNode) next.parentNode.removeChild(next);
|
|
69
|
+
next.parentNode = this;
|
|
70
|
+
this.childNodes[i] = next;
|
|
71
|
+
old.parentNode = null;
|
|
72
|
+
}
|
|
73
|
+
return old;
|
|
74
|
+
}
|
|
75
|
+
// Event listeners are inert on the server.
|
|
76
|
+
addEventListener() {
|
|
77
|
+
}
|
|
78
|
+
removeEventListener() {
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var ServerText = class _ServerText extends ServerNode {
|
|
82
|
+
constructor(value) {
|
|
83
|
+
super();
|
|
84
|
+
this.nodeType = NODE_TEXT;
|
|
85
|
+
this.data = value;
|
|
86
|
+
}
|
|
87
|
+
get nodeValue() {
|
|
88
|
+
return this.data;
|
|
89
|
+
}
|
|
90
|
+
set nodeValue(v) {
|
|
91
|
+
this.data = v == null ? "" : String(v);
|
|
92
|
+
}
|
|
93
|
+
get textContent() {
|
|
94
|
+
return this.data;
|
|
95
|
+
}
|
|
96
|
+
set textContent(v) {
|
|
97
|
+
this.data = v == null ? "" : String(v);
|
|
98
|
+
}
|
|
99
|
+
cloneNode() {
|
|
100
|
+
return new _ServerText(this.data);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var ServerComment = class _ServerComment extends ServerNode {
|
|
104
|
+
constructor(value) {
|
|
105
|
+
super();
|
|
106
|
+
this.nodeType = NODE_COMMENT;
|
|
107
|
+
this.data = value;
|
|
108
|
+
}
|
|
109
|
+
get nodeValue() {
|
|
110
|
+
return this.data;
|
|
111
|
+
}
|
|
112
|
+
set nodeValue(v) {
|
|
113
|
+
this.data = v == null ? "" : String(v);
|
|
114
|
+
}
|
|
115
|
+
cloneNode() {
|
|
116
|
+
return new _ServerComment(this.data);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var ServerStyle = class {
|
|
120
|
+
constructor() {
|
|
121
|
+
// declared keys are stored as own props; cssText holds a raw string blob.
|
|
122
|
+
this.cssText = "";
|
|
123
|
+
}
|
|
124
|
+
setProperty(name, value) {
|
|
125
|
+
this[name] = value;
|
|
126
|
+
}
|
|
127
|
+
removeProperty(name) {
|
|
128
|
+
delete this[name];
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var ServerClassList = class {
|
|
132
|
+
constructor(el) {
|
|
133
|
+
this.el = el;
|
|
134
|
+
}
|
|
135
|
+
list() {
|
|
136
|
+
const c = this.el.getAttribute("class");
|
|
137
|
+
return c ? c.split(/\s+/).filter(Boolean) : [];
|
|
138
|
+
}
|
|
139
|
+
write(arr) {
|
|
140
|
+
if (arr.length) this.el.setAttribute("class", arr.join(" "));
|
|
141
|
+
else this.el.removeAttribute("class");
|
|
142
|
+
}
|
|
143
|
+
add(...names) {
|
|
144
|
+
const arr = this.list();
|
|
145
|
+
for (const n of names) if (!arr.includes(n)) arr.push(n);
|
|
146
|
+
this.write(arr);
|
|
147
|
+
}
|
|
148
|
+
remove(...names) {
|
|
149
|
+
this.write(this.list().filter((c) => !names.includes(c)));
|
|
150
|
+
}
|
|
151
|
+
contains(name) {
|
|
152
|
+
return this.list().includes(name);
|
|
153
|
+
}
|
|
154
|
+
toggle(name, force) {
|
|
155
|
+
const has = this.contains(name);
|
|
156
|
+
const on = force === void 0 ? !has : force;
|
|
157
|
+
if (on) this.add(name);
|
|
158
|
+
else this.remove(name);
|
|
159
|
+
return on;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var ServerElement = class _ServerElement extends ServerNode {
|
|
163
|
+
constructor(tag, isSVG = false) {
|
|
164
|
+
super();
|
|
165
|
+
this.nodeType = NODE_ELEMENT;
|
|
166
|
+
this.attributes = /* @__PURE__ */ new Map();
|
|
167
|
+
this.style = new ServerStyle();
|
|
168
|
+
this.classList = new ServerClassList(this);
|
|
169
|
+
/** raw HTML set via innerHTML: emitted verbatim, bypassing childNodes. */
|
|
170
|
+
this.rawHTML = null;
|
|
171
|
+
this.localName = tag.toLowerCase();
|
|
172
|
+
this.tagName = isSVG ? tag : tag.toUpperCase();
|
|
173
|
+
this.isSVG = isSVG;
|
|
174
|
+
this.namespaceURI = isSVG ? "http://www.w3.org/2000/svg" : null;
|
|
175
|
+
}
|
|
176
|
+
setAttribute(name, value) {
|
|
177
|
+
this.attributes.set(name, String(value));
|
|
178
|
+
}
|
|
179
|
+
removeAttribute(name) {
|
|
180
|
+
this.attributes.delete(name);
|
|
181
|
+
}
|
|
182
|
+
getAttribute(name) {
|
|
183
|
+
return this.attributes.has(name) ? this.attributes.get(name) : null;
|
|
184
|
+
}
|
|
185
|
+
hasAttribute(name) {
|
|
186
|
+
return this.attributes.has(name);
|
|
187
|
+
}
|
|
188
|
+
get id() {
|
|
189
|
+
return this.getAttribute("id") ?? "";
|
|
190
|
+
}
|
|
191
|
+
set id(v) {
|
|
192
|
+
if (v == null) this.removeAttribute("id");
|
|
193
|
+
else this.setAttribute("id", v);
|
|
194
|
+
}
|
|
195
|
+
// JSX_PROPERTIES: className/value/checked/selected/innerHTML/innerText/
|
|
196
|
+
// textContent/indeterminate/htmlFor flow through setProperty (element[k]=v).
|
|
197
|
+
get className() {
|
|
198
|
+
return this.getAttribute("class") ?? "";
|
|
199
|
+
}
|
|
200
|
+
set className(v) {
|
|
201
|
+
if (v == null) this.removeAttribute("class");
|
|
202
|
+
else this.setAttribute("class", v);
|
|
203
|
+
}
|
|
204
|
+
get htmlFor() {
|
|
205
|
+
return this.getAttribute("for") ?? "";
|
|
206
|
+
}
|
|
207
|
+
set htmlFor(v) {
|
|
208
|
+
if (v == null) this.removeAttribute("for");
|
|
209
|
+
else this.setAttribute("for", v);
|
|
210
|
+
}
|
|
211
|
+
set value(v) {
|
|
212
|
+
if (v == null) this.removeAttribute("value");
|
|
213
|
+
else this.setAttribute("value", String(v));
|
|
214
|
+
}
|
|
215
|
+
set checked(v) {
|
|
216
|
+
if (v) this.setAttribute("checked", "");
|
|
217
|
+
else this.removeAttribute("checked");
|
|
218
|
+
}
|
|
219
|
+
set selected(v) {
|
|
220
|
+
if (v) this.setAttribute("selected", "");
|
|
221
|
+
else this.removeAttribute("selected");
|
|
222
|
+
}
|
|
223
|
+
// indeterminate is a live-only DOM property with no HTML serialization.
|
|
224
|
+
set indeterminate(_v) {
|
|
225
|
+
}
|
|
226
|
+
get textContent() {
|
|
227
|
+
return this.childNodes.map((c) => c.textContent ?? "").join("");
|
|
228
|
+
}
|
|
229
|
+
set textContent(v) {
|
|
230
|
+
for (const c of this.childNodes) c.parentNode = null;
|
|
231
|
+
this.childNodes = [];
|
|
232
|
+
this.rawHTML = null;
|
|
233
|
+
if (v != null && v !== "") this.appendChild(new ServerText(String(v)));
|
|
234
|
+
}
|
|
235
|
+
set innerText(v) {
|
|
236
|
+
this.textContent = v;
|
|
237
|
+
}
|
|
238
|
+
set innerHTML(v) {
|
|
239
|
+
for (const c of this.childNodes) c.parentNode = null;
|
|
240
|
+
this.childNodes = [];
|
|
241
|
+
this.rawHTML = v == null ? "" : String(v);
|
|
242
|
+
}
|
|
243
|
+
cloneNode(deep = false) {
|
|
244
|
+
const el = new _ServerElement(this.localName, this.isSVG);
|
|
245
|
+
el.attributes = new Map(this.attributes);
|
|
246
|
+
el.style.cssText = this.style.cssText;
|
|
247
|
+
el.rawHTML = this.rawHTML;
|
|
248
|
+
if (deep) for (const c of this.childNodes) el.appendChild(c.cloneNode(true));
|
|
249
|
+
return el;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// src/lib/dom/server/parse-template.ts
|
|
254
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
255
|
+
"area",
|
|
256
|
+
"base",
|
|
257
|
+
"br",
|
|
258
|
+
"col",
|
|
259
|
+
"embed",
|
|
260
|
+
"hr",
|
|
261
|
+
"img",
|
|
262
|
+
"input",
|
|
263
|
+
"link",
|
|
264
|
+
"meta",
|
|
265
|
+
"param",
|
|
266
|
+
"source",
|
|
267
|
+
"track",
|
|
268
|
+
"wbr"
|
|
269
|
+
]);
|
|
270
|
+
var ENTITIES = {
|
|
271
|
+
amp: "&",
|
|
272
|
+
lt: "<",
|
|
273
|
+
gt: ">",
|
|
274
|
+
quot: '"',
|
|
275
|
+
"#39": "'"
|
|
276
|
+
};
|
|
277
|
+
function unescape(text) {
|
|
278
|
+
return text.replace(/&(#?\w+);/g, (whole, name) => ENTITIES[name] ?? whole);
|
|
279
|
+
}
|
|
280
|
+
var TemplateParseError = class extends Error {
|
|
281
|
+
};
|
|
282
|
+
function parseTemplate(html, isSVG = false) {
|
|
283
|
+
let i = 0;
|
|
284
|
+
const roots = [];
|
|
285
|
+
const stack = [];
|
|
286
|
+
const append = (node) => {
|
|
287
|
+
const parent = stack[stack.length - 1];
|
|
288
|
+
if (parent) parent.appendChild(node);
|
|
289
|
+
else roots.push(node);
|
|
290
|
+
};
|
|
291
|
+
while (i < html.length) {
|
|
292
|
+
const lt = html.indexOf("<", i);
|
|
293
|
+
if (lt === -1) {
|
|
294
|
+
addText(html.slice(i));
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
if (lt > i) addText(html.slice(i, lt));
|
|
298
|
+
if (html.startsWith("<!--", lt)) {
|
|
299
|
+
const end = html.indexOf("-->", lt);
|
|
300
|
+
if (end === -1) throw new TemplateParseError(`unterminated comment at ${lt}`);
|
|
301
|
+
append(new ServerComment(html.slice(lt + 4, end)));
|
|
302
|
+
i = end + 3;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (html[lt + 1] === "/") {
|
|
306
|
+
const end = html.indexOf(">", lt);
|
|
307
|
+
if (end === -1) throw new TemplateParseError(`unterminated closing tag at ${lt}`);
|
|
308
|
+
const tag = html.slice(lt + 2, end).trim().toLowerCase();
|
|
309
|
+
const open = stack.pop();
|
|
310
|
+
if (!open || open.localName !== tag) {
|
|
311
|
+
throw new TemplateParseError(
|
|
312
|
+
`</${tag}> does not close <${open?.localName ?? "nothing"}>`
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
i = end + 1;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
i = openTag(lt);
|
|
319
|
+
}
|
|
320
|
+
if (stack.length > 0) {
|
|
321
|
+
throw new TemplateParseError(`unclosed <${stack[stack.length - 1].localName}>`);
|
|
322
|
+
}
|
|
323
|
+
const root = roots[0];
|
|
324
|
+
if (roots.length !== 1 || !(root instanceof ServerElement)) {
|
|
325
|
+
throw new TemplateParseError(`expected exactly one root element, got ${roots.length}`);
|
|
326
|
+
}
|
|
327
|
+
return root;
|
|
328
|
+
function addText(raw) {
|
|
329
|
+
if (raw === "") return;
|
|
330
|
+
append(new ServerText(unescape(raw)));
|
|
331
|
+
}
|
|
332
|
+
function openTag(lt) {
|
|
333
|
+
const nameEnd = /[\s/>]/.exec(html.slice(lt + 1));
|
|
334
|
+
if (!nameEnd) throw new TemplateParseError(`unterminated tag at ${lt}`);
|
|
335
|
+
const tag = html.slice(lt + 1, lt + 1 + nameEnd.index).toLowerCase();
|
|
336
|
+
const el = new ServerElement(tag, isSVG);
|
|
337
|
+
let j = lt + 1 + nameEnd.index;
|
|
338
|
+
while (j < html.length) {
|
|
339
|
+
while (j < html.length && /\s/.test(html[j])) j++;
|
|
340
|
+
if (html[j] === ">") {
|
|
341
|
+
j++;
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
if (html[j] === "/" && html[j + 1] === ">") {
|
|
345
|
+
j += 2;
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
const attrStart = j;
|
|
349
|
+
while (j < html.length && !/[\s=/>]/.test(html[j])) j++;
|
|
350
|
+
const name = html.slice(attrStart, j);
|
|
351
|
+
if (name === "") throw new TemplateParseError(`malformed attribute at ${j}`);
|
|
352
|
+
if (html[j] === "=") {
|
|
353
|
+
if (html[j + 1] !== '"') {
|
|
354
|
+
throw new TemplateParseError(`attribute ${name} must have a double-quoted value`);
|
|
355
|
+
}
|
|
356
|
+
const close = html.indexOf('"', j + 2);
|
|
357
|
+
if (close === -1) throw new TemplateParseError(`unterminated value for ${name}`);
|
|
358
|
+
el.setAttribute(name, unescape(html.slice(j + 2, close)));
|
|
359
|
+
j = close + 1;
|
|
360
|
+
} else {
|
|
361
|
+
el.setAttribute(name, "");
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
append(el);
|
|
365
|
+
if (!VOID_ELEMENTS.has(tag)) stack.push(el);
|
|
366
|
+
return j;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
export {
|
|
370
|
+
TemplateParseError,
|
|
371
|
+
parseTemplate
|
|
372
|
+
};
|