sibujs 4.1.0 → 4.2.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 +24 -0
- package/dist/browser.cjs +13 -21
- package/dist/browser.js +6 -6
- package/dist/build.cjs +278 -104
- package/dist/build.js +15 -15
- package/dist/cdn.dev.global.js +398 -0
- package/dist/cdn.global.js +10 -10
- package/dist/{chunk-DCDS2PQ6.js → chunk-2LOYNGBY.js} +2 -2
- package/dist/{chunk-VPP2FONR.js → chunk-2WLZ6757.js} +17 -10
- package/dist/{chunk-IM7N5WR4.js → chunk-3VTSPNC5.js} +2 -2
- package/dist/{chunk-TIRZCERI.js → chunk-5DXA2J44.js} +1 -1
- package/dist/{chunk-I3VI34DP.js → chunk-6ZGI3RBE.js} +149 -33
- package/dist/{chunk-D3SZ4LVS.js → chunk-7ALC7KGE.js} +5 -6
- package/dist/{chunk-PFTDGEPZ.js → chunk-7VEC3UD2.js} +3 -3
- package/dist/{chunk-KSOEJGFO.js → chunk-BMYYZWHX.js} +3 -3
- package/dist/{chunk-LOFZHP6V.js → chunk-BNKV4REK.js} +7 -8
- package/dist/{chunk-5GJ5RTHA.js → chunk-FOWBJZDL.js} +7 -8
- package/dist/{chunk-FB7KQXZI.js → chunk-GDUNQCCW.js} +4 -4
- package/dist/{chunk-UFSQEO7P.js → chunk-HECVW343.js} +7 -8
- package/dist/{chunk-SHDVWATN.js → chunk-HJEPKZ2O.js} +7 -8
- package/dist/{chunk-ANGSYNPX.js → chunk-HZEBO22J.js} +57 -37
- package/dist/{chunk-5INI7D2L.js → chunk-IXKSNWV5.js} +74 -11
- package/dist/{chunk-DAKLOMKS.js → chunk-KE4KWRDY.js} +3 -3
- package/dist/{chunk-AW6HPJ3L.js → chunk-KKLW7YWL.js} +1 -1
- package/dist/{chunk-BMSN6NWQ.js → chunk-NEYWS4EX.js} +6 -6
- package/dist/{chunk-HYCCIYNS.js → chunk-NIOYEGBQ.js} +13 -14
- package/dist/{chunk-4U7KD3RY.js → chunk-OUWAIXIK.js} +3 -3
- package/dist/{chunk-MRAMKDHQ.js → chunk-P3DHXBR6.js} +1 -1
- package/dist/{chunk-FMHIQNMP.js → chunk-QCFLDD7C.js} +5 -5
- package/dist/{chunk-DHDZ7IVN.js → chunk-QKRPLZ2V.js} +7 -8
- package/dist/{chunk-4RH6D7GR.js → chunk-QL4UREZO.js} +6 -6
- package/dist/{chunk-XIHMS2Y6.js → chunk-SF3TB4K6.js} +8 -8
- package/dist/{chunk-XSZRJW76.js → chunk-XZ2N525U.js} +6 -6
- package/dist/{customElement-CKLoO63w.d.ts → customElement-CNZxEB9G.d.cts} +77 -0
- package/dist/{customElement-CKLoO63w.d.cts → customElement-CNZxEB9G.d.ts} +77 -0
- package/dist/data.cjs +15 -24
- package/dist/data.js +9 -9
- package/dist/devtools.cjs +18 -22
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +8 -8
- package/dist/{dispose-4FZ6OFXR.js → dispose-46BOMMQJ.js} +2 -2
- package/dist/ecosystem.cjs +222 -67
- package/dist/ecosystem.js +11 -11
- package/dist/extras.cjs +243 -86
- package/dist/extras.d.cts +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/extras.js +25 -25
- package/dist/index.cjs +272 -98
- package/dist/index.d.cts +154 -33
- package/dist/index.d.ts +154 -33
- package/dist/index.js +15 -15
- package/dist/{introspect-RjLfIFpL.d.cts → introspect-D5xF-0Es.d.cts} +7 -0
- package/dist/{introspect-DOZfmC-4.d.ts → introspect-rSBIxEQi.d.ts} +7 -0
- package/dist/motion.cjs +13 -22
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +16 -24
- package/dist/patterns.d.cts +8 -0
- package/dist/patterns.d.ts +8 -0
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +16 -27
- package/dist/performance.js +9 -9
- package/dist/plugins.cjs +260 -86
- package/dist/plugins.d.cts +92 -0
- package/dist/plugins.d.ts +92 -0
- package/dist/plugins.js +18 -17
- package/dist/{ssr-JFP5535P.js → ssr-Y7XOEPEN.js} +5 -5
- package/dist/ssr.cjs +233 -79
- package/dist/ssr.js +12 -12
- package/dist/testing.cjs +11 -19
- package/dist/testing.js +5 -5
- package/dist/ui.cjs +98 -43
- package/dist/ui.d.cts +7 -1
- package/dist/ui.d.ts +7 -1
- package/dist/ui.js +10 -10
- package/dist/widgets.cjs +13 -21
- package/dist/widgets.d.cts +8 -0
- package/dist/widgets.d.ts +8 -0
- package/dist/widgets.js +9 -9
- package/package.json +5 -2
package/dist/plugins.cjs
CHANGED
|
@@ -22,29 +22,34 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
22
22
|
|
|
23
23
|
// src/core/dev.ts
|
|
24
24
|
function isDev() {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// this branch is unreachable here.
|
|
29
|
-
/* v8 ignore next 2 */
|
|
30
|
-
typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
|
|
31
|
-
);
|
|
25
|
+
if (typeof globalThis.__SIBU_DEV__ !== "undefined") return !!globalThis.__SIBU_DEV__;
|
|
26
|
+
if (typeof __SIBU_DEV__ !== "undefined") return !!__SIBU_DEV__;
|
|
27
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
32
28
|
}
|
|
33
29
|
function devAssert(condition, message) {
|
|
34
|
-
if (
|
|
30
|
+
if ((typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) && !condition) {
|
|
35
31
|
throw new Error(`[SibuJS] ${message}`);
|
|
36
32
|
}
|
|
37
33
|
}
|
|
34
|
+
function devWarnLazy(build) {
|
|
35
|
+
if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
|
|
36
|
+
const message = build();
|
|
37
|
+
if (message) console.warn(`[SibuJS] ${message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
38
40
|
function devWarn(message) {
|
|
39
|
-
if (
|
|
41
|
+
if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
|
|
40
42
|
console.warn(`[SibuJS] ${message}`);
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
|
-
var
|
|
45
|
+
var DEV;
|
|
44
46
|
var init_dev = __esm({
|
|
45
47
|
"src/core/dev.ts"() {
|
|
46
48
|
"use strict";
|
|
47
|
-
|
|
49
|
+
DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
|
|
50
|
+
// safe default: off in browser, on in test/dev Node
|
|
51
|
+
typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
|
|
52
|
+
);
|
|
48
53
|
}
|
|
49
54
|
});
|
|
50
55
|
|
|
@@ -234,20 +239,61 @@ function decodeCssEscapes(value) {
|
|
|
234
239
|
}
|
|
235
240
|
return out;
|
|
236
241
|
}
|
|
237
|
-
function
|
|
238
|
-
if (!
|
|
242
|
+
function describeElement(el) {
|
|
243
|
+
if (!el) return "an element";
|
|
244
|
+
let out = el.tagName.toLowerCase();
|
|
245
|
+
const id = el.getAttribute("id");
|
|
246
|
+
if (id) out += `#${id}`;
|
|
247
|
+
const cls = el.getAttribute("class");
|
|
248
|
+
if (cls) out += `.${cls.trim().split(/\s+/).slice(0, 3).join(".")}`;
|
|
249
|
+
return `<${out}>`;
|
|
250
|
+
}
|
|
251
|
+
function warnDroppedDeclaration(value, reason, ctx) {
|
|
252
|
+
devWarnLazy(() => {
|
|
253
|
+
const reasons = [
|
|
254
|
+
"url() in an inline style is an exfiltration channel: the browser fetches it immediately and the URL's path or query can carry page data off-origin",
|
|
255
|
+
"expression() executes arbitrary script in legacy engines",
|
|
256
|
+
"the javascript: scheme executes script",
|
|
257
|
+
"the vbscript: scheme executes script",
|
|
258
|
+
"-moz-binding loads and runs remote XBL",
|
|
259
|
+
"behavior: loads and runs a remote HTC script",
|
|
260
|
+
"@import pulls in a remote stylesheet",
|
|
261
|
+
"image-set() fetches remote images, the same exfiltration channel as url()",
|
|
262
|
+
"filter:progid activates legacy scriptable filters"
|
|
263
|
+
];
|
|
264
|
+
const declaration = ctx?.property ? `${ctx.property}: ${value}` : value;
|
|
265
|
+
const where = describeElement(ctx?.element);
|
|
266
|
+
const key = `${where}|${declaration}`;
|
|
267
|
+
if (warnedDeclarations.has(key)) return "";
|
|
268
|
+
if (warnedDeclarations.size >= MAX_WARNED_DECLARATIONS) {
|
|
269
|
+
if (declarationCapAnnounced) return "";
|
|
270
|
+
declarationCapAnnounced = true;
|
|
271
|
+
return `${MAX_WARNED_DECLARATIONS} distinct dropped style declarations have been reported; suppressing further ones for the rest of this session so they cannot flood the console. The declarations are still dropped \u2014 only the reporting stops. Fix the reported ones and reload to see any that remain.`;
|
|
272
|
+
}
|
|
273
|
+
warnedDeclarations.add(key);
|
|
274
|
+
return `style declaration "${declaration}" was dropped by the style sanitizer on ${where} \u2014 ${reasons[reason]}. The element renders without it, which usually looks like a missing image rather than an error. Sanctioned alternatives: for a content image use an <img> element (or a <picture>); for decoration, put the rule in a stylesheet and set a class instead \u2014 stylesheet CSS is not sanitized, only inline style attributes are. If this declaration is not yours, it came from untrusted data and the drop just prevented an exfiltration.`;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function blockedCssReason(value) {
|
|
278
|
+
if (!CSS_DANGER_GATE.test(value)) return -1;
|
|
239
279
|
const normalized = value.includes("\\") ? decodeCssEscapes(value) : value;
|
|
240
280
|
const lower = normalized.toLowerCase().replace(/\s+/g, "");
|
|
241
|
-
|
|
242
|
-
return
|
|
281
|
+
for (let i2 = 0; i2 < BLOCKED_CSS_NEEDLES.length; i2++) {
|
|
282
|
+
if (lower.includes(BLOCKED_CSS_NEEDLES[i2])) return i2;
|
|
243
283
|
}
|
|
244
|
-
return
|
|
284
|
+
return -1;
|
|
285
|
+
}
|
|
286
|
+
function sanitizeCSSValue(value, context) {
|
|
287
|
+
const reason = blockedCssReason(value);
|
|
288
|
+
if (reason === -1) return value;
|
|
289
|
+
warnDroppedDeclaration(value, reason, context);
|
|
290
|
+
return "";
|
|
245
291
|
}
|
|
246
|
-
function sanitizeStyleAttribute(cssText) {
|
|
292
|
+
function sanitizeStyleAttribute(cssText, context) {
|
|
247
293
|
const input2 = String(cssText);
|
|
248
294
|
if (input2.trim() === "") return "";
|
|
249
295
|
if (typeof document === "undefined") {
|
|
250
|
-
return sanitizeCSSValue(input2) === "" ? "" : input2;
|
|
296
|
+
return sanitizeCSSValue(input2, context) === "" ? "" : input2;
|
|
251
297
|
}
|
|
252
298
|
const probe = document.createElement("div");
|
|
253
299
|
try {
|
|
@@ -259,8 +305,12 @@ function sanitizeStyleAttribute(cssText) {
|
|
|
259
305
|
for (let i2 = 0; i2 < probe.style.length; i2++) {
|
|
260
306
|
const property = probe.style[i2];
|
|
261
307
|
const value = probe.style.getPropertyValue(property);
|
|
262
|
-
|
|
263
|
-
if (
|
|
308
|
+
let reason = blockedCssReason(value);
|
|
309
|
+
if (reason === -1) reason = blockedCssReason(`${property}:${value}`);
|
|
310
|
+
if (reason !== -1) {
|
|
311
|
+
warnDroppedDeclaration(value, reason, { property, element: context?.element });
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
264
314
|
const priority = probe.style.getPropertyPriority(property);
|
|
265
315
|
declarations.push(`${property}: ${value}${priority ? ` !${priority}` : ""}`);
|
|
266
316
|
}
|
|
@@ -276,21 +326,36 @@ function isPolicyAttribute(name) {
|
|
|
276
326
|
const lower = name.toLowerCase();
|
|
277
327
|
return lower === "style" || URL_ATTRIBUTES.has(lower);
|
|
278
328
|
}
|
|
279
|
-
function sanitizeAttributeString(attr, value) {
|
|
329
|
+
function sanitizeAttributeString(attr, value, context) {
|
|
280
330
|
const lower = attr.toLowerCase();
|
|
281
331
|
if (lower === "srcset") return sanitizeSrcset(value);
|
|
282
332
|
if (URL_ATTRIBUTES.has(lower)) return sanitizeUrl(value);
|
|
283
|
-
if (lower === "style") return sanitizeStyleAttribute(value);
|
|
333
|
+
if (lower === "style") return sanitizeStyleAttribute(value, context);
|
|
284
334
|
return value;
|
|
285
335
|
}
|
|
286
|
-
var SAFE_URL_PROTOCOLS, OUTER_TRIM, SRCSET_DESCRIPTOR, CSS_DANGER_GATE, URL_ATTRIBUTES, HTML_CONTENT_ATTRIBUTES;
|
|
336
|
+
var SAFE_URL_PROTOCOLS, OUTER_TRIM, SRCSET_DESCRIPTOR, CSS_DANGER_GATE, BLOCKED_CSS_NEEDLES, warnedDeclarations, MAX_WARNED_DECLARATIONS, declarationCapAnnounced, URL_ATTRIBUTES, HTML_CONTENT_ATTRIBUTES;
|
|
287
337
|
var init_sanitize = __esm({
|
|
288
338
|
"src/utils/sanitize.ts"() {
|
|
289
339
|
"use strict";
|
|
340
|
+
init_dev();
|
|
290
341
|
SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
291
342
|
OUTER_TRIM = /^[\x00-\x20\x7f-\x9f]+|[\x00-\x20\x7f-\x9f]+$/g;
|
|
292
343
|
SRCSET_DESCRIPTOR = /^\s+\d+(\.\d+)?[wx]$/;
|
|
293
344
|
CSS_DANGER_GATE = /[(:@\\]/;
|
|
345
|
+
BLOCKED_CSS_NEEDLES = [
|
|
346
|
+
"url(",
|
|
347
|
+
"expression(",
|
|
348
|
+
"javascript:",
|
|
349
|
+
"vbscript:",
|
|
350
|
+
"-moz-binding",
|
|
351
|
+
"behavior:",
|
|
352
|
+
"@import",
|
|
353
|
+
"image-set(",
|
|
354
|
+
"filter:progid"
|
|
355
|
+
];
|
|
356
|
+
warnedDeclarations = /* @__PURE__ */ new Set();
|
|
357
|
+
MAX_WARNED_DECLARATIONS = 100;
|
|
358
|
+
declarationCapAnnounced = false;
|
|
294
359
|
URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
295
360
|
"href",
|
|
296
361
|
"xlink:href",
|
|
@@ -338,7 +403,7 @@ function registerDisposer(node, teardown) {
|
|
|
338
403
|
elementDisposers.set(node, disposers);
|
|
339
404
|
}
|
|
340
405
|
disposers.push(teardown);
|
|
341
|
-
if (
|
|
406
|
+
if (DEV) activeBindingCount++;
|
|
342
407
|
}
|
|
343
408
|
function unregisterDisposer(node, teardown) {
|
|
344
409
|
const disposers = elementDisposers.get(node);
|
|
@@ -346,7 +411,7 @@ function unregisterDisposer(node, teardown) {
|
|
|
346
411
|
const index = disposers.indexOf(teardown);
|
|
347
412
|
if (index === -1) return;
|
|
348
413
|
disposers.splice(index, 1);
|
|
349
|
-
if (
|
|
414
|
+
if (DEV) activeBindingCount--;
|
|
350
415
|
if (disposers.length === 0) elementDisposers.delete(node);
|
|
351
416
|
}
|
|
352
417
|
function dispose(node) {
|
|
@@ -370,13 +435,13 @@ function dispose(node) {
|
|
|
370
435
|
if (!pending || pending.length === 0) break;
|
|
371
436
|
const snapshot = pending.slice();
|
|
372
437
|
elementDisposers.delete(current);
|
|
373
|
-
if (
|
|
438
|
+
if (DEV) activeBindingCount -= snapshot.length;
|
|
374
439
|
for (let i3 = 0; i3 < snapshot.length; i3++) {
|
|
375
440
|
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
376
441
|
const rest = snapshot.slice(i3);
|
|
377
442
|
const added = elementDisposers.get(current);
|
|
378
443
|
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
379
|
-
if (
|
|
444
|
+
if (DEV) activeBindingCount += rest.length;
|
|
380
445
|
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
381
446
|
runaway = true;
|
|
382
447
|
break;
|
|
@@ -404,7 +469,7 @@ function replaceChildrenSafely(parent, ...next) {
|
|
|
404
469
|
parent.replaceChildren(...next);
|
|
405
470
|
}
|
|
406
471
|
function checkLeaks(warnThreshold = 0) {
|
|
407
|
-
if (!
|
|
472
|
+
if (!DEV) return 0;
|
|
408
473
|
if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
|
|
409
474
|
devWarn(
|
|
410
475
|
`checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
|
|
@@ -412,7 +477,7 @@ function checkLeaks(warnThreshold = 0) {
|
|
|
412
477
|
}
|
|
413
478
|
return activeBindingCount;
|
|
414
479
|
}
|
|
415
|
-
var elementDisposers, MAX_DRAIN_TEARDOWNS,
|
|
480
|
+
var elementDisposers, MAX_DRAIN_TEARDOWNS, activeBindingCount;
|
|
416
481
|
var init_dispose = __esm({
|
|
417
482
|
"src/core/rendering/dispose.ts"() {
|
|
418
483
|
"use strict";
|
|
@@ -420,7 +485,6 @@ var init_dispose = __esm({
|
|
|
420
485
|
init_errors();
|
|
421
486
|
elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
422
487
|
MAX_DRAIN_TEARDOWNS = 1e4;
|
|
423
|
-
_isDev4 = isDev();
|
|
424
488
|
activeBindingCount = 0;
|
|
425
489
|
}
|
|
426
490
|
});
|
|
@@ -507,9 +571,9 @@ function parseMetaRefreshContent(content) {
|
|
|
507
571
|
i2++;
|
|
508
572
|
while (i2 < raw.length && isAsciiWhitespace(raw[i2])) i2++;
|
|
509
573
|
let destination;
|
|
510
|
-
const
|
|
511
|
-
if (
|
|
512
|
-
const close = raw.indexOf(
|
|
574
|
+
const quote2 = raw[i2];
|
|
575
|
+
if (quote2 === '"' || quote2 === "'") {
|
|
576
|
+
const close = raw.indexOf(quote2, i2 + 1);
|
|
513
577
|
if (close === -1) return forbidden("unterminated quoted destination");
|
|
514
578
|
destination = raw.slice(i2 + 1, close);
|
|
515
579
|
const rest = trimAsciiWhitespace(raw.slice(close + 1));
|
|
@@ -681,7 +745,7 @@ function isSafeAttrName(name) {
|
|
|
681
745
|
return SAFE_ATTR_NAME.test(name);
|
|
682
746
|
}
|
|
683
747
|
function ssrErrorComment(err) {
|
|
684
|
-
if (
|
|
748
|
+
if (DEV) {
|
|
685
749
|
const msg = escapeHtml(err instanceof Error ? err.message : String(err));
|
|
686
750
|
return `<!--SSR error: ${safeCommentText(msg)}-->`;
|
|
687
751
|
}
|
|
@@ -711,10 +775,10 @@ function renderToString(element) {
|
|
|
711
775
|
}
|
|
712
776
|
const tag = element.tagName.toLowerCase();
|
|
713
777
|
if (tag === "script" || tag === "style") {
|
|
714
|
-
return
|
|
778
|
+
return DEV ? `<!--ssr:${tag}-stripped-->` : "";
|
|
715
779
|
}
|
|
716
780
|
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
717
|
-
return
|
|
781
|
+
return DEV ? "<!--ssr:invalid-tag-->" : "";
|
|
718
782
|
}
|
|
719
783
|
let html2 = `<${tag}`;
|
|
720
784
|
for (const attr of Array.from(element.attributes)) {
|
|
@@ -756,7 +820,7 @@ function hydrate(component, container, options = {}) {
|
|
|
756
820
|
const first = mismatches[0];
|
|
757
821
|
if (options.onMismatch) {
|
|
758
822
|
options.onMismatch(first);
|
|
759
|
-
} else if (
|
|
823
|
+
} else if (DEV) {
|
|
760
824
|
console.warn(
|
|
761
825
|
`[SibuJS hydration] ${first.message}
|
|
762
826
|
at ${first.path}
|
|
@@ -957,11 +1021,11 @@ async function* renderToStream(element) {
|
|
|
957
1021
|
}
|
|
958
1022
|
const tag = element.tagName.toLowerCase();
|
|
959
1023
|
if (tag === "script" || tag === "style") {
|
|
960
|
-
if (
|
|
1024
|
+
if (DEV) yield `<!--ssr:${tag}-stripped-->`;
|
|
961
1025
|
return;
|
|
962
1026
|
}
|
|
963
1027
|
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
964
|
-
if (
|
|
1028
|
+
if (DEV) yield "<!--ssr:invalid-tag-->";
|
|
965
1029
|
return;
|
|
966
1030
|
}
|
|
967
1031
|
let openTag = `<${tag}`;
|
|
@@ -1103,7 +1167,7 @@ function ssrSuspense(props) {
|
|
|
1103
1167
|
},
|
|
1104
1168
|
(err) => {
|
|
1105
1169
|
if (timer) clearTimeout(timer);
|
|
1106
|
-
if (
|
|
1170
|
+
if (DEV) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
|
|
1107
1171
|
return { id, html: fallbackHtml };
|
|
1108
1172
|
}
|
|
1109
1173
|
);
|
|
@@ -1146,7 +1210,7 @@ function serializeState(state2, nonce, options) {
|
|
|
1146
1210
|
}
|
|
1147
1211
|
function deserializeState(validate) {
|
|
1148
1212
|
if (typeof window === "undefined") return void 0;
|
|
1149
|
-
if (
|
|
1213
|
+
if (DEV && !validate) {
|
|
1150
1214
|
console.warn(
|
|
1151
1215
|
"[SibuJS SSR] deserializeState() called without a validate guard \u2014 tampered SSR payloads will not be detected."
|
|
1152
1216
|
);
|
|
@@ -1163,7 +1227,7 @@ function escapeHtml(str) {
|
|
|
1163
1227
|
function escapeAttr(str) {
|
|
1164
1228
|
return str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
1165
1229
|
}
|
|
1166
|
-
var
|
|
1230
|
+
var SAFE_ATTR_NAME, VOID_ELEMENTS, SAFE_ID, SAFE_SUSPENSE_ID, SSR_DATA_ATTR, DEFAULT_MAX_SSR_BYTES;
|
|
1167
1231
|
var init_ssr = __esm({
|
|
1168
1232
|
"src/platform/ssr.ts"() {
|
|
1169
1233
|
"use strict";
|
|
@@ -1173,7 +1237,6 @@ var init_ssr = __esm({
|
|
|
1173
1237
|
init_headEntry();
|
|
1174
1238
|
init_metaRefresh();
|
|
1175
1239
|
init_sanitize();
|
|
1176
|
-
_isDev8 = isDev();
|
|
1177
1240
|
SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
1178
1241
|
VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
1179
1242
|
"area",
|
|
@@ -1290,7 +1353,6 @@ init_sanitize();
|
|
|
1290
1353
|
// src/utils/setSafeAttribute.ts
|
|
1291
1354
|
init_dev();
|
|
1292
1355
|
init_sanitize();
|
|
1293
|
-
var _isDev2 = isDev();
|
|
1294
1356
|
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
1295
1357
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1296
1358
|
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
@@ -1313,7 +1375,7 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
1313
1375
|
const ns = namespaceFor(el, name);
|
|
1314
1376
|
const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
|
|
1315
1377
|
if (isEventHandlerAttr(name)) {
|
|
1316
|
-
if (
|
|
1378
|
+
if (DEV) {
|
|
1317
1379
|
devWarn(
|
|
1318
1380
|
`${options.label ?? "setSafeAttribute"}: refusing to set event-handler attribute "${name}". Its value would be evaluated as JavaScript. Use on:{ ${name.slice(2)}: fn } instead.`
|
|
1319
1381
|
);
|
|
@@ -1328,7 +1390,7 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
1328
1390
|
return true;
|
|
1329
1391
|
}
|
|
1330
1392
|
if (isHtmlContentAttribute(name)) {
|
|
1331
|
-
if (
|
|
1393
|
+
if (DEV) {
|
|
1332
1394
|
devWarn(
|
|
1333
1395
|
`${options.label ?? "setSafeAttribute"}: refusing to set "${name}". The browser parses this attribute as a nested HTML document, so a generic string value cannot be made safe \u2014 attribute escaping is undone before the parse. Build the frame's content another way.`
|
|
1334
1396
|
);
|
|
@@ -1357,7 +1419,7 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
1357
1419
|
setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
|
|
1358
1420
|
return true;
|
|
1359
1421
|
}
|
|
1360
|
-
const safe = sanitizeAttributeString(name, str);
|
|
1422
|
+
const safe = sanitizeAttributeString(name, str, { element: el });
|
|
1361
1423
|
const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
|
|
1362
1424
|
if (current === safe) return true;
|
|
1363
1425
|
if (ns) el.setAttributeNS(ns, name, safe);
|
|
@@ -1825,17 +1887,16 @@ function forEachSubscriber(signal2, visit) {
|
|
|
1825
1887
|
}
|
|
1826
1888
|
|
|
1827
1889
|
// src/reactivity/track.ts
|
|
1828
|
-
var
|
|
1829
|
-
var _runtimeVersion = true ? "4.1.0" : "dev";
|
|
1890
|
+
var _runtimeVersion = true ? "4.2.0" : "dev";
|
|
1830
1891
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
1831
1892
|
function resolveReactiveApi() {
|
|
1832
1893
|
const g2 = globalThis;
|
|
1833
1894
|
const existing = g2[REGISTRY_KEY];
|
|
1834
1895
|
if (existing) {
|
|
1835
|
-
if (
|
|
1896
|
+
if (DEV && !existing.__dupWarned) {
|
|
1836
1897
|
existing.__dupWarned = true;
|
|
1837
1898
|
devWarn(
|
|
1838
|
-
`Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity
|
|
1899
|
+
`Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity is NOT broken and no bundler configuration is required: every copy routes through the first one via a global registry, so signal writes still reach subscribers registered by any copy. This is only a SIZE issue \u2014 the duplicate copy's bytes are downloaded and parsed for nothing. If you want them back, de-duplicate sibujs in your bundler (Vite: resolve.dedupe: ['sibujs']). Mismatched VERSIONS above are worth fixing regardless, since only the first one loaded is used.`
|
|
1839
1900
|
);
|
|
1840
1901
|
}
|
|
1841
1902
|
return existing;
|
|
@@ -1906,7 +1967,103 @@ function bindAttribute(el, attr, getter) {
|
|
|
1906
1967
|
init_dev();
|
|
1907
1968
|
init_errors();
|
|
1908
1969
|
init_dispose();
|
|
1909
|
-
|
|
1970
|
+
|
|
1971
|
+
// src/core/rendering/focusPreservation.ts
|
|
1972
|
+
init_dev();
|
|
1973
|
+
var IDENTITY_ATTRS = ["data-focus-key", "id", "name"];
|
|
1974
|
+
var SELECTABLE_TYPES = /* @__PURE__ */ new Set(["text", "search", "url", "tel", "password", ""]);
|
|
1975
|
+
function selectionOf(el) {
|
|
1976
|
+
const tag = el.tagName;
|
|
1977
|
+
const selectable = tag === "TEXTAREA" || tag === "INPUT" && SELECTABLE_TYPES.has(el.type.toLowerCase());
|
|
1978
|
+
if (!selectable) return { start: null, end: null, direction: null };
|
|
1979
|
+
const field = el;
|
|
1980
|
+
return { start: field.selectionStart, end: field.selectionEnd, direction: field.selectionDirection };
|
|
1981
|
+
}
|
|
1982
|
+
function captureFocusWithin(nodes) {
|
|
1983
|
+
if (nodes.length === 0 || typeof document === "undefined") return null;
|
|
1984
|
+
const active = document.activeElement;
|
|
1985
|
+
if (!active || active === document.body) return null;
|
|
1986
|
+
let inside = false;
|
|
1987
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
1988
|
+
const n = nodes[i2];
|
|
1989
|
+
if (n === active || n.nodeType === 1 && n.contains(active)) {
|
|
1990
|
+
inside = true;
|
|
1991
|
+
break;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
if (!inside) return null;
|
|
1995
|
+
let attr = null;
|
|
1996
|
+
let value = null;
|
|
1997
|
+
for (let i2 = 0; i2 < IDENTITY_ATTRS.length; i2++) {
|
|
1998
|
+
const candidate = active.getAttribute(IDENTITY_ATTRS[i2]);
|
|
1999
|
+
if (candidate) {
|
|
2000
|
+
attr = IDENTITY_ATTRS[i2];
|
|
2001
|
+
value = candidate;
|
|
2002
|
+
break;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
return { el: active, attr, value, tag: active.tagName, ...selectionOf(active) };
|
|
2006
|
+
}
|
|
2007
|
+
function quote(value) {
|
|
2008
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
2009
|
+
}
|
|
2010
|
+
function findUniqueByIdentity(nodes, selector) {
|
|
2011
|
+
let el = null;
|
|
2012
|
+
let count = 0;
|
|
2013
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
2014
|
+
const n = nodes[i2];
|
|
2015
|
+
if (n.nodeType !== 1) continue;
|
|
2016
|
+
const root = n;
|
|
2017
|
+
if (root.matches(selector)) {
|
|
2018
|
+
count++;
|
|
2019
|
+
el ?? (el = root);
|
|
2020
|
+
}
|
|
2021
|
+
const inner = root.querySelectorAll(selector);
|
|
2022
|
+
for (let j = 0; j < inner.length; j++) {
|
|
2023
|
+
count++;
|
|
2024
|
+
el ?? (el = inner[j]);
|
|
2025
|
+
}
|
|
2026
|
+
if (count > 1) return { el: null, count };
|
|
2027
|
+
}
|
|
2028
|
+
return count === 1 ? { el, count } : { el: null, count };
|
|
2029
|
+
}
|
|
2030
|
+
function refocus(el, snapshot) {
|
|
2031
|
+
el.focus();
|
|
2032
|
+
if (snapshot.start !== null && typeof el.setSelectionRange === "function") {
|
|
2033
|
+
const field = el;
|
|
2034
|
+
const max = field.value.length;
|
|
2035
|
+
const start = Math.min(snapshot.start, max);
|
|
2036
|
+
const end = Math.min(snapshot.end ?? start, max);
|
|
2037
|
+
field.setSelectionRange(start, end, snapshot.direction ?? "none");
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
function restoreFocusWithin(snapshot, nodes, where) {
|
|
2041
|
+
if (!snapshot) return;
|
|
2042
|
+
if (typeof document === "undefined") return;
|
|
2043
|
+
const active = document.activeElement;
|
|
2044
|
+
if (active === snapshot.el) return;
|
|
2045
|
+
if (active && active !== document.body && active !== document.documentElement) return;
|
|
2046
|
+
if (snapshot.el.isConnected) {
|
|
2047
|
+
refocus(snapshot.el, snapshot);
|
|
2048
|
+
return;
|
|
2049
|
+
}
|
|
2050
|
+
let ambiguous = false;
|
|
2051
|
+
if (snapshot.attr && snapshot.value) {
|
|
2052
|
+
const { el: replacement, count } = findUniqueByIdentity(nodes, `[${snapshot.attr}=${quote(snapshot.value)}]`);
|
|
2053
|
+
if (replacement && replacement.tagName === snapshot.tag) {
|
|
2054
|
+
refocus(replacement, snapshot);
|
|
2055
|
+
return;
|
|
2056
|
+
}
|
|
2057
|
+
ambiguous = count > 1;
|
|
2058
|
+
}
|
|
2059
|
+
devWarnLazy(() => {
|
|
2060
|
+
const id = snapshot.attr ? ` (${snapshot.attr}="${snapshot.value}")` : "";
|
|
2061
|
+
const why = ambiguous ? `several elements in the rebuilt subtree share ${snapshot.attr}="${snapshot.value}", so there is no way to tell which one the user was in \u2014 a shared name (a radio group) identifies a GROUP, not a control. Add a unique id or data-focus-key to each` : "no element in the rebuilt subtree carries the same identity. Give it a stable id, name, or data-focus-key that the rebuild reproduces";
|
|
2062
|
+
return `${where}: a reactive rebuild discarded the focused element <${snapshot.tag.toLowerCase()}>${id} and could not re-establish it, so focus fell back to <body>. An in-progress edit ends here, and an in-progress IME composition is lost outright \u2014 a composition belongs to the DOM node, so it cannot survive the node being destroyed. ${why}, or stop the rebuild from happening: key the subtree with match(() => shapeKey(), { \u2026 }) so it is re-created only when the shape actually changes, and drive the rest with reactive attributes and text children, which mutate nodes in place instead of replacing them.`;
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
// src/reactivity/bindChildNode.ts
|
|
1910
2067
|
function bindChildNode(placeholder, getter) {
|
|
1911
2068
|
let lastNodes = [];
|
|
1912
2069
|
function commit() {
|
|
@@ -1917,6 +2074,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
1917
2074
|
reportError(err, { phase: "binding", name: "bindChildNode", node: placeholder });
|
|
1918
2075
|
return;
|
|
1919
2076
|
}
|
|
2077
|
+
const focused = captureFocusWithin(lastNodes);
|
|
1920
2078
|
if (result == null || typeof result === "boolean") {
|
|
1921
2079
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
1922
2080
|
const node = lastNodes[i2];
|
|
@@ -1924,6 +2082,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
1924
2082
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
1925
2083
|
}
|
|
1926
2084
|
lastNodes.length = 0;
|
|
2085
|
+
restoreFocusWithin(focused, lastNodes, "bindChildNode");
|
|
1927
2086
|
return;
|
|
1928
2087
|
}
|
|
1929
2088
|
const parent = placeholder.parentNode;
|
|
@@ -1940,8 +2099,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
1940
2099
|
if (item == null || typeof item === "boolean") continue;
|
|
1941
2100
|
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
1942
2101
|
if (seen.has(node)) {
|
|
1943
|
-
if (
|
|
1944
|
-
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
2102
|
+
if (DEV) devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
1945
2103
|
continue;
|
|
1946
2104
|
}
|
|
1947
2105
|
seen.add(node);
|
|
@@ -1974,6 +2132,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
1974
2132
|
prev = node;
|
|
1975
2133
|
}
|
|
1976
2134
|
lastNodes = newNodes;
|
|
2135
|
+
restoreFocusWithin(focused, newNodes, "bindChildNode");
|
|
1977
2136
|
}
|
|
1978
2137
|
return reactiveBinding2(commit, placeholder);
|
|
1979
2138
|
}
|
|
@@ -1982,7 +2141,6 @@ function bindChildNode(placeholder, getter) {
|
|
|
1982
2141
|
init_sanitize();
|
|
1983
2142
|
init_dispose();
|
|
1984
2143
|
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
1985
|
-
var _isDev6 = isDev();
|
|
1986
2144
|
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
1987
2145
|
function isBlockedTag(tag) {
|
|
1988
2146
|
return BLOCKED_TAGS.has(tag.toLowerCase());
|
|
@@ -2000,18 +2158,9 @@ var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
|
2000
2158
|
"self",
|
|
2001
2159
|
"frames"
|
|
2002
2160
|
]);
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
const tokens = t2.split(/\s+/);
|
|
2007
|
-
let sawClassish = false;
|
|
2008
|
-
for (let i2 = 0; i2 < tokens.length; i2++) {
|
|
2009
|
-
const tok = tokens[i2];
|
|
2010
|
-
if (!/^-?[A-Za-z_][A-Za-z0-9_:/.-]*$/.test(tok)) return false;
|
|
2011
|
-
if (/[-:/0-9]/.test(tok)) sawClassish = true;
|
|
2012
|
-
}
|
|
2013
|
-
return sawClassish;
|
|
2014
|
-
}
|
|
2161
|
+
var warnedLoneStrings = /* @__PURE__ */ new Set();
|
|
2162
|
+
var MAX_WARNED_LONE_STRINGS = 100;
|
|
2163
|
+
var loneStringCapAnnounced = false;
|
|
2015
2164
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
2016
2165
|
function toKebab(prop) {
|
|
2017
2166
|
let cached = kebabCache.get(prop);
|
|
@@ -2023,13 +2172,13 @@ function toKebab(prop) {
|
|
|
2023
2172
|
function applyStyle(el, style2) {
|
|
2024
2173
|
if (typeof style2 === "function") {
|
|
2025
2174
|
const teardown = reactiveBinding2(() => {
|
|
2026
|
-
el.setAttribute("style", sanitizeStyleAttribute(String(style2())));
|
|
2175
|
+
el.setAttribute("style", sanitizeStyleAttribute(String(style2()), { element: el }));
|
|
2027
2176
|
}, el);
|
|
2028
2177
|
registerDisposer(el, teardown);
|
|
2029
2178
|
return;
|
|
2030
2179
|
}
|
|
2031
2180
|
if (typeof style2 === "string") {
|
|
2032
|
-
el.setAttribute("style", sanitizeStyleAttribute(style2));
|
|
2181
|
+
el.setAttribute("style", sanitizeStyleAttribute(style2, { element: el }));
|
|
2033
2182
|
return;
|
|
2034
2183
|
}
|
|
2035
2184
|
const htmlEl = el;
|
|
@@ -2039,14 +2188,26 @@ function applyStyle(el, style2) {
|
|
|
2039
2188
|
if (typeof val === "function") {
|
|
2040
2189
|
const getter = val;
|
|
2041
2190
|
const teardown = reactiveBinding2(() => {
|
|
2042
|
-
htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter())));
|
|
2191
|
+
htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter()), { property: name, element: el }));
|
|
2043
2192
|
}, el);
|
|
2044
2193
|
registerDisposer(el, teardown);
|
|
2045
2194
|
} else {
|
|
2046
|
-
htmlEl.style.setProperty(name, sanitizeCSSValue(String(val)));
|
|
2195
|
+
htmlEl.style.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
|
|
2047
2196
|
}
|
|
2048
2197
|
}
|
|
2049
2198
|
}
|
|
2199
|
+
function resolveClassValue(cls) {
|
|
2200
|
+
if (typeof cls === "string") return cls;
|
|
2201
|
+
if (typeof cls === "function") return cls();
|
|
2202
|
+
if (!cls) return "";
|
|
2203
|
+
let out = "";
|
|
2204
|
+
for (const name in cls) {
|
|
2205
|
+
const val = cls[name];
|
|
2206
|
+
const active = typeof val === "function" ? val() : val;
|
|
2207
|
+
if (active) out = out ? `${out} ${name}` : name;
|
|
2208
|
+
}
|
|
2209
|
+
return out;
|
|
2210
|
+
}
|
|
2050
2211
|
function applyClass(el, cls) {
|
|
2051
2212
|
if (typeof cls === "string") {
|
|
2052
2213
|
el.setAttribute("class", cls);
|
|
@@ -2150,11 +2311,26 @@ var tagFactory = (tag, ns) => {
|
|
|
2150
2311
|
appendChildren(el, second);
|
|
2151
2312
|
return el;
|
|
2152
2313
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2314
|
+
devWarnLazy(() => {
|
|
2315
|
+
const tokens = first.trim().split(/\s+/);
|
|
2316
|
+
if (tokens.length < 2) return "";
|
|
2317
|
+
let utilityTokens = 0;
|
|
2318
|
+
for (let i2 = 0; i2 < tokens.length; i2++) {
|
|
2319
|
+
const tok = tokens[i2];
|
|
2320
|
+
if (!/^-?[A-Za-z_][A-Za-z0-9_:/.-]*$/.test(tok)) return "";
|
|
2321
|
+
if (/[-:/0-9]/.test(tok)) utilityTokens++;
|
|
2322
|
+
}
|
|
2323
|
+
if (utilityTokens < 2) return "";
|
|
2324
|
+
const key = `${tag}|${first}`;
|
|
2325
|
+
if (warnedLoneStrings.has(key)) return "";
|
|
2326
|
+
if (warnedLoneStrings.size >= MAX_WARNED_LONE_STRINGS) {
|
|
2327
|
+
if (loneStringCapAnnounced) return "";
|
|
2328
|
+
loneStringCapAnnounced = true;
|
|
2329
|
+
return `tagFactory: ${MAX_WARNED_LONE_STRINGS} distinct lone-string class warnings have been reported; suppressing further ones for the rest of this session so they cannot flood the console. Fix the reported ones and reload to see any that remain.`;
|
|
2330
|
+
}
|
|
2331
|
+
warnedLoneStrings.add(key);
|
|
2332
|
+
return `tagFactory: lone string "${first}" looks like a class list but is being rendered as TEXT. For a class, use ${tag}({ class: "${first}" }) \u2014 or ${tag}("${first}", children) to set the class AND add children.`;
|
|
2333
|
+
});
|
|
2158
2334
|
el.textContent = first;
|
|
2159
2335
|
return el;
|
|
2160
2336
|
}
|
|
@@ -2171,7 +2347,7 @@ var tagFactory = (tag, ns) => {
|
|
|
2171
2347
|
if (pClass != null) applyClass(el, pClass);
|
|
2172
2348
|
const pId = props.id;
|
|
2173
2349
|
if (pId != null) {
|
|
2174
|
-
if (
|
|
2350
|
+
if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
2175
2351
|
devWarn(
|
|
2176
2352
|
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
2177
2353
|
);
|
|
@@ -2186,7 +2362,7 @@ var tagFactory = (tag, ns) => {
|
|
|
2186
2362
|
const handler = pOn[ev];
|
|
2187
2363
|
if (typeof handler === "function") {
|
|
2188
2364
|
el.addEventListener(ev, handler);
|
|
2189
|
-
} else if (
|
|
2365
|
+
} else if (DEV) {
|
|
2190
2366
|
devWarn(
|
|
2191
2367
|
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
2192
2368
|
);
|
|
@@ -2418,7 +2594,6 @@ var isBatching = API2.isBatching;
|
|
|
2418
2594
|
// src/core/signals/signal.ts
|
|
2419
2595
|
init_dev();
|
|
2420
2596
|
var _g = globalThis;
|
|
2421
|
-
var _isDev7 = isDev();
|
|
2422
2597
|
function signal(initial, options) {
|
|
2423
2598
|
const state2 = {
|
|
2424
2599
|
value: initial,
|
|
@@ -2431,7 +2606,7 @@ function signal(initial, options) {
|
|
|
2431
2606
|
_d: false,
|
|
2432
2607
|
_validate: void 0
|
|
2433
2608
|
};
|
|
2434
|
-
const debugName =
|
|
2609
|
+
const debugName = DEV ? options?.name : void 0;
|
|
2435
2610
|
const equalsFn = options?.equals;
|
|
2436
2611
|
if (debugName) state2.__name = debugName;
|
|
2437
2612
|
function get() {
|
|
@@ -2448,7 +2623,7 @@ function signal(initial, options) {
|
|
|
2448
2623
|
if (equalsFn(prev, newValue)) return;
|
|
2449
2624
|
state2.value = newValue;
|
|
2450
2625
|
state2.__v++;
|
|
2451
|
-
if (
|
|
2626
|
+
if (DEV) {
|
|
2452
2627
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2453
2628
|
if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
2454
2629
|
}
|
|
@@ -2456,7 +2631,7 @@ function signal(initial, options) {
|
|
|
2456
2631
|
notifySubscribers2(state2);
|
|
2457
2632
|
}
|
|
2458
2633
|
};
|
|
2459
|
-
} else if (
|
|
2634
|
+
} else if (DEV) {
|
|
2460
2635
|
set = (next) => {
|
|
2461
2636
|
const prev = state2.value;
|
|
2462
2637
|
const newValue = typeof next === "function" ? next(prev) : next;
|
|
@@ -2481,7 +2656,7 @@ function signal(initial, options) {
|
|
|
2481
2656
|
}
|
|
2482
2657
|
};
|
|
2483
2658
|
}
|
|
2484
|
-
if (
|
|
2659
|
+
if (DEV) {
|
|
2485
2660
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2486
2661
|
if (hook) hook.emit("signal:create", { signal: state2, name: debugName, getter: get, initial });
|
|
2487
2662
|
}
|
|
@@ -4147,7 +4322,6 @@ function RouterLink(props, children) {
|
|
|
4147
4322
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4148
4323
|
const { to, replace: replace2 = false, activeClass, exactActiveClass, nodes, target, rel, class: classAttr, ...attrs } = props;
|
|
4149
4324
|
const content = children !== void 0 ? children : nodes;
|
|
4150
|
-
const baseClass = typeof classAttr === "string" ? classAttr : "";
|
|
4151
4325
|
const routeGetter = _routerRef.current.routeGetter;
|
|
4152
4326
|
const rawHref = _routerRef.current["resolvePath"](to);
|
|
4153
4327
|
const kind = classifyNavigationTarget(rawHref);
|
|
@@ -4183,7 +4357,7 @@ function RouterLink(props, children) {
|
|
|
4183
4357
|
if (exactActiveClass) classes.push(exactActiveClass);
|
|
4184
4358
|
else if (options.linkExactActiveClass) classes.push(options.linkExactActiveClass);
|
|
4185
4359
|
}
|
|
4186
|
-
link2.className = [
|
|
4360
|
+
link2.className = [resolveClassValue(classAttr), ...classes].filter(Boolean).join(" ");
|
|
4187
4361
|
});
|
|
4188
4362
|
registerDisposer(link2, effectCleanup);
|
|
4189
4363
|
Object.entries(attrs).forEach(([key, value]) => {
|
|
@@ -4195,7 +4369,7 @@ function RouterLink(props, children) {
|
|
|
4195
4369
|
const safe = sanitizeUrl(str);
|
|
4196
4370
|
if (safe) link2.setAttribute(key, safe);
|
|
4197
4371
|
} else if (lkey === "style") {
|
|
4198
|
-
link2.setAttribute(key, sanitizeStyleAttribute(str));
|
|
4372
|
+
link2.setAttribute(key, sanitizeStyleAttribute(str, { element: link2 }));
|
|
4199
4373
|
} else {
|
|
4200
4374
|
link2.setAttribute(key, str);
|
|
4201
4375
|
}
|