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