sibujs 1.2.0 → 1.3.0
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/README.md +29 -25
- package/dist/browser.cjs +804 -2
- package/dist/browser.d.cts +591 -1
- package/dist/browser.d.ts +591 -1
- package/dist/browser.js +50 -8
- package/dist/build.cjs +654 -144
- package/dist/build.js +14 -12
- package/dist/cdn.global.js +188 -7
- package/dist/chunk-2BYQDGN3.js +742 -0
- package/dist/chunk-32DY64NT.js +282 -0
- package/dist/chunk-3AIRKM3B.js +1263 -0
- package/dist/chunk-3X2YG6YM.js +505 -0
- package/dist/chunk-5X6PP2UK.js +28 -0
- package/dist/chunk-77L6NL3X.js +1097 -0
- package/dist/chunk-BGN5ZMP4.js +26 -0
- package/dist/chunk-BTU3TJDS.js +365 -0
- package/dist/chunk-CHF5OHIA.js +61 -0
- package/dist/chunk-CMBFNA7L.js +27 -0
- package/dist/chunk-DAHRH4ON.js +331 -0
- package/dist/chunk-EBGIRKQY.js +616 -0
- package/dist/chunk-EUZND3CB.js +27 -0
- package/dist/chunk-F3FA4F32.js +292 -0
- package/dist/chunk-JAKHTMQU.js +1000 -0
- package/dist/chunk-JCI5M6U6.js +956 -0
- package/dist/chunk-KQPDEVVS.js +398 -0
- package/dist/chunk-NEKUBFPT.js +60 -0
- package/dist/chunk-NYVAC6P5.js +37 -0
- package/dist/chunk-PTQJDMRT.js +146 -0
- package/dist/chunk-QWZG56ET.js +2744 -0
- package/dist/chunk-TSOKIX5Z.js +654 -0
- package/dist/chunk-VRW3FULF.js +725 -0
- package/dist/chunk-WZSPOOER.js +84 -0
- package/dist/chunk-YT6HQ6AM.js +14 -0
- package/dist/chunk-ZD6OAMTH.js +277 -0
- package/dist/contracts-DDrwxvJ-.d.cts +245 -0
- package/dist/contracts-DDrwxvJ-.d.ts +245 -0
- package/dist/data.cjs +35 -2
- package/dist/data.d.cts +7 -0
- package/dist/data.d.ts +7 -0
- package/dist/data.js +9 -8
- package/dist/devtools.cjs +122 -0
- package/dist/devtools.d.cts +69 -461
- package/dist/devtools.d.ts +69 -461
- package/dist/devtools.js +127 -6
- package/dist/ecosystem.cjs +23 -6
- package/dist/ecosystem.d.cts +1 -1
- package/dist/ecosystem.d.ts +1 -1
- package/dist/ecosystem.js +10 -9
- package/dist/extras.cjs +1207 -65
- package/dist/extras.d.cts +5 -5
- package/dist/extras.d.ts +5 -5
- package/dist/extras.js +69 -24
- package/dist/index.cjs +663 -144
- package/dist/index.d.cts +397 -17
- package/dist/index.d.ts +397 -17
- package/dist/index.js +39 -17
- package/dist/introspect-BumjnBKr.d.cts +477 -0
- package/dist/introspect-CZrlcaYy.d.ts +477 -0
- package/dist/introspect-Cb0zgpi2.d.cts +477 -0
- package/dist/introspect-Y2xNXGSf.d.ts +477 -0
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +51 -2
- package/dist/patterns.d.cts +18 -8
- package/dist/patterns.d.ts +18 -8
- package/dist/patterns.js +7 -7
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +428 -81
- package/dist/plugins.d.cts +27 -4
- package/dist/plugins.d.ts +27 -4
- package/dist/plugins.js +156 -37
- package/dist/ssr-4PBXAOO3.js +40 -0
- package/dist/ssr-Do_SiVoL.d.cts +201 -0
- package/dist/ssr-Do_SiVoL.d.ts +201 -0
- package/dist/ssr.cjs +312 -60
- package/dist/ssr.d.cts +10 -1
- package/dist/ssr.d.ts +10 -1
- package/dist/ssr.js +13 -10
- package/dist/tagFactory-DaJ0YWX6.d.cts +47 -0
- package/dist/tagFactory-DaJ0YWX6.d.ts +47 -0
- package/dist/testing.cjs +233 -2
- package/dist/testing.d.cts +42 -1
- package/dist/testing.d.ts +42 -1
- package/dist/testing.js +129 -2
- package/dist/ui.cjs +374 -3
- package/dist/ui.d.cts +252 -2
- package/dist/ui.d.ts +252 -2
- package/dist/ui.js +328 -8
- package/dist/widgets.js +7 -7
- package/package.json +1 -1
package/dist/extras.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(extras_exports, {
|
|
|
32
32
|
VirtualList: () => VirtualList,
|
|
33
33
|
accordion: () => accordion,
|
|
34
34
|
animate: () => animate,
|
|
35
|
+
animationFrame: () => animationFrame,
|
|
35
36
|
announce: () => announce,
|
|
36
37
|
antdAdapter: () => antdAdapter,
|
|
37
38
|
aria: () => aria,
|
|
@@ -44,6 +45,8 @@ __export(extras_exports, {
|
|
|
44
45
|
block: () => block,
|
|
45
46
|
bounceIn: () => bounceIn,
|
|
46
47
|
bounceOut: () => bounceOut,
|
|
48
|
+
bounds: () => bounds,
|
|
49
|
+
broadcast: () => broadcast,
|
|
47
50
|
bundlerMetadata: () => bundlerMetadata,
|
|
48
51
|
calculateDelay: () => calculateDelay,
|
|
49
52
|
chakraAdapter: () => chakraAdapter,
|
|
@@ -117,10 +120,12 @@ __export(extras_exports, {
|
|
|
117
120
|
email: () => email,
|
|
118
121
|
enableDebug: () => enableDebug,
|
|
119
122
|
env: () => env,
|
|
123
|
+
escapeScriptJson: () => escapeScriptJson,
|
|
120
124
|
eventBus: () => eventBus,
|
|
121
125
|
executeLoader: () => executeLoader,
|
|
122
126
|
fadeIn: () => fadeIn,
|
|
123
127
|
fadeOut: () => fadeOut,
|
|
128
|
+
favicon: () => favicon,
|
|
124
129
|
fileUpload: () => fileUpload,
|
|
125
130
|
flipIn: () => flipIn,
|
|
126
131
|
flushScheduler: () => flushScheduler,
|
|
@@ -129,6 +134,8 @@ __export(extras_exports, {
|
|
|
129
134
|
formatCurrency: () => formatCurrency,
|
|
130
135
|
formatError: () => formatError,
|
|
131
136
|
formatNumber: () => formatNumber,
|
|
137
|
+
fullscreen: () => fullscreen,
|
|
138
|
+
gamepad: () => gamepad,
|
|
132
139
|
generateStaticSite: () => generateStaticSite,
|
|
133
140
|
geo: () => geo,
|
|
134
141
|
getActiveDevTools: () => getActiveDevTools,
|
|
@@ -147,6 +154,7 @@ __export(extras_exports, {
|
|
|
147
154
|
hydrateIslands: () => hydrateIslands,
|
|
148
155
|
hydrateProgressively: () => hydrateProgressively,
|
|
149
156
|
idle: () => idle,
|
|
157
|
+
imageLoader: () => imageLoader,
|
|
150
158
|
infiniteQuery: () => infiniteQuery,
|
|
151
159
|
infiniteScroll: () => infiniteScroll,
|
|
152
160
|
initDevTools: () => initDevTools,
|
|
@@ -159,6 +167,7 @@ __export(extras_exports, {
|
|
|
159
167
|
isHMRAvailable: () => isHMRAvailable,
|
|
160
168
|
isWasmCached: () => isWasmCached,
|
|
161
169
|
island: () => island,
|
|
170
|
+
keyboard: () => keyboard,
|
|
162
171
|
lazyChunk: () => lazyChunk,
|
|
163
172
|
lazyLoad: () => lazyLoad,
|
|
164
173
|
lazyModule: () => lazyModule,
|
|
@@ -175,7 +184,10 @@ __export(extras_exports, {
|
|
|
175
184
|
min: () => min,
|
|
176
185
|
minLength: () => minLength,
|
|
177
186
|
mobXAdapter: () => mobXAdapter,
|
|
187
|
+
mouse: () => mouse,
|
|
178
188
|
mutation: () => mutation,
|
|
189
|
+
mutationObserver: () => mutationObserver,
|
|
190
|
+
network: () => network,
|
|
179
191
|
noSideEffect: () => noSideEffect,
|
|
180
192
|
normalize: () => normalize,
|
|
181
193
|
normalizedStore: () => normalizedStore,
|
|
@@ -192,6 +204,7 @@ __export(extras_exports, {
|
|
|
192
204
|
persisted: () => persisted,
|
|
193
205
|
phoneMask: () => phoneMask,
|
|
194
206
|
plugin: () => plugin,
|
|
207
|
+
pointerLock: () => pointerLock,
|
|
195
208
|
popover: () => popover,
|
|
196
209
|
precompile: () => precompile,
|
|
197
210
|
prefetch: () => prefetch,
|
|
@@ -243,6 +256,7 @@ __export(extras_exports, {
|
|
|
243
256
|
slideIn: () => slideIn,
|
|
244
257
|
slideOut: () => slideOut,
|
|
245
258
|
socket: () => socket,
|
|
259
|
+
speech: () => speech,
|
|
246
260
|
spring: () => spring,
|
|
247
261
|
springSignal: () => springSignal,
|
|
248
262
|
ssnMask: () => ssnMask,
|
|
@@ -254,8 +268,11 @@ __export(extras_exports, {
|
|
|
254
268
|
stream: () => stream,
|
|
255
269
|
suspenseSwapScript: () => suspenseSwapScript,
|
|
256
270
|
svgElement: () => svgElement,
|
|
271
|
+
svgFavicon: () => svgFavicon,
|
|
272
|
+
swipe: () => swipe,
|
|
257
273
|
syncAdapter: () => syncAdapter,
|
|
258
274
|
tabs: () => tabs,
|
|
275
|
+
textSelection: () => textSelection,
|
|
259
276
|
throttle: () => throttle,
|
|
260
277
|
timeMask: () => timeMask,
|
|
261
278
|
timeline: () => timeline,
|
|
@@ -270,11 +287,16 @@ __export(extras_exports, {
|
|
|
270
287
|
triggerPluginUnmount: () => triggerPluginUnmount,
|
|
271
288
|
trustHTML: () => trustHTML,
|
|
272
289
|
uniqueId: () => uniqueId,
|
|
290
|
+
urlState: () => urlState,
|
|
273
291
|
validateProps: () => validateProps,
|
|
274
292
|
validators: () => validators,
|
|
293
|
+
vibrate: () => vibrate,
|
|
275
294
|
viewTransition: () => viewTransition,
|
|
295
|
+
visibility: () => visibility,
|
|
296
|
+
wakeLock: () => wakeLock,
|
|
276
297
|
walkDependencyGraph: () => walkDependencyGraph,
|
|
277
298
|
wasm: () => wasm,
|
|
299
|
+
windowSize: () => windowSize,
|
|
278
300
|
withBoundary: () => withBoundary,
|
|
279
301
|
withDefaults: () => withDefaults,
|
|
280
302
|
withErrorTracking: () => withErrorTracking,
|
|
@@ -1512,6 +1534,13 @@ async function preloadRoute(route, context2) {
|
|
|
1512
1534
|
}
|
|
1513
1535
|
|
|
1514
1536
|
// src/ui/socket.ts
|
|
1537
|
+
function validateWsUrl(raw) {
|
|
1538
|
+
const trimmed = raw.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1539
|
+
if (!trimmed) return null;
|
|
1540
|
+
const lower = trimmed.toLowerCase();
|
|
1541
|
+
if (lower.startsWith("ws://") || lower.startsWith("wss://")) return trimmed;
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1515
1544
|
function socket(url, options) {
|
|
1516
1545
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
1517
1546
|
const reconnectDelay = options?.reconnectDelay ?? 1e3;
|
|
@@ -1530,8 +1559,13 @@ function socket(url, options) {
|
|
|
1530
1559
|
}
|
|
1531
1560
|
function connect() {
|
|
1532
1561
|
if (disposed) return;
|
|
1562
|
+
const safeUrl = validateWsUrl(getUrl());
|
|
1563
|
+
if (safeUrl === null) {
|
|
1564
|
+
setStatus("closed");
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1533
1567
|
setStatus("connecting");
|
|
1534
|
-
ws = new WebSocket(
|
|
1568
|
+
ws = new WebSocket(safeUrl, protocols);
|
|
1535
1569
|
ws.onopen = () => {
|
|
1536
1570
|
setStatus("open");
|
|
1537
1571
|
reconnectCount = 0;
|
|
@@ -1592,7 +1626,34 @@ function socket(url, options) {
|
|
|
1592
1626
|
return { data: data2, status, send, close, dispose };
|
|
1593
1627
|
}
|
|
1594
1628
|
|
|
1629
|
+
// src/utils/sanitize.ts
|
|
1630
|
+
function sanitizeUrl(url) {
|
|
1631
|
+
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1632
|
+
if (!trimmed) return "";
|
|
1633
|
+
const lower = trimmed.toLowerCase();
|
|
1634
|
+
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
1635
|
+
return "";
|
|
1636
|
+
}
|
|
1637
|
+
return trimmed;
|
|
1638
|
+
}
|
|
1639
|
+
function sanitizeCSSValue(value) {
|
|
1640
|
+
const lower = value.toLowerCase().replace(/\s+/g, "");
|
|
1641
|
+
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("-moz-binding")) {
|
|
1642
|
+
return "";
|
|
1643
|
+
}
|
|
1644
|
+
return value;
|
|
1645
|
+
}
|
|
1646
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
1647
|
+
function isUrlAttribute(attr) {
|
|
1648
|
+
return URL_ATTRIBUTES.has(attr);
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1595
1651
|
// src/ui/stream.ts
|
|
1652
|
+
function validateSseUrl(raw) {
|
|
1653
|
+
const safe = sanitizeUrl(raw);
|
|
1654
|
+
if (!safe) return null;
|
|
1655
|
+
return safe;
|
|
1656
|
+
}
|
|
1596
1657
|
function stream(url, options) {
|
|
1597
1658
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
1598
1659
|
const [data2, setData] = signal(null);
|
|
@@ -1603,8 +1664,13 @@ function stream(url, options) {
|
|
|
1603
1664
|
let reconnectTimer = null;
|
|
1604
1665
|
function connect() {
|
|
1605
1666
|
if (disposed) return;
|
|
1667
|
+
const safeUrl = validateSseUrl(url);
|
|
1668
|
+
if (safeUrl === null) {
|
|
1669
|
+
setStatus("closed");
|
|
1670
|
+
return;
|
|
1671
|
+
}
|
|
1606
1672
|
setStatus("connecting");
|
|
1607
|
-
source2 = new EventSource(
|
|
1673
|
+
source2 = new EventSource(safeUrl, {
|
|
1608
1674
|
withCredentials: options?.withCredentials ?? false
|
|
1609
1675
|
});
|
|
1610
1676
|
source2.onopen = () => {
|
|
@@ -2103,6 +2169,766 @@ function formatCurrency(value, currency, options) {
|
|
|
2103
2169
|
}).format(value);
|
|
2104
2170
|
}
|
|
2105
2171
|
|
|
2172
|
+
// src/browser/visibility.ts
|
|
2173
|
+
function visibility() {
|
|
2174
|
+
if (typeof document === "undefined") {
|
|
2175
|
+
const [visible2] = signal(true);
|
|
2176
|
+
return { visible: visible2, dispose: () => {
|
|
2177
|
+
} };
|
|
2178
|
+
}
|
|
2179
|
+
const [visible, setVisible] = signal(!document.hidden);
|
|
2180
|
+
const handler = () => setVisible(!document.hidden);
|
|
2181
|
+
document.addEventListener("visibilitychange", handler);
|
|
2182
|
+
function dispose() {
|
|
2183
|
+
document.removeEventListener("visibilitychange", handler);
|
|
2184
|
+
}
|
|
2185
|
+
return { visible, dispose };
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
// src/browser/network.ts
|
|
2189
|
+
function network() {
|
|
2190
|
+
const connection = typeof navigator !== "undefined" ? navigator.connection ?? navigator.mozConnection ?? navigator.webkitConnection : void 0;
|
|
2191
|
+
const [effectiveType, setEffectiveType] = signal(connection?.effectiveType ?? "unknown");
|
|
2192
|
+
const [downlink, setDownlink] = signal(connection?.downlink ?? 0);
|
|
2193
|
+
const [rtt, setRtt] = signal(connection?.rtt ?? 0);
|
|
2194
|
+
const [saveData, setSaveData] = signal(connection?.saveData ?? false);
|
|
2195
|
+
if (!connection) {
|
|
2196
|
+
return { effectiveType, downlink, rtt, saveData, dispose: () => {
|
|
2197
|
+
} };
|
|
2198
|
+
}
|
|
2199
|
+
const update = () => {
|
|
2200
|
+
setEffectiveType(connection.effectiveType ?? "unknown");
|
|
2201
|
+
setDownlink(connection.downlink ?? 0);
|
|
2202
|
+
setRtt(connection.rtt ?? 0);
|
|
2203
|
+
setSaveData(connection.saveData ?? false);
|
|
2204
|
+
};
|
|
2205
|
+
connection.addEventListener("change", update);
|
|
2206
|
+
function dispose() {
|
|
2207
|
+
connection?.removeEventListener("change", update);
|
|
2208
|
+
}
|
|
2209
|
+
return { effectiveType, downlink, rtt, saveData, dispose };
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
// src/browser/mouse.ts
|
|
2213
|
+
function mouse(options = {}) {
|
|
2214
|
+
const [x, setX] = signal(0);
|
|
2215
|
+
const [y, setY] = signal(0);
|
|
2216
|
+
if (typeof window === "undefined") {
|
|
2217
|
+
return { x, y, dispose: () => {
|
|
2218
|
+
} };
|
|
2219
|
+
}
|
|
2220
|
+
const target = options.target ?? window;
|
|
2221
|
+
const trackTouch = options.touch ?? true;
|
|
2222
|
+
const onMove = (e) => {
|
|
2223
|
+
setX(e.clientX);
|
|
2224
|
+
setY(e.clientY);
|
|
2225
|
+
};
|
|
2226
|
+
const onTouchMove = (e) => {
|
|
2227
|
+
if (e.touches.length === 0) return;
|
|
2228
|
+
setX(e.touches[0].clientX);
|
|
2229
|
+
setY(e.touches[0].clientY);
|
|
2230
|
+
};
|
|
2231
|
+
target.addEventListener("mousemove", onMove, { passive: true });
|
|
2232
|
+
if (trackTouch) {
|
|
2233
|
+
target.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
2234
|
+
}
|
|
2235
|
+
function dispose() {
|
|
2236
|
+
target.removeEventListener("mousemove", onMove);
|
|
2237
|
+
if (trackTouch) {
|
|
2238
|
+
target.removeEventListener("touchmove", onTouchMove);
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
return { x, y, dispose };
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
// src/browser/swipe.ts
|
|
2245
|
+
function swipe(target, options = {}) {
|
|
2246
|
+
const threshold = options.threshold ?? 50;
|
|
2247
|
+
const [direction, setDirection] = signal(null);
|
|
2248
|
+
if (typeof window === "undefined") {
|
|
2249
|
+
return { direction, dispose: () => {
|
|
2250
|
+
} };
|
|
2251
|
+
}
|
|
2252
|
+
let startX = 0;
|
|
2253
|
+
let startY = 0;
|
|
2254
|
+
let tracking = false;
|
|
2255
|
+
const onStart = (e) => {
|
|
2256
|
+
if (e.touches.length === 0) return;
|
|
2257
|
+
startX = e.touches[0].clientX;
|
|
2258
|
+
startY = e.touches[0].clientY;
|
|
2259
|
+
tracking = true;
|
|
2260
|
+
};
|
|
2261
|
+
const onEnd = (e) => {
|
|
2262
|
+
if (!tracking) return;
|
|
2263
|
+
tracking = false;
|
|
2264
|
+
const touch = e.changedTouches[0];
|
|
2265
|
+
if (!touch) return;
|
|
2266
|
+
const dx = touch.clientX - startX;
|
|
2267
|
+
const dy = touch.clientY - startY;
|
|
2268
|
+
const absX = Math.abs(dx);
|
|
2269
|
+
const absY = Math.abs(dy);
|
|
2270
|
+
if (Math.max(absX, absY) < threshold) return;
|
|
2271
|
+
let dir;
|
|
2272
|
+
if (absX > absY) {
|
|
2273
|
+
dir = dx > 0 ? "right" : "left";
|
|
2274
|
+
} else {
|
|
2275
|
+
dir = dy > 0 ? "down" : "up";
|
|
2276
|
+
}
|
|
2277
|
+
setDirection(dir);
|
|
2278
|
+
options.onSwipe?.(dir, Math.max(absX, absY));
|
|
2279
|
+
};
|
|
2280
|
+
target.addEventListener("touchstart", onStart, { passive: true });
|
|
2281
|
+
target.addEventListener("touchend", onEnd, { passive: true });
|
|
2282
|
+
function dispose() {
|
|
2283
|
+
target.removeEventListener("touchstart", onStart);
|
|
2284
|
+
target.removeEventListener("touchend", onEnd);
|
|
2285
|
+
}
|
|
2286
|
+
return { direction, dispose };
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// src/browser/windowSize.ts
|
|
2290
|
+
function windowSize() {
|
|
2291
|
+
if (typeof window === "undefined") {
|
|
2292
|
+
const [width2] = signal(0);
|
|
2293
|
+
const [height2] = signal(0);
|
|
2294
|
+
return { width: width2, height: height2, dispose: () => {
|
|
2295
|
+
} };
|
|
2296
|
+
}
|
|
2297
|
+
const [width, setWidth] = signal(window.innerWidth);
|
|
2298
|
+
const [height, setHeight] = signal(window.innerHeight);
|
|
2299
|
+
const handler = () => {
|
|
2300
|
+
setWidth(window.innerWidth);
|
|
2301
|
+
setHeight(window.innerHeight);
|
|
2302
|
+
};
|
|
2303
|
+
window.addEventListener("resize", handler, { passive: true });
|
|
2304
|
+
function dispose() {
|
|
2305
|
+
window.removeEventListener("resize", handler);
|
|
2306
|
+
}
|
|
2307
|
+
return { width, height, dispose };
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
// src/browser/urlState.ts
|
|
2311
|
+
function urlState() {
|
|
2312
|
+
if (typeof window === "undefined") {
|
|
2313
|
+
const [params2] = signal(new URLSearchParams());
|
|
2314
|
+
const [hash2] = signal("");
|
|
2315
|
+
return {
|
|
2316
|
+
params: params2,
|
|
2317
|
+
hash: hash2,
|
|
2318
|
+
setParams: () => {
|
|
2319
|
+
},
|
|
2320
|
+
setHash: () => {
|
|
2321
|
+
},
|
|
2322
|
+
dispose: () => {
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
const [params, setParamsSignal] = signal(new URLSearchParams(window.location.search));
|
|
2327
|
+
const [hash, setHashSignal] = signal(window.location.hash);
|
|
2328
|
+
const syncFromLocation = () => {
|
|
2329
|
+
setParamsSignal(new URLSearchParams(window.location.search));
|
|
2330
|
+
setHashSignal(window.location.hash);
|
|
2331
|
+
};
|
|
2332
|
+
const onPopState = () => syncFromLocation();
|
|
2333
|
+
window.addEventListener("popstate", onPopState);
|
|
2334
|
+
function setParams(next, opts = {}) {
|
|
2335
|
+
const p2 = next instanceof URLSearchParams ? next : new URLSearchParams(next);
|
|
2336
|
+
const query2 = p2.toString();
|
|
2337
|
+
const newUrl = `${window.location.pathname}${query2 ? `?${query2}` : ""}${window.location.hash}`;
|
|
2338
|
+
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
2339
|
+
else window.history.pushState(null, "", newUrl);
|
|
2340
|
+
setParamsSignal(new URLSearchParams(p2));
|
|
2341
|
+
}
|
|
2342
|
+
function setHash(next, opts = {}) {
|
|
2343
|
+
const normalized = next.startsWith("#") ? next : next ? `#${next}` : "";
|
|
2344
|
+
const newUrl = `${window.location.pathname}${window.location.search}${normalized}`;
|
|
2345
|
+
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
2346
|
+
else window.history.pushState(null, "", newUrl);
|
|
2347
|
+
setHashSignal(normalized);
|
|
2348
|
+
}
|
|
2349
|
+
function dispose() {
|
|
2350
|
+
window.removeEventListener("popstate", onPopState);
|
|
2351
|
+
}
|
|
2352
|
+
return { params, hash, setParams, setHash, dispose };
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
// src/browser/broadcast.ts
|
|
2356
|
+
function broadcast(channelName) {
|
|
2357
|
+
if (typeof BroadcastChannel === "undefined") {
|
|
2358
|
+
const [last2] = signal(null);
|
|
2359
|
+
return { last: last2, post: () => {
|
|
2360
|
+
}, dispose: () => {
|
|
2361
|
+
} };
|
|
2362
|
+
}
|
|
2363
|
+
const [last, setLast] = signal(null);
|
|
2364
|
+
const channel = new BroadcastChannel(channelName);
|
|
2365
|
+
const handler = (ev) => setLast(ev.data);
|
|
2366
|
+
channel.addEventListener("message", handler);
|
|
2367
|
+
function post(message) {
|
|
2368
|
+
channel.postMessage(message);
|
|
2369
|
+
}
|
|
2370
|
+
function dispose() {
|
|
2371
|
+
channel.removeEventListener("message", handler);
|
|
2372
|
+
channel.close();
|
|
2373
|
+
}
|
|
2374
|
+
return { last, post, dispose };
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
// src/browser/fullscreen.ts
|
|
2378
|
+
function fullscreen() {
|
|
2379
|
+
if (typeof document === "undefined") {
|
|
2380
|
+
const [isFullscreen2] = signal(false);
|
|
2381
|
+
const [element2] = signal(null);
|
|
2382
|
+
return {
|
|
2383
|
+
isFullscreen: isFullscreen2,
|
|
2384
|
+
element: element2,
|
|
2385
|
+
enter: async () => {
|
|
2386
|
+
},
|
|
2387
|
+
exit: async () => {
|
|
2388
|
+
},
|
|
2389
|
+
toggle: async () => {
|
|
2390
|
+
},
|
|
2391
|
+
dispose: () => {
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
const [isFullscreen, setIsFullscreen] = signal(!!document.fullscreenElement);
|
|
2396
|
+
const [element, setElement] = signal(document.fullscreenElement);
|
|
2397
|
+
const handler = () => {
|
|
2398
|
+
setIsFullscreen(!!document.fullscreenElement);
|
|
2399
|
+
setElement(document.fullscreenElement);
|
|
2400
|
+
};
|
|
2401
|
+
document.addEventListener("fullscreenchange", handler);
|
|
2402
|
+
async function enter(el) {
|
|
2403
|
+
if (!document.fullscreenElement && el.requestFullscreen) {
|
|
2404
|
+
await el.requestFullscreen();
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
async function exit() {
|
|
2408
|
+
if (document.fullscreenElement && document.exitFullscreen) {
|
|
2409
|
+
await document.exitFullscreen();
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
async function toggle(el) {
|
|
2413
|
+
if (document.fullscreenElement) await exit();
|
|
2414
|
+
else await enter(el);
|
|
2415
|
+
}
|
|
2416
|
+
function dispose() {
|
|
2417
|
+
document.removeEventListener("fullscreenchange", handler);
|
|
2418
|
+
}
|
|
2419
|
+
return { isFullscreen, element, enter, exit, toggle, dispose };
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
// src/browser/wakeLock.ts
|
|
2423
|
+
function wakeLock() {
|
|
2424
|
+
const [active, setActive] = signal(false);
|
|
2425
|
+
if (typeof navigator === "undefined" || !("wakeLock" in navigator) || typeof document === "undefined") {
|
|
2426
|
+
return {
|
|
2427
|
+
active,
|
|
2428
|
+
request: async () => {
|
|
2429
|
+
},
|
|
2430
|
+
release: async () => {
|
|
2431
|
+
},
|
|
2432
|
+
dispose: () => {
|
|
2433
|
+
}
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
const api = navigator.wakeLock;
|
|
2437
|
+
let sentinel = null;
|
|
2438
|
+
async function request() {
|
|
2439
|
+
try {
|
|
2440
|
+
sentinel = await api.request("screen");
|
|
2441
|
+
setActive(true);
|
|
2442
|
+
sentinel.addEventListener("release", () => {
|
|
2443
|
+
setActive(false);
|
|
2444
|
+
});
|
|
2445
|
+
} catch {
|
|
2446
|
+
setActive(false);
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
async function release() {
|
|
2450
|
+
if (sentinel && !sentinel.released) {
|
|
2451
|
+
await sentinel.release();
|
|
2452
|
+
}
|
|
2453
|
+
sentinel = null;
|
|
2454
|
+
setActive(false);
|
|
2455
|
+
}
|
|
2456
|
+
const onVisibility = () => {
|
|
2457
|
+
if (sentinel?.released && !document.hidden) {
|
|
2458
|
+
void request();
|
|
2459
|
+
}
|
|
2460
|
+
};
|
|
2461
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
2462
|
+
function dispose() {
|
|
2463
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
2464
|
+
void release();
|
|
2465
|
+
}
|
|
2466
|
+
return { active, request, release, dispose };
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
// src/browser/animationFrame.ts
|
|
2470
|
+
function animationFrame(options = {}) {
|
|
2471
|
+
const [delta, setDelta] = signal(0);
|
|
2472
|
+
const [elapsed, setElapsed] = signal(0);
|
|
2473
|
+
const [running, setRunning] = signal(false);
|
|
2474
|
+
if (typeof requestAnimationFrame === "undefined") {
|
|
2475
|
+
return {
|
|
2476
|
+
delta,
|
|
2477
|
+
elapsed,
|
|
2478
|
+
running,
|
|
2479
|
+
pause: () => {
|
|
2480
|
+
},
|
|
2481
|
+
resume: () => {
|
|
2482
|
+
},
|
|
2483
|
+
dispose: () => {
|
|
2484
|
+
}
|
|
2485
|
+
};
|
|
2486
|
+
}
|
|
2487
|
+
let id = null;
|
|
2488
|
+
let prev = -1;
|
|
2489
|
+
let start = -1;
|
|
2490
|
+
const minFrameMs = options.fpsLimit ? 1e3 / options.fpsLimit : 0;
|
|
2491
|
+
const step = (now) => {
|
|
2492
|
+
if (start < 0) start = now;
|
|
2493
|
+
const firstTick = prev < 0;
|
|
2494
|
+
const dt2 = firstTick ? 0 : now - prev;
|
|
2495
|
+
if (firstTick || dt2 >= minFrameMs) {
|
|
2496
|
+
setDelta(dt2);
|
|
2497
|
+
setElapsed(now - start);
|
|
2498
|
+
prev = now;
|
|
2499
|
+
}
|
|
2500
|
+
id = requestAnimationFrame(step);
|
|
2501
|
+
};
|
|
2502
|
+
function resume() {
|
|
2503
|
+
if (id !== null) return;
|
|
2504
|
+
setRunning(true);
|
|
2505
|
+
id = requestAnimationFrame(step);
|
|
2506
|
+
}
|
|
2507
|
+
function pause() {
|
|
2508
|
+
if (id !== null) {
|
|
2509
|
+
cancelAnimationFrame(id);
|
|
2510
|
+
id = null;
|
|
2511
|
+
}
|
|
2512
|
+
setRunning(false);
|
|
2513
|
+
prev = -1;
|
|
2514
|
+
start = -1;
|
|
2515
|
+
}
|
|
2516
|
+
function dispose() {
|
|
2517
|
+
pause();
|
|
2518
|
+
}
|
|
2519
|
+
if (options.immediate !== false) resume();
|
|
2520
|
+
return { delta, elapsed, running, pause, resume, dispose };
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
// src/browser/mutationObserver.ts
|
|
2524
|
+
function mutationObserver(target, options = { childList: true, subtree: true }) {
|
|
2525
|
+
const [records, setRecords] = signal([]);
|
|
2526
|
+
if (typeof MutationObserver === "undefined") {
|
|
2527
|
+
return { records, dispose: () => {
|
|
2528
|
+
} };
|
|
2529
|
+
}
|
|
2530
|
+
const observer = new MutationObserver((batch2) => {
|
|
2531
|
+
setRecords(batch2);
|
|
2532
|
+
});
|
|
2533
|
+
observer.observe(target, options);
|
|
2534
|
+
function dispose() {
|
|
2535
|
+
observer.disconnect();
|
|
2536
|
+
}
|
|
2537
|
+
return { records, dispose };
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
// src/browser/bounds.ts
|
|
2541
|
+
var ZERO = {
|
|
2542
|
+
x: 0,
|
|
2543
|
+
y: 0,
|
|
2544
|
+
width: 0,
|
|
2545
|
+
height: 0,
|
|
2546
|
+
top: 0,
|
|
2547
|
+
left: 0,
|
|
2548
|
+
right: 0,
|
|
2549
|
+
bottom: 0
|
|
2550
|
+
};
|
|
2551
|
+
function readRect(el) {
|
|
2552
|
+
const r = el.getBoundingClientRect();
|
|
2553
|
+
return {
|
|
2554
|
+
x: r.x,
|
|
2555
|
+
y: r.y,
|
|
2556
|
+
width: r.width,
|
|
2557
|
+
height: r.height,
|
|
2558
|
+
top: r.top,
|
|
2559
|
+
left: r.left,
|
|
2560
|
+
right: r.right,
|
|
2561
|
+
bottom: r.bottom
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
function bounds(target) {
|
|
2565
|
+
const [rect2, setRect] = signal(ZERO);
|
|
2566
|
+
if (typeof window === "undefined" || !target) {
|
|
2567
|
+
return {
|
|
2568
|
+
rect: rect2,
|
|
2569
|
+
refresh: () => {
|
|
2570
|
+
},
|
|
2571
|
+
dispose: () => {
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
function refresh() {
|
|
2576
|
+
setRect(readRect(target));
|
|
2577
|
+
}
|
|
2578
|
+
refresh();
|
|
2579
|
+
let resizeObserver = null;
|
|
2580
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2581
|
+
resizeObserver = new ResizeObserver(refresh);
|
|
2582
|
+
resizeObserver.observe(target);
|
|
2583
|
+
}
|
|
2584
|
+
const onScroll = () => refresh();
|
|
2585
|
+
window.addEventListener("scroll", onScroll, { passive: true, capture: true });
|
|
2586
|
+
function dispose() {
|
|
2587
|
+
resizeObserver?.disconnect();
|
|
2588
|
+
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
2589
|
+
}
|
|
2590
|
+
return { rect: rect2, refresh, dispose };
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
// src/browser/keyboard.ts
|
|
2594
|
+
function keyboard(options = {}) {
|
|
2595
|
+
const [pressed, setPressed] = signal(/* @__PURE__ */ new Set());
|
|
2596
|
+
if (typeof window === "undefined") {
|
|
2597
|
+
return {
|
|
2598
|
+
pressed,
|
|
2599
|
+
isPressed: () => false,
|
|
2600
|
+
dispose: () => {
|
|
2601
|
+
}
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
const target = options.target ?? window;
|
|
2605
|
+
const filter = options.keys ? new Set(options.keys) : null;
|
|
2606
|
+
const onDown = (e) => {
|
|
2607
|
+
if (filter && !filter.has(e.key)) return;
|
|
2608
|
+
setPressed((prev) => {
|
|
2609
|
+
if (prev.has(e.key)) return prev;
|
|
2610
|
+
const next = new Set(prev);
|
|
2611
|
+
next.add(e.key);
|
|
2612
|
+
return next;
|
|
2613
|
+
});
|
|
2614
|
+
};
|
|
2615
|
+
const onUp = (e) => {
|
|
2616
|
+
if (filter && !filter.has(e.key)) return;
|
|
2617
|
+
setPressed((prev) => {
|
|
2618
|
+
if (!prev.has(e.key)) return prev;
|
|
2619
|
+
const next = new Set(prev);
|
|
2620
|
+
next.delete(e.key);
|
|
2621
|
+
return next;
|
|
2622
|
+
});
|
|
2623
|
+
};
|
|
2624
|
+
const onBlur = () => setPressed(/* @__PURE__ */ new Set());
|
|
2625
|
+
target.addEventListener("keydown", onDown);
|
|
2626
|
+
target.addEventListener("keyup", onUp);
|
|
2627
|
+
window.addEventListener("blur", onBlur);
|
|
2628
|
+
function isPressed(key) {
|
|
2629
|
+
return pressed().has(key);
|
|
2630
|
+
}
|
|
2631
|
+
function dispose() {
|
|
2632
|
+
target.removeEventListener("keydown", onDown);
|
|
2633
|
+
target.removeEventListener("keyup", onUp);
|
|
2634
|
+
window.removeEventListener("blur", onBlur);
|
|
2635
|
+
}
|
|
2636
|
+
return { pressed, isPressed, dispose };
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
// src/browser/speech.ts
|
|
2640
|
+
function speech() {
|
|
2641
|
+
const [speaking, setSpeaking] = signal(false);
|
|
2642
|
+
const [paused, setPaused] = signal(false);
|
|
2643
|
+
if (typeof window === "undefined" || typeof window.speechSynthesis === "undefined") {
|
|
2644
|
+
return {
|
|
2645
|
+
speaking,
|
|
2646
|
+
paused,
|
|
2647
|
+
speak: () => {
|
|
2648
|
+
},
|
|
2649
|
+
pause: () => {
|
|
2650
|
+
},
|
|
2651
|
+
resume: () => {
|
|
2652
|
+
},
|
|
2653
|
+
cancel: () => {
|
|
2654
|
+
},
|
|
2655
|
+
dispose: () => {
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
}
|
|
2659
|
+
const synth = window.speechSynthesis;
|
|
2660
|
+
const interval = setInterval(() => {
|
|
2661
|
+
setSpeaking(synth.speaking);
|
|
2662
|
+
setPaused(synth.paused);
|
|
2663
|
+
}, 200);
|
|
2664
|
+
function speak(text2, options = {}) {
|
|
2665
|
+
const u2 = new SpeechSynthesisUtterance(text2);
|
|
2666
|
+
if (options.lang) u2.lang = options.lang;
|
|
2667
|
+
if (options.rate != null) u2.rate = options.rate;
|
|
2668
|
+
if (options.pitch != null) u2.pitch = options.pitch;
|
|
2669
|
+
if (options.volume != null) u2.volume = options.volume;
|
|
2670
|
+
if (options.voice) {
|
|
2671
|
+
const voices = synth.getVoices();
|
|
2672
|
+
const match = voices.find((v) => v.name === options.voice);
|
|
2673
|
+
if (match) u2.voice = match;
|
|
2674
|
+
}
|
|
2675
|
+
u2.addEventListener("start", () => setSpeaking(true));
|
|
2676
|
+
u2.addEventListener("end", () => {
|
|
2677
|
+
setSpeaking(false);
|
|
2678
|
+
setPaused(false);
|
|
2679
|
+
});
|
|
2680
|
+
u2.addEventListener("error", () => {
|
|
2681
|
+
setSpeaking(false);
|
|
2682
|
+
setPaused(false);
|
|
2683
|
+
});
|
|
2684
|
+
synth.speak(u2);
|
|
2685
|
+
}
|
|
2686
|
+
function dispose() {
|
|
2687
|
+
clearInterval(interval);
|
|
2688
|
+
synth.cancel();
|
|
2689
|
+
}
|
|
2690
|
+
return {
|
|
2691
|
+
speaking,
|
|
2692
|
+
paused,
|
|
2693
|
+
speak,
|
|
2694
|
+
pause: () => synth.pause(),
|
|
2695
|
+
resume: () => synth.resume(),
|
|
2696
|
+
cancel: () => synth.cancel(),
|
|
2697
|
+
dispose
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
// src/browser/gamepad.ts
|
|
2702
|
+
function gamepad() {
|
|
2703
|
+
const [pads, setPads] = signal([]);
|
|
2704
|
+
if (typeof window === "undefined" || typeof navigator === "undefined" || typeof navigator.getGamepads !== "function") {
|
|
2705
|
+
return { pads, dispose: () => {
|
|
2706
|
+
} };
|
|
2707
|
+
}
|
|
2708
|
+
let rafId = null;
|
|
2709
|
+
function snapshot(pad) {
|
|
2710
|
+
return {
|
|
2711
|
+
index: pad.index,
|
|
2712
|
+
id: pad.id,
|
|
2713
|
+
connected: pad.connected,
|
|
2714
|
+
buttons: pad.buttons.map((b2) => ({ pressed: b2.pressed, value: b2.value })),
|
|
2715
|
+
axes: [...pad.axes]
|
|
2716
|
+
};
|
|
2717
|
+
}
|
|
2718
|
+
function equal(a2, b2) {
|
|
2719
|
+
if (a2.length !== b2.length) return false;
|
|
2720
|
+
for (let i2 = 0; i2 < a2.length; i2++) {
|
|
2721
|
+
const pa = a2[i2];
|
|
2722
|
+
const pb = b2[i2];
|
|
2723
|
+
if (pa.index !== pb.index || pa.connected !== pb.connected) return false;
|
|
2724
|
+
if (pa.buttons.length !== pb.buttons.length) return false;
|
|
2725
|
+
for (let j = 0; j < pa.buttons.length; j++) {
|
|
2726
|
+
if (pa.buttons[j].pressed !== pb.buttons[j].pressed) return false;
|
|
2727
|
+
if (pa.buttons[j].value !== pb.buttons[j].value) return false;
|
|
2728
|
+
}
|
|
2729
|
+
if (pa.axes.length !== pb.axes.length) return false;
|
|
2730
|
+
for (let j = 0; j < pa.axes.length; j++) {
|
|
2731
|
+
if (pa.axes[j] !== pb.axes[j]) return false;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
return true;
|
|
2735
|
+
}
|
|
2736
|
+
function poll() {
|
|
2737
|
+
const raw = navigator.getGamepads();
|
|
2738
|
+
const snap = Array.from(raw).filter((g2) => g2 !== null).map(snapshot);
|
|
2739
|
+
const current = pads();
|
|
2740
|
+
if (!equal(current, snap)) setPads(snap);
|
|
2741
|
+
rafId = requestAnimationFrame(poll);
|
|
2742
|
+
}
|
|
2743
|
+
function startPolling() {
|
|
2744
|
+
if (rafId === null) poll();
|
|
2745
|
+
}
|
|
2746
|
+
function stopPolling() {
|
|
2747
|
+
if (rafId !== null) {
|
|
2748
|
+
cancelAnimationFrame(rafId);
|
|
2749
|
+
rafId = null;
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
const onConnect = () => startPolling();
|
|
2753
|
+
const onDisconnect = () => {
|
|
2754
|
+
const raw = navigator.getGamepads();
|
|
2755
|
+
const hasAny = Array.from(raw).some((g2) => g2 !== null);
|
|
2756
|
+
if (!hasAny) stopPolling();
|
|
2757
|
+
};
|
|
2758
|
+
window.addEventListener("gamepadconnected", onConnect);
|
|
2759
|
+
window.addEventListener("gamepaddisconnected", onDisconnect);
|
|
2760
|
+
const initial = Array.from(navigator.getGamepads()).some((g2) => g2 !== null);
|
|
2761
|
+
if (initial) startPolling();
|
|
2762
|
+
function dispose() {
|
|
2763
|
+
stopPolling();
|
|
2764
|
+
window.removeEventListener("gamepadconnected", onConnect);
|
|
2765
|
+
window.removeEventListener("gamepaddisconnected", onDisconnect);
|
|
2766
|
+
}
|
|
2767
|
+
return { pads, dispose };
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
// src/browser/pointerLock.ts
|
|
2771
|
+
function pointerLock() {
|
|
2772
|
+
const [locked, setLocked] = signal(false);
|
|
2773
|
+
if (typeof document === "undefined") {
|
|
2774
|
+
return {
|
|
2775
|
+
locked,
|
|
2776
|
+
request: () => {
|
|
2777
|
+
},
|
|
2778
|
+
exit: () => {
|
|
2779
|
+
},
|
|
2780
|
+
dispose: () => {
|
|
2781
|
+
}
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
const handler = () => {
|
|
2785
|
+
setLocked(!!document.pointerLockElement);
|
|
2786
|
+
};
|
|
2787
|
+
document.addEventListener("pointerlockchange", handler);
|
|
2788
|
+
function request(element) {
|
|
2789
|
+
if (typeof element.requestPointerLock === "function") {
|
|
2790
|
+
element.requestPointerLock();
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
function exit() {
|
|
2794
|
+
if (typeof document.exitPointerLock === "function") {
|
|
2795
|
+
document.exitPointerLock();
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
function dispose() {
|
|
2799
|
+
document.removeEventListener("pointerlockchange", handler);
|
|
2800
|
+
}
|
|
2801
|
+
return { locked, request, exit, dispose };
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
// src/browser/vibrate.ts
|
|
2805
|
+
function vibrate(pattern2) {
|
|
2806
|
+
if (typeof navigator === "undefined" || typeof navigator.vibrate !== "function") {
|
|
2807
|
+
return false;
|
|
2808
|
+
}
|
|
2809
|
+
return navigator.vibrate(pattern2);
|
|
2810
|
+
}
|
|
2811
|
+
|
|
2812
|
+
// src/browser/favicon.ts
|
|
2813
|
+
function favicon(url) {
|
|
2814
|
+
if (typeof document === "undefined") return;
|
|
2815
|
+
let link2 = document.querySelector("link[rel='icon']");
|
|
2816
|
+
if (!link2) {
|
|
2817
|
+
link2 = document.createElement("link");
|
|
2818
|
+
link2.rel = "icon";
|
|
2819
|
+
document.head.appendChild(link2);
|
|
2820
|
+
}
|
|
2821
|
+
link2.href = url;
|
|
2822
|
+
}
|
|
2823
|
+
function svgFavicon(svg2) {
|
|
2824
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg2)}`;
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
// src/browser/textSelection.ts
|
|
2828
|
+
function textSelection() {
|
|
2829
|
+
const [text2, setText] = signal("");
|
|
2830
|
+
const [rect2, setRect] = signal(null);
|
|
2831
|
+
if (typeof document === "undefined") {
|
|
2832
|
+
return {
|
|
2833
|
+
text: text2,
|
|
2834
|
+
rect: rect2,
|
|
2835
|
+
hasSelection: () => false,
|
|
2836
|
+
clear: () => {
|
|
2837
|
+
},
|
|
2838
|
+
dispose: () => {
|
|
2839
|
+
}
|
|
2840
|
+
};
|
|
2841
|
+
}
|
|
2842
|
+
const handler = () => {
|
|
2843
|
+
const sel = document.getSelection();
|
|
2844
|
+
if (!sel || sel.rangeCount === 0 || sel.isCollapsed) {
|
|
2845
|
+
setText("");
|
|
2846
|
+
setRect(null);
|
|
2847
|
+
return;
|
|
2848
|
+
}
|
|
2849
|
+
setText(sel.toString());
|
|
2850
|
+
try {
|
|
2851
|
+
const r = sel.getRangeAt(0).getBoundingClientRect();
|
|
2852
|
+
setRect(r.width > 0 || r.height > 0 ? r : null);
|
|
2853
|
+
} catch {
|
|
2854
|
+
setRect(null);
|
|
2855
|
+
}
|
|
2856
|
+
};
|
|
2857
|
+
document.addEventListener("selectionchange", handler);
|
|
2858
|
+
function clear() {
|
|
2859
|
+
const sel = document.getSelection();
|
|
2860
|
+
sel?.removeAllRanges();
|
|
2861
|
+
setText("");
|
|
2862
|
+
setRect(null);
|
|
2863
|
+
}
|
|
2864
|
+
function dispose() {
|
|
2865
|
+
document.removeEventListener("selectionchange", handler);
|
|
2866
|
+
}
|
|
2867
|
+
return {
|
|
2868
|
+
text: text2,
|
|
2869
|
+
rect: rect2,
|
|
2870
|
+
hasSelection: () => text2().length > 0,
|
|
2871
|
+
clear,
|
|
2872
|
+
dispose
|
|
2873
|
+
};
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
// src/browser/imageLoader.ts
|
|
2877
|
+
function imageLoader(src) {
|
|
2878
|
+
const [status, setStatus] = signal("pending");
|
|
2879
|
+
const [image, setImage] = signal(null);
|
|
2880
|
+
const [width, setWidth] = signal(0);
|
|
2881
|
+
const [height, setHeight] = signal(0);
|
|
2882
|
+
if (typeof Image === "undefined") {
|
|
2883
|
+
return {
|
|
2884
|
+
status,
|
|
2885
|
+
image,
|
|
2886
|
+
width,
|
|
2887
|
+
height,
|
|
2888
|
+
dispose: () => {
|
|
2889
|
+
}
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
let current = null;
|
|
2893
|
+
let disposed = false;
|
|
2894
|
+
function start(url) {
|
|
2895
|
+
if (current) {
|
|
2896
|
+
current.onload = null;
|
|
2897
|
+
current.onerror = null;
|
|
2898
|
+
}
|
|
2899
|
+
setStatus("pending");
|
|
2900
|
+
setImage(null);
|
|
2901
|
+
const img2 = new Image();
|
|
2902
|
+
current = img2;
|
|
2903
|
+
img2.onload = () => {
|
|
2904
|
+
if (disposed || current !== img2) return;
|
|
2905
|
+
setImage(img2);
|
|
2906
|
+
setWidth(img2.naturalWidth);
|
|
2907
|
+
setHeight(img2.naturalHeight);
|
|
2908
|
+
setStatus("loaded");
|
|
2909
|
+
};
|
|
2910
|
+
img2.onerror = () => {
|
|
2911
|
+
if (disposed || current !== img2) return;
|
|
2912
|
+
setStatus("error");
|
|
2913
|
+
};
|
|
2914
|
+
img2.src = url;
|
|
2915
|
+
}
|
|
2916
|
+
if (typeof src === "function") {
|
|
2917
|
+
start(src());
|
|
2918
|
+
} else {
|
|
2919
|
+
start(src);
|
|
2920
|
+
}
|
|
2921
|
+
function dispose() {
|
|
2922
|
+
disposed = true;
|
|
2923
|
+
if (current) {
|
|
2924
|
+
current.onload = null;
|
|
2925
|
+
current.onerror = null;
|
|
2926
|
+
current = null;
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
return { status, image, width, height, dispose };
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2106
2932
|
// src/patterns/machine.ts
|
|
2107
2933
|
function machine(config) {
|
|
2108
2934
|
const [state, setState] = signal(config.initial);
|
|
@@ -2133,8 +2959,13 @@ function machine(config) {
|
|
|
2133
2959
|
stateDef.exit(ctx);
|
|
2134
2960
|
}
|
|
2135
2961
|
if (action) {
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2962
|
+
const rawPatch = action(ctx);
|
|
2963
|
+
const next = { ...ctx };
|
|
2964
|
+
for (const key of Object.keys(rawPatch)) {
|
|
2965
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
2966
|
+
next[key] = rawPatch[key];
|
|
2967
|
+
}
|
|
2968
|
+
setContext(next);
|
|
2138
2969
|
}
|
|
2139
2970
|
setState(target);
|
|
2140
2971
|
const targetDef = config.states[target];
|
|
@@ -2167,6 +2998,7 @@ function persisted(key, initial, options = {}) {
|
|
|
2167
2998
|
const deserialize = options.deserialize || JSON.parse;
|
|
2168
2999
|
const encrypt = options.encrypt;
|
|
2169
3000
|
const decrypt = options.decrypt;
|
|
3001
|
+
const syncTabs = options.session ? false : options.syncTabs ?? true;
|
|
2170
3002
|
let restored = initial;
|
|
2171
3003
|
try {
|
|
2172
3004
|
let raw = storage.getItem(key);
|
|
@@ -2178,8 +3010,10 @@ function persisted(key, initial, options = {}) {
|
|
|
2178
3010
|
} catch {
|
|
2179
3011
|
}
|
|
2180
3012
|
const [value, setValue] = signal(restored);
|
|
3013
|
+
let applyingFromStorage = false;
|
|
2181
3014
|
effect(() => {
|
|
2182
3015
|
const current = value();
|
|
3016
|
+
if (applyingFromStorage) return;
|
|
2183
3017
|
try {
|
|
2184
3018
|
let serialized = serialize(current);
|
|
2185
3019
|
if (encrypt) serialized = encrypt(serialized);
|
|
@@ -2187,6 +3021,47 @@ function persisted(key, initial, options = {}) {
|
|
|
2187
3021
|
} catch {
|
|
2188
3022
|
}
|
|
2189
3023
|
});
|
|
3024
|
+
let storageListener = null;
|
|
3025
|
+
if (syncTabs && typeof window !== "undefined") {
|
|
3026
|
+
storageListener = (e) => {
|
|
3027
|
+
if (e.storageArea !== storage || e.key !== key) return;
|
|
3028
|
+
if (e.newValue === null) {
|
|
3029
|
+
applyingFromStorage = true;
|
|
3030
|
+
try {
|
|
3031
|
+
setValue(initial);
|
|
3032
|
+
} finally {
|
|
3033
|
+
applyingFromStorage = false;
|
|
3034
|
+
}
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
try {
|
|
3038
|
+
let raw = e.newValue;
|
|
3039
|
+
if (decrypt) raw = decrypt(raw);
|
|
3040
|
+
const parsed = deserialize(raw);
|
|
3041
|
+
if (options.validate && !options.validate(parsed)) return;
|
|
3042
|
+
applyingFromStorage = true;
|
|
3043
|
+
try {
|
|
3044
|
+
setValue(parsed);
|
|
3045
|
+
} finally {
|
|
3046
|
+
applyingFromStorage = false;
|
|
3047
|
+
}
|
|
3048
|
+
} catch {
|
|
3049
|
+
}
|
|
3050
|
+
};
|
|
3051
|
+
window.addEventListener("storage", storageListener);
|
|
3052
|
+
}
|
|
3053
|
+
const dispose = () => {
|
|
3054
|
+
if (storageListener && typeof window !== "undefined") {
|
|
3055
|
+
window.removeEventListener("storage", storageListener);
|
|
3056
|
+
storageListener = null;
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
Object.defineProperty(setValue, "dispose", {
|
|
3060
|
+
value: dispose,
|
|
3061
|
+
enumerable: false,
|
|
3062
|
+
writable: false,
|
|
3063
|
+
configurable: false
|
|
3064
|
+
});
|
|
2190
3065
|
return [value, setValue];
|
|
2191
3066
|
}
|
|
2192
3067
|
|
|
@@ -3375,8 +4250,25 @@ function announce(message, priority = "polite") {
|
|
|
3375
4250
|
|
|
3376
4251
|
// src/ui/scopedStyle.ts
|
|
3377
4252
|
var scopeCounter = 0;
|
|
4253
|
+
function decodeCssEscapes(css) {
|
|
4254
|
+
return css.replace(/\\([0-9a-f]{1,6})[ \t\n\r\f]?|\\([^\n])/gi, (_match, hex, ch) => {
|
|
4255
|
+
if (hex) {
|
|
4256
|
+
const code2 = Number.parseInt(hex, 16);
|
|
4257
|
+
if (Number.isFinite(code2) && code2 > 0 && code2 <= 1114111) {
|
|
4258
|
+
try {
|
|
4259
|
+
return String.fromCodePoint(code2);
|
|
4260
|
+
} catch {
|
|
4261
|
+
return "";
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
return "";
|
|
4265
|
+
}
|
|
4266
|
+
return ch || "";
|
|
4267
|
+
});
|
|
4268
|
+
}
|
|
3378
4269
|
function sanitizeCSS(css) {
|
|
3379
|
-
let sanitized = css
|
|
4270
|
+
let sanitized = decodeCssEscapes(css);
|
|
4271
|
+
sanitized = sanitized.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
|
|
3380
4272
|
sanitized = sanitized.replace(/url\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* url() removed */");
|
|
3381
4273
|
sanitized = sanitized.replace(/expression\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* expression() removed */");
|
|
3382
4274
|
sanitized = sanitized.replace(/-moz-binding\s*:[^;]+;/gi, "/* -moz-binding removed */");
|
|
@@ -3426,31 +4318,22 @@ function removeScopedStyle(scopeId) {
|
|
|
3426
4318
|
if (el) el.remove();
|
|
3427
4319
|
}
|
|
3428
4320
|
|
|
3429
|
-
// src/utils/sanitize.ts
|
|
3430
|
-
function sanitizeUrl(url) {
|
|
3431
|
-
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
3432
|
-
if (!trimmed) return "";
|
|
3433
|
-
const lower = trimmed.toLowerCase();
|
|
3434
|
-
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
3435
|
-
return "";
|
|
3436
|
-
}
|
|
3437
|
-
return trimmed;
|
|
3438
|
-
}
|
|
3439
|
-
function sanitizeCSSValue(value) {
|
|
3440
|
-
const lower = value.toLowerCase().replace(/\s+/g, "");
|
|
3441
|
-
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("-moz-binding")) {
|
|
3442
|
-
return "";
|
|
3443
|
-
}
|
|
3444
|
-
return value;
|
|
3445
|
-
}
|
|
3446
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
3447
|
-
function isUrlAttribute(attr) {
|
|
3448
|
-
return URL_ATTRIBUTES.has(attr);
|
|
3449
|
-
}
|
|
3450
|
-
|
|
3451
4321
|
// src/reactivity/bindAttribute.ts
|
|
3452
4322
|
var _isDev4 = isDev();
|
|
4323
|
+
function isEventHandlerAttr(name) {
|
|
4324
|
+
if (name.length < 3) return false;
|
|
4325
|
+
const lower = name.toLowerCase();
|
|
4326
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
4327
|
+
}
|
|
3453
4328
|
function bindAttribute(el, attr, getter) {
|
|
4329
|
+
if (isEventHandlerAttr(attr)) {
|
|
4330
|
+
if (_isDev4)
|
|
4331
|
+
devWarn(
|
|
4332
|
+
`bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
|
|
4333
|
+
);
|
|
4334
|
+
return () => {
|
|
4335
|
+
};
|
|
4336
|
+
}
|
|
3454
4337
|
function commit() {
|
|
3455
4338
|
let value;
|
|
3456
4339
|
try {
|
|
@@ -4374,11 +5257,34 @@ function preloadModules(urls) {
|
|
|
4374
5257
|
}
|
|
4375
5258
|
|
|
4376
5259
|
// src/platform/head.ts
|
|
4377
|
-
var HEAD_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"
|
|
5260
|
+
var HEAD_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"]);
|
|
4378
5261
|
function sanitizeHeadAttr(key, value) {
|
|
4379
5262
|
if (HEAD_URL_ATTRS.has(key)) return sanitizeUrl(value);
|
|
4380
5263
|
return value;
|
|
4381
5264
|
}
|
|
5265
|
+
function isDangerousMetaRefresh(metaProps) {
|
|
5266
|
+
const httpEquiv = metaProps["http-equiv"];
|
|
5267
|
+
if (typeof httpEquiv !== "string") return false;
|
|
5268
|
+
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
5269
|
+
const content = metaProps.content;
|
|
5270
|
+
if (typeof content !== "string") return false;
|
|
5271
|
+
const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
|
|
5272
|
+
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
5273
|
+
}
|
|
5274
|
+
var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
5275
|
+
function isEventHandlerAttr2(name) {
|
|
5276
|
+
if (name.length < 3) return false;
|
|
5277
|
+
const lower = name.toLowerCase();
|
|
5278
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5279
|
+
}
|
|
5280
|
+
function isSafeHeadAttr(name) {
|
|
5281
|
+
if (!SAFE_HEAD_ATTR_NAME.test(name)) return false;
|
|
5282
|
+
if (isEventHandlerAttr2(name)) return false;
|
|
5283
|
+
return true;
|
|
5284
|
+
}
|
|
5285
|
+
function escapeScriptJsonLocal(json) {
|
|
5286
|
+
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
5287
|
+
}
|
|
4382
5288
|
function Head(props) {
|
|
4383
5289
|
const anchor = document.createComment("sibu-head");
|
|
4384
5290
|
const managedElements = [];
|
|
@@ -4405,15 +5311,17 @@ function Head(props) {
|
|
|
4405
5311
|
}
|
|
4406
5312
|
if (props.meta) {
|
|
4407
5313
|
for (const metaProps of props.meta) {
|
|
5314
|
+
if (isDangerousMetaRefresh(metaProps)) continue;
|
|
4408
5315
|
const el = document.createElement("meta");
|
|
4409
5316
|
for (const [key, value] of Object.entries(metaProps)) {
|
|
5317
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4410
5318
|
if (typeof value === "function") {
|
|
4411
5319
|
const cleanupFn = effect(() => {
|
|
4412
|
-
el.setAttribute(key, value());
|
|
5320
|
+
el.setAttribute(key, sanitizeHeadAttr(key, value()));
|
|
4413
5321
|
});
|
|
4414
5322
|
effectCleanups.push(cleanupFn);
|
|
4415
5323
|
} else {
|
|
4416
|
-
el.setAttribute(key, value);
|
|
5324
|
+
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4417
5325
|
}
|
|
4418
5326
|
}
|
|
4419
5327
|
document.head.appendChild(el);
|
|
@@ -4424,6 +5332,7 @@ function Head(props) {
|
|
|
4424
5332
|
for (const linkProps of props.link) {
|
|
4425
5333
|
const el = document.createElement("link");
|
|
4426
5334
|
for (const [key, value] of Object.entries(linkProps)) {
|
|
5335
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4427
5336
|
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4428
5337
|
}
|
|
4429
5338
|
document.head.appendChild(el);
|
|
@@ -4434,6 +5343,7 @@ function Head(props) {
|
|
|
4434
5343
|
for (const scriptProps of props.script) {
|
|
4435
5344
|
const el = document.createElement("script");
|
|
4436
5345
|
for (const [key, value] of Object.entries(scriptProps)) {
|
|
5346
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4437
5347
|
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4438
5348
|
}
|
|
4439
5349
|
document.head.appendChild(el);
|
|
@@ -4444,7 +5354,10 @@ function Head(props) {
|
|
|
4444
5354
|
const existing = document.head.querySelector("base");
|
|
4445
5355
|
if (existing) existing.remove();
|
|
4446
5356
|
const el = document.createElement("base");
|
|
4447
|
-
if (props.base.href)
|
|
5357
|
+
if (props.base.href) {
|
|
5358
|
+
const safeHref = sanitizeUrl(props.base.href);
|
|
5359
|
+
if (safeHref) el.href = safeHref;
|
|
5360
|
+
}
|
|
4448
5361
|
if (props.base.target) el.target = props.base.target;
|
|
4449
5362
|
document.head.appendChild(el);
|
|
4450
5363
|
managedElements.push(el);
|
|
@@ -4459,7 +5372,7 @@ function setStructuredData(data2) {
|
|
|
4459
5372
|
const script2 = document.createElement("script");
|
|
4460
5373
|
script2.type = "application/ld+json";
|
|
4461
5374
|
script2.setAttribute("data-sibu", "true");
|
|
4462
|
-
script2.textContent = JSON.stringify(data2);
|
|
5375
|
+
script2.textContent = escapeScriptJsonLocal(JSON.stringify(data2));
|
|
4463
5376
|
document.head.appendChild(script2);
|
|
4464
5377
|
}
|
|
4465
5378
|
function setCanonical(url) {
|
|
@@ -4474,12 +5387,39 @@ function setCanonical(url) {
|
|
|
4474
5387
|
|
|
4475
5388
|
// src/platform/ssr.ts
|
|
4476
5389
|
var _isDev5 = isDev();
|
|
5390
|
+
var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
5391
|
+
function isSafeAttrName(name) {
|
|
5392
|
+
return SAFE_ATTR_NAME.test(name);
|
|
5393
|
+
}
|
|
5394
|
+
function isEventHandlerAttr3(name) {
|
|
5395
|
+
if (name.length < 3) return false;
|
|
5396
|
+
const lower = name.toLowerCase();
|
|
5397
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5398
|
+
}
|
|
5399
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
5400
|
+
"href",
|
|
5401
|
+
"src",
|
|
5402
|
+
"action",
|
|
5403
|
+
"formaction",
|
|
5404
|
+
"cite",
|
|
5405
|
+
"poster",
|
|
5406
|
+
"background",
|
|
5407
|
+
"srcset",
|
|
5408
|
+
"ping",
|
|
5409
|
+
"manifest",
|
|
5410
|
+
"data",
|
|
5411
|
+
"xlink:href"
|
|
5412
|
+
]);
|
|
4477
5413
|
function ssrErrorComment(err) {
|
|
4478
5414
|
if (_isDev5) {
|
|
4479
|
-
|
|
5415
|
+
const msg = escapeHtml(err instanceof Error ? err.message : String(err));
|
|
5416
|
+
return `<!--SSR error: ${safeCommentText(msg)}-->`;
|
|
4480
5417
|
}
|
|
4481
5418
|
return "<!--SSR error-->";
|
|
4482
5419
|
}
|
|
5420
|
+
function safeCommentText(text2) {
|
|
5421
|
+
return text2.replace(/-->/g, "-->").replace(/--!>/g, "--!>").replace(/<!--/g, "<!--").replace(/--$/g, "---");
|
|
5422
|
+
}
|
|
4483
5423
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
4484
5424
|
"area",
|
|
4485
5425
|
"base",
|
|
@@ -4510,16 +5450,30 @@ function renderToString(element) {
|
|
|
4510
5450
|
return escapeHtml(element.textContent || "");
|
|
4511
5451
|
}
|
|
4512
5452
|
if (element.nodeType === 8) {
|
|
4513
|
-
|
|
4514
|
-
return `<!--${content}-->`;
|
|
5453
|
+
return `<!--${safeCommentText(element.textContent || "")}-->`;
|
|
4515
5454
|
}
|
|
4516
5455
|
if (!(element instanceof HTMLElement)) {
|
|
4517
|
-
return element.textContent || "";
|
|
5456
|
+
return escapeHtml(element.textContent || "");
|
|
4518
5457
|
}
|
|
4519
5458
|
const tag = element.tagName.toLowerCase();
|
|
5459
|
+
if (tag === "script" || tag === "style") {
|
|
5460
|
+
return _isDev5 ? `<!--ssr:${tag}-stripped-->` : "";
|
|
5461
|
+
}
|
|
5462
|
+
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
5463
|
+
return _isDev5 ? "<!--ssr:invalid-tag-->" : "";
|
|
5464
|
+
}
|
|
4520
5465
|
let html2 = `<${tag}`;
|
|
4521
5466
|
for (const attr of Array.from(element.attributes)) {
|
|
4522
|
-
|
|
5467
|
+
const rawName = attr.name;
|
|
5468
|
+
if (!isSafeAttrName(rawName)) continue;
|
|
5469
|
+
if (isEventHandlerAttr3(rawName)) continue;
|
|
5470
|
+
const lowerName = rawName.toLowerCase();
|
|
5471
|
+
let value = attr.value;
|
|
5472
|
+
if (URL_ATTRS.has(lowerName)) {
|
|
5473
|
+
value = sanitizeUrl(value);
|
|
5474
|
+
if (!value) continue;
|
|
5475
|
+
}
|
|
5476
|
+
html2 += ` ${rawName}="${escapeAttr(value)}"`;
|
|
4523
5477
|
}
|
|
4524
5478
|
if (element.dataset && !element.dataset.sibuHydrate) {
|
|
4525
5479
|
html2 += ` data-sibu-ssr="true"`;
|
|
@@ -4538,8 +5492,25 @@ function renderToString(element) {
|
|
|
4538
5492
|
html2 += `</${tag}>`;
|
|
4539
5493
|
return html2;
|
|
4540
5494
|
}
|
|
4541
|
-
function hydrate(component, container) {
|
|
5495
|
+
function hydrate(component, container, options = {}) {
|
|
4542
5496
|
const clientTree = component();
|
|
5497
|
+
if (options.diagnostics) {
|
|
5498
|
+
const mismatches = [];
|
|
5499
|
+
collectMismatches(container.firstElementChild, clientTree, "", mismatches);
|
|
5500
|
+
if (mismatches.length > 0) {
|
|
5501
|
+
const first = mismatches[0];
|
|
5502
|
+
if (options.onMismatch) {
|
|
5503
|
+
options.onMismatch(first);
|
|
5504
|
+
} else if (_isDev5) {
|
|
5505
|
+
console.warn(
|
|
5506
|
+
`[Sibu hydration] ${first.message}
|
|
5507
|
+
at ${first.path}
|
|
5508
|
+
server: ${first.serverValue}
|
|
5509
|
+
client: ${first.clientValue}`
|
|
5510
|
+
);
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5513
|
+
}
|
|
4543
5514
|
hydrateNode(container.firstElementChild, clientTree);
|
|
4544
5515
|
container.setAttribute("data-sibu-hydrated", "true");
|
|
4545
5516
|
}
|
|
@@ -4551,9 +5522,119 @@ function hydrateNode(serverNode, clientNode) {
|
|
|
4551
5522
|
hydrateNode(serverChildren[i2], clientChildren[i2]);
|
|
4552
5523
|
}
|
|
4553
5524
|
}
|
|
5525
|
+
function collectMismatches(serverNode, clientNode, path2, out, max2 = 5) {
|
|
5526
|
+
if (out.length >= max2) return;
|
|
5527
|
+
const nodePath = path2 || clientNode?.tagName?.toLowerCase() || "(root)";
|
|
5528
|
+
if (!serverNode && clientNode) {
|
|
5529
|
+
out.push({
|
|
5530
|
+
kind: "child-count",
|
|
5531
|
+
path: nodePath,
|
|
5532
|
+
serverValue: "(missing)",
|
|
5533
|
+
clientValue: clientNode.tagName.toLowerCase(),
|
|
5534
|
+
message: "Client rendered a node that the server did not emit."
|
|
5535
|
+
});
|
|
5536
|
+
return;
|
|
5537
|
+
}
|
|
5538
|
+
if (serverNode && !clientNode) {
|
|
5539
|
+
out.push({
|
|
5540
|
+
kind: "child-count",
|
|
5541
|
+
path: nodePath,
|
|
5542
|
+
serverValue: serverNode.tagName.toLowerCase(),
|
|
5543
|
+
clientValue: "(missing)",
|
|
5544
|
+
message: "Server rendered a node that the client did not produce."
|
|
5545
|
+
});
|
|
5546
|
+
return;
|
|
5547
|
+
}
|
|
5548
|
+
if (!serverNode || !clientNode) return;
|
|
5549
|
+
if (serverNode.tagName !== clientNode.tagName) {
|
|
5550
|
+
out.push({
|
|
5551
|
+
kind: "tag",
|
|
5552
|
+
path: nodePath,
|
|
5553
|
+
serverValue: serverNode.tagName.toLowerCase(),
|
|
5554
|
+
clientValue: clientNode.tagName.toLowerCase(),
|
|
5555
|
+
message: "Element tag mismatch \u2014 server and client disagree on the element type."
|
|
5556
|
+
});
|
|
5557
|
+
return;
|
|
5558
|
+
}
|
|
5559
|
+
const skipAttrs = /* @__PURE__ */ new Set(["data-sibu-ssr", "data-sibu-hydrated", "data-sibu-island"]);
|
|
5560
|
+
const serverAttrs = /* @__PURE__ */ new Map();
|
|
5561
|
+
for (const a2 of Array.from(serverNode.attributes)) {
|
|
5562
|
+
if (!skipAttrs.has(a2.name)) serverAttrs.set(a2.name, a2.value);
|
|
5563
|
+
}
|
|
5564
|
+
const clientAttrs = /* @__PURE__ */ new Map();
|
|
5565
|
+
for (const a2 of Array.from(clientNode.attributes)) {
|
|
5566
|
+
if (!skipAttrs.has(a2.name)) clientAttrs.set(a2.name, a2.value);
|
|
5567
|
+
}
|
|
5568
|
+
for (const [name, value] of serverAttrs) {
|
|
5569
|
+
if (out.length >= max2) return;
|
|
5570
|
+
if (!clientAttrs.has(name)) {
|
|
5571
|
+
out.push({
|
|
5572
|
+
kind: "attribute",
|
|
5573
|
+
path: `${nodePath}[${name}]`,
|
|
5574
|
+
serverValue: value,
|
|
5575
|
+
clientValue: "(missing)",
|
|
5576
|
+
message: `Attribute "${name}" present on server but missing on client.`
|
|
5577
|
+
});
|
|
5578
|
+
} else if (clientAttrs.get(name) !== value) {
|
|
5579
|
+
out.push({
|
|
5580
|
+
kind: "attribute",
|
|
5581
|
+
path: `${nodePath}[${name}]`,
|
|
5582
|
+
serverValue: value,
|
|
5583
|
+
clientValue: clientAttrs.get(name) ?? "",
|
|
5584
|
+
message: `Attribute "${name}" differs between server and client.`
|
|
5585
|
+
});
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
for (const [name, value] of clientAttrs) {
|
|
5589
|
+
if (out.length >= max2) return;
|
|
5590
|
+
if (!serverAttrs.has(name)) {
|
|
5591
|
+
out.push({
|
|
5592
|
+
kind: "attribute",
|
|
5593
|
+
path: `${nodePath}[${name}]`,
|
|
5594
|
+
serverValue: "(missing)",
|
|
5595
|
+
clientValue: value,
|
|
5596
|
+
message: `Attribute "${name}" present on client but missing on server.`
|
|
5597
|
+
});
|
|
5598
|
+
}
|
|
5599
|
+
}
|
|
5600
|
+
const serverChildren = Array.from(serverNode.children);
|
|
5601
|
+
const clientChildren = Array.from(clientNode.children);
|
|
5602
|
+
const max22 = Math.max(serverChildren.length, clientChildren.length);
|
|
5603
|
+
for (let i2 = 0; i2 < max22; i2++) {
|
|
5604
|
+
if (out.length >= max2) return;
|
|
5605
|
+
const childPath = `${nodePath} > ${clientChildren[i2]?.tagName?.toLowerCase() ?? serverChildren[i2]?.tagName?.toLowerCase() ?? "?"}:nth-child(${i2 + 1})`;
|
|
5606
|
+
collectMismatches(serverChildren[i2] ?? null, clientChildren[i2] ?? null, childPath, out, max2);
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
4554
5609
|
function trustHTML(html2) {
|
|
4555
5610
|
return html2;
|
|
4556
5611
|
}
|
|
5612
|
+
function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
|
|
5613
|
+
if (!attrs) return "";
|
|
5614
|
+
const out = [];
|
|
5615
|
+
for (const rawKey of Object.keys(attrs)) {
|
|
5616
|
+
if (!Object.hasOwn(attrs, rawKey)) continue;
|
|
5617
|
+
if (!isSafeAttrName(rawKey)) continue;
|
|
5618
|
+
if (!allowEventHandlers && isEventHandlerAttr3(rawKey)) continue;
|
|
5619
|
+
const lowerKey = rawKey.toLowerCase();
|
|
5620
|
+
let value = String(attrs[rawKey]);
|
|
5621
|
+
if (URL_ATTRS.has(lowerKey)) {
|
|
5622
|
+
value = sanitizeUrl(value);
|
|
5623
|
+
if (!value) continue;
|
|
5624
|
+
}
|
|
5625
|
+
out.push(`${rawKey}="${escapeAttr(value)}"`);
|
|
5626
|
+
}
|
|
5627
|
+
return out.join(" ");
|
|
5628
|
+
}
|
|
5629
|
+
function isDangerousMetaRefresh2(metaProps) {
|
|
5630
|
+
const httpEquiv = metaProps["http-equiv"];
|
|
5631
|
+
if (typeof httpEquiv !== "string") return false;
|
|
5632
|
+
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
5633
|
+
const content = metaProps.content;
|
|
5634
|
+
if (typeof content !== "string") return false;
|
|
5635
|
+
const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
|
|
5636
|
+
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
5637
|
+
}
|
|
4557
5638
|
function renderToDocument(component, options = {}) {
|
|
4558
5639
|
let content;
|
|
4559
5640
|
try {
|
|
@@ -4561,14 +5642,22 @@ function renderToDocument(component, options = {}) {
|
|
|
4561
5642
|
} catch (err) {
|
|
4562
5643
|
content = ssrErrorComment(err);
|
|
4563
5644
|
}
|
|
4564
|
-
const metaTags = (options.meta || []).map(
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
).
|
|
4570
|
-
|
|
4571
|
-
|
|
5645
|
+
const metaTags = (options.meta || []).map((attrs) => {
|
|
5646
|
+
if (isDangerousMetaRefresh2(attrs)) return "";
|
|
5647
|
+
const pairs = buildAttrString(attrs);
|
|
5648
|
+
return pairs ? `<meta ${pairs} />` : "";
|
|
5649
|
+
}).filter(Boolean).join("\n ");
|
|
5650
|
+
const linkTags = (options.links || []).map((attrs) => {
|
|
5651
|
+
const pairs = buildAttrString(attrs);
|
|
5652
|
+
return pairs ? `<link ${pairs} />` : "";
|
|
5653
|
+
}).filter(Boolean).join("\n ");
|
|
5654
|
+
const scriptTags = (options.scripts || []).map((src) => {
|
|
5655
|
+
const safe = sanitizeUrl(String(src));
|
|
5656
|
+
if (!safe) return "";
|
|
5657
|
+
return `<script src="${escapeAttr(safe)}"></script>`;
|
|
5658
|
+
}).filter(Boolean).join("\n ");
|
|
5659
|
+
const bodyAttrPairs = buildAttrString(options.bodyAttrs);
|
|
5660
|
+
const bodyAttrs = bodyAttrPairs ? ` ${bodyAttrPairs}` : "";
|
|
4572
5661
|
return `<!DOCTYPE html>
|
|
4573
5662
|
<html>
|
|
4574
5663
|
<head>
|
|
@@ -4601,18 +5690,34 @@ async function* renderToStream(element) {
|
|
|
4601
5690
|
return;
|
|
4602
5691
|
}
|
|
4603
5692
|
if (element.nodeType === 8) {
|
|
4604
|
-
|
|
4605
|
-
yield `<!--${content}-->`;
|
|
5693
|
+
yield `<!--${safeCommentText(element.textContent || "")}-->`;
|
|
4606
5694
|
return;
|
|
4607
5695
|
}
|
|
4608
5696
|
if (!(element instanceof HTMLElement)) {
|
|
4609
|
-
yield element.textContent || "";
|
|
5697
|
+
yield escapeHtml(element.textContent || "");
|
|
4610
5698
|
return;
|
|
4611
5699
|
}
|
|
4612
5700
|
const tag = element.tagName.toLowerCase();
|
|
5701
|
+
if (tag === "script" || tag === "style") {
|
|
5702
|
+
if (_isDev5) yield `<!--ssr:${tag}-stripped-->`;
|
|
5703
|
+
return;
|
|
5704
|
+
}
|
|
5705
|
+
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
5706
|
+
if (_isDev5) yield "<!--ssr:invalid-tag-->";
|
|
5707
|
+
return;
|
|
5708
|
+
}
|
|
4613
5709
|
let openTag = `<${tag}`;
|
|
4614
5710
|
for (const attr of Array.from(element.attributes)) {
|
|
4615
|
-
|
|
5711
|
+
const rawName = attr.name;
|
|
5712
|
+
if (!isSafeAttrName(rawName)) continue;
|
|
5713
|
+
if (isEventHandlerAttr3(rawName)) continue;
|
|
5714
|
+
const lowerName = rawName.toLowerCase();
|
|
5715
|
+
let value = attr.value;
|
|
5716
|
+
if (URL_ATTRS.has(lowerName)) {
|
|
5717
|
+
value = sanitizeUrl(value);
|
|
5718
|
+
if (!value) continue;
|
|
5719
|
+
}
|
|
5720
|
+
openTag += ` ${rawName}="${escapeAttr(value)}"`;
|
|
4616
5721
|
}
|
|
4617
5722
|
if (VOID_ELEMENTS.has(tag)) {
|
|
4618
5723
|
yield `${openTag} />`;
|
|
@@ -4660,8 +5765,9 @@ function hydrateIslands(container, islands) {
|
|
|
4660
5765
|
const markers = container.querySelectorAll("[data-sibu-island]");
|
|
4661
5766
|
for (const marker2 of Array.from(markers)) {
|
|
4662
5767
|
const id = marker2.getAttribute("data-sibu-island") ?? "";
|
|
5768
|
+
if (!Object.hasOwn(islands, id)) continue;
|
|
4663
5769
|
const factory = islands[id];
|
|
4664
|
-
if (
|
|
5770
|
+
if (typeof factory !== "function") continue;
|
|
4665
5771
|
const clientTree = factory();
|
|
4666
5772
|
hydrateNode(marker2, clientTree);
|
|
4667
5773
|
marker2.setAttribute("data-sibu-hydrated", "true");
|
|
@@ -4673,8 +5779,9 @@ function hydrateProgressively(container, islands, options) {
|
|
|
4673
5779
|
const cleanups = [];
|
|
4674
5780
|
for (const marker2 of Array.from(markers)) {
|
|
4675
5781
|
const id = marker2.getAttribute("data-sibu-island") ?? "";
|
|
5782
|
+
if (!Object.hasOwn(islands, id)) continue;
|
|
4676
5783
|
const factory = islands[id];
|
|
4677
|
-
if (
|
|
5784
|
+
if (typeof factory !== "function") continue;
|
|
4678
5785
|
const observer = new IntersectionObserver(
|
|
4679
5786
|
(entries) => {
|
|
4680
5787
|
for (const entry of entries) {
|
|
@@ -4713,24 +5820,33 @@ function ssrSuspense(props) {
|
|
|
4713
5820
|
}));
|
|
4714
5821
|
return { element: wrapper, promise };
|
|
4715
5822
|
}
|
|
5823
|
+
var SAFE_SUSPENSE_ID = /^[A-Za-z0-9_-]+$/;
|
|
4716
5824
|
function suspenseSwapScript(id, nonce) {
|
|
4717
|
-
|
|
5825
|
+
if (!SAFE_SUSPENSE_ID.test(id)) {
|
|
5826
|
+
throw new Error(
|
|
5827
|
+
`[SibuJS SSR] suspenseSwapScript: id must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(id.slice(0, 32))})`
|
|
5828
|
+
);
|
|
5829
|
+
}
|
|
4718
5830
|
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
|
|
4719
|
-
return `<script${nonceAttr}>(function(){var t=document.getElementById("sibu-resolved-${
|
|
5831
|
+
return `<script${nonceAttr}>(function(){var t=document.getElementById("sibu-resolved-${id}");var f=document.querySelector('[data-sibu-suspense-id="${id}"]');if(t&&f){while(t.firstChild)f.appendChild(t.firstChild);t.remove();f.removeAttribute("data-sibu-suspense-id");}})()</script>`;
|
|
4720
5832
|
}
|
|
4721
|
-
async function* renderToSuspenseStream(element, pendingBoundaries = []) {
|
|
5833
|
+
async function* renderToSuspenseStream(element, pendingBoundaries = [], options) {
|
|
4722
5834
|
yield* renderToStream(element);
|
|
4723
5835
|
if (pendingBoundaries.length > 0) {
|
|
4724
5836
|
const resolved = await Promise.all(pendingBoundaries);
|
|
4725
5837
|
for (const { id, html: html2 } of resolved) {
|
|
4726
|
-
|
|
4727
|
-
yield
|
|
5838
|
+
if (!SAFE_SUSPENSE_ID.test(id)) continue;
|
|
5839
|
+
yield `<div hidden id="sibu-resolved-${id}">${html2}</div>`;
|
|
5840
|
+
yield suspenseSwapScript(id, options?.nonce);
|
|
4728
5841
|
}
|
|
4729
5842
|
}
|
|
4730
5843
|
}
|
|
4731
5844
|
var SSR_DATA_ATTR = "__SIBU_SSR_DATA__";
|
|
5845
|
+
function escapeScriptJson(json) {
|
|
5846
|
+
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
5847
|
+
}
|
|
4732
5848
|
function serializeState(state, nonce) {
|
|
4733
|
-
const json = JSON.stringify(state)
|
|
5849
|
+
const json = escapeScriptJson(JSON.stringify(state));
|
|
4734
5850
|
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
|
|
4735
5851
|
return `<script${nonceAttr}>window.${SSR_DATA_ATTR}=${json}</script>`;
|
|
4736
5852
|
}
|
|
@@ -4745,7 +5861,7 @@ function escapeHtml(str) {
|
|
|
4745
5861
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
4746
5862
|
}
|
|
4747
5863
|
function escapeAttr(str) {
|
|
4748
|
-
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
5864
|
+
return str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
4749
5865
|
}
|
|
4750
5866
|
|
|
4751
5867
|
// src/platform/customElement.ts
|
|
@@ -5300,16 +6416,20 @@ function appendChildren(el, nodes) {
|
|
|
5300
6416
|
var tagFactory = (tag, ns) => (first, second) => {
|
|
5301
6417
|
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
5302
6418
|
if (first === void 0) return el;
|
|
5303
|
-
if (
|
|
6419
|
+
if (typeof first === "string") {
|
|
6420
|
+
if (second !== void 0) {
|
|
6421
|
+
el.setAttribute("class", first);
|
|
6422
|
+
appendChildren(el, second);
|
|
6423
|
+
return el;
|
|
6424
|
+
}
|
|
5304
6425
|
el.textContent = first;
|
|
5305
6426
|
return el;
|
|
5306
6427
|
}
|
|
5307
|
-
if (
|
|
5308
|
-
el.
|
|
5309
|
-
appendChildren(el, second);
|
|
6428
|
+
if (typeof first === "number") {
|
|
6429
|
+
el.textContent = String(first);
|
|
5310
6430
|
return el;
|
|
5311
6431
|
}
|
|
5312
|
-
if (Array.isArray(first) || first instanceof Node) {
|
|
6432
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
5313
6433
|
appendChildren(el, first);
|
|
5314
6434
|
return el;
|
|
5315
6435
|
}
|
|
@@ -5318,7 +6438,7 @@ var tagFactory = (tag, ns) => (first, second) => {
|
|
|
5318
6438
|
if (pClass != null) applyClass(el, pClass);
|
|
5319
6439
|
const pId = props.id;
|
|
5320
6440
|
if (pId != null) el.id = pId;
|
|
5321
|
-
const pNodes = props.nodes;
|
|
6441
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
5322
6442
|
if (pNodes != null) appendChildren(el, pNodes);
|
|
5323
6443
|
const pOn = props.on;
|
|
5324
6444
|
if (pOn) {
|
|
@@ -8619,6 +9739,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8619
9739
|
VirtualList,
|
|
8620
9740
|
accordion,
|
|
8621
9741
|
animate,
|
|
9742
|
+
animationFrame,
|
|
8622
9743
|
announce,
|
|
8623
9744
|
antdAdapter,
|
|
8624
9745
|
aria,
|
|
@@ -8631,6 +9752,8 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8631
9752
|
block,
|
|
8632
9753
|
bounceIn,
|
|
8633
9754
|
bounceOut,
|
|
9755
|
+
bounds,
|
|
9756
|
+
broadcast,
|
|
8634
9757
|
bundlerMetadata,
|
|
8635
9758
|
calculateDelay,
|
|
8636
9759
|
chakraAdapter,
|
|
@@ -8704,10 +9827,12 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8704
9827
|
email,
|
|
8705
9828
|
enableDebug,
|
|
8706
9829
|
env,
|
|
9830
|
+
escapeScriptJson,
|
|
8707
9831
|
eventBus,
|
|
8708
9832
|
executeLoader,
|
|
8709
9833
|
fadeIn,
|
|
8710
9834
|
fadeOut,
|
|
9835
|
+
favicon,
|
|
8711
9836
|
fileUpload,
|
|
8712
9837
|
flipIn,
|
|
8713
9838
|
flushScheduler,
|
|
@@ -8716,6 +9841,8 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8716
9841
|
formatCurrency,
|
|
8717
9842
|
formatError,
|
|
8718
9843
|
formatNumber,
|
|
9844
|
+
fullscreen,
|
|
9845
|
+
gamepad,
|
|
8719
9846
|
generateStaticSite,
|
|
8720
9847
|
geo,
|
|
8721
9848
|
getActiveDevTools,
|
|
@@ -8734,6 +9861,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8734
9861
|
hydrateIslands,
|
|
8735
9862
|
hydrateProgressively,
|
|
8736
9863
|
idle,
|
|
9864
|
+
imageLoader,
|
|
8737
9865
|
infiniteQuery,
|
|
8738
9866
|
infiniteScroll,
|
|
8739
9867
|
initDevTools,
|
|
@@ -8746,6 +9874,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8746
9874
|
isHMRAvailable,
|
|
8747
9875
|
isWasmCached,
|
|
8748
9876
|
island,
|
|
9877
|
+
keyboard,
|
|
8749
9878
|
lazyChunk,
|
|
8750
9879
|
lazyLoad,
|
|
8751
9880
|
lazyModule,
|
|
@@ -8762,7 +9891,10 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8762
9891
|
min,
|
|
8763
9892
|
minLength,
|
|
8764
9893
|
mobXAdapter,
|
|
9894
|
+
mouse,
|
|
8765
9895
|
mutation,
|
|
9896
|
+
mutationObserver,
|
|
9897
|
+
network,
|
|
8766
9898
|
noSideEffect,
|
|
8767
9899
|
normalize,
|
|
8768
9900
|
normalizedStore,
|
|
@@ -8779,6 +9911,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8779
9911
|
persisted,
|
|
8780
9912
|
phoneMask,
|
|
8781
9913
|
plugin,
|
|
9914
|
+
pointerLock,
|
|
8782
9915
|
popover,
|
|
8783
9916
|
precompile,
|
|
8784
9917
|
prefetch,
|
|
@@ -8830,6 +9963,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8830
9963
|
slideIn,
|
|
8831
9964
|
slideOut,
|
|
8832
9965
|
socket,
|
|
9966
|
+
speech,
|
|
8833
9967
|
spring,
|
|
8834
9968
|
springSignal,
|
|
8835
9969
|
ssnMask,
|
|
@@ -8841,8 +9975,11 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8841
9975
|
stream,
|
|
8842
9976
|
suspenseSwapScript,
|
|
8843
9977
|
svgElement,
|
|
9978
|
+
svgFavicon,
|
|
9979
|
+
swipe,
|
|
8844
9980
|
syncAdapter,
|
|
8845
9981
|
tabs,
|
|
9982
|
+
textSelection,
|
|
8846
9983
|
throttle,
|
|
8847
9984
|
timeMask,
|
|
8848
9985
|
timeline,
|
|
@@ -8857,11 +9994,16 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8857
9994
|
triggerPluginUnmount,
|
|
8858
9995
|
trustHTML,
|
|
8859
9996
|
uniqueId,
|
|
9997
|
+
urlState,
|
|
8860
9998
|
validateProps,
|
|
8861
9999
|
validators,
|
|
10000
|
+
vibrate,
|
|
8862
10001
|
viewTransition,
|
|
10002
|
+
visibility,
|
|
10003
|
+
wakeLock,
|
|
8863
10004
|
walkDependencyGraph,
|
|
8864
10005
|
wasm,
|
|
10006
|
+
windowSize,
|
|
8865
10007
|
withBoundary,
|
|
8866
10008
|
withDefaults,
|
|
8867
10009
|
withErrorTracking,
|