elit 3.6.5 → 3.6.7
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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/README.md +6 -0
- package/dist/build.cjs +421 -331
- package/dist/build.d.ts +1 -16
- package/dist/build.js +420 -330
- package/dist/build.mjs +420 -330
- package/dist/chokidar.cjs +219 -182
- package/dist/chokidar.d.ts +25 -10
- package/dist/chokidar.js +217 -182
- package/dist/chokidar.mjs +218 -183
- package/dist/cli.cjs +21608 -20241
- package/dist/cli.d.ts +19 -37
- package/dist/cli.mjs +21262 -19910
- package/dist/config.cjs +357 -350
- package/dist/config.d.ts +19 -240
- package/dist/config.js +520 -515
- package/dist/config.mjs +346 -341
- package/dist/contracts-BeW9k0yZ.d.ts +54 -0
- package/dist/contracts-D7KIS-TK.d.ts +36 -0
- package/dist/coverage.cjs +448 -485
- package/dist/coverage.d.ts +13 -59
- package/dist/coverage.js +447 -484
- package/dist/coverage.mjs +447 -484
- package/dist/database.cjs +819 -828
- package/dist/database.d.ts +8 -24
- package/dist/database.js +818 -829
- package/dist/database.mjs +818 -829
- package/dist/desktop-auto-render.cjs +1700 -1522
- package/dist/desktop-auto-render.d.ts +4 -9
- package/dist/desktop-auto-render.js +1695 -1517
- package/dist/desktop-auto-render.mjs +1696 -1518
- package/dist/desktop.cjs +3 -1
- package/dist/desktop.d.ts +4 -1
- package/dist/desktop.js +1 -1
- package/dist/desktop.mjs +1 -1
- package/dist/dev-build.cjs +830 -0
- package/dist/dev-build.d.ts +53 -0
- package/dist/dev-build.js +3318 -0
- package/dist/dev-build.mjs +797 -0
- package/dist/dom.cjs +717 -590
- package/dist/dom.d.ts +2 -15
- package/dist/dom.js +714 -587
- package/dist/dom.mjs +716 -589
- package/dist/el.cjs +62 -52
- package/dist/el.d.ts +5 -10
- package/dist/el.js +60 -52
- package/dist/el.mjs +60 -52
- package/dist/fs.cjs +72 -63
- package/dist/fs.d.ts +22 -19
- package/dist/fs.js +71 -62
- package/dist/fs.mjs +71 -62
- package/dist/hmr.cjs +40 -14
- package/dist/hmr.d.ts +11 -23
- package/dist/hmr.js +38 -14
- package/dist/hmr.mjs +38 -14
- package/dist/http.cjs +251 -99
- package/dist/http.d.ts +38 -104
- package/dist/http.js +249 -99
- package/dist/http.mjs +249 -99
- package/dist/https.cjs +524 -228
- package/dist/https.d.ts +44 -36
- package/dist/https.js +520 -226
- package/dist/https.mjs +522 -228
- package/dist/index.cjs +7502 -7690
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7486 -7676
- package/dist/index.mjs +7497 -7686
- package/dist/mime-types.cjs +10 -4
- package/dist/mime-types.d.ts +8 -11
- package/dist/mime-types.js +9 -3
- package/dist/mime-types.mjs +9 -3
- package/dist/native.cjs +8616 -8869
- package/dist/native.d.ts +7 -8
- package/dist/native.js +8682 -8935
- package/dist/native.mjs +8615 -8868
- package/dist/path.cjs +83 -77
- package/dist/path.d.ts +29 -29
- package/dist/path.js +82 -76
- package/dist/path.mjs +82 -76
- package/dist/pm.cjs +3300 -0
- package/dist/pm.d.ts +256 -0
- package/dist/pm.js +5638 -0
- package/dist/pm.mjs +3196 -0
- package/dist/preview-build.cjs +712 -0
- package/dist/preview-build.d.ts +59 -0
- package/dist/preview-build.js +3194 -0
- package/dist/preview-build.mjs +676 -0
- package/dist/render-context.cjs +13 -2
- package/dist/render-context.d.ts +9 -31
- package/dist/render-context.js +11 -2
- package/dist/render-context.mjs +11 -2
- package/dist/router.cjs +787 -645
- package/dist/router.d.ts +8 -12
- package/dist/router.js +786 -644
- package/dist/router.mjs +786 -644
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/server.cjs +3315 -2603
- package/dist/server.d.ts +49 -4
- package/dist/server.js +7611 -2834
- package/dist/server.mjs +3317 -2607
- package/dist/smtp-server.cjs +128 -0
- package/dist/smtp-server.d.ts +27 -0
- package/dist/smtp-server.js +4199 -0
- package/dist/smtp-server.mjs +100 -0
- package/dist/state-DvEkDehk.d.ts +195 -0
- package/dist/state.cjs +768 -658
- package/dist/state.d.ts +11 -69
- package/dist/state.js +760 -650
- package/dist/state.mjs +767 -657
- package/dist/style.cjs +1011 -968
- package/dist/style.d.ts +13 -127
- package/dist/style.js +1009 -970
- package/dist/style.mjs +1011 -971
- package/dist/test-reporter.cjs +332 -316
- package/dist/test-reporter.d.ts +28 -33
- package/dist/test-reporter.js +328 -312
- package/dist/test-reporter.mjs +328 -312
- package/dist/test-runtime.cjs +927 -968
- package/dist/test-runtime.d.ts +24 -99
- package/dist/test-runtime.js +922 -965
- package/dist/test-runtime.mjs +922 -965
- package/dist/test.cjs +4428 -4273
- package/dist/test.d.ts +2 -8
- package/dist/test.js +4307 -4154
- package/dist/test.mjs +4419 -4267
- package/dist/types-BONVzPtp.d.ts +59 -0
- package/dist/types-BR4wMiVx.d.ts +32 -0
- package/dist/types-C4gKykuG.d.ts +23 -0
- package/dist/types-CIhpN1-K.d.ts +64 -0
- package/dist/types-Ckj8md_j.d.ts +84 -0
- package/dist/types-CpjQTAkX.d.ts +24 -0
- package/dist/types-D0LjrYjS.d.ts +14 -0
- package/dist/types-DAisuVr5.d.ts +75 -0
- package/dist/types-tJn88E1N.d.ts +242 -0
- package/dist/types.d.ts +71 -226
- package/dist/universal.cjs +1 -1
- package/dist/universal.d.ts +1 -5
- package/dist/universal.js +1 -1
- package/dist/universal.mjs +1 -1
- package/dist/websocket-XfyK23zD.d.ts +119 -0
- package/dist/ws.cjs +129 -108
- package/dist/ws.d.ts +21 -131
- package/dist/ws.js +128 -109
- package/dist/ws.mjs +128 -109
- package/dist/wss.cjs +757 -479
- package/dist/wss.d.ts +31 -28
- package/dist/wss.js +755 -479
- package/dist/wss.mjs +758 -482
- package/package.json +16 -1
- package/vendor/epaint-0.31.1/src/image.rs +418 -0
- package/dist/server-CcBFc2F5.d.ts +0 -449
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
(() => {
|
|
3
|
-
// src/render-context.ts
|
|
3
|
+
// src/desktop/render-context/constants.ts
|
|
4
4
|
var RUNTIME_TARGET_KEY = "__ELIT_RUNTIME_TARGET__";
|
|
5
5
|
var CAPTURED_RENDER_KEY = "__ELIT_CAPTURED_RENDER__";
|
|
6
6
|
var DESKTOP_RENDER_OPTIONS_KEY = "__ELIT_DESKTOP_RENDER_OPTIONS__";
|
|
7
7
|
var RUNTIME_TARGET_ENV = "ELIT_RUNTIME_TARGET";
|
|
8
|
+
|
|
9
|
+
// src/desktop/render-context/globals.ts
|
|
8
10
|
function getGlobalRenderScope() {
|
|
9
11
|
return globalThis;
|
|
10
12
|
}
|
|
13
|
+
|
|
14
|
+
// src/desktop/render-context/runtime-target.ts
|
|
11
15
|
function isRenderRuntimeTarget(value) {
|
|
12
16
|
return value === "web" || value === "desktop" || value === "mobile" || value === "unknown";
|
|
13
17
|
}
|
|
@@ -23,7 +27,8 @@
|
|
|
23
27
|
if (typeof globalScope.createWindow === "function") {
|
|
24
28
|
return "desktop";
|
|
25
29
|
}
|
|
26
|
-
const
|
|
30
|
+
const argvValues = globalScope.process?.argv;
|
|
31
|
+
const argv = Array.isArray(argvValues) ? argvValues.join(" ") : "";
|
|
27
32
|
if (/\bdesktop\b/i.test(argv)) {
|
|
28
33
|
return "desktop";
|
|
29
34
|
}
|
|
@@ -32,6 +37,8 @@
|
|
|
32
37
|
}
|
|
33
38
|
return "unknown";
|
|
34
39
|
}
|
|
40
|
+
|
|
41
|
+
// src/desktop/render-context/captured-render.ts
|
|
35
42
|
function captureRenderedVNode(rootElement, vNode, target = detectRenderRuntimeTarget()) {
|
|
36
43
|
const globalScope = getGlobalRenderScope();
|
|
37
44
|
globalScope[RUNTIME_TARGET_KEY] = target;
|
|
@@ -47,11 +54,13 @@
|
|
|
47
54
|
function clearCapturedRenderedVNode() {
|
|
48
55
|
delete getGlobalRenderScope()[CAPTURED_RENDER_KEY];
|
|
49
56
|
}
|
|
57
|
+
|
|
58
|
+
// src/desktop/render-context/desktop-options.ts
|
|
50
59
|
function getDesktopRenderOptions() {
|
|
51
60
|
return getGlobalRenderScope()[DESKTOP_RENDER_OPTIONS_KEY];
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
// src/dom.ts
|
|
63
|
+
// src/client/dom/helpers.ts
|
|
55
64
|
function resolveElement(rootElement) {
|
|
56
65
|
return typeof rootElement === "string" ? document.getElementById(rootElement.replace("#", "")) : rootElement;
|
|
57
66
|
}
|
|
@@ -79,1029 +88,1248 @@
|
|
|
79
88
|
function hasDocumentApi() {
|
|
80
89
|
return typeof document !== "undefined";
|
|
81
90
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
vNode.subscribe((newValue) => {
|
|
100
|
-
textNode.textContent = String(newValue ?? "");
|
|
101
|
-
});
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (Array.isArray(vNode)) {
|
|
105
|
-
for (const child of vNode) {
|
|
106
|
-
this.renderToDOM(child, parent);
|
|
107
|
-
}
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const { tagName, props, children } = vNode;
|
|
111
|
-
const textareaValue = resolveTextareaValue(tagName, props);
|
|
112
|
-
if (!tagName) {
|
|
113
|
-
for (const child of children) {
|
|
114
|
-
if (shouldSkipChild(child)) continue;
|
|
115
|
-
if (Array.isArray(child)) {
|
|
116
|
-
for (const c of child) {
|
|
117
|
-
!shouldSkipChild(c) && this.renderToDOM(c, parent);
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
this.renderToDOM(child, parent);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
const isSVG = tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
|
|
126
|
-
const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
|
|
127
|
-
for (const key in props) {
|
|
128
|
-
const value = props[key];
|
|
129
|
-
if (value == null || value === false) continue;
|
|
130
|
-
const c = key.charCodeAt(0);
|
|
131
|
-
if (c === 99 && (key.length < 6 || key[5] === "N")) {
|
|
132
|
-
const classValue = Array.isArray(value) ? value.join(" ") : value;
|
|
133
|
-
isSVG ? el.setAttribute("class", classValue) : el.className = classValue;
|
|
134
|
-
} else if (c === 115 && key.length === 5) {
|
|
135
|
-
if (typeof value === "string") {
|
|
136
|
-
el.style.cssText = value;
|
|
137
|
-
} else {
|
|
138
|
-
const s = el.style;
|
|
139
|
-
for (const k in value) s[k] = value[k];
|
|
140
|
-
}
|
|
141
|
-
} else if (c === 111 && key.charCodeAt(1) === 110) {
|
|
142
|
-
el[key.toLowerCase()] = value;
|
|
143
|
-
} else if (c === 100 && key.length > 20) {
|
|
144
|
-
el.innerHTML = value.__html;
|
|
145
|
-
} else if (c === 114 && key === "ref") {
|
|
146
|
-
setTimeout(() => {
|
|
147
|
-
typeof value === "function" ? value(el) : value.current = el;
|
|
148
|
-
}, 0);
|
|
149
|
-
} else if (textareaValue !== void 0 && key === "value") {
|
|
150
|
-
continue;
|
|
91
|
+
function isState(value) {
|
|
92
|
+
return value && typeof value === "object" && "value" in value && "subscribe" in value && typeof value.subscribe === "function";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/client/dom/dom-render.ts
|
|
96
|
+
function isSvgElement(tagName, parent) {
|
|
97
|
+
return tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
|
|
98
|
+
}
|
|
99
|
+
function applyProps(el, props, textareaValue) {
|
|
100
|
+
for (const key in props) {
|
|
101
|
+
const value = props[key];
|
|
102
|
+
if (value == null || value === false) continue;
|
|
103
|
+
const c = key.charCodeAt(0);
|
|
104
|
+
if (c === 99 && (key.length < 6 || key[5] === "N")) {
|
|
105
|
+
const classValue = Array.isArray(value) ? value.join(" ") : String(value);
|
|
106
|
+
if (el instanceof SVGElement) {
|
|
107
|
+
el.setAttribute("class", classValue);
|
|
151
108
|
} else {
|
|
152
|
-
el.
|
|
109
|
+
el.className = classValue;
|
|
153
110
|
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
111
|
+
} else if (c === 115 && key.length === 5) {
|
|
112
|
+
if (typeof value === "string") {
|
|
113
|
+
el.style.cssText = value;
|
|
114
|
+
} else {
|
|
115
|
+
const style = el.style;
|
|
116
|
+
for (const styleKey in value) {
|
|
117
|
+
style[styleKey] = value[styleKey];
|
|
118
|
+
}
|
|
160
119
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
for (let j = 0, cLen = child.length; j < cLen; j++) {
|
|
170
|
-
const c = child[j];
|
|
171
|
-
!shouldSkipChild(c) && this.renderToDOM(c, target);
|
|
172
|
-
}
|
|
120
|
+
} else if (c === 111 && key.charCodeAt(1) === 110) {
|
|
121
|
+
el[key.toLowerCase()] = value;
|
|
122
|
+
} else if (c === 100 && key.length > 20) {
|
|
123
|
+
el.innerHTML = value.__html;
|
|
124
|
+
} else if (c === 114 && key === "ref") {
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
if (typeof value === "function") {
|
|
127
|
+
value(el);
|
|
173
128
|
} else {
|
|
174
|
-
|
|
129
|
+
value.current = el;
|
|
175
130
|
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const fragment = document.createDocumentFragment();
|
|
180
|
-
renderChildren(fragment);
|
|
181
|
-
el.appendChild(fragment);
|
|
131
|
+
}, 0);
|
|
132
|
+
} else if (textareaValue !== void 0 && key === "value") {
|
|
133
|
+
continue;
|
|
182
134
|
} else {
|
|
183
|
-
|
|
135
|
+
el.setAttribute(key, value === true ? "" : String(value));
|
|
184
136
|
}
|
|
185
|
-
parent.appendChild(el);
|
|
186
137
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
138
|
+
}
|
|
139
|
+
function renderChildren(children, target) {
|
|
140
|
+
const len = children.length;
|
|
141
|
+
for (let i = 0; i < len; i++) {
|
|
142
|
+
const child = children[i];
|
|
143
|
+
if (shouldSkipChild(child)) continue;
|
|
144
|
+
if (Array.isArray(child)) {
|
|
145
|
+
for (let j = 0, childLen = child.length; j < childLen; j++) {
|
|
146
|
+
const nestedChild = child[j];
|
|
147
|
+
if (!shouldSkipChild(nestedChild)) {
|
|
148
|
+
renderToDOM(nestedChild, target);
|
|
149
|
+
}
|
|
193
150
|
}
|
|
194
|
-
throw new Error("render() requires a DOM or an Elit desktop/mobile runtime target.");
|
|
195
|
-
}
|
|
196
|
-
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
197
|
-
el.innerHTML = "";
|
|
198
|
-
if (vNode.children && vNode.children.length > 500) {
|
|
199
|
-
const fragment = document.createDocumentFragment();
|
|
200
|
-
this.renderToDOM(vNode, fragment);
|
|
201
|
-
el.appendChild(fragment);
|
|
202
151
|
} else {
|
|
203
|
-
|
|
152
|
+
renderToDOM(child, target);
|
|
204
153
|
}
|
|
205
|
-
return el;
|
|
206
154
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const chunkSize = 1500;
|
|
214
|
-
const processChunk = () => {
|
|
215
|
-
const end = Math.min(processed + chunkSize, len);
|
|
216
|
-
for (let i = processed; i < end; i++) {
|
|
217
|
-
this.renderToDOM(vNodes[i], fragment);
|
|
218
|
-
}
|
|
219
|
-
processed = end;
|
|
220
|
-
if (processed >= len) {
|
|
221
|
-
el.appendChild(fragment);
|
|
222
|
-
} else {
|
|
223
|
-
requestAnimationFrame(processChunk);
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
processChunk();
|
|
227
|
-
} else {
|
|
228
|
-
const fragment = document.createDocumentFragment();
|
|
229
|
-
for (let i = 0; i < len; i++) {
|
|
230
|
-
this.renderToDOM(vNodes[i], fragment);
|
|
231
|
-
}
|
|
232
|
-
el.appendChild(fragment);
|
|
233
|
-
}
|
|
234
|
-
return el;
|
|
155
|
+
}
|
|
156
|
+
function renderToDOM(vNode, parent) {
|
|
157
|
+
if (vNode == null || vNode === false) return;
|
|
158
|
+
if (typeof vNode !== "object") {
|
|
159
|
+
parent.appendChild(document.createTextNode(String(vNode)));
|
|
160
|
+
return;
|
|
235
161
|
}
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
for (let i = index; i < end; i++) {
|
|
244
|
-
this.renderToDOM(vNodes[i], fragment);
|
|
245
|
-
}
|
|
246
|
-
el.appendChild(fragment);
|
|
247
|
-
index = end;
|
|
248
|
-
if (onProgress) onProgress(index, len);
|
|
249
|
-
if (index < len) {
|
|
250
|
-
requestAnimationFrame(renderChunk);
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
requestAnimationFrame(renderChunk);
|
|
254
|
-
return el;
|
|
162
|
+
if (isState(vNode)) {
|
|
163
|
+
const textNode = document.createTextNode(String(vNode.value ?? ""));
|
|
164
|
+
parent.appendChild(textNode);
|
|
165
|
+
vNode.subscribe((newValue) => {
|
|
166
|
+
textNode.textContent = String(newValue ?? "");
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
255
169
|
}
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
for (const vNode of vNodes.flat()) {
|
|
260
|
-
vNode && this.renderToDOM(vNode, head);
|
|
261
|
-
}
|
|
170
|
+
if (Array.isArray(vNode)) {
|
|
171
|
+
for (const child of vNode) {
|
|
172
|
+
renderToDOM(child, parent);
|
|
262
173
|
}
|
|
263
|
-
return
|
|
174
|
+
return;
|
|
264
175
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
176
|
+
const { tagName, props, children } = vNode;
|
|
177
|
+
const textareaValue = resolveTextareaValue(tagName, props);
|
|
178
|
+
if (!tagName) {
|
|
179
|
+
renderChildren(children, parent);
|
|
180
|
+
return;
|
|
269
181
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
182
|
+
const el = isSvgElement(tagName, parent) ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
|
|
183
|
+
applyProps(el, props, textareaValue);
|
|
184
|
+
const renderableChildren = textareaValue === void 0 ? children : [];
|
|
185
|
+
if (!renderableChildren.length) {
|
|
186
|
+
if (textareaValue !== void 0) {
|
|
187
|
+
el.value = textareaValue;
|
|
188
|
+
}
|
|
189
|
+
parent.appendChild(el);
|
|
190
|
+
return;
|
|
274
191
|
}
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
192
|
+
if (renderableChildren.length > 30) {
|
|
193
|
+
const fragment = document.createDocumentFragment();
|
|
194
|
+
renderChildren(renderableChildren, fragment);
|
|
195
|
+
el.appendChild(fragment);
|
|
196
|
+
} else {
|
|
197
|
+
renderChildren(renderableChildren, el);
|
|
279
198
|
}
|
|
280
|
-
|
|
281
|
-
|
|
199
|
+
parent.appendChild(el);
|
|
200
|
+
}
|
|
201
|
+
function render(rootElement, vNode) {
|
|
202
|
+
if (!hasDocumentApi()) {
|
|
203
|
+
const runtimeTarget = detectRenderRuntimeTarget();
|
|
204
|
+
if (runtimeTarget === "desktop" || runtimeTarget === "mobile") {
|
|
205
|
+
captureRenderedVNode(rootElement, vNode, runtimeTarget);
|
|
206
|
+
return {};
|
|
207
|
+
}
|
|
208
|
+
throw new Error("render() requires a DOM or an Elit desktop/mobile runtime target.");
|
|
209
|
+
}
|
|
210
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
211
|
+
el.innerHTML = "";
|
|
212
|
+
if (vNode.children && vNode.children.length > 500) {
|
|
213
|
+
const fragment = document.createDocumentFragment();
|
|
214
|
+
renderToDOM(vNode, fragment);
|
|
215
|
+
el.appendChild(fragment);
|
|
216
|
+
} else {
|
|
217
|
+
renderToDOM(vNode, el);
|
|
282
218
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
219
|
+
return el;
|
|
220
|
+
}
|
|
221
|
+
function batchRender(rootElement, vNodes) {
|
|
222
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
223
|
+
const len = vNodes.length;
|
|
224
|
+
if (len > 3e3) {
|
|
225
|
+
const fragment = document.createDocumentFragment();
|
|
226
|
+
let processed = 0;
|
|
227
|
+
const chunkSize = 1500;
|
|
228
|
+
const processChunk = () => {
|
|
229
|
+
const end = Math.min(processed + chunkSize, len);
|
|
230
|
+
for (let i = processed; i < end; i++) {
|
|
231
|
+
renderToDOM(vNodes[i], fragment);
|
|
232
|
+
}
|
|
233
|
+
processed = end;
|
|
234
|
+
if (processed >= len) {
|
|
235
|
+
el.appendChild(fragment);
|
|
298
236
|
} else {
|
|
299
|
-
|
|
237
|
+
requestAnimationFrame(processChunk);
|
|
300
238
|
}
|
|
301
239
|
};
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
240
|
+
processChunk();
|
|
241
|
+
} else {
|
|
242
|
+
const fragment = document.createDocumentFragment();
|
|
243
|
+
for (let i = 0; i < len; i++) {
|
|
244
|
+
renderToDOM(vNodes[i], fragment);
|
|
245
|
+
}
|
|
246
|
+
el.appendChild(fragment);
|
|
247
|
+
}
|
|
248
|
+
return el;
|
|
249
|
+
}
|
|
250
|
+
function renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
|
|
251
|
+
const el = ensureElement(resolveElement(rootElement), rootElement);
|
|
252
|
+
const len = vNodes.length;
|
|
253
|
+
let index = 0;
|
|
254
|
+
const renderChunkFrame = () => {
|
|
255
|
+
const end = Math.min(index + chunkSize, len);
|
|
256
|
+
const fragment = document.createDocumentFragment();
|
|
257
|
+
for (let i = index; i < end; i++) {
|
|
258
|
+
renderToDOM(vNodes[i], fragment);
|
|
259
|
+
}
|
|
260
|
+
el.appendChild(fragment);
|
|
261
|
+
index = end;
|
|
262
|
+
if (onProgress) {
|
|
263
|
+
onProgress(index, len);
|
|
264
|
+
}
|
|
265
|
+
if (index < len) {
|
|
266
|
+
requestAnimationFrame(renderChunkFrame);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
requestAnimationFrame(renderChunkFrame);
|
|
270
|
+
return el;
|
|
271
|
+
}
|
|
272
|
+
function renderToHead(...vNodes) {
|
|
273
|
+
const head = document.head;
|
|
274
|
+
if (head) {
|
|
275
|
+
for (const vNode of vNodes.flat()) {
|
|
276
|
+
if (vNode) {
|
|
277
|
+
renderToDOM(vNode, head);
|
|
320
278
|
}
|
|
321
|
-
}
|
|
279
|
+
}
|
|
322
280
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
281
|
+
return head;
|
|
282
|
+
}
|
|
283
|
+
function addStyle(cssText) {
|
|
284
|
+
const el = document.createElement("style");
|
|
285
|
+
el.textContent = cssText;
|
|
286
|
+
return document.head.appendChild(el);
|
|
287
|
+
}
|
|
288
|
+
function addMeta(attrs) {
|
|
289
|
+
const el = document.createElement("meta");
|
|
290
|
+
for (const key in attrs) {
|
|
291
|
+
el.setAttribute(key, attrs[key]);
|
|
333
292
|
}
|
|
334
|
-
|
|
335
|
-
|
|
293
|
+
return document.head.appendChild(el);
|
|
294
|
+
}
|
|
295
|
+
function addLink(attrs) {
|
|
296
|
+
const el = document.createElement("link");
|
|
297
|
+
for (const key in attrs) {
|
|
298
|
+
el.setAttribute(key, attrs[key]);
|
|
336
299
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
|
|
351
|
-
for (let i = start; i < end; i++) {
|
|
352
|
-
const itemEl = document.createElement("div");
|
|
353
|
-
itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
|
|
354
|
-
this.renderToDOM(renderItem(items[i], i), itemEl);
|
|
355
|
-
wrapper.appendChild(itemEl);
|
|
356
|
-
}
|
|
357
|
-
container2.innerHTML = "";
|
|
358
|
-
container2.appendChild(wrapper);
|
|
359
|
-
};
|
|
360
|
-
const scrollHandler = () => {
|
|
361
|
-
scrollTop = container2.scrollTop;
|
|
362
|
-
requestAnimationFrame(render2);
|
|
363
|
-
};
|
|
364
|
-
container2.addEventListener("scroll", scrollHandler);
|
|
365
|
-
render2();
|
|
366
|
-
return {
|
|
367
|
-
render: render2,
|
|
368
|
-
destroy: () => {
|
|
369
|
-
container2.removeEventListener("scroll", scrollHandler);
|
|
370
|
-
container2.innerHTML = "";
|
|
371
|
-
}
|
|
372
|
-
};
|
|
300
|
+
return document.head.appendChild(el);
|
|
301
|
+
}
|
|
302
|
+
function setTitle(text) {
|
|
303
|
+
return document.title = text;
|
|
304
|
+
}
|
|
305
|
+
function cleanupUnusedElements(root, elementCache) {
|
|
306
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
307
|
+
const toRemove = [];
|
|
308
|
+
while (walker.nextNode()) {
|
|
309
|
+
const node = walker.currentNode;
|
|
310
|
+
if (node.id && node.id.startsWith("r") && !elementCache.has(node)) {
|
|
311
|
+
toRemove.push(node);
|
|
312
|
+
}
|
|
373
313
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
314
|
+
toRemove.forEach((el) => el.remove());
|
|
315
|
+
return toRemove.length;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/client/dom/reactive.ts
|
|
319
|
+
function createReactiveChild(state, reactiveNodes, renderFn) {
|
|
320
|
+
const currentValue = renderFn(state.value);
|
|
321
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
322
|
+
const entry = { node: null, renderFn };
|
|
323
|
+
reactiveNodes.set(state, entry);
|
|
324
|
+
state.subscribe(() => {
|
|
325
|
+
if (entry.node && entry.node.parentNode) {
|
|
326
|
+
const newValue = renderFn(state.value);
|
|
327
|
+
entry.node.textContent = String(newValue ?? "");
|
|
383
328
|
}
|
|
384
|
-
|
|
385
|
-
};
|
|
329
|
+
});
|
|
386
330
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
331
|
+
return currentValue;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/client/dom/string-render.ts
|
|
335
|
+
var SELF_CLOSING_TAGS = /* @__PURE__ */ new Set([
|
|
336
|
+
"area",
|
|
337
|
+
"base",
|
|
338
|
+
"br",
|
|
339
|
+
"col",
|
|
340
|
+
"embed",
|
|
341
|
+
"hr",
|
|
342
|
+
"img",
|
|
343
|
+
"input",
|
|
344
|
+
"link",
|
|
345
|
+
"meta",
|
|
346
|
+
"param",
|
|
347
|
+
"source",
|
|
348
|
+
"track",
|
|
349
|
+
"wbr"
|
|
350
|
+
]);
|
|
351
|
+
function resolveStateValue(value) {
|
|
352
|
+
return isState(value) ? value.value : value;
|
|
353
|
+
}
|
|
354
|
+
function isReactiveWrapper(vNode) {
|
|
355
|
+
if (!vNode || typeof vNode !== "object" || !vNode.tagName) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
return vNode.tagName === "span" && vNode.props?.id && typeof vNode.props.id === "string" && /^r[a-z0-9]{9}$/.test(vNode.props.id);
|
|
359
|
+
}
|
|
360
|
+
function unwrapReactive(vNode) {
|
|
361
|
+
if (!isReactiveWrapper(vNode)) {
|
|
362
|
+
return vNode;
|
|
363
|
+
}
|
|
364
|
+
const children = vNode.children;
|
|
365
|
+
if (!children || children.length === 0) {
|
|
366
|
+
return "";
|
|
367
|
+
}
|
|
368
|
+
if (children.length === 1) {
|
|
369
|
+
const child = children[0];
|
|
370
|
+
if (child && typeof child === "object" && child.tagName === "span") {
|
|
371
|
+
const props = child.props;
|
|
372
|
+
const hasNoProps = !props || Object.keys(props).length === 0;
|
|
373
|
+
const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
|
|
374
|
+
if (hasNoProps && hasSingleStringChild) {
|
|
375
|
+
return child.children[0];
|
|
395
376
|
}
|
|
396
377
|
}
|
|
397
|
-
|
|
398
|
-
return toRemove.length;
|
|
378
|
+
return unwrapReactive(child);
|
|
399
379
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
380
|
+
return children.map((child) => unwrapReactive(child));
|
|
381
|
+
}
|
|
382
|
+
function escapeHtml(text) {
|
|
383
|
+
const htmlEscapes = {
|
|
384
|
+
"&": "&",
|
|
385
|
+
"<": "<",
|
|
386
|
+
">": ">",
|
|
387
|
+
'"': """,
|
|
388
|
+
"'": "'"
|
|
389
|
+
};
|
|
390
|
+
return text.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
|
|
391
|
+
}
|
|
392
|
+
function isSelfClosingTag(tagName) {
|
|
393
|
+
return SELF_CLOSING_TAGS.has(tagName.toLowerCase());
|
|
394
|
+
}
|
|
395
|
+
function styleToString(style) {
|
|
396
|
+
if (typeof style === "string") {
|
|
397
|
+
return style;
|
|
398
|
+
}
|
|
399
|
+
if (typeof style === "object" && style !== null) {
|
|
400
|
+
const styles2 = [];
|
|
401
|
+
for (const key in style) {
|
|
402
|
+
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
403
|
+
styles2.push(`${cssKey}:${style[key]}`);
|
|
404
|
+
}
|
|
405
|
+
return styles2.join(";");
|
|
406
|
+
}
|
|
407
|
+
return "";
|
|
408
|
+
}
|
|
409
|
+
function propsToAttributes(props, tagName) {
|
|
410
|
+
const attrs = [];
|
|
411
|
+
for (const key in props) {
|
|
412
|
+
if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref" || tagName === "textarea" && key === "value") {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
let value = props[key];
|
|
416
|
+
value = resolveStateValue(value);
|
|
417
|
+
if (value == null || value === false) continue;
|
|
418
|
+
if (key.startsWith("on") && typeof value === "function") {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
if (key === "className" || key === "class") {
|
|
422
|
+
const className = Array.isArray(value) ? value.join(" ") : value;
|
|
423
|
+
if (className) {
|
|
424
|
+
attrs.push(`class="${escapeHtml(String(className))}"`);
|
|
413
425
|
}
|
|
414
|
-
|
|
426
|
+
continue;
|
|
415
427
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
html += ` ${attrs}`;
|
|
428
|
+
if (key === "style") {
|
|
429
|
+
const styleStr = styleToString(value);
|
|
430
|
+
if (styleStr) {
|
|
431
|
+
attrs.push(`style="${escapeHtml(styleStr)}"`);
|
|
432
|
+
}
|
|
433
|
+
continue;
|
|
423
434
|
}
|
|
424
|
-
if (
|
|
425
|
-
|
|
426
|
-
|
|
435
|
+
if (value === true) {
|
|
436
|
+
attrs.push(key);
|
|
437
|
+
continue;
|
|
427
438
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
439
|
+
attrs.push(`${key}="${escapeHtml(String(value))}"`);
|
|
440
|
+
}
|
|
441
|
+
return attrs.join(" ");
|
|
442
|
+
}
|
|
443
|
+
function renderToString(vNode, options = {}) {
|
|
444
|
+
const { pretty = false, indent = 0 } = options;
|
|
445
|
+
const indentStr = pretty ? " ".repeat(indent) : "";
|
|
446
|
+
const newLine = pretty ? "\n" : "";
|
|
447
|
+
let resolvedVNode = resolveStateValue(vNode);
|
|
448
|
+
resolvedVNode = unwrapReactive(resolvedVNode);
|
|
449
|
+
if (Array.isArray(resolvedVNode)) {
|
|
450
|
+
return resolvedVNode.map((child) => renderToString(child, options)).join("");
|
|
451
|
+
}
|
|
452
|
+
if (typeof resolvedVNode !== "object" || resolvedVNode === null) {
|
|
453
|
+
if (resolvedVNode === null || resolvedVNode === void 0 || resolvedVNode === false) {
|
|
454
|
+
return "";
|
|
455
|
+
}
|
|
456
|
+
return escapeHtml(String(resolvedVNode));
|
|
457
|
+
}
|
|
458
|
+
const { tagName, props, children } = resolvedVNode;
|
|
459
|
+
const textareaValue = resolveTextareaValue(tagName, props);
|
|
460
|
+
const selfClosing = isSelfClosingTag(tagName);
|
|
461
|
+
let html = `${indentStr}<${tagName}`;
|
|
462
|
+
const attrs = propsToAttributes(props, tagName);
|
|
463
|
+
if (attrs) {
|
|
464
|
+
html += ` ${attrs}`;
|
|
465
|
+
}
|
|
466
|
+
if (selfClosing) {
|
|
467
|
+
html += ` />${newLine}`;
|
|
468
|
+
return html;
|
|
469
|
+
}
|
|
470
|
+
html += ">";
|
|
471
|
+
if (textareaValue !== void 0) {
|
|
472
|
+
html += escapeHtml(textareaValue);
|
|
473
|
+
html += `</${tagName}>${newLine}`;
|
|
474
|
+
return html;
|
|
475
|
+
}
|
|
476
|
+
if (props.dangerouslySetInnerHTML) {
|
|
477
|
+
html += props.dangerouslySetInnerHTML.__html;
|
|
478
|
+
html += `</${tagName}>${newLine}`;
|
|
479
|
+
return html;
|
|
480
|
+
}
|
|
481
|
+
const isRawText = tagName === "script" || tagName === "style";
|
|
482
|
+
if (children && children.length > 0) {
|
|
483
|
+
const resolvedChildren = children.map((child) => unwrapReactive(resolveStateValue(child)));
|
|
484
|
+
const hasComplexChildren = resolvedChildren.some(
|
|
485
|
+
(child) => typeof child === "object" && child !== null && !Array.isArray(child) && "tagName" in child
|
|
486
|
+
);
|
|
487
|
+
if (pretty && hasComplexChildren) {
|
|
488
|
+
html += newLine;
|
|
489
|
+
for (const child of resolvedChildren) {
|
|
490
|
+
if (shouldSkipChild(child)) continue;
|
|
491
|
+
if (Array.isArray(child)) {
|
|
492
|
+
for (const nestedChild of child) {
|
|
493
|
+
if (!shouldSkipChild(nestedChild)) {
|
|
494
|
+
html += isRawText && typeof nestedChild === "string" ? nestedChild : renderToString(nestedChild, { pretty, indent: indent + 1 });
|
|
456
495
|
}
|
|
457
|
-
} else {
|
|
458
|
-
html += this.renderToString(child, { pretty, indent: indent + 1 });
|
|
459
496
|
}
|
|
497
|
+
} else {
|
|
498
|
+
html += isRawText && typeof child === "string" ? child : renderToString(child, { pretty, indent: indent + 1 });
|
|
460
499
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
500
|
+
}
|
|
501
|
+
html += indentStr;
|
|
502
|
+
} else {
|
|
503
|
+
for (const child of resolvedChildren) {
|
|
504
|
+
if (shouldSkipChild(child)) continue;
|
|
505
|
+
if (Array.isArray(child)) {
|
|
506
|
+
for (const nestedChild of child) {
|
|
507
|
+
if (!shouldSkipChild(nestedChild)) {
|
|
508
|
+
html += isRawText && typeof nestedChild === "string" ? nestedChild : renderToString(nestedChild, { pretty: false, indent: 0 });
|
|
470
509
|
}
|
|
471
|
-
} else {
|
|
472
|
-
html += this.renderToString(child, { pretty: false, indent: 0 });
|
|
473
510
|
}
|
|
511
|
+
} else {
|
|
512
|
+
html += isRawText && typeof child === "string" ? child : renderToString(child, { pretty: false, indent: 0 });
|
|
474
513
|
}
|
|
475
514
|
}
|
|
476
515
|
}
|
|
477
|
-
html += `</${tagName}>${newLine}`;
|
|
478
|
-
return html;
|
|
479
516
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
517
|
+
html += `</${tagName}>${newLine}`;
|
|
518
|
+
return html;
|
|
519
|
+
}
|
|
520
|
+
function renderToHTMLDocument(vNode, options = {}) {
|
|
521
|
+
const {
|
|
522
|
+
title = "",
|
|
523
|
+
meta = [],
|
|
524
|
+
links = [],
|
|
525
|
+
scripts = [],
|
|
526
|
+
styles: styles2 = [],
|
|
527
|
+
lang = "en",
|
|
528
|
+
head = "",
|
|
529
|
+
bodyAttrs = {},
|
|
530
|
+
pretty = false
|
|
531
|
+
} = options;
|
|
532
|
+
const nl = pretty ? "\n" : "";
|
|
533
|
+
const indent = pretty ? " " : "";
|
|
534
|
+
const indent2 = pretty ? " " : "";
|
|
535
|
+
let html = `<!DOCTYPE html>${nl}<html lang="${lang}">${nl}${indent}<head>${nl}${indent2}<meta charset="UTF-8">${nl}${indent2}<meta name="viewport" content="width=device-width, initial-scale=1.0">${nl}`;
|
|
536
|
+
if (title) {
|
|
537
|
+
html += `${indent2}<title>${escapeHtml(title)}</title>${nl}`;
|
|
538
|
+
}
|
|
539
|
+
for (const metaAttrs of meta) {
|
|
540
|
+
html += `${indent2}<meta`;
|
|
541
|
+
for (const key in metaAttrs) {
|
|
542
|
+
html += ` ${key}="${escapeHtml(metaAttrs[key])}"`;
|
|
483
543
|
}
|
|
484
|
-
|
|
544
|
+
html += `>${nl}`;
|
|
485
545
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
546
|
+
for (const linkAttrs of links) {
|
|
547
|
+
html += `${indent2}<link`;
|
|
548
|
+
for (const key in linkAttrs) {
|
|
549
|
+
html += ` ${key}="${escapeHtml(linkAttrs[key])}"`;
|
|
489
550
|
}
|
|
490
|
-
|
|
551
|
+
html += `>${nl}`;
|
|
491
552
|
}
|
|
492
|
-
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
if (!children || children.length === 0) {
|
|
498
|
-
return "";
|
|
553
|
+
for (const style of styles2) {
|
|
554
|
+
if (style.href) {
|
|
555
|
+
html += `${indent2}<link rel="stylesheet" href="${escapeHtml(style.href)}">${nl}`;
|
|
556
|
+
} else if (style.content) {
|
|
557
|
+
html += `${indent2}<style>${style.content}</style>${nl}`;
|
|
499
558
|
}
|
|
500
|
-
if (children.length === 1) {
|
|
501
|
-
const child = children[0];
|
|
502
|
-
if (child && typeof child === "object" && child.tagName === "span") {
|
|
503
|
-
const props = child.props;
|
|
504
|
-
const hasNoProps = !props || Object.keys(props).length === 0;
|
|
505
|
-
const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
|
|
506
|
-
if (hasNoProps && hasSingleStringChild) {
|
|
507
|
-
return child.children[0];
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
return this.unwrapReactive(child);
|
|
511
|
-
}
|
|
512
|
-
return children.map((c) => this.unwrapReactive(c));
|
|
513
559
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
"'": "'"
|
|
521
|
-
};
|
|
522
|
-
return text.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
|
|
523
|
-
}
|
|
524
|
-
isSelfClosingTag(tagName) {
|
|
525
|
-
const selfClosingTags = /* @__PURE__ */ new Set([
|
|
526
|
-
"area",
|
|
527
|
-
"base",
|
|
528
|
-
"br",
|
|
529
|
-
"col",
|
|
530
|
-
"embed",
|
|
531
|
-
"hr",
|
|
532
|
-
"img",
|
|
533
|
-
"input",
|
|
534
|
-
"link",
|
|
535
|
-
"meta",
|
|
536
|
-
"param",
|
|
537
|
-
"source",
|
|
538
|
-
"track",
|
|
539
|
-
"wbr"
|
|
540
|
-
]);
|
|
541
|
-
return selfClosingTags.has(tagName.toLowerCase());
|
|
542
|
-
}
|
|
543
|
-
propsToAttributes(props, tagName) {
|
|
544
|
-
const attrs = [];
|
|
545
|
-
for (const key in props) {
|
|
546
|
-
if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref" || tagName === "textarea" && key === "value") {
|
|
547
|
-
continue;
|
|
548
|
-
}
|
|
549
|
-
let value = props[key];
|
|
550
|
-
value = this.resolveStateValue(value);
|
|
551
|
-
if (value == null || value === false) continue;
|
|
552
|
-
if (key.startsWith("on") && typeof value === "function") {
|
|
553
|
-
continue;
|
|
554
|
-
}
|
|
555
|
-
if (key === "className" || key === "class") {
|
|
556
|
-
const className = Array.isArray(value) ? value.join(" ") : value;
|
|
557
|
-
if (className) {
|
|
558
|
-
attrs.push(`class="${this.escapeHtml(String(className))}"`);
|
|
559
|
-
}
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
if (key === "style") {
|
|
563
|
-
const styleStr = this.styleToString(value);
|
|
564
|
-
if (styleStr) {
|
|
565
|
-
attrs.push(`style="${this.escapeHtml(styleStr)}"`);
|
|
566
|
-
}
|
|
567
|
-
continue;
|
|
568
|
-
}
|
|
569
|
-
if (value === true) {
|
|
570
|
-
attrs.push(key);
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
attrs.push(`${key}="${this.escapeHtml(String(value))}"`);
|
|
574
|
-
}
|
|
575
|
-
return attrs.join(" ");
|
|
560
|
+
if (head) {
|
|
561
|
+
html += head + nl;
|
|
562
|
+
}
|
|
563
|
+
html += `${indent}</head>${nl}${indent}<body`;
|
|
564
|
+
for (const key in bodyAttrs) {
|
|
565
|
+
html += ` ${key}="${escapeHtml(bodyAttrs[key])}"`;
|
|
576
566
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
567
|
+
html += `>${nl}`;
|
|
568
|
+
html += renderToString(vNode, { pretty, indent: 2 });
|
|
569
|
+
for (const script of scripts) {
|
|
570
|
+
html += `${indent2}<script`;
|
|
571
|
+
if (script.type) {
|
|
572
|
+
html += ` type="${escapeHtml(script.type)}"`;
|
|
580
573
|
}
|
|
581
|
-
if (
|
|
582
|
-
|
|
583
|
-
for (const key in style) {
|
|
584
|
-
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
585
|
-
styles2.push(`${cssKey}:${style[key]}`);
|
|
586
|
-
}
|
|
587
|
-
return styles2.join(";");
|
|
574
|
+
if (script.async) {
|
|
575
|
+
html += " async";
|
|
588
576
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
this.reactiveNodes.set(state, entry);
|
|
599
|
-
state.subscribe(() => {
|
|
600
|
-
if (entry.node && entry.node.parentNode) {
|
|
601
|
-
const newValue = renderFn(state.value);
|
|
602
|
-
entry.node.textContent = String(newValue ?? "");
|
|
603
|
-
}
|
|
604
|
-
});
|
|
577
|
+
if (script.defer) {
|
|
578
|
+
html += " defer";
|
|
579
|
+
}
|
|
580
|
+
if (script.src) {
|
|
581
|
+
html += ` src="${escapeHtml(script.src)}"></script>${nl}`;
|
|
582
|
+
} else if (script.content) {
|
|
583
|
+
html += `>${script.content}</script>${nl}`;
|
|
584
|
+
} else {
|
|
585
|
+
html += `></script>${nl}`;
|
|
605
586
|
}
|
|
606
|
-
return currentValue;
|
|
607
587
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
588
|
+
html += `${indent}</body>${nl}</html>`;
|
|
589
|
+
return html;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/client/dom/json.ts
|
|
593
|
+
function jsonToVNode(json, reactiveNodes) {
|
|
594
|
+
if (isState(json)) {
|
|
595
|
+
return createReactiveChild(json, reactiveNodes, (value) => value);
|
|
596
|
+
}
|
|
597
|
+
if (isPrimitiveJson(json)) {
|
|
598
|
+
return json;
|
|
599
|
+
}
|
|
600
|
+
const { tag, attributes = {}, children } = json;
|
|
601
|
+
const props = {};
|
|
602
|
+
for (const key in attributes) {
|
|
603
|
+
const value = attributes[key];
|
|
604
|
+
if (key === "class") {
|
|
605
|
+
props.className = isState(value) ? value.value : value;
|
|
606
|
+
} else {
|
|
607
|
+
props[key] = isState(value) ? value.value : value;
|
|
624
608
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
609
|
+
}
|
|
610
|
+
const childrenArray = [];
|
|
611
|
+
if (children != null) {
|
|
612
|
+
if (Array.isArray(children)) {
|
|
613
|
+
for (const child of children) {
|
|
614
|
+
if (isState(child)) {
|
|
615
|
+
childrenArray.push(createReactiveChild(child, reactiveNodes, (value) => value));
|
|
616
|
+
} else {
|
|
617
|
+
const converted = jsonToVNode(child, reactiveNodes);
|
|
618
|
+
if (converted != null && converted !== false) {
|
|
619
|
+
childrenArray.push(converted);
|
|
636
620
|
}
|
|
637
621
|
}
|
|
638
|
-
} else if (this.isState(children)) {
|
|
639
|
-
childrenArray.push(this.createReactiveChild(children, (v) => v));
|
|
640
|
-
} else if (typeof children === "object" && "tag" in children) {
|
|
641
|
-
const converted = this.jsonToVNode(children);
|
|
642
|
-
if (converted != null && converted !== false) {
|
|
643
|
-
childrenArray.push(converted);
|
|
644
|
-
}
|
|
645
|
-
} else {
|
|
646
|
-
childrenArray.push(children);
|
|
647
622
|
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
if (isPrimitiveJson(json)) {
|
|
656
|
-
return json;
|
|
657
|
-
}
|
|
658
|
-
const { tagName, props = {}, children = [] } = json;
|
|
659
|
-
const resolvedProps = {};
|
|
660
|
-
for (const key in props) {
|
|
661
|
-
const value = props[key];
|
|
662
|
-
resolvedProps[key] = this.isState(value) ? value.value : value;
|
|
663
|
-
}
|
|
664
|
-
const childrenArray = [];
|
|
665
|
-
for (const child of children) {
|
|
666
|
-
if (this.isState(child)) {
|
|
667
|
-
childrenArray.push(this.createReactiveChild(child, (v) => v));
|
|
668
|
-
} else {
|
|
669
|
-
const converted = this.vNodeJsonToVNode(child);
|
|
670
|
-
if (converted != null && converted !== false) {
|
|
671
|
-
childrenArray.push(converted);
|
|
672
|
-
}
|
|
623
|
+
} else if (isState(children)) {
|
|
624
|
+
childrenArray.push(createReactiveChild(children, reactiveNodes, (value) => value));
|
|
625
|
+
} else if (typeof children === "object" && children !== null && "tag" in children) {
|
|
626
|
+
const converted = jsonToVNode(children, reactiveNodes);
|
|
627
|
+
if (converted != null && converted !== false) {
|
|
628
|
+
childrenArray.push(converted);
|
|
673
629
|
}
|
|
630
|
+
} else {
|
|
631
|
+
childrenArray.push(children);
|
|
674
632
|
}
|
|
675
|
-
return { tagName, props: resolvedProps, children: childrenArray };
|
|
676
|
-
}
|
|
677
|
-
renderJson(rootElement, json) {
|
|
678
|
-
const vNode = this.jsonToVNode(json);
|
|
679
|
-
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
680
|
-
throw new Error("Invalid JSON structure");
|
|
681
|
-
}
|
|
682
|
-
return this.render(rootElement, vNode);
|
|
683
633
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
634
|
+
return { tagName: tag, props, children: childrenArray };
|
|
635
|
+
}
|
|
636
|
+
function vNodeJsonToVNode(json, reactiveNodes) {
|
|
637
|
+
if (isState(json)) {
|
|
638
|
+
return createReactiveChild(json, reactiveNodes, (value) => value);
|
|
639
|
+
}
|
|
640
|
+
if (isPrimitiveJson(json)) {
|
|
641
|
+
return json;
|
|
642
|
+
}
|
|
643
|
+
const { tagName, props = {}, children = [] } = json;
|
|
644
|
+
const resolvedProps = {};
|
|
645
|
+
for (const key in props) {
|
|
646
|
+
const value = props[key];
|
|
647
|
+
resolvedProps[key] = isState(value) ? value.value : value;
|
|
648
|
+
}
|
|
649
|
+
const childrenArray = [];
|
|
650
|
+
for (const child of children) {
|
|
651
|
+
if (isState(child)) {
|
|
652
|
+
childrenArray.push(createReactiveChild(child, reactiveNodes, (value) => value));
|
|
653
|
+
} else {
|
|
654
|
+
const converted = vNodeJsonToVNode(child, reactiveNodes);
|
|
655
|
+
if (converted != null && converted !== false) {
|
|
656
|
+
childrenArray.push(converted);
|
|
657
|
+
}
|
|
688
658
|
}
|
|
689
|
-
return this.render(rootElement, vNode);
|
|
690
659
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
660
|
+
return { tagName, props: resolvedProps, children: childrenArray };
|
|
661
|
+
}
|
|
662
|
+
function renderJson(rootElement, json, reactiveNodes) {
|
|
663
|
+
const vNode = jsonToVNode(json, reactiveNodes);
|
|
664
|
+
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
665
|
+
throw new Error("Invalid JSON structure");
|
|
694
666
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
667
|
+
return render(rootElement, vNode);
|
|
668
|
+
}
|
|
669
|
+
function renderVNode(rootElement, json, reactiveNodes) {
|
|
670
|
+
const vNode = vNodeJsonToVNode(json, reactiveNodes);
|
|
671
|
+
if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
|
|
672
|
+
throw new Error("Invalid VNode JSON structure");
|
|
698
673
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
674
|
+
return render(rootElement, vNode);
|
|
675
|
+
}
|
|
676
|
+
function renderJsonToString(json, reactiveNodes, options = {}) {
|
|
677
|
+
const vNode = jsonToVNode(json, reactiveNodes);
|
|
678
|
+
return renderToString(vNode, options);
|
|
679
|
+
}
|
|
680
|
+
function renderVNodeToString(json, reactiveNodes, options = {}) {
|
|
681
|
+
const vNode = vNodeJsonToVNode(json, reactiveNodes);
|
|
682
|
+
return renderToString(vNode, options);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// src/client/dom/state-utils.ts
|
|
686
|
+
function createState(initialValue, options = {}) {
|
|
687
|
+
let value = initialValue;
|
|
688
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
689
|
+
let updateTimer = null;
|
|
690
|
+
const { throttle = 0, deep = false } = options;
|
|
691
|
+
const notify = () => listeners.forEach((listener) => listener(value));
|
|
692
|
+
const scheduleUpdate = () => {
|
|
693
|
+
if (throttle > 0) {
|
|
694
|
+
if (!updateTimer) {
|
|
695
|
+
updateTimer = setTimeout(() => {
|
|
696
|
+
updateTimer = null;
|
|
697
|
+
notify();
|
|
698
|
+
}, throttle);
|
|
722
699
|
}
|
|
700
|
+
} else {
|
|
701
|
+
notify();
|
|
723
702
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
703
|
+
};
|
|
704
|
+
return {
|
|
705
|
+
get value() {
|
|
706
|
+
return value;
|
|
707
|
+
},
|
|
708
|
+
set value(newValue) {
|
|
709
|
+
const changed = deep ? JSON.stringify(value) !== JSON.stringify(newValue) : value !== newValue;
|
|
710
|
+
if (changed) {
|
|
711
|
+
value = newValue;
|
|
712
|
+
scheduleUpdate();
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
subscribe(fn) {
|
|
716
|
+
listeners.add(fn);
|
|
717
|
+
return () => listeners.delete(fn);
|
|
718
|
+
},
|
|
719
|
+
destroy() {
|
|
720
|
+
listeners.clear();
|
|
721
|
+
if (updateTimer) {
|
|
722
|
+
clearTimeout(updateTimer);
|
|
740
723
|
}
|
|
741
724
|
}
|
|
742
|
-
html += `${indent}</body>${nl}</html>`;
|
|
743
|
-
return html;
|
|
744
|
-
}
|
|
745
|
-
// Expose elementCache for reactive updates
|
|
746
|
-
getElementCache() {
|
|
747
|
-
return this.elementCache;
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
var dom = new DomNode();
|
|
751
|
-
var render = dom.render.bind(dom);
|
|
752
|
-
var renderToString = dom.renderToString.bind(dom);
|
|
753
|
-
|
|
754
|
-
// src/style.ts
|
|
755
|
-
var ELIT_SHARED_STYLE_STORE_KEY = "__elitSharedStyleStore__";
|
|
756
|
-
function createStyleStore() {
|
|
757
|
-
return {
|
|
758
|
-
variables: [],
|
|
759
|
-
rules: [],
|
|
760
|
-
mediaRules: [],
|
|
761
|
-
keyframes: [],
|
|
762
|
-
fontFaces: [],
|
|
763
|
-
imports: [],
|
|
764
|
-
containerRules: [],
|
|
765
|
-
supportsRules: [],
|
|
766
|
-
layerRules: [],
|
|
767
|
-
layerOrder: []
|
|
768
725
|
};
|
|
769
726
|
}
|
|
770
|
-
function
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
727
|
+
function computed(states, computeFn) {
|
|
728
|
+
const values = states.map((state) => state.value);
|
|
729
|
+
const result = createState(computeFn(...values));
|
|
730
|
+
states.forEach((state, index) => {
|
|
731
|
+
state.subscribe((newValue) => {
|
|
732
|
+
values[index] = newValue;
|
|
733
|
+
result.value = computeFn(...values);
|
|
734
|
+
});
|
|
735
|
+
});
|
|
736
|
+
return result;
|
|
776
737
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
738
|
+
function effect(stateFn) {
|
|
739
|
+
stateFn();
|
|
740
|
+
}
|
|
741
|
+
function createVirtualList(container2, items, renderItem, itemHeight = 50, bufferSize = 5) {
|
|
742
|
+
const viewportHeight = container2.clientHeight;
|
|
743
|
+
const totalHeight = items.length * itemHeight;
|
|
744
|
+
let scrollTop = 0;
|
|
745
|
+
const getVisibleRange = () => {
|
|
746
|
+
const start = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
|
|
747
|
+
const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
|
|
748
|
+
return { start, end };
|
|
749
|
+
};
|
|
750
|
+
const render3 = () => {
|
|
751
|
+
const { start, end } = getVisibleRange();
|
|
752
|
+
const wrapper = document.createElement("div");
|
|
753
|
+
wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
|
|
754
|
+
for (let i = start; i < end; i++) {
|
|
755
|
+
const itemEl = document.createElement("div");
|
|
756
|
+
itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
|
|
757
|
+
renderToDOM(renderItem(items[i], i), itemEl);
|
|
758
|
+
wrapper.appendChild(itemEl);
|
|
759
|
+
}
|
|
760
|
+
container2.innerHTML = "";
|
|
761
|
+
container2.appendChild(wrapper);
|
|
762
|
+
};
|
|
763
|
+
const scrollHandler = () => {
|
|
764
|
+
scrollTop = container2.scrollTop;
|
|
765
|
+
requestAnimationFrame(render3);
|
|
766
|
+
};
|
|
767
|
+
container2.addEventListener("scroll", scrollHandler);
|
|
768
|
+
render3();
|
|
769
|
+
return {
|
|
770
|
+
render: render3,
|
|
771
|
+
destroy: () => {
|
|
772
|
+
container2.removeEventListener("scroll", scrollHandler);
|
|
773
|
+
container2.innerHTML = "";
|
|
792
774
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function lazy(loadFn) {
|
|
778
|
+
let component = null;
|
|
779
|
+
let loading = false;
|
|
780
|
+
return async (...args) => {
|
|
781
|
+
if (!component && !loading) {
|
|
782
|
+
loading = true;
|
|
783
|
+
component = await loadFn();
|
|
784
|
+
loading = false;
|
|
785
|
+
}
|
|
786
|
+
return component ? component(...args) : { tagName: "div", props: { class: "loading" }, children: ["Loading..."] };
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// src/client/dom/index.ts
|
|
791
|
+
var DomNode = class {
|
|
792
|
+
constructor() {
|
|
793
|
+
this.elementCache = /* @__PURE__ */ new WeakMap();
|
|
794
|
+
this.reactiveNodes = /* @__PURE__ */ new Map();
|
|
803
795
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
const cssVar = {
|
|
807
|
-
name: name.startsWith("--") ? name : `--${name}`,
|
|
808
|
-
value,
|
|
809
|
-
toString() {
|
|
810
|
-
return `var(${this.name})`;
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
this.variables.push(cssVar);
|
|
814
|
-
return cssVar;
|
|
796
|
+
createElement(tagName, props = {}, children = []) {
|
|
797
|
+
return { tagName, props, children };
|
|
815
798
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
return fallback ? `var(${varName}, ${fallback})` : `var(${varName})`;
|
|
799
|
+
renderToDOM(vNode, parent) {
|
|
800
|
+
return renderToDOM(vNode, parent);
|
|
819
801
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
const rule = { selector: tag, styles: styles2, type: "tag" };
|
|
823
|
-
this.rules.push(rule);
|
|
824
|
-
return rule;
|
|
802
|
+
render(rootElement, vNode) {
|
|
803
|
+
return render(rootElement, vNode);
|
|
825
804
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const rule = { selector, styles: styles2, type: "class" };
|
|
829
|
-
this.rules.push(rule);
|
|
830
|
-
return rule;
|
|
805
|
+
batchRender(rootElement, vNodes) {
|
|
806
|
+
return batchRender(rootElement, vNodes);
|
|
831
807
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
const rule = { selector, styles: styles2, type: "id" };
|
|
835
|
-
this.rules.push(rule);
|
|
836
|
-
return rule;
|
|
808
|
+
renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
|
|
809
|
+
return renderChunked(rootElement, vNodes, chunkSize, onProgress);
|
|
837
810
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const pseudoClass = pseudo.startsWith(":") ? pseudo : `:${pseudo}`;
|
|
841
|
-
const selector = baseSelector ? `${baseSelector}${pseudoClass}` : pseudoClass;
|
|
842
|
-
const rule = { selector, styles: styles2, type: "pseudo-class" };
|
|
843
|
-
this.rules.push(rule);
|
|
844
|
-
return rule;
|
|
811
|
+
renderToHead(...vNodes) {
|
|
812
|
+
return renderToHead(...vNodes);
|
|
845
813
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
const selector = baseSelector ? `${baseSelector}${pseudoElement}` : pseudoElement;
|
|
849
|
-
const rule = { selector, styles: styles2, type: "pseudo-element" };
|
|
850
|
-
this.rules.push(rule);
|
|
851
|
-
return rule;
|
|
814
|
+
addStyle(cssText) {
|
|
815
|
+
return addStyle(cssText);
|
|
852
816
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
const attrSelector = attr.startsWith("[") ? attr : `[${attr}]`;
|
|
856
|
-
const selector = baseSelector ? `${baseSelector}${attrSelector}` : attrSelector;
|
|
857
|
-
const rule = { selector, styles: styles2, type: "attribute" };
|
|
858
|
-
this.rules.push(rule);
|
|
859
|
-
return rule;
|
|
817
|
+
addMeta(attrs) {
|
|
818
|
+
return addMeta(attrs);
|
|
860
819
|
}
|
|
861
|
-
|
|
862
|
-
return
|
|
820
|
+
addLink(attrs) {
|
|
821
|
+
return addLink(attrs);
|
|
863
822
|
}
|
|
864
|
-
|
|
865
|
-
return
|
|
823
|
+
setTitle(text) {
|
|
824
|
+
return setTitle(text);
|
|
866
825
|
}
|
|
867
|
-
|
|
868
|
-
|
|
826
|
+
// Reactive State Management
|
|
827
|
+
createState(initialValue, options = {}) {
|
|
828
|
+
return createState(initialValue, options);
|
|
869
829
|
}
|
|
870
|
-
|
|
871
|
-
return
|
|
830
|
+
computed(states, computeFn) {
|
|
831
|
+
return computed(states, computeFn);
|
|
872
832
|
}
|
|
873
|
-
|
|
874
|
-
|
|
833
|
+
effect(stateFn) {
|
|
834
|
+
effect(stateFn);
|
|
875
835
|
}
|
|
876
|
-
//
|
|
877
|
-
|
|
878
|
-
return
|
|
836
|
+
// Virtual scrolling helper for large lists
|
|
837
|
+
createVirtualList(container2, items, renderItem, itemHeight = 50, bufferSize = 5) {
|
|
838
|
+
return createVirtualList(container2, items, renderItem, itemHeight, bufferSize);
|
|
879
839
|
}
|
|
880
|
-
|
|
881
|
-
|
|
840
|
+
// Lazy load components
|
|
841
|
+
lazy(loadFn) {
|
|
842
|
+
return lazy(loadFn);
|
|
882
843
|
}
|
|
883
|
-
|
|
884
|
-
|
|
844
|
+
// Memory management - cleanup unused elements
|
|
845
|
+
cleanupUnusedElements(root) {
|
|
846
|
+
return cleanupUnusedElements(root, this.elementCache);
|
|
885
847
|
}
|
|
886
|
-
|
|
887
|
-
|
|
848
|
+
// Server-Side Rendering - convert VNode to HTML string
|
|
849
|
+
renderToString(vNode, options = {}) {
|
|
850
|
+
return renderToString(vNode, options);
|
|
888
851
|
}
|
|
889
|
-
|
|
890
|
-
return
|
|
852
|
+
jsonToVNode(json) {
|
|
853
|
+
return jsonToVNode(json, this.reactiveNodes);
|
|
891
854
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
const selector = name.startsWith("--") ? `&${name}` : `&--${name}`;
|
|
895
|
-
const rule = { selector, styles: styles2, type: "name" };
|
|
896
|
-
return rule;
|
|
855
|
+
vNodeJsonToVNode(json) {
|
|
856
|
+
return vNodeJsonToVNode(json, this.reactiveNodes);
|
|
897
857
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
return parentRule;
|
|
858
|
+
renderJson(rootElement, json) {
|
|
859
|
+
return renderJson(rootElement, json, this.reactiveNodes);
|
|
901
860
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
const keyframeSteps = Object.entries(steps).map(([step, styles2]) => ({
|
|
905
|
-
step: step === "from" ? "from" : step === "to" ? "to" : `${step}%`,
|
|
906
|
-
styles: styles2
|
|
907
|
-
}));
|
|
908
|
-
const kf = { name, steps: keyframeSteps };
|
|
909
|
-
this.keyframes.push(kf);
|
|
910
|
-
return kf;
|
|
861
|
+
renderVNode(rootElement, json) {
|
|
862
|
+
return renderVNode(rootElement, json, this.reactiveNodes);
|
|
911
863
|
}
|
|
912
|
-
|
|
913
|
-
return
|
|
864
|
+
renderJsonToString(json, options = {}) {
|
|
865
|
+
return renderJsonToString(json, this.reactiveNodes, options);
|
|
914
866
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
this.fontFaces.push(options);
|
|
918
|
-
return options;
|
|
867
|
+
renderVNodeToString(json, options = {}) {
|
|
868
|
+
return renderVNodeToString(json, this.reactiveNodes, options);
|
|
919
869
|
}
|
|
920
|
-
//
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
this.imports.push(importRule);
|
|
924
|
-
return importRule;
|
|
870
|
+
// Generate complete HTML document as string (for SSR)
|
|
871
|
+
renderToHTMLDocument(vNode, options = {}) {
|
|
872
|
+
return renderToHTMLDocument(vNode, options);
|
|
925
873
|
}
|
|
926
|
-
//
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
this.mediaRules.push(mediaRule);
|
|
930
|
-
return mediaRule;
|
|
874
|
+
// Expose elementCache for reactive updates
|
|
875
|
+
getElementCache() {
|
|
876
|
+
return this.elementCache;
|
|
931
877
|
}
|
|
932
|
-
|
|
933
|
-
|
|
878
|
+
};
|
|
879
|
+
var dom = new DomNode();
|
|
880
|
+
var render2 = dom.render.bind(dom);
|
|
881
|
+
var renderToString2 = dom.renderToString.bind(dom);
|
|
882
|
+
|
|
883
|
+
// src/client/style/condition-utils.ts
|
|
884
|
+
function splitConditionalClauses(value, operator) {
|
|
885
|
+
const clauses = [];
|
|
886
|
+
let token = "";
|
|
887
|
+
let depth = 0;
|
|
888
|
+
for (let index = 0; index < value.length; index++) {
|
|
889
|
+
const char = value[index];
|
|
890
|
+
if (char === "(") {
|
|
891
|
+
depth += 1;
|
|
892
|
+
} else if (char === ")" && depth > 0) {
|
|
893
|
+
depth -= 1;
|
|
894
|
+
}
|
|
895
|
+
const operatorToken = ` ${operator} `;
|
|
896
|
+
if (depth === 0 && value.slice(index, index + operatorToken.length).toLowerCase() === operatorToken) {
|
|
897
|
+
const trimmed = token.trim();
|
|
898
|
+
if (trimmed) {
|
|
899
|
+
clauses.push(trimmed);
|
|
900
|
+
}
|
|
901
|
+
token = "";
|
|
902
|
+
index += operatorToken.length - 1;
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
token += char;
|
|
906
|
+
}
|
|
907
|
+
const trailing = token.trim();
|
|
908
|
+
if (trailing) {
|
|
909
|
+
clauses.push(trailing);
|
|
910
|
+
}
|
|
911
|
+
return clauses;
|
|
912
|
+
}
|
|
913
|
+
function matchesSupportsDeclaration(property, value) {
|
|
914
|
+
const normalizedProperty = property.trim().toLowerCase();
|
|
915
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
916
|
+
const supportedProperties = /* @__PURE__ */ new Set([
|
|
917
|
+
"align-items",
|
|
918
|
+
"background",
|
|
919
|
+
"background-color",
|
|
920
|
+
"backdrop-filter",
|
|
921
|
+
"border",
|
|
922
|
+
"border-radius",
|
|
923
|
+
"box-shadow",
|
|
924
|
+
"color",
|
|
925
|
+
"column-gap",
|
|
926
|
+
"container-name",
|
|
927
|
+
"container-type",
|
|
928
|
+
"display",
|
|
929
|
+
"flex",
|
|
930
|
+
"flex-direction",
|
|
931
|
+
"flex-grow",
|
|
932
|
+
"flex-wrap",
|
|
933
|
+
"font-family",
|
|
934
|
+
"font-size",
|
|
935
|
+
"font-weight",
|
|
936
|
+
"gap",
|
|
937
|
+
"grid-template-columns",
|
|
938
|
+
"height",
|
|
939
|
+
"justify-content",
|
|
940
|
+
"letter-spacing",
|
|
941
|
+
"line-height",
|
|
942
|
+
"margin",
|
|
943
|
+
"margin-bottom",
|
|
944
|
+
"margin-left",
|
|
945
|
+
"margin-right",
|
|
946
|
+
"margin-top",
|
|
947
|
+
"max-height",
|
|
948
|
+
"max-width",
|
|
949
|
+
"min-height",
|
|
950
|
+
"min-width",
|
|
951
|
+
"padding",
|
|
952
|
+
"padding-bottom",
|
|
953
|
+
"padding-end",
|
|
954
|
+
"padding-horizontal",
|
|
955
|
+
"padding-left",
|
|
956
|
+
"padding-right",
|
|
957
|
+
"padding-start",
|
|
958
|
+
"padding-top",
|
|
959
|
+
"padding-vertical",
|
|
960
|
+
"row-gap",
|
|
961
|
+
"text-align",
|
|
962
|
+
"text-decoration",
|
|
963
|
+
"text-transform",
|
|
964
|
+
"width"
|
|
965
|
+
]);
|
|
966
|
+
if (!supportedProperties.has(normalizedProperty)) {
|
|
967
|
+
return false;
|
|
934
968
|
}
|
|
935
|
-
|
|
936
|
-
return
|
|
969
|
+
if (normalizedProperty === "display") {
|
|
970
|
+
return (/* @__PURE__ */ new Set(["block", "flex", "grid", "inline", "inline-block", "inline-flex", "inline-grid"])).has(normalizedValue);
|
|
937
971
|
}
|
|
938
|
-
|
|
939
|
-
return
|
|
972
|
+
if (normalizedProperty === "backdrop-filter") {
|
|
973
|
+
return /blur\(/.test(normalizedValue);
|
|
940
974
|
}
|
|
941
|
-
|
|
942
|
-
return
|
|
975
|
+
if (normalizedProperty === "container-type") {
|
|
976
|
+
return (/* @__PURE__ */ new Set(["inline-size", "size"])).has(normalizedValue);
|
|
943
977
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
978
|
+
return true;
|
|
979
|
+
}
|
|
980
|
+
function matchesSupportsCondition(condition) {
|
|
981
|
+
const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim();
|
|
982
|
+
if (!normalized) {
|
|
983
|
+
return true;
|
|
948
984
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
this.mediaRules.push(mediaRule);
|
|
952
|
-
return mediaRule;
|
|
985
|
+
if (normalized.toLowerCase().startsWith("not ")) {
|
|
986
|
+
return !matchesSupportsCondition(normalized.slice(4));
|
|
953
987
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
return mediaRule;
|
|
988
|
+
const orClauses = splitConditionalClauses(normalized, "or");
|
|
989
|
+
if (orClauses.length > 1) {
|
|
990
|
+
return orClauses.some((clause) => matchesSupportsCondition(clause));
|
|
958
991
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
this.containerRules.push(containerRule);
|
|
963
|
-
return containerRule;
|
|
992
|
+
const andClauses = splitConditionalClauses(normalized, "and");
|
|
993
|
+
if (andClauses.length > 1) {
|
|
994
|
+
return andClauses.every((clause) => matchesSupportsCondition(clause));
|
|
964
995
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
return
|
|
996
|
+
const declarationMatch = normalized.match(/^([a-z-]+)\s*:\s*(.+)$/i);
|
|
997
|
+
if (!declarationMatch) {
|
|
998
|
+
return false;
|
|
968
999
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1000
|
+
return matchesSupportsDeclaration(declarationMatch[1], declarationMatch[2]);
|
|
1001
|
+
}
|
|
1002
|
+
function findMatchingContainerTarget(ancestors, name) {
|
|
1003
|
+
const normalizedName = typeof name === "string" && name.trim() ? name.trim().toLowerCase() : void 0;
|
|
1004
|
+
for (let index = ancestors.length - 1; index >= 0; index--) {
|
|
1005
|
+
const ancestor = ancestors[index];
|
|
1006
|
+
if (!ancestor?.isContainer || ancestor.containerWidth === void 0) {
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
if (!normalizedName) {
|
|
1010
|
+
return ancestor;
|
|
1011
|
+
}
|
|
1012
|
+
if ((ancestor.containerNames ?? []).includes(normalizedName)) {
|
|
1013
|
+
return ancestor;
|
|
1014
|
+
}
|
|
974
1015
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1016
|
+
return void 0;
|
|
1017
|
+
}
|
|
1018
|
+
function matchesContainerCondition(condition, containerWidth) {
|
|
1019
|
+
const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
|
|
1020
|
+
if (!normalized) {
|
|
1021
|
+
return true;
|
|
978
1022
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
this.layerRules.push(layerRule);
|
|
982
|
-
return layerRule;
|
|
1023
|
+
if (normalized.startsWith("not ")) {
|
|
1024
|
+
return !matchesContainerCondition(normalized.slice(4), containerWidth);
|
|
983
1025
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
const rule = { selector, styles: styles2, type: "custom" };
|
|
988
|
-
this.rules.push(rule);
|
|
989
|
-
return rule;
|
|
990
|
-
});
|
|
991
|
-
return cssRules;
|
|
1026
|
+
const orClauses = splitConditionalClauses(normalized, "or");
|
|
1027
|
+
if (orClauses.length > 1) {
|
|
1028
|
+
return orClauses.some((clause) => matchesContainerCondition(clause, containerWidth));
|
|
992
1029
|
}
|
|
993
|
-
|
|
994
|
-
|
|
1030
|
+
const andClauses = splitConditionalClauses(normalized, "and");
|
|
1031
|
+
if (andClauses.length > 1) {
|
|
1032
|
+
return andClauses.every((clause) => matchesContainerCondition(clause, containerWidth));
|
|
995
1033
|
}
|
|
996
|
-
|
|
997
|
-
|
|
1034
|
+
if (normalized.startsWith("min-width:")) {
|
|
1035
|
+
const minWidth = parseMediaLength(normalized.slice("min-width:".length));
|
|
1036
|
+
return minWidth !== void 0 && containerWidth >= minWidth;
|
|
998
1037
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1038
|
+
if (normalized.startsWith("max-width:")) {
|
|
1039
|
+
const maxWidth = parseMediaLength(normalized.slice("max-width:".length));
|
|
1040
|
+
return maxWidth !== void 0 && containerWidth <= maxWidth;
|
|
1041
|
+
}
|
|
1042
|
+
return false;
|
|
1043
|
+
}
|
|
1044
|
+
function parseMediaLength(value) {
|
|
1045
|
+
const match = value.trim().match(/^(-?\d+(?:\.\d+)?)(px|rem|em)?$/i);
|
|
1046
|
+
if (!match) {
|
|
1047
|
+
return void 0;
|
|
1048
|
+
}
|
|
1049
|
+
const numericValue = Number(match[1]);
|
|
1050
|
+
const unit = (match[2] ?? "px").toLowerCase();
|
|
1051
|
+
if (unit === "rem" || unit === "em") {
|
|
1052
|
+
return numericValue * 16;
|
|
1053
|
+
}
|
|
1054
|
+
return numericValue;
|
|
1055
|
+
}
|
|
1056
|
+
function matchesMediaCondition(condition, options) {
|
|
1057
|
+
const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
|
|
1058
|
+
if (!normalized) {
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
1061
|
+
if (normalized.startsWith("min-width:")) {
|
|
1062
|
+
const minWidth = parseMediaLength(normalized.slice("min-width:".length));
|
|
1063
|
+
return minWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth >= minWidth;
|
|
1064
|
+
}
|
|
1065
|
+
if (normalized.startsWith("max-width:")) {
|
|
1066
|
+
const maxWidth = parseMediaLength(normalized.slice("max-width:".length));
|
|
1067
|
+
return maxWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth <= maxWidth;
|
|
1068
|
+
}
|
|
1069
|
+
if (normalized === "prefers-color-scheme: dark") {
|
|
1070
|
+
return options.colorScheme === "dark";
|
|
1071
|
+
}
|
|
1072
|
+
if (normalized === "prefers-color-scheme: light") {
|
|
1073
|
+
return (options.colorScheme ?? "light") === "light";
|
|
1074
|
+
}
|
|
1075
|
+
if (normalized === "prefers-reduced-motion: reduce") {
|
|
1076
|
+
return options.reducedMotion === true;
|
|
1077
|
+
}
|
|
1078
|
+
return false;
|
|
1079
|
+
}
|
|
1080
|
+
function matchesMediaRule(rule, options) {
|
|
1081
|
+
const mediaType = options.mediaType ?? "screen";
|
|
1082
|
+
if (rule.type && rule.type !== mediaType && rule.type !== "all") {
|
|
1083
|
+
return false;
|
|
1084
|
+
}
|
|
1085
|
+
if (!rule.condition.trim()) {
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
return rule.condition.split(/\band\b/i).map((part) => part.trim()).filter(Boolean).every((part) => matchesMediaCondition(part, options));
|
|
1089
|
+
}
|
|
1090
|
+
function getOrderedLayerNames(layerOrder2, layerRules) {
|
|
1091
|
+
const orderedLayerNames = [];
|
|
1092
|
+
for (const layerName of layerOrder2) {
|
|
1093
|
+
const normalizedName = layerName.trim();
|
|
1094
|
+
if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
|
|
1095
|
+
orderedLayerNames.push(normalizedName);
|
|
1018
1096
|
}
|
|
1019
|
-
return resolved.replace(/\s*!important\s*$/i, "").trim();
|
|
1020
1097
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
Object.entries(target.attributes).filter(([, value]) => value !== void 0 && value !== null && value !== false).map(([name, value]) => [name.toLowerCase(), String(value)])
|
|
1027
|
-
) : {},
|
|
1028
|
-
pseudoStates: Array.isArray(target.pseudoStates) ? [...new Set(target.pseudoStates.map((pseudoState) => pseudoState.trim().toLowerCase()).filter(Boolean))] : [],
|
|
1029
|
-
childIndex: typeof target.childIndex === "number" && Number.isFinite(target.childIndex) ? target.childIndex : void 0,
|
|
1030
|
-
siblingCount: typeof target.siblingCount === "number" && Number.isFinite(target.siblingCount) ? target.siblingCount : void 0,
|
|
1031
|
-
sameTypeIndex: typeof target.sameTypeIndex === "number" && Number.isFinite(target.sameTypeIndex) ? target.sameTypeIndex : void 0,
|
|
1032
|
-
sameTypeCount: typeof target.sameTypeCount === "number" && Number.isFinite(target.sameTypeCount) ? target.sameTypeCount : void 0,
|
|
1033
|
-
containerNames: Array.isArray(target.containerNames) ? [...new Set(target.containerNames.map((containerName) => containerName.trim().toLowerCase()).filter(Boolean))] : [],
|
|
1034
|
-
containerWidth: typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth) ? target.containerWidth : void 0,
|
|
1035
|
-
isContainer: target.isContainer === true,
|
|
1036
|
-
isScopeReference: target.isScopeReference === true
|
|
1037
|
-
};
|
|
1098
|
+
for (const layerRule of layerRules) {
|
|
1099
|
+
const normalizedName = layerRule.name.trim();
|
|
1100
|
+
if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
|
|
1101
|
+
orderedLayerNames.push(normalizedName);
|
|
1102
|
+
}
|
|
1038
1103
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1104
|
+
return orderedLayerNames;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// src/client/style/selector-parser.ts
|
|
1108
|
+
function splitSelectorList(value) {
|
|
1109
|
+
const selectors = [];
|
|
1110
|
+
let token = "";
|
|
1111
|
+
let attributeDepth = 0;
|
|
1112
|
+
let parenthesisDepth = 0;
|
|
1113
|
+
let quoted;
|
|
1114
|
+
for (let index = 0; index < value.length; index++) {
|
|
1115
|
+
const char = value[index];
|
|
1116
|
+
if (quoted) {
|
|
1117
|
+
token += char;
|
|
1118
|
+
if (char === quoted && value[index - 1] !== "\\") {
|
|
1119
|
+
quoted = void 0;
|
|
1120
|
+
}
|
|
1121
|
+
continue;
|
|
1043
1122
|
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1123
|
+
if (char === '"' || char === "'") {
|
|
1124
|
+
quoted = char;
|
|
1125
|
+
token += char;
|
|
1126
|
+
continue;
|
|
1127
|
+
}
|
|
1128
|
+
if (char === "[") {
|
|
1129
|
+
attributeDepth += 1;
|
|
1130
|
+
token += char;
|
|
1131
|
+
continue;
|
|
1132
|
+
}
|
|
1133
|
+
if (char === "]" && attributeDepth > 0) {
|
|
1134
|
+
attributeDepth -= 1;
|
|
1135
|
+
token += char;
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
if (attributeDepth === 0 && char === "(") {
|
|
1139
|
+
parenthesisDepth += 1;
|
|
1140
|
+
token += char;
|
|
1141
|
+
continue;
|
|
1142
|
+
}
|
|
1143
|
+
if (attributeDepth === 0 && char === ")" && parenthesisDepth > 0) {
|
|
1144
|
+
parenthesisDepth -= 1;
|
|
1145
|
+
token += char;
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
if (attributeDepth === 0 && parenthesisDepth === 0 && char === ",") {
|
|
1149
|
+
const trimmed = token.trim();
|
|
1150
|
+
if (trimmed) {
|
|
1151
|
+
selectors.push(trimmed);
|
|
1152
|
+
}
|
|
1153
|
+
token = "";
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
token += char;
|
|
1055
1157
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1158
|
+
const trailing = token.trim();
|
|
1159
|
+
if (trailing) {
|
|
1160
|
+
selectors.push(trailing);
|
|
1161
|
+
}
|
|
1162
|
+
return selectors;
|
|
1163
|
+
}
|
|
1164
|
+
function parsePseudoSelectorToken(token, startIndex) {
|
|
1165
|
+
if (token[startIndex] !== ":" || token[startIndex + 1] === ":") {
|
|
1166
|
+
return void 0;
|
|
1167
|
+
}
|
|
1168
|
+
let cursor = startIndex + 1;
|
|
1169
|
+
const nameMatch = token.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1170
|
+
if (!nameMatch) {
|
|
1171
|
+
return void 0;
|
|
1172
|
+
}
|
|
1173
|
+
const pseudoName = nameMatch[1].toLowerCase();
|
|
1174
|
+
cursor += nameMatch[0].length;
|
|
1175
|
+
if (token[cursor] !== "(") {
|
|
1176
|
+
return { value: pseudoName, nextIndex: cursor };
|
|
1177
|
+
}
|
|
1178
|
+
const argumentStart = cursor + 1;
|
|
1179
|
+
let attributeDepth = 0;
|
|
1180
|
+
let parenthesisDepth = 1;
|
|
1181
|
+
let quoted;
|
|
1182
|
+
cursor += 1;
|
|
1183
|
+
while (cursor < token.length) {
|
|
1184
|
+
const char = token[cursor];
|
|
1185
|
+
if (quoted) {
|
|
1186
|
+
if (char === quoted && token[cursor - 1] !== "\\") {
|
|
1187
|
+
quoted = void 0;
|
|
1188
|
+
}
|
|
1189
|
+
cursor += 1;
|
|
1190
|
+
continue;
|
|
1191
|
+
}
|
|
1192
|
+
if (char === '"' || char === "'") {
|
|
1193
|
+
quoted = char;
|
|
1194
|
+
cursor += 1;
|
|
1195
|
+
continue;
|
|
1063
1196
|
}
|
|
1197
|
+
if (char === "[") {
|
|
1198
|
+
attributeDepth += 1;
|
|
1199
|
+
cursor += 1;
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
if (char === "]" && attributeDepth > 0) {
|
|
1203
|
+
attributeDepth -= 1;
|
|
1204
|
+
cursor += 1;
|
|
1205
|
+
continue;
|
|
1206
|
+
}
|
|
1207
|
+
if (attributeDepth === 0 && char === "(") {
|
|
1208
|
+
parenthesisDepth += 1;
|
|
1209
|
+
cursor += 1;
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
if (attributeDepth === 0 && char === ")") {
|
|
1213
|
+
parenthesisDepth -= 1;
|
|
1214
|
+
if (parenthesisDepth === 0) {
|
|
1215
|
+
const pseudoArgument = token.slice(argumentStart, cursor).trim();
|
|
1216
|
+
return {
|
|
1217
|
+
value: pseudoArgument.length > 0 ? `${pseudoName}(${pseudoArgument})` : `${pseudoName}()`,
|
|
1218
|
+
nextIndex: cursor + 1
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
cursor += 1;
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
cursor += 1;
|
|
1064
1225
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1226
|
+
return void 0;
|
|
1227
|
+
}
|
|
1228
|
+
function parseSimpleSelectorToken(token) {
|
|
1229
|
+
const trimmed = token.trim();
|
|
1230
|
+
if (!trimmed || /[*&]/.test(trimmed)) {
|
|
1231
|
+
return void 0;
|
|
1232
|
+
}
|
|
1233
|
+
let cursor = 0;
|
|
1234
|
+
let tagName;
|
|
1235
|
+
let idName;
|
|
1236
|
+
const classNames = [];
|
|
1237
|
+
const attributes = [];
|
|
1238
|
+
const pseudoClasses = [];
|
|
1239
|
+
const tagMatch = trimmed.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1240
|
+
if (tagMatch) {
|
|
1241
|
+
tagName = tagMatch[1].toLowerCase();
|
|
1242
|
+
cursor += tagMatch[0].length;
|
|
1243
|
+
}
|
|
1244
|
+
while (cursor < trimmed.length) {
|
|
1245
|
+
const char = trimmed[cursor];
|
|
1246
|
+
if (char === ".") {
|
|
1247
|
+
const classMatch = trimmed.slice(cursor).match(/^\.([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1248
|
+
if (!classMatch) {
|
|
1249
|
+
return void 0;
|
|
1075
1250
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
continue;
|
|
1251
|
+
classNames.push(classMatch[1]);
|
|
1252
|
+
cursor += classMatch[0].length;
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
if (char === "#") {
|
|
1256
|
+
const idMatch = trimmed.slice(cursor).match(/^#([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1257
|
+
if (!idMatch || idName) {
|
|
1258
|
+
return void 0;
|
|
1085
1259
|
}
|
|
1086
|
-
|
|
1260
|
+
idName = idMatch[1];
|
|
1261
|
+
cursor += idMatch[0].length;
|
|
1262
|
+
continue;
|
|
1263
|
+
}
|
|
1264
|
+
if (char === "[") {
|
|
1265
|
+
const endIndex = trimmed.indexOf("]", cursor + 1);
|
|
1266
|
+
if (endIndex === -1) {
|
|
1267
|
+
return void 0;
|
|
1268
|
+
}
|
|
1269
|
+
const rawAttribute = trimmed.slice(cursor + 1, endIndex).trim();
|
|
1270
|
+
const attrMatch = rawAttribute.match(/^([_a-zA-Z][-_a-zA-Z0-9]*)(?:\s*(=|~=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+)))?$/);
|
|
1271
|
+
if (!attrMatch) {
|
|
1272
|
+
return void 0;
|
|
1273
|
+
}
|
|
1274
|
+
attributes.push({
|
|
1275
|
+
name: attrMatch[1].toLowerCase(),
|
|
1276
|
+
operator: attrMatch[2],
|
|
1277
|
+
value: attrMatch[3] ?? attrMatch[4] ?? attrMatch[5]
|
|
1278
|
+
});
|
|
1279
|
+
cursor = endIndex + 1;
|
|
1280
|
+
continue;
|
|
1087
1281
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1282
|
+
if (char === ":") {
|
|
1283
|
+
const pseudoToken = parsePseudoSelectorToken(trimmed, cursor);
|
|
1284
|
+
if (!pseudoToken) {
|
|
1285
|
+
return void 0;
|
|
1286
|
+
}
|
|
1287
|
+
pseudoClasses.push(pseudoToken.value);
|
|
1288
|
+
cursor = pseudoToken.nextIndex;
|
|
1289
|
+
continue;
|
|
1091
1290
|
}
|
|
1092
|
-
return
|
|
1291
|
+
return void 0;
|
|
1093
1292
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1293
|
+
if (!tagName && !idName && classNames.length === 0 && attributes.length === 0 && pseudoClasses.length === 0) {
|
|
1294
|
+
return void 0;
|
|
1295
|
+
}
|
|
1296
|
+
return { tagName, idName, classNames, attributes, pseudoClasses };
|
|
1297
|
+
}
|
|
1298
|
+
function extractSupportedSelectorChains(selector, parsedSelectorChainCache) {
|
|
1299
|
+
const cached = parsedSelectorChainCache.get(selector);
|
|
1300
|
+
if (cached) {
|
|
1301
|
+
return cached;
|
|
1302
|
+
}
|
|
1303
|
+
const parsedChains = splitSelectorList(selector).map((segment) => segment.trim()).map((segment) => {
|
|
1304
|
+
const chain = [];
|
|
1096
1305
|
let token = "";
|
|
1306
|
+
let combinator = "descendant";
|
|
1307
|
+
let invalid = false;
|
|
1097
1308
|
let attributeDepth = 0;
|
|
1098
1309
|
let parenthesisDepth = 0;
|
|
1099
1310
|
let quoted;
|
|
1100
|
-
|
|
1101
|
-
const
|
|
1311
|
+
const flushToken = () => {
|
|
1312
|
+
const trimmedToken = token.trim();
|
|
1313
|
+
token = "";
|
|
1314
|
+
if (!trimmedToken || invalid) {
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
const parsed = parseSimpleSelectorToken(trimmedToken);
|
|
1318
|
+
if (!parsed) {
|
|
1319
|
+
invalid = true;
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
if (chain.length > 0) {
|
|
1323
|
+
parsed.combinator = combinator;
|
|
1324
|
+
}
|
|
1325
|
+
chain.push(parsed);
|
|
1326
|
+
combinator = "descendant";
|
|
1327
|
+
};
|
|
1328
|
+
for (let index = 0; index < segment.length; index++) {
|
|
1329
|
+
const char = segment[index];
|
|
1102
1330
|
if (quoted) {
|
|
1103
1331
|
token += char;
|
|
1104
|
-
if (char === quoted &&
|
|
1332
|
+
if (char === quoted && segment[index - 1] !== "\\") {
|
|
1105
1333
|
quoted = void 0;
|
|
1106
1334
|
}
|
|
1107
1335
|
continue;
|
|
@@ -1116,8 +1344,10 @@
|
|
|
1116
1344
|
token += char;
|
|
1117
1345
|
continue;
|
|
1118
1346
|
}
|
|
1119
|
-
if (char === "]"
|
|
1120
|
-
attributeDepth
|
|
1347
|
+
if (char === "]") {
|
|
1348
|
+
if (attributeDepth > 0) {
|
|
1349
|
+
attributeDepth -= 1;
|
|
1350
|
+
}
|
|
1121
1351
|
token += char;
|
|
1122
1352
|
continue;
|
|
1123
1353
|
}
|
|
@@ -1131,374 +1361,159 @@
|
|
|
1131
1361
|
token += char;
|
|
1132
1362
|
continue;
|
|
1133
1363
|
}
|
|
1134
|
-
if (attributeDepth === 0 && parenthesisDepth === 0 && char === "
|
|
1135
|
-
|
|
1136
|
-
if (
|
|
1137
|
-
|
|
1138
|
-
}
|
|
1139
|
-
token = "";
|
|
1140
|
-
continue;
|
|
1141
|
-
}
|
|
1142
|
-
token += char;
|
|
1143
|
-
}
|
|
1144
|
-
const trailing = token.trim();
|
|
1145
|
-
if (trailing) {
|
|
1146
|
-
selectors.push(trailing);
|
|
1147
|
-
}
|
|
1148
|
-
return selectors;
|
|
1149
|
-
}
|
|
1150
|
-
parsePseudoSelectorToken(token, startIndex) {
|
|
1151
|
-
if (token[startIndex] !== ":" || token[startIndex + 1] === ":") {
|
|
1152
|
-
return void 0;
|
|
1153
|
-
}
|
|
1154
|
-
let cursor = startIndex + 1;
|
|
1155
|
-
const nameMatch = token.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1156
|
-
if (!nameMatch) {
|
|
1157
|
-
return void 0;
|
|
1158
|
-
}
|
|
1159
|
-
const pseudoName = nameMatch[1].toLowerCase();
|
|
1160
|
-
cursor += nameMatch[0].length;
|
|
1161
|
-
if (token[cursor] !== "(") {
|
|
1162
|
-
return { value: pseudoName, nextIndex: cursor };
|
|
1163
|
-
}
|
|
1164
|
-
const argumentStart = cursor + 1;
|
|
1165
|
-
let attributeDepth = 0;
|
|
1166
|
-
let parenthesisDepth = 1;
|
|
1167
|
-
let quoted;
|
|
1168
|
-
cursor += 1;
|
|
1169
|
-
while (cursor < token.length) {
|
|
1170
|
-
const char = token[cursor];
|
|
1171
|
-
if (quoted) {
|
|
1172
|
-
if (char === quoted && token[cursor - 1] !== "\\") {
|
|
1173
|
-
quoted = void 0;
|
|
1364
|
+
if (attributeDepth === 0 && parenthesisDepth === 0 && (char === ">" || char === "+" || char === "~")) {
|
|
1365
|
+
flushToken();
|
|
1366
|
+
if (invalid) {
|
|
1367
|
+
break;
|
|
1174
1368
|
}
|
|
1175
|
-
|
|
1369
|
+
combinator = char === ">" ? "child" : char === "+" ? "adjacent-sibling" : "general-sibling";
|
|
1176
1370
|
continue;
|
|
1177
1371
|
}
|
|
1178
|
-
if (
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
}
|
|
1183
|
-
if (char === "[") {
|
|
1184
|
-
attributeDepth += 1;
|
|
1185
|
-
cursor += 1;
|
|
1186
|
-
continue;
|
|
1187
|
-
}
|
|
1188
|
-
if (char === "]" && attributeDepth > 0) {
|
|
1189
|
-
attributeDepth -= 1;
|
|
1190
|
-
cursor += 1;
|
|
1191
|
-
continue;
|
|
1192
|
-
}
|
|
1193
|
-
if (attributeDepth === 0 && char === "(") {
|
|
1194
|
-
parenthesisDepth += 1;
|
|
1195
|
-
cursor += 1;
|
|
1196
|
-
continue;
|
|
1197
|
-
}
|
|
1198
|
-
if (attributeDepth === 0 && char === ")") {
|
|
1199
|
-
parenthesisDepth -= 1;
|
|
1200
|
-
if (parenthesisDepth === 0) {
|
|
1201
|
-
const pseudoArgument = token.slice(argumentStart, cursor).trim();
|
|
1202
|
-
return {
|
|
1203
|
-
value: pseudoArgument.length > 0 ? `${pseudoName}(${pseudoArgument})` : `${pseudoName}()`,
|
|
1204
|
-
nextIndex: cursor + 1
|
|
1205
|
-
};
|
|
1372
|
+
if (attributeDepth === 0 && parenthesisDepth === 0 && /\s/.test(char)) {
|
|
1373
|
+
flushToken();
|
|
1374
|
+
if (invalid) {
|
|
1375
|
+
break;
|
|
1206
1376
|
}
|
|
1207
|
-
cursor += 1;
|
|
1208
1377
|
continue;
|
|
1209
1378
|
}
|
|
1210
|
-
|
|
1211
|
-
}
|
|
1212
|
-
return void 0;
|
|
1213
|
-
}
|
|
1214
|
-
matchesSupportsDeclaration(property, value) {
|
|
1215
|
-
const normalizedProperty = property.trim().toLowerCase();
|
|
1216
|
-
const normalizedValue = value.trim().toLowerCase();
|
|
1217
|
-
const supportedProperties = /* @__PURE__ */ new Set([
|
|
1218
|
-
"align-items",
|
|
1219
|
-
"background",
|
|
1220
|
-
"background-color",
|
|
1221
|
-
"backdrop-filter",
|
|
1222
|
-
"border",
|
|
1223
|
-
"border-radius",
|
|
1224
|
-
"box-shadow",
|
|
1225
|
-
"color",
|
|
1226
|
-
"column-gap",
|
|
1227
|
-
"container-name",
|
|
1228
|
-
"container-type",
|
|
1229
|
-
"display",
|
|
1230
|
-
"flex",
|
|
1231
|
-
"flex-direction",
|
|
1232
|
-
"flex-grow",
|
|
1233
|
-
"flex-wrap",
|
|
1234
|
-
"font-family",
|
|
1235
|
-
"font-size",
|
|
1236
|
-
"font-weight",
|
|
1237
|
-
"gap",
|
|
1238
|
-
"grid-template-columns",
|
|
1239
|
-
"height",
|
|
1240
|
-
"justify-content",
|
|
1241
|
-
"letter-spacing",
|
|
1242
|
-
"line-height",
|
|
1243
|
-
"margin",
|
|
1244
|
-
"margin-bottom",
|
|
1245
|
-
"margin-left",
|
|
1246
|
-
"margin-right",
|
|
1247
|
-
"margin-top",
|
|
1248
|
-
"max-height",
|
|
1249
|
-
"max-width",
|
|
1250
|
-
"min-height",
|
|
1251
|
-
"min-width",
|
|
1252
|
-
"padding",
|
|
1253
|
-
"padding-bottom",
|
|
1254
|
-
"padding-end",
|
|
1255
|
-
"padding-horizontal",
|
|
1256
|
-
"padding-left",
|
|
1257
|
-
"padding-right",
|
|
1258
|
-
"padding-start",
|
|
1259
|
-
"padding-top",
|
|
1260
|
-
"padding-vertical",
|
|
1261
|
-
"row-gap",
|
|
1262
|
-
"text-align",
|
|
1263
|
-
"text-decoration",
|
|
1264
|
-
"text-transform",
|
|
1265
|
-
"width"
|
|
1266
|
-
]);
|
|
1267
|
-
if (!supportedProperties.has(normalizedProperty)) {
|
|
1268
|
-
return false;
|
|
1269
|
-
}
|
|
1270
|
-
if (normalizedProperty === "display") {
|
|
1271
|
-
return (/* @__PURE__ */ new Set(["block", "flex", "grid", "inline", "inline-block", "inline-flex", "inline-grid"])).has(normalizedValue);
|
|
1272
|
-
}
|
|
1273
|
-
if (normalizedProperty === "backdrop-filter") {
|
|
1274
|
-
return /blur\(/.test(normalizedValue);
|
|
1275
|
-
}
|
|
1276
|
-
if (normalizedProperty === "container-type") {
|
|
1277
|
-
return (/* @__PURE__ */ new Set(["inline-size", "size"])).has(normalizedValue);
|
|
1278
|
-
}
|
|
1279
|
-
return true;
|
|
1280
|
-
}
|
|
1281
|
-
matchesSupportsCondition(condition) {
|
|
1282
|
-
const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim();
|
|
1283
|
-
if (!normalized) {
|
|
1284
|
-
return true;
|
|
1285
|
-
}
|
|
1286
|
-
if (normalized.toLowerCase().startsWith("not ")) {
|
|
1287
|
-
return !this.matchesSupportsCondition(normalized.slice(4));
|
|
1288
|
-
}
|
|
1289
|
-
const orClauses = this.splitConditionalClauses(normalized, "or");
|
|
1290
|
-
if (orClauses.length > 1) {
|
|
1291
|
-
return orClauses.some((clause) => this.matchesSupportsCondition(clause));
|
|
1292
|
-
}
|
|
1293
|
-
const andClauses = this.splitConditionalClauses(normalized, "and");
|
|
1294
|
-
if (andClauses.length > 1) {
|
|
1295
|
-
return andClauses.every((clause) => this.matchesSupportsCondition(clause));
|
|
1379
|
+
token += char;
|
|
1296
1380
|
}
|
|
1297
|
-
|
|
1298
|
-
if (
|
|
1299
|
-
return
|
|
1381
|
+
flushToken();
|
|
1382
|
+
if (invalid || chain.length === 0) {
|
|
1383
|
+
return void 0;
|
|
1300
1384
|
}
|
|
1301
|
-
return
|
|
1385
|
+
return chain.some((part) => Boolean(part.tagName) || Boolean(part.idName) || part.classNames.length > 0 || part.attributes.length > 0 || part.pseudoClasses.length > 0) ? chain : void 0;
|
|
1386
|
+
}).filter((segment) => Array.isArray(segment) && segment.length > 0);
|
|
1387
|
+
parsedSelectorChainCache.set(selector, parsedChains);
|
|
1388
|
+
return parsedChains;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// src/client/style/native-resolver.ts
|
|
1392
|
+
var NativeStyleResolver = class {
|
|
1393
|
+
constructor() {
|
|
1394
|
+
this.parsedSelectorChainCache = /* @__PURE__ */ new Map();
|
|
1302
1395
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
continue;
|
|
1309
|
-
}
|
|
1310
|
-
if (!normalizedName) {
|
|
1311
|
-
return ancestor;
|
|
1312
|
-
}
|
|
1313
|
-
if ((ancestor.containerNames ?? []).includes(normalizedName)) {
|
|
1314
|
-
return ancestor;
|
|
1396
|
+
resolveNativeStyles(target, ancestors = [], options = {}, context) {
|
|
1397
|
+
return this.withNativeTargetNormalizationCache(() => {
|
|
1398
|
+
const normalizedTarget = this.normalizeTarget(target);
|
|
1399
|
+
if (!normalizedTarget.tagName && (!normalizedTarget.classNames || normalizedTarget.classNames.length === 0)) {
|
|
1400
|
+
return {};
|
|
1315
1401
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
}
|
|
1339
|
-
if (normalized.startsWith("max-width:")) {
|
|
1340
|
-
const maxWidth = this.parseMediaLength(normalized.slice("max-width:".length));
|
|
1341
|
-
return maxWidth !== void 0 && containerWidth <= maxWidth;
|
|
1342
|
-
}
|
|
1343
|
-
return false;
|
|
1344
|
-
}
|
|
1345
|
-
parseSimpleSelectorToken(token) {
|
|
1346
|
-
const trimmed = token.trim();
|
|
1347
|
-
if (!trimmed || /[*&]/.test(trimmed)) {
|
|
1348
|
-
return void 0;
|
|
1349
|
-
}
|
|
1350
|
-
let cursor = 0;
|
|
1351
|
-
let tagName;
|
|
1352
|
-
let idName;
|
|
1353
|
-
const classNames = [];
|
|
1354
|
-
const attributes = [];
|
|
1355
|
-
const pseudoClasses = [];
|
|
1356
|
-
const tagMatch = trimmed.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1357
|
-
if (tagMatch) {
|
|
1358
|
-
tagName = tagMatch[1].toLowerCase();
|
|
1359
|
-
cursor += tagMatch[0].length;
|
|
1360
|
-
}
|
|
1361
|
-
while (cursor < trimmed.length) {
|
|
1362
|
-
const char = trimmed[cursor];
|
|
1363
|
-
if (char === ".") {
|
|
1364
|
-
const classMatch = trimmed.slice(cursor).match(/^\.([_a-zA-Z][-_a-zA-Z0-9]*)/);
|
|
1365
|
-
if (!classMatch) {
|
|
1366
|
-
return void 0;
|
|
1402
|
+
const normalizedAncestors = ancestors.map((ancestor) => this.normalizeTarget(ancestor));
|
|
1403
|
+
const resolved = {};
|
|
1404
|
+
const applyRules = (rules) => {
|
|
1405
|
+
for (const rule of rules) {
|
|
1406
|
+
const selectorChains = extractSupportedSelectorChains(rule.selector, this.parsedSelectorChainCache);
|
|
1407
|
+
if (selectorChains.length === 0) {
|
|
1408
|
+
continue;
|
|
1409
|
+
}
|
|
1410
|
+
const matches = selectorChains.some((selectorChain) => this.matchesSelectorChain(normalizedTarget, normalizedAncestors, selectorChain));
|
|
1411
|
+
if (!matches) {
|
|
1412
|
+
continue;
|
|
1413
|
+
}
|
|
1414
|
+
for (const [property, value] of Object.entries(rule.styles)) {
|
|
1415
|
+
resolved[property] = typeof value === "string" ? this.resolveVariableReferences(value, context.variables) : value;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
for (const layerName of getOrderedLayerNames(context.layerOrder, context.layerRules)) {
|
|
1420
|
+
for (const layerRule of context.layerRules) {
|
|
1421
|
+
if (layerRule.name.trim() === layerName) {
|
|
1422
|
+
applyRules(layerRule.rules);
|
|
1423
|
+
}
|
|
1367
1424
|
}
|
|
1368
|
-
classNames.push(classMatch[1]);
|
|
1369
|
-
cursor += classMatch[0].length;
|
|
1370
|
-
continue;
|
|
1371
1425
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
if (
|
|
1375
|
-
|
|
1426
|
+
applyRules(context.rules);
|
|
1427
|
+
for (const supportsRule of context.supportsRules) {
|
|
1428
|
+
if (matchesSupportsCondition(supportsRule.condition)) {
|
|
1429
|
+
applyRules(supportsRule.rules);
|
|
1376
1430
|
}
|
|
1377
|
-
idName = idMatch[1];
|
|
1378
|
-
cursor += idMatch[0].length;
|
|
1379
|
-
continue;
|
|
1380
1431
|
}
|
|
1381
|
-
|
|
1382
|
-
const
|
|
1383
|
-
if (
|
|
1384
|
-
|
|
1432
|
+
for (const containerRule of context.containerRules) {
|
|
1433
|
+
const matchingContainer = findMatchingContainerTarget(normalizedAncestors, containerRule.name);
|
|
1434
|
+
if (matchingContainer && this.hasContainerWidth(matchingContainer) && matchesContainerCondition(containerRule.condition, matchingContainer.containerWidth)) {
|
|
1435
|
+
applyRules(containerRule.rules);
|
|
1385
1436
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
if (
|
|
1389
|
-
|
|
1437
|
+
}
|
|
1438
|
+
for (const mediaRule of context.mediaRules) {
|
|
1439
|
+
if (matchesMediaRule(mediaRule, options)) {
|
|
1440
|
+
applyRules(mediaRule.rules);
|
|
1390
1441
|
}
|
|
1391
|
-
attributes.push({
|
|
1392
|
-
name: attrMatch[1].toLowerCase(),
|
|
1393
|
-
operator: attrMatch[2],
|
|
1394
|
-
value: attrMatch[3] ?? attrMatch[4] ?? attrMatch[5]
|
|
1395
|
-
});
|
|
1396
|
-
cursor = endIndex + 1;
|
|
1397
|
-
continue;
|
|
1398
1442
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1443
|
+
return resolved;
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
resolveClassStyles(classNames, context) {
|
|
1447
|
+
return this.resolveNativeStyles({ classNames }, [], {}, context);
|
|
1448
|
+
}
|
|
1449
|
+
hasContainerWidth(target) {
|
|
1450
|
+
return typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth);
|
|
1451
|
+
}
|
|
1452
|
+
resolveVariableReferences(value, variables) {
|
|
1453
|
+
let resolved = value;
|
|
1454
|
+
for (let index = 0; index < 8; index++) {
|
|
1455
|
+
let replaced = false;
|
|
1456
|
+
resolved = resolved.replace(/var\(\s*(--[\w-]+)\s*(?:,\s*([^\)]+))?\)/g, (match, name, fallback) => {
|
|
1457
|
+
const variableValue = variables[name];
|
|
1458
|
+
if (variableValue !== void 0) {
|
|
1459
|
+
replaced = true;
|
|
1460
|
+
return variableValue;
|
|
1403
1461
|
}
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1462
|
+
if (fallback !== void 0) {
|
|
1463
|
+
replaced = true;
|
|
1464
|
+
return fallback.trim();
|
|
1465
|
+
}
|
|
1466
|
+
return match;
|
|
1467
|
+
});
|
|
1468
|
+
if (!replaced) {
|
|
1469
|
+
break;
|
|
1407
1470
|
}
|
|
1408
|
-
return void 0;
|
|
1409
1471
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
return {
|
|
1472
|
+
return resolved.replace(/\s*!important\s*$/i, "").trim();
|
|
1473
|
+
}
|
|
1474
|
+
normalizeTargetIdentity(target) {
|
|
1475
|
+
return {
|
|
1476
|
+
tagName: typeof target.tagName === "string" && target.tagName.trim() ? target.tagName.trim().toLowerCase() : void 0,
|
|
1477
|
+
classNames: Array.isArray(target.classNames) ? target.classNames.map((className) => className.trim()).filter(Boolean) : [],
|
|
1478
|
+
attributes: target.attributes ? Object.fromEntries(
|
|
1479
|
+
Object.entries(target.attributes).filter(([, value]) => value !== void 0 && value !== null && value !== false).map(([name, value]) => [name.toLowerCase(), String(value)])
|
|
1480
|
+
) : {},
|
|
1481
|
+
pseudoStates: Array.isArray(target.pseudoStates) ? [...new Set(target.pseudoStates.map((pseudoState) => pseudoState.trim().toLowerCase()).filter(Boolean))] : [],
|
|
1482
|
+
childIndex: typeof target.childIndex === "number" && Number.isFinite(target.childIndex) ? target.childIndex : void 0,
|
|
1483
|
+
siblingCount: typeof target.siblingCount === "number" && Number.isFinite(target.siblingCount) ? target.siblingCount : void 0,
|
|
1484
|
+
sameTypeIndex: typeof target.sameTypeIndex === "number" && Number.isFinite(target.sameTypeIndex) ? target.sameTypeIndex : void 0,
|
|
1485
|
+
sameTypeCount: typeof target.sameTypeCount === "number" && Number.isFinite(target.sameTypeCount) ? target.sameTypeCount : void 0,
|
|
1486
|
+
containerNames: Array.isArray(target.containerNames) ? [...new Set(target.containerNames.map((containerName) => containerName.trim().toLowerCase()).filter(Boolean))] : [],
|
|
1487
|
+
containerWidth: typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth) ? target.containerWidth : void 0,
|
|
1488
|
+
isContainer: target.isContainer === true,
|
|
1489
|
+
isScopeReference: target.isScopeReference === true
|
|
1490
|
+
};
|
|
1414
1491
|
}
|
|
1415
|
-
|
|
1416
|
-
const cached = this.
|
|
1492
|
+
normalizeTarget(target) {
|
|
1493
|
+
const cached = this.nativeTargetNormalizationCache?.get(target);
|
|
1417
1494
|
if (cached) {
|
|
1418
1495
|
return cached;
|
|
1419
1496
|
}
|
|
1420
|
-
const
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
parsed.combinator = combinator;
|
|
1441
|
-
}
|
|
1442
|
-
chain.push(parsed);
|
|
1443
|
-
combinator = "descendant";
|
|
1444
|
-
};
|
|
1445
|
-
for (let index = 0; index < segment.length; index++) {
|
|
1446
|
-
const char = segment[index];
|
|
1447
|
-
if (quoted) {
|
|
1448
|
-
token += char;
|
|
1449
|
-
if (char === quoted && segment[index - 1] !== "\\") {
|
|
1450
|
-
quoted = void 0;
|
|
1451
|
-
}
|
|
1452
|
-
continue;
|
|
1453
|
-
}
|
|
1454
|
-
if (char === '"' || char === "'") {
|
|
1455
|
-
quoted = char;
|
|
1456
|
-
token += char;
|
|
1457
|
-
continue;
|
|
1458
|
-
}
|
|
1459
|
-
if (char === "[") {
|
|
1460
|
-
attributeDepth += 1;
|
|
1461
|
-
token += char;
|
|
1462
|
-
continue;
|
|
1463
|
-
}
|
|
1464
|
-
if (char === "]") {
|
|
1465
|
-
if (attributeDepth > 0) {
|
|
1466
|
-
attributeDepth -= 1;
|
|
1467
|
-
}
|
|
1468
|
-
token += char;
|
|
1469
|
-
continue;
|
|
1470
|
-
}
|
|
1471
|
-
if (attributeDepth === 0 && char === "(") {
|
|
1472
|
-
parenthesisDepth += 1;
|
|
1473
|
-
token += char;
|
|
1474
|
-
continue;
|
|
1475
|
-
}
|
|
1476
|
-
if (attributeDepth === 0 && char === ")" && parenthesisDepth > 0) {
|
|
1477
|
-
parenthesisDepth -= 1;
|
|
1478
|
-
token += char;
|
|
1479
|
-
continue;
|
|
1480
|
-
}
|
|
1481
|
-
if (attributeDepth === 0 && parenthesisDepth === 0 && (char === ">" || char === "+" || char === "~")) {
|
|
1482
|
-
flushToken();
|
|
1483
|
-
if (invalid) break;
|
|
1484
|
-
combinator = char === ">" ? "child" : char === "+" ? "adjacent-sibling" : "general-sibling";
|
|
1485
|
-
continue;
|
|
1486
|
-
}
|
|
1487
|
-
if (attributeDepth === 0 && parenthesisDepth === 0 && /\s/.test(char)) {
|
|
1488
|
-
flushToken();
|
|
1489
|
-
if (invalid) break;
|
|
1490
|
-
continue;
|
|
1491
|
-
}
|
|
1492
|
-
token += char;
|
|
1493
|
-
}
|
|
1494
|
-
flushToken();
|
|
1495
|
-
if (invalid || chain.length === 0) {
|
|
1496
|
-
return void 0;
|
|
1497
|
-
}
|
|
1498
|
-
return chain.some((part) => Boolean(part.tagName) || Boolean(part.idName) || part.classNames.length > 0 || part.attributes.length > 0 || part.pseudoClasses.length > 0) ? chain : void 0;
|
|
1499
|
-
}).filter((segment) => Array.isArray(segment) && segment.length > 0);
|
|
1500
|
-
this.parsedSelectorChainCache.set(selector, parsedChains);
|
|
1501
|
-
return parsedChains;
|
|
1497
|
+
const normalized = {
|
|
1498
|
+
...this.normalizeTargetIdentity(target),
|
|
1499
|
+
previousSiblings: [],
|
|
1500
|
+
nextSiblings: [],
|
|
1501
|
+
children: []
|
|
1502
|
+
};
|
|
1503
|
+
this.nativeTargetNormalizationCache?.set(target, normalized);
|
|
1504
|
+
normalized.previousSiblings = Array.isArray(target.previousSiblings) ? target.previousSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
|
|
1505
|
+
normalized.nextSiblings = Array.isArray(target.nextSiblings) ? target.nextSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
|
|
1506
|
+
normalized.children = Array.isArray(target.children) ? target.children.map((child) => this.normalizeTarget(child)) : [];
|
|
1507
|
+
return normalized;
|
|
1508
|
+
}
|
|
1509
|
+
withNativeTargetNormalizationCache(callback) {
|
|
1510
|
+
const previousCache = this.nativeTargetNormalizationCache;
|
|
1511
|
+
this.nativeTargetNormalizationCache = /* @__PURE__ */ new WeakMap();
|
|
1512
|
+
try {
|
|
1513
|
+
return callback();
|
|
1514
|
+
} finally {
|
|
1515
|
+
this.nativeTargetNormalizationCache = previousCache;
|
|
1516
|
+
}
|
|
1502
1517
|
}
|
|
1503
1518
|
matchesAttributeSelector(targetValue, selector) {
|
|
1504
1519
|
if (selector.operator === void 0) {
|
|
@@ -1585,13 +1600,13 @@
|
|
|
1585
1600
|
if (!pseudoArgument) {
|
|
1586
1601
|
return false;
|
|
1587
1602
|
}
|
|
1588
|
-
const selectorArguments =
|
|
1603
|
+
const selectorArguments = splitSelectorList(pseudoArgument);
|
|
1589
1604
|
if (selectorArguments.length === 0) {
|
|
1590
1605
|
return false;
|
|
1591
1606
|
}
|
|
1592
1607
|
const parsedSelectors = [];
|
|
1593
1608
|
for (const selectorArgument of selectorArguments) {
|
|
1594
|
-
const parsedSelector =
|
|
1609
|
+
const parsedSelector = parseSimpleSelectorToken(selectorArgument);
|
|
1595
1610
|
if (!parsedSelector) {
|
|
1596
1611
|
return false;
|
|
1597
1612
|
}
|
|
@@ -1640,7 +1655,7 @@
|
|
|
1640
1655
|
return Number.isInteger(n) && n >= 0;
|
|
1641
1656
|
}
|
|
1642
1657
|
matchesHasPseudoClass(target, pseudoArgument) {
|
|
1643
|
-
const selectorArguments =
|
|
1658
|
+
const selectorArguments = splitSelectorList(pseudoArgument);
|
|
1644
1659
|
if (selectorArguments.length === 0) {
|
|
1645
1660
|
return false;
|
|
1646
1661
|
}
|
|
@@ -1655,7 +1670,7 @@
|
|
|
1655
1670
|
if (!scopeRelativeSelector) {
|
|
1656
1671
|
return false;
|
|
1657
1672
|
}
|
|
1658
|
-
const selectorChains =
|
|
1673
|
+
const selectorChains = extractSupportedSelectorChains(scopeRelativeSelector, this.parsedSelectorChainCache);
|
|
1659
1674
|
if (selectorChains.length === 0) {
|
|
1660
1675
|
return false;
|
|
1661
1676
|
}
|
|
@@ -1762,289 +1777,404 @@
|
|
|
1762
1777
|
}
|
|
1763
1778
|
}
|
|
1764
1779
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
// src/client/style/renderer.ts
|
|
1783
|
+
function toKebabCase(str) {
|
|
1784
|
+
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1785
|
+
}
|
|
1786
|
+
function stylesToString(styles2, indent = " ") {
|
|
1787
|
+
return Object.entries(styles2).map(([prop, value]) => {
|
|
1788
|
+
const cssValue = typeof value === "object" && value !== null && "name" in value ? `var(${value.name})` : value;
|
|
1789
|
+
return `${indent}${toKebabCase(prop)}: ${cssValue};`;
|
|
1790
|
+
}).join("\n");
|
|
1791
|
+
}
|
|
1792
|
+
function renderRule(rule, indent = "") {
|
|
1793
|
+
let css = `${indent}${rule.selector} {
|
|
1794
|
+
${stylesToString(rule.styles, indent + " ")}
|
|
1795
|
+
`;
|
|
1796
|
+
if (rule.nested && rule.nested.length > 0) {
|
|
1797
|
+
for (const nestedRule of rule.nested) {
|
|
1798
|
+
const nestedSelector = nestedRule.selector.startsWith("&") ? nestedRule.selector.replace(/&/g, rule.selector) : `${rule.selector} ${nestedRule.selector}`;
|
|
1799
|
+
css += `
|
|
1800
|
+
${indent}${nestedSelector} {
|
|
1801
|
+
${stylesToString(nestedRule.styles, indent + " ")}
|
|
1802
|
+
${indent}}
|
|
1803
|
+
`;
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
css += `${indent}}`;
|
|
1807
|
+
return css;
|
|
1808
|
+
}
|
|
1809
|
+
function renderRulesWithIndent(rules, indent = " ") {
|
|
1810
|
+
return rules.map((rule) => renderRule(rule, indent)).join("\n");
|
|
1811
|
+
}
|
|
1812
|
+
function renderMediaRule(media) {
|
|
1813
|
+
const condition = media.type && media.condition ? `${media.type} and (${media.condition})` : media.type ? media.type : `(${media.condition})`;
|
|
1814
|
+
return `@media ${condition} {
|
|
1815
|
+
${renderRulesWithIndent(media.rules)}
|
|
1816
|
+
}`;
|
|
1817
|
+
}
|
|
1818
|
+
function renderKeyframes(kf) {
|
|
1819
|
+
let css = `@keyframes ${kf.name} {
|
|
1820
|
+
`;
|
|
1821
|
+
for (const step of kf.steps) {
|
|
1822
|
+
css += ` ${step.step} {
|
|
1823
|
+
${stylesToString(step.styles, " ")}
|
|
1824
|
+
}
|
|
1825
|
+
`;
|
|
1826
|
+
}
|
|
1827
|
+
css += "}";
|
|
1828
|
+
return css;
|
|
1829
|
+
}
|
|
1830
|
+
function renderFontFace(ff) {
|
|
1831
|
+
let css = "@font-face {\n";
|
|
1832
|
+
css += ` font-family: "${ff.fontFamily}";
|
|
1833
|
+
`;
|
|
1834
|
+
css += ` src: ${ff.src};
|
|
1835
|
+
`;
|
|
1836
|
+
if (ff.fontWeight) css += ` font-weight: ${ff.fontWeight};
|
|
1837
|
+
`;
|
|
1838
|
+
if (ff.fontStyle) css += ` font-style: ${ff.fontStyle};
|
|
1839
|
+
`;
|
|
1840
|
+
if (ff.fontDisplay) css += ` font-display: ${ff.fontDisplay};
|
|
1841
|
+
`;
|
|
1842
|
+
if (ff.unicodeRange) css += ` unicode-range: ${ff.unicodeRange};
|
|
1843
|
+
`;
|
|
1844
|
+
css += "}";
|
|
1845
|
+
return css;
|
|
1846
|
+
}
|
|
1847
|
+
function renderContainerRule(container2) {
|
|
1848
|
+
const nameStr = container2.name ? `${container2.name} ` : "";
|
|
1849
|
+
return `@container ${nameStr}(${container2.condition}) {
|
|
1850
|
+
${renderRulesWithIndent(container2.rules)}
|
|
1851
|
+
}`;
|
|
1852
|
+
}
|
|
1853
|
+
function renderSupportsRule(supports) {
|
|
1854
|
+
return `@supports (${supports.condition}) {
|
|
1855
|
+
${renderRulesWithIndent(supports.rules)}
|
|
1856
|
+
}`;
|
|
1857
|
+
}
|
|
1858
|
+
function renderLayerRule(layer2) {
|
|
1859
|
+
return `@layer ${layer2.name} {
|
|
1860
|
+
${renderRulesWithIndent(layer2.rules)}
|
|
1861
|
+
}`;
|
|
1862
|
+
}
|
|
1863
|
+
function renderStyleSheet(context, ...additionalRules) {
|
|
1864
|
+
const parts = [];
|
|
1865
|
+
if (context.imports.length > 0) {
|
|
1866
|
+
parts.push(context.imports.join("\n"));
|
|
1867
|
+
}
|
|
1868
|
+
if (context.layerOrder.length > 0) {
|
|
1869
|
+
parts.push(`@layer ${context.layerOrder.join(", ")};`);
|
|
1870
|
+
}
|
|
1871
|
+
if (context.variables.length > 0) {
|
|
1872
|
+
const varDeclarations = context.variables.map((variable) => ` ${variable.name}: ${variable.value};`).join("\n");
|
|
1873
|
+
parts.push(`:root {
|
|
1874
|
+
${varDeclarations}
|
|
1875
|
+
}`);
|
|
1876
|
+
}
|
|
1877
|
+
for (const ff of context.fontFaces) {
|
|
1878
|
+
parts.push(renderFontFace(ff));
|
|
1879
|
+
}
|
|
1880
|
+
for (const kf of context.keyframes) {
|
|
1881
|
+
parts.push(renderKeyframes(kf));
|
|
1882
|
+
}
|
|
1883
|
+
const allRules = [...context.rules];
|
|
1884
|
+
const allMediaRules = [...context.mediaRules];
|
|
1885
|
+
const allKeyframes = [];
|
|
1886
|
+
const allContainerRules = [...context.containerRules];
|
|
1887
|
+
const allSupportsRules = [...context.supportsRules];
|
|
1888
|
+
const allLayerRules = [...context.layerRules];
|
|
1889
|
+
for (const item of additionalRules) {
|
|
1890
|
+
if (!item) {
|
|
1891
|
+
continue;
|
|
1892
|
+
}
|
|
1893
|
+
if (Array.isArray(item)) {
|
|
1894
|
+
allRules.push(...item);
|
|
1895
|
+
} else if ("condition" in item && "rules" in item && !("name" in item && "steps" in item)) {
|
|
1896
|
+
if ("type" in item) {
|
|
1897
|
+
allMediaRules.push(item);
|
|
1898
|
+
} else if ("name" in item && typeof item.name === "string") {
|
|
1899
|
+
allContainerRules.push(item);
|
|
1900
|
+
} else {
|
|
1901
|
+
allSupportsRules.push(item);
|
|
1902
|
+
}
|
|
1903
|
+
} else if ("name" in item && "steps" in item) {
|
|
1904
|
+
allKeyframes.push(item);
|
|
1905
|
+
} else if ("name" in item && "rules" in item) {
|
|
1906
|
+
allLayerRules.push(item);
|
|
1907
|
+
} else {
|
|
1908
|
+
allRules.push(item);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
for (const kf of allKeyframes) {
|
|
1912
|
+
parts.push(renderKeyframes(kf));
|
|
1913
|
+
}
|
|
1914
|
+
for (const layer2 of allLayerRules) {
|
|
1915
|
+
parts.push(renderLayerRule(layer2));
|
|
1916
|
+
}
|
|
1917
|
+
for (const rule of allRules) {
|
|
1918
|
+
parts.push(renderRule(rule));
|
|
1919
|
+
}
|
|
1920
|
+
for (const supports of allSupportsRules) {
|
|
1921
|
+
parts.push(renderSupportsRule(supports));
|
|
1922
|
+
}
|
|
1923
|
+
for (const container2 of allContainerRules) {
|
|
1924
|
+
parts.push(renderContainerRule(container2));
|
|
1925
|
+
}
|
|
1926
|
+
for (const media of allMediaRules) {
|
|
1927
|
+
parts.push(renderMediaRule(media));
|
|
1928
|
+
}
|
|
1929
|
+
return parts.join("\n\n");
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// src/client/style/store.ts
|
|
1933
|
+
var ELIT_SHARED_STYLE_STORE_KEY = "__elitSharedStyleStore__";
|
|
1934
|
+
function createStyleStore() {
|
|
1935
|
+
return {
|
|
1936
|
+
variables: [],
|
|
1937
|
+
rules: [],
|
|
1938
|
+
mediaRules: [],
|
|
1939
|
+
keyframes: [],
|
|
1940
|
+
fontFaces: [],
|
|
1941
|
+
imports: [],
|
|
1942
|
+
containerRules: [],
|
|
1943
|
+
supportsRules: [],
|
|
1944
|
+
layerRules: [],
|
|
1945
|
+
layerOrder: []
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
function getSharedStyleStore() {
|
|
1949
|
+
const globalScope = globalThis;
|
|
1950
|
+
if (!globalScope[ELIT_SHARED_STYLE_STORE_KEY]) {
|
|
1951
|
+
globalScope[ELIT_SHARED_STYLE_STORE_KEY] = createStyleStore();
|
|
1952
|
+
}
|
|
1953
|
+
return globalScope[ELIT_SHARED_STYLE_STORE_KEY];
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// src/client/style/index.ts
|
|
1957
|
+
var CreateStyle = class {
|
|
1958
|
+
constructor(store) {
|
|
1959
|
+
this.variables = [];
|
|
1960
|
+
this.rules = [];
|
|
1961
|
+
this.mediaRules = [];
|
|
1962
|
+
this.keyframes = [];
|
|
1963
|
+
this.fontFaces = [];
|
|
1964
|
+
this.imports = [];
|
|
1965
|
+
this.containerRules = [];
|
|
1966
|
+
this.supportsRules = [];
|
|
1967
|
+
this.layerRules = [];
|
|
1968
|
+
this._layerOrder = [];
|
|
1969
|
+
this.nativeStyleResolver = new NativeStyleResolver();
|
|
1970
|
+
if (!store) {
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
this.variables = store.variables;
|
|
1974
|
+
this.rules = store.rules;
|
|
1975
|
+
this.mediaRules = store.mediaRules;
|
|
1976
|
+
this.keyframes = store.keyframes;
|
|
1977
|
+
this.fontFaces = store.fontFaces;
|
|
1978
|
+
this.imports = store.imports;
|
|
1979
|
+
this.containerRules = store.containerRules;
|
|
1980
|
+
this.supportsRules = store.supportsRules;
|
|
1981
|
+
this.layerRules = store.layerRules;
|
|
1982
|
+
this._layerOrder = store.layerOrder;
|
|
1983
|
+
}
|
|
1984
|
+
addVar(name, value) {
|
|
1985
|
+
const cssVar = {
|
|
1986
|
+
name: name.startsWith("--") ? name : `--${name}`,
|
|
1987
|
+
value,
|
|
1988
|
+
toString() {
|
|
1989
|
+
return `var(${this.name})`;
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1992
|
+
this.variables.push(cssVar);
|
|
1993
|
+
return cssVar;
|
|
1994
|
+
}
|
|
1995
|
+
var(variable, fallback) {
|
|
1996
|
+
const varName = typeof variable === "string" ? variable.startsWith("--") ? variable : `--${variable}` : variable.name;
|
|
1997
|
+
return fallback ? `var(${varName}, ${fallback})` : `var(${varName})`;
|
|
1998
|
+
}
|
|
1999
|
+
addTag(tag, styles2) {
|
|
2000
|
+
const rule = { selector: tag, styles: styles2, type: "tag" };
|
|
2001
|
+
this.rules.push(rule);
|
|
2002
|
+
return rule;
|
|
2003
|
+
}
|
|
2004
|
+
addClass(name, styles2) {
|
|
2005
|
+
const selector = name.startsWith(".") ? name : `.${name}`;
|
|
2006
|
+
const rule = { selector, styles: styles2, type: "class" };
|
|
2007
|
+
this.rules.push(rule);
|
|
2008
|
+
return rule;
|
|
2009
|
+
}
|
|
2010
|
+
addId(name, styles2) {
|
|
2011
|
+
const selector = name.startsWith("#") ? name : `#${name}`;
|
|
2012
|
+
const rule = { selector, styles: styles2, type: "id" };
|
|
2013
|
+
this.rules.push(rule);
|
|
2014
|
+
return rule;
|
|
2015
|
+
}
|
|
2016
|
+
addPseudoClass(pseudo, styles2, baseSelector) {
|
|
2017
|
+
const pseudoClass = pseudo.startsWith(":") ? pseudo : `:${pseudo}`;
|
|
2018
|
+
const selector = baseSelector ? `${baseSelector}${pseudoClass}` : pseudoClass;
|
|
2019
|
+
const rule = { selector, styles: styles2, type: "pseudo-class" };
|
|
2020
|
+
this.rules.push(rule);
|
|
2021
|
+
return rule;
|
|
2022
|
+
}
|
|
2023
|
+
addPseudoElement(pseudo, styles2, baseSelector) {
|
|
2024
|
+
const pseudoElement = pseudo.startsWith("::") ? pseudo : `::${pseudo}`;
|
|
2025
|
+
const selector = baseSelector ? `${baseSelector}${pseudoElement}` : pseudoElement;
|
|
2026
|
+
const rule = { selector, styles: styles2, type: "pseudo-element" };
|
|
2027
|
+
this.rules.push(rule);
|
|
2028
|
+
return rule;
|
|
2029
|
+
}
|
|
2030
|
+
addAttribute(attr, styles2, baseSelector) {
|
|
2031
|
+
const attrSelector = attr.startsWith("[") ? attr : `[${attr}]`;
|
|
2032
|
+
const selector = baseSelector ? `${baseSelector}${attrSelector}` : attrSelector;
|
|
2033
|
+
const rule = { selector, styles: styles2, type: "attribute" };
|
|
2034
|
+
this.rules.push(rule);
|
|
2035
|
+
return rule;
|
|
2036
|
+
}
|
|
2037
|
+
attrEquals(attr, value, styles2, baseSelector) {
|
|
2038
|
+
return this.addAttribute(`${attr}="${value}"`, styles2, baseSelector);
|
|
2039
|
+
}
|
|
2040
|
+
attrContainsWord(attr, value, styles2, baseSelector) {
|
|
2041
|
+
return this.addAttribute(`${attr}~="${value}"`, styles2, baseSelector);
|
|
2042
|
+
}
|
|
2043
|
+
attrStartsWith(attr, value, styles2, baseSelector) {
|
|
2044
|
+
return this.addAttribute(`${attr}^="${value}"`, styles2, baseSelector);
|
|
1776
2045
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
if (!normalized) {
|
|
1780
|
-
return true;
|
|
1781
|
-
}
|
|
1782
|
-
if (normalized.startsWith("min-width:")) {
|
|
1783
|
-
const minWidth = this.parseMediaLength(normalized.slice("min-width:".length));
|
|
1784
|
-
return minWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth >= minWidth;
|
|
1785
|
-
}
|
|
1786
|
-
if (normalized.startsWith("max-width:")) {
|
|
1787
|
-
const maxWidth = this.parseMediaLength(normalized.slice("max-width:".length));
|
|
1788
|
-
return maxWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth <= maxWidth;
|
|
1789
|
-
}
|
|
1790
|
-
if (normalized === "prefers-color-scheme: dark") {
|
|
1791
|
-
return options.colorScheme === "dark";
|
|
1792
|
-
}
|
|
1793
|
-
if (normalized === "prefers-color-scheme: light") {
|
|
1794
|
-
return (options.colorScheme ?? "light") === "light";
|
|
1795
|
-
}
|
|
1796
|
-
if (normalized === "prefers-reduced-motion: reduce") {
|
|
1797
|
-
return options.reducedMotion === true;
|
|
1798
|
-
}
|
|
1799
|
-
return false;
|
|
2046
|
+
attrEndsWith(attr, value, styles2, baseSelector) {
|
|
2047
|
+
return this.addAttribute(`${attr}$="${value}"`, styles2, baseSelector);
|
|
1800
2048
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
if (rule.type && rule.type !== mediaType && rule.type !== "all") {
|
|
1804
|
-
return false;
|
|
1805
|
-
}
|
|
1806
|
-
if (!rule.condition.trim()) {
|
|
1807
|
-
return true;
|
|
1808
|
-
}
|
|
1809
|
-
return rule.condition.split(/\band\b/i).map((part) => part.trim()).filter(Boolean).every((part) => this.matchesMediaCondition(part, options));
|
|
2049
|
+
attrContains(attr, value, styles2, baseSelector) {
|
|
2050
|
+
return this.addAttribute(`${attr}*="${value}"`, styles2, baseSelector);
|
|
1810
2051
|
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
for (const layerName of this._layerOrder) {
|
|
1814
|
-
const normalizedName = layerName.trim();
|
|
1815
|
-
if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
|
|
1816
|
-
orderedLayerNames.push(normalizedName);
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
for (const layerRule of this.layerRules) {
|
|
1820
|
-
const normalizedName = layerRule.name.trim();
|
|
1821
|
-
if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
|
|
1822
|
-
orderedLayerNames.push(normalizedName);
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
return orderedLayerNames;
|
|
2052
|
+
descendant(ancestor, descendant2, styles2) {
|
|
2053
|
+
return this.createAndAddRule(`${ancestor} ${descendant2}`, styles2);
|
|
1826
2054
|
}
|
|
1827
|
-
|
|
1828
|
-
return this.
|
|
1829
|
-
const normalizedTarget = this.normalizeTarget(target);
|
|
1830
|
-
if (!normalizedTarget.tagName && (!normalizedTarget.classNames || normalizedTarget.classNames.length === 0)) {
|
|
1831
|
-
return {};
|
|
1832
|
-
}
|
|
1833
|
-
const normalizedAncestors = ancestors.map((ancestor) => this.normalizeTarget(ancestor));
|
|
1834
|
-
const variables = this.getVariables();
|
|
1835
|
-
const resolved = {};
|
|
1836
|
-
const applyRules = (rules) => {
|
|
1837
|
-
for (const rule of rules) {
|
|
1838
|
-
const selectorChains = this.extractSupportedSelectorChains(rule.selector);
|
|
1839
|
-
if (selectorChains.length === 0) {
|
|
1840
|
-
continue;
|
|
1841
|
-
}
|
|
1842
|
-
const matches = selectorChains.some((selectorChain) => this.matchesSelectorChain(normalizedTarget, normalizedAncestors, selectorChain));
|
|
1843
|
-
if (!matches) {
|
|
1844
|
-
continue;
|
|
1845
|
-
}
|
|
1846
|
-
for (const [property, value] of Object.entries(rule.styles)) {
|
|
1847
|
-
resolved[property] = typeof value === "string" ? this.resolveVariableReferences(value, variables) : value;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
};
|
|
1851
|
-
for (const layerName of this.getOrderedLayerNames()) {
|
|
1852
|
-
for (const layerRule of this.layerRules) {
|
|
1853
|
-
if (layerRule.name.trim() === layerName) {
|
|
1854
|
-
applyRules(layerRule.rules);
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
applyRules(this.rules);
|
|
1859
|
-
for (const supportsRule of this.supportsRules) {
|
|
1860
|
-
if (this.matchesSupportsCondition(supportsRule.condition)) {
|
|
1861
|
-
applyRules(supportsRule.rules);
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
for (const containerRule of this.containerRules) {
|
|
1865
|
-
const matchingContainer = this.findMatchingContainerTarget(normalizedAncestors, containerRule.name);
|
|
1866
|
-
if (matchingContainer && this.matchesContainerCondition(containerRule.condition, matchingContainer.containerWidth)) {
|
|
1867
|
-
applyRules(containerRule.rules);
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
for (const mediaRule of this.mediaRules) {
|
|
1871
|
-
if (this.matchesMediaRule(mediaRule, options)) {
|
|
1872
|
-
applyRules(mediaRule.rules);
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
return resolved;
|
|
1876
|
-
});
|
|
2055
|
+
child(parent, childSel, styles2) {
|
|
2056
|
+
return this.createAndAddRule(`${parent} > ${childSel}`, styles2);
|
|
1877
2057
|
}
|
|
1878
|
-
|
|
1879
|
-
return this.
|
|
2058
|
+
adjacentSibling(element, sibling, styles2) {
|
|
2059
|
+
return this.createAndAddRule(`${element} + ${sibling}`, styles2);
|
|
1880
2060
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2061
|
+
generalSibling(element, sibling, styles2) {
|
|
2062
|
+
return this.createAndAddRule(`${element} ~ ${sibling}`, styles2);
|
|
1884
2063
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
const rule = { selector, styles: styles2, type };
|
|
1888
|
-
this.rules.push(rule);
|
|
1889
|
-
return rule;
|
|
2064
|
+
multiple(selectors, styles2) {
|
|
2065
|
+
return this.createAndAddRule(selectors.join(", "), styles2);
|
|
1890
2066
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
return
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
2067
|
+
addName(name, styles2) {
|
|
2068
|
+
const selector = name.startsWith("--") ? `&${name}` : `&--${name}`;
|
|
2069
|
+
return { selector, styles: styles2, type: "name" };
|
|
2070
|
+
}
|
|
2071
|
+
nesting(parentRule, ...childRules) {
|
|
2072
|
+
parentRule.nested = childRules;
|
|
2073
|
+
return parentRule;
|
|
2074
|
+
}
|
|
2075
|
+
keyframe(name, steps) {
|
|
2076
|
+
const keyframeSteps = Object.entries(steps).map(([step, styles2]) => ({
|
|
2077
|
+
step: step === "from" ? "from" : step === "to" ? "to" : `${step}%`,
|
|
2078
|
+
styles: styles2
|
|
1897
2079
|
}));
|
|
2080
|
+
const kf = { name, steps: keyframeSteps };
|
|
2081
|
+
this.keyframes.push(kf);
|
|
2082
|
+
return kf;
|
|
1898
2083
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
return rules.map((rule) => this.renderRule(rule, indent)).join("\n");
|
|
2084
|
+
keyframeFromTo(name, from, to) {
|
|
2085
|
+
return this.keyframe(name, { from, to });
|
|
1902
2086
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
return `${indent}${this.toKebabCase(prop)}: ${cssValue};`;
|
|
1907
|
-
}).join("\n");
|
|
2087
|
+
fontFace(options) {
|
|
2088
|
+
this.fontFaces.push(options);
|
|
2089
|
+
return options;
|
|
1908
2090
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
if (rule.nested && rule.nested.length > 0) {
|
|
1914
|
-
for (const nestedRule of rule.nested) {
|
|
1915
|
-
const nestedSelector = nestedRule.selector.startsWith("&") ? nestedRule.selector.replace(/&/g, rule.selector) : `${rule.selector} ${nestedRule.selector}`;
|
|
1916
|
-
css += `
|
|
1917
|
-
${indent}${nestedSelector} {
|
|
1918
|
-
${this.stylesToString(nestedRule.styles, indent + " ")}
|
|
1919
|
-
${indent}}
|
|
1920
|
-
`;
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
css += `${indent}}`;
|
|
1924
|
-
return css;
|
|
2091
|
+
import(url, mediaQuery) {
|
|
2092
|
+
const importRule = mediaQuery ? `@import url("${url}") ${mediaQuery};` : `@import url("${url}");`;
|
|
2093
|
+
this.imports.push(importRule);
|
|
2094
|
+
return importRule;
|
|
1925
2095
|
}
|
|
1926
|
-
|
|
1927
|
-
const
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
}`;
|
|
2096
|
+
media(type, condition, rules) {
|
|
2097
|
+
const mediaRule = { type, condition, rules: this.rulesToCSSRules(rules) };
|
|
2098
|
+
this.mediaRules.push(mediaRule);
|
|
2099
|
+
return mediaRule;
|
|
1931
2100
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
`;
|
|
1935
|
-
for (const step of kf.steps) {
|
|
1936
|
-
css += ` ${step.step} {
|
|
1937
|
-
${this.stylesToString(step.styles, " ")}
|
|
2101
|
+
mediaScreen(condition, rules) {
|
|
2102
|
+
return this.media("screen", condition, rules);
|
|
1938
2103
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
css += "}";
|
|
1942
|
-
return css;
|
|
2104
|
+
mediaPrint(rules) {
|
|
2105
|
+
return this.media("print", "", rules);
|
|
1943
2106
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
css += ` font-family: "${ff.fontFamily}";
|
|
1947
|
-
`;
|
|
1948
|
-
css += ` src: ${ff.src};
|
|
1949
|
-
`;
|
|
1950
|
-
if (ff.fontWeight) css += ` font-weight: ${ff.fontWeight};
|
|
1951
|
-
`;
|
|
1952
|
-
if (ff.fontStyle) css += ` font-style: ${ff.fontStyle};
|
|
1953
|
-
`;
|
|
1954
|
-
if (ff.fontDisplay) css += ` font-display: ${ff.fontDisplay};
|
|
1955
|
-
`;
|
|
1956
|
-
if (ff.unicodeRange) css += ` unicode-range: ${ff.unicodeRange};
|
|
1957
|
-
`;
|
|
1958
|
-
css += "}";
|
|
1959
|
-
return css;
|
|
2107
|
+
mediaMinWidth(minWidth, rules) {
|
|
2108
|
+
return this.media("screen", `min-width: ${minWidth}`, rules);
|
|
1960
2109
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
return `@container ${nameStr}(${container2.condition}) {
|
|
1964
|
-
${this.renderRulesWithIndent(container2.rules)}
|
|
1965
|
-
}`;
|
|
2110
|
+
mediaMaxWidth(maxWidth, rules) {
|
|
2111
|
+
return this.media("screen", `max-width: ${maxWidth}`, rules);
|
|
1966
2112
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2113
|
+
mediaDark(rules) {
|
|
2114
|
+
const mediaRule = { type: "", condition: "prefers-color-scheme: dark", rules: this.rulesToCSSRules(rules) };
|
|
2115
|
+
this.mediaRules.push(mediaRule);
|
|
2116
|
+
return mediaRule;
|
|
1971
2117
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2118
|
+
mediaLight(rules) {
|
|
2119
|
+
const mediaRule = { type: "", condition: "prefers-color-scheme: light", rules: this.rulesToCSSRules(rules) };
|
|
2120
|
+
this.mediaRules.push(mediaRule);
|
|
2121
|
+
return mediaRule;
|
|
2122
|
+
}
|
|
2123
|
+
mediaReducedMotion(rules) {
|
|
2124
|
+
const mediaRule = { type: "", condition: "prefers-reduced-motion: reduce", rules: this.rulesToCSSRules(rules) };
|
|
2125
|
+
this.mediaRules.push(mediaRule);
|
|
2126
|
+
return mediaRule;
|
|
2127
|
+
}
|
|
2128
|
+
container(condition, rules, name) {
|
|
2129
|
+
const containerRule = { name, condition, rules: this.rulesToCSSRules(rules) };
|
|
2130
|
+
this.containerRules.push(containerRule);
|
|
2131
|
+
return containerRule;
|
|
2132
|
+
}
|
|
2133
|
+
addContainer(name, styles2) {
|
|
2134
|
+
const containerStyles = { ...styles2, containerName: name };
|
|
2135
|
+
return this.addClass(name, containerStyles);
|
|
2136
|
+
}
|
|
2137
|
+
supports(condition, rules) {
|
|
2138
|
+
const supportsRule = { condition, rules: this.rulesToCSSRules(rules) };
|
|
2139
|
+
this.supportsRules.push(supportsRule);
|
|
2140
|
+
return supportsRule;
|
|
2141
|
+
}
|
|
2142
|
+
layerOrder(...layers) {
|
|
2143
|
+
this._layerOrder = layers;
|
|
2144
|
+
}
|
|
2145
|
+
layer(name, rules) {
|
|
2146
|
+
const layerRule = { name, rules: this.rulesToCSSRules(rules) };
|
|
2147
|
+
this.layerRules.push(layerRule);
|
|
2148
|
+
return layerRule;
|
|
2149
|
+
}
|
|
2150
|
+
add(rules) {
|
|
2151
|
+
return Object.entries(rules).map(([selector, styles2]) => {
|
|
2152
|
+
const rule = { selector, styles: styles2, type: "custom" };
|
|
2153
|
+
this.rules.push(rule);
|
|
2154
|
+
return rule;
|
|
2155
|
+
});
|
|
2156
|
+
}
|
|
2157
|
+
important(value) {
|
|
2158
|
+
return `${value} !important`;
|
|
2159
|
+
}
|
|
2160
|
+
getVariables() {
|
|
2161
|
+
return Object.fromEntries(this.variables.map((variable) => [variable.name, variable.value]));
|
|
2162
|
+
}
|
|
2163
|
+
resolveNativeStyles(target, ancestors = [], options = {}) {
|
|
2164
|
+
return this.nativeStyleResolver.resolveNativeStyles(target, ancestors, options, this.getResolverContext());
|
|
2165
|
+
}
|
|
2166
|
+
resolveClassStyles(classNames) {
|
|
2167
|
+
return this.nativeStyleResolver.resolveClassStyles(classNames, this.getResolverContext());
|
|
1976
2168
|
}
|
|
1977
|
-
// Render Output
|
|
1978
2169
|
render(...additionalRules) {
|
|
1979
|
-
|
|
1980
|
-
if (this.imports.length > 0) {
|
|
1981
|
-
parts.push(this.imports.join("\n"));
|
|
1982
|
-
}
|
|
1983
|
-
if (this._layerOrder.length > 0) {
|
|
1984
|
-
parts.push(`@layer ${this._layerOrder.join(", ")};`);
|
|
1985
|
-
}
|
|
1986
|
-
if (this.variables.length > 0) {
|
|
1987
|
-
const varDeclarations = this.variables.map((v) => ` ${v.name}: ${v.value};`).join("\n");
|
|
1988
|
-
parts.push(`:root {
|
|
1989
|
-
${varDeclarations}
|
|
1990
|
-
}`);
|
|
1991
|
-
}
|
|
1992
|
-
for (const ff of this.fontFaces) {
|
|
1993
|
-
parts.push(this.renderFontFace(ff));
|
|
1994
|
-
}
|
|
1995
|
-
for (const kf of this.keyframes) {
|
|
1996
|
-
parts.push(this.renderKeyframes(kf));
|
|
1997
|
-
}
|
|
1998
|
-
const allRules = [...this.rules];
|
|
1999
|
-
const allMediaRules = [...this.mediaRules];
|
|
2000
|
-
const allKeyframes = [];
|
|
2001
|
-
const allContainerRules = [...this.containerRules];
|
|
2002
|
-
const allSupportsRules = [...this.supportsRules];
|
|
2003
|
-
const allLayerRules = [...this.layerRules];
|
|
2004
|
-
for (const item of additionalRules) {
|
|
2005
|
-
if (!item) continue;
|
|
2006
|
-
if (Array.isArray(item)) {
|
|
2007
|
-
allRules.push(...item);
|
|
2008
|
-
} else if ("condition" in item && "rules" in item && !("name" in item && "steps" in item)) {
|
|
2009
|
-
if ("type" in item) {
|
|
2010
|
-
allMediaRules.push(item);
|
|
2011
|
-
} else if ("name" in item && typeof item.name === "string") {
|
|
2012
|
-
allContainerRules.push(item);
|
|
2013
|
-
} else {
|
|
2014
|
-
allSupportsRules.push(item);
|
|
2015
|
-
}
|
|
2016
|
-
} else if ("name" in item && "steps" in item) {
|
|
2017
|
-
allKeyframes.push(item);
|
|
2018
|
-
} else if ("name" in item && "rules" in item) {
|
|
2019
|
-
allLayerRules.push(item);
|
|
2020
|
-
} else {
|
|
2021
|
-
allRules.push(item);
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
for (const kf of allKeyframes) {
|
|
2025
|
-
parts.push(this.renderKeyframes(kf));
|
|
2026
|
-
}
|
|
2027
|
-
for (const layer2 of allLayerRules) {
|
|
2028
|
-
parts.push(this.renderLayerRule(layer2));
|
|
2029
|
-
}
|
|
2030
|
-
for (const rule of allRules) {
|
|
2031
|
-
parts.push(this.renderRule(rule));
|
|
2032
|
-
}
|
|
2033
|
-
for (const supports of allSupportsRules) {
|
|
2034
|
-
parts.push(this.renderSupportsRule(supports));
|
|
2035
|
-
}
|
|
2036
|
-
for (const container2 of allContainerRules) {
|
|
2037
|
-
parts.push(this.renderContainerRule(container2));
|
|
2038
|
-
}
|
|
2039
|
-
for (const media of allMediaRules) {
|
|
2040
|
-
parts.push(this.renderMediaRule(media));
|
|
2041
|
-
}
|
|
2042
|
-
return parts.join("\n\n");
|
|
2170
|
+
return renderStyleSheet(this.getRenderContext(), ...additionalRules);
|
|
2043
2171
|
}
|
|
2044
2172
|
inject(styleId) {
|
|
2045
2173
|
const css = this.render();
|
|
2046
2174
|
const style = document.createElement("style");
|
|
2047
|
-
if (styleId)
|
|
2175
|
+
if (styleId) {
|
|
2176
|
+
style.id = styleId;
|
|
2177
|
+
}
|
|
2048
2178
|
style.textContent = css;
|
|
2049
2179
|
document.head.appendChild(style);
|
|
2050
2180
|
return style;
|
|
@@ -2061,6 +2191,43 @@ ${varDeclarations}
|
|
|
2061
2191
|
this.layerRules.length = 0;
|
|
2062
2192
|
this._layerOrder.length = 0;
|
|
2063
2193
|
}
|
|
2194
|
+
getResolverContext() {
|
|
2195
|
+
return {
|
|
2196
|
+
variables: this.getVariables(),
|
|
2197
|
+
rules: this.rules,
|
|
2198
|
+
mediaRules: this.mediaRules,
|
|
2199
|
+
containerRules: this.containerRules,
|
|
2200
|
+
supportsRules: this.supportsRules,
|
|
2201
|
+
layerRules: this.layerRules,
|
|
2202
|
+
layerOrder: this._layerOrder
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
getRenderContext() {
|
|
2206
|
+
return {
|
|
2207
|
+
imports: this.imports,
|
|
2208
|
+
layerOrder: this._layerOrder,
|
|
2209
|
+
variables: this.variables,
|
|
2210
|
+
fontFaces: this.fontFaces,
|
|
2211
|
+
keyframes: this.keyframes,
|
|
2212
|
+
rules: this.rules,
|
|
2213
|
+
mediaRules: this.mediaRules,
|
|
2214
|
+
containerRules: this.containerRules,
|
|
2215
|
+
supportsRules: this.supportsRules,
|
|
2216
|
+
layerRules: this.layerRules
|
|
2217
|
+
};
|
|
2218
|
+
}
|
|
2219
|
+
createAndAddRule(selector, styles2, type = "custom") {
|
|
2220
|
+
const rule = { selector, styles: styles2, type };
|
|
2221
|
+
this.rules.push(rule);
|
|
2222
|
+
return rule;
|
|
2223
|
+
}
|
|
2224
|
+
rulesToCSSRules(rules) {
|
|
2225
|
+
return Object.entries(rules).map(([selector, styles2]) => ({
|
|
2226
|
+
selector,
|
|
2227
|
+
styles: styles2,
|
|
2228
|
+
type: "custom"
|
|
2229
|
+
}));
|
|
2230
|
+
}
|
|
2064
2231
|
};
|
|
2065
2232
|
var styles = new CreateStyle(getSharedStyleStore());
|
|
2066
2233
|
var {
|
|
@@ -2101,23 +2268,28 @@ ${varDeclarations}
|
|
|
2101
2268
|
supports: supportsStyle,
|
|
2102
2269
|
layerOrder,
|
|
2103
2270
|
layer,
|
|
2104
|
-
add:
|
|
2271
|
+
add: addStyle2,
|
|
2105
2272
|
important,
|
|
2106
2273
|
getVariables: getStyleVariables,
|
|
2274
|
+
resolveNativeStyles,
|
|
2107
2275
|
resolveClassStyles,
|
|
2108
2276
|
render: renderStyle,
|
|
2109
2277
|
inject: injectStyle,
|
|
2110
2278
|
clear: clearStyle
|
|
2111
2279
|
} = styles;
|
|
2112
2280
|
|
|
2113
|
-
// src/desktop
|
|
2281
|
+
// src/desktop/auto-render/constants.ts
|
|
2114
2282
|
var DESKTOP_RENDER_TRACKED_KEY = "__ELIT_DESKTOP_RENDER_TRACKED__";
|
|
2115
2283
|
var DESKTOP_WINDOW_CREATED_KEY = "__ELIT_DESKTOP_WINDOW_CREATED__";
|
|
2116
2284
|
var DESKTOP_MESSAGE_HANDLER_KEY = "__ELIT_DESKTOP_MESSAGE_HANDLER__";
|
|
2285
|
+
|
|
2286
|
+
// src/desktop/auto-render/globals.ts
|
|
2117
2287
|
function getDesktopAutoRenderGlobals() {
|
|
2118
2288
|
return globalThis;
|
|
2119
2289
|
}
|
|
2120
|
-
|
|
2290
|
+
|
|
2291
|
+
// src/desktop/auto-render/html.ts
|
|
2292
|
+
function escapeHtml2(text) {
|
|
2121
2293
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2122
2294
|
}
|
|
2123
2295
|
function escapeStyleText(css) {
|
|
@@ -2130,7 +2302,7 @@ ${varDeclarations}
|
|
|
2130
2302
|
<head>
|
|
2131
2303
|
<meta charset="utf-8" />
|
|
2132
2304
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2133
|
-
<title>${
|
|
2305
|
+
<title>${escapeHtml2(options.title)}</title>
|
|
2134
2306
|
${styleTag}
|
|
2135
2307
|
</head>
|
|
2136
2308
|
<body>
|
|
@@ -2165,6 +2337,8 @@ ${styleTag}
|
|
|
2165
2337
|
</body>
|
|
2166
2338
|
</html>`;
|
|
2167
2339
|
}
|
|
2340
|
+
|
|
2341
|
+
// src/desktop/auto-render/message-handler.ts
|
|
2168
2342
|
function resolveDesktopBridgePayloadRoute(payload) {
|
|
2169
2343
|
if (!payload) {
|
|
2170
2344
|
return void 0;
|
|
@@ -2181,19 +2355,6 @@ ${styleTag}
|
|
|
2181
2355
|
}
|
|
2182
2356
|
return void 0;
|
|
2183
2357
|
}
|
|
2184
|
-
function installDesktopRenderTracking() {
|
|
2185
|
-
const globalScope = getDesktopAutoRenderGlobals();
|
|
2186
|
-
globalScope[DESKTOP_WINDOW_CREATED_KEY] = false;
|
|
2187
|
-
if (globalScope[DESKTOP_RENDER_TRACKED_KEY] || typeof globalScope.createWindow !== "function") {
|
|
2188
|
-
return;
|
|
2189
|
-
}
|
|
2190
|
-
const originalCreateWindow = globalScope.createWindow.bind(globalScope);
|
|
2191
|
-
globalScope.createWindow = (options) => {
|
|
2192
|
-
globalScope[DESKTOP_WINDOW_CREATED_KEY] = true;
|
|
2193
|
-
return originalCreateWindow(options);
|
|
2194
|
-
};
|
|
2195
|
-
globalScope[DESKTOP_RENDER_TRACKED_KEY] = true;
|
|
2196
|
-
}
|
|
2197
2358
|
function installDesktopMessageHandler(options) {
|
|
2198
2359
|
const globalScope = getDesktopAutoRenderGlobals();
|
|
2199
2360
|
let routeHistory = [];
|
|
@@ -2301,6 +2462,23 @@ ${styleTag}
|
|
|
2301
2462
|
});
|
|
2302
2463
|
globalScope[DESKTOP_MESSAGE_HANDLER_KEY] = true;
|
|
2303
2464
|
}
|
|
2465
|
+
|
|
2466
|
+
// src/desktop/auto-render/tracking.ts
|
|
2467
|
+
function installDesktopRenderTracking() {
|
|
2468
|
+
const globalScope = getDesktopAutoRenderGlobals();
|
|
2469
|
+
globalScope[DESKTOP_WINDOW_CREATED_KEY] = false;
|
|
2470
|
+
if (globalScope[DESKTOP_RENDER_TRACKED_KEY] || typeof globalScope.createWindow !== "function") {
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
const originalCreateWindow = globalScope.createWindow.bind(globalScope);
|
|
2474
|
+
globalScope.createWindow = (options) => {
|
|
2475
|
+
globalScope[DESKTOP_WINDOW_CREATED_KEY] = true;
|
|
2476
|
+
return originalCreateWindow(options);
|
|
2477
|
+
};
|
|
2478
|
+
globalScope[DESKTOP_RENDER_TRACKED_KEY] = true;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
// src/desktop/auto-render/complete.ts
|
|
2304
2482
|
function completeDesktopAutoRender(options = {}) {
|
|
2305
2483
|
installDesktopRenderTracking();
|
|
2306
2484
|
const globalScope = getDesktopAutoRenderGlobals();
|
|
@@ -2332,7 +2510,7 @@ ${styleTag}
|
|
|
2332
2510
|
icon: resolvedOptions.icon,
|
|
2333
2511
|
html: buildDesktopAutoHtml({
|
|
2334
2512
|
css: styles.render(),
|
|
2335
|
-
markup:
|
|
2513
|
+
markup: renderToString2(capturedRender.vNode),
|
|
2336
2514
|
title: resolvedOptions.title
|
|
2337
2515
|
})
|
|
2338
2516
|
});
|