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