sibujs 4.7.0 → 4.9.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/dist/browser.cjs +48 -6
- package/dist/browser.d.cts +26 -2
- package/dist/browser.d.ts +26 -2
- package/dist/browser.js +6 -5
- package/dist/build.cjs +539 -96
- package/dist/build.d.cts +22 -8
- package/dist/build.d.ts +22 -8
- package/dist/build.js +68 -21
- package/dist/cdn.dev.global.js +15 -13
- package/dist/cdn.full.dev.global.js +15 -13
- package/dist/cdn.full.global.js +14 -12
- package/dist/cdn.global.js +14 -12
- package/dist/{chunk-Z3OHK6QT.js → chunk-2K3Z3XO4.js} +5 -5
- package/dist/chunk-3ACAAQIN.js +224 -0
- package/dist/{chunk-WOLJZUFQ.js → chunk-562UVHMM.js} +32 -15
- package/dist/{chunk-UOL2ECCS.js → chunk-5MLWTIQE.js} +18 -12
- package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
- package/dist/{chunk-3QWBSL5R.js → chunk-7OV5Q2UU.js} +8 -5
- package/dist/{chunk-SLM3IA34.js → chunk-CDBKFGXN.js} +1 -1
- package/dist/{chunk-4AWA2PVD.js → chunk-CF2KCWRE.js} +10 -5
- package/dist/{chunk-BSY63EM6.js → chunk-DRMLIF6M.js} +20 -5
- package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
- package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
- package/dist/{chunk-BC2SECJD.js → chunk-FHCZMHHE.js} +1 -1
- package/dist/{chunk-XYV3EDB7.js → chunk-FNOK662L.js} +63 -38
- package/dist/{chunk-JWKYU5GV.js → chunk-G2WHYEL7.js} +1 -1
- package/dist/{chunk-DKXRACVN.js → chunk-K6K5ACO6.js} +6 -6
- package/dist/{chunk-VZSG24LS.js → chunk-KG25XMGP.js} +45 -17
- package/dist/{chunk-FNJXNGYZ.js → chunk-MPWDSTYK.js} +58 -6
- package/dist/{chunk-UNWRJRKC.js → chunk-NQMKWBKU.js} +1 -1
- package/dist/{chunk-7LUJQAOJ.js → chunk-QBKCK6MJ.js} +1 -1
- package/dist/{chunk-WEQ3DMVL.js → chunk-SBTZEYNI.js} +1 -1
- package/dist/{chunk-FQRUXCEE.js → chunk-SYHGGDNW.js} +1 -1
- package/dist/{chunk-XZR4PXRE.js → chunk-TV464N2M.js} +13 -10
- package/dist/{chunk-RUSSKG6G.js → chunk-X7NRHFZR.js} +1 -1
- package/dist/{chunk-2BPG2XDA.js → chunk-XJVTQUIV.js} +18 -36
- package/dist/{chunk-ZVL7TY4K.js → chunk-YW6HQKGO.js} +25 -10
- package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
- package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
- package/dist/data.cjs +29 -9
- package/dist/data.d.cts +23 -4
- package/dist/data.d.ts +23 -4
- package/dist/data.js +6 -6
- package/dist/devtools.cjs +1 -1
- package/dist/devtools.js +5 -5
- package/dist/ecosystem.cjs +400 -37
- package/dist/ecosystem.js +9 -8
- package/dist/extras.cjs +672 -269
- package/dist/extras.d.cts +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/extras.js +24 -23
- package/dist/index.cjs +490 -88
- package/dist/index.d.cts +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +16 -12
- package/dist/motion.cjs +1 -1
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +10 -7
- package/dist/patterns.js +6 -6
- package/dist/performance.cjs +31 -2
- package/dist/performance.d.cts +12 -2
- package/dist/performance.d.ts +12 -2
- package/dist/performance.js +8 -6
- package/dist/plugins.cjs +571 -240
- package/dist/plugins.d.cts +14 -3
- package/dist/plugins.d.ts +14 -3
- package/dist/plugins.js +35 -37
- package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
- package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.cts} +6 -0
- package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.ts} +6 -0
- package/dist/ssr.cjs +484 -138
- package/dist/ssr.d.cts +59 -5
- package/dist/ssr.d.ts +59 -5
- package/dist/ssr.js +11 -9
- package/dist/testing.cjs +3 -3
- package/dist/testing.js +4 -4
- package/dist/ui.cjs +609 -241
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +9 -8
- package/dist/widgets.cjs +1 -1
- package/dist/widgets.js +7 -7
- package/package.json +5 -4
package/dist/build.cjs
CHANGED
|
@@ -791,6 +791,11 @@ function devWarn(message) {
|
|
|
791
791
|
function stripControlChars(value) {
|
|
792
792
|
return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
|
|
793
793
|
}
|
|
794
|
+
var ASCII_UPPER = /[A-Z]/;
|
|
795
|
+
var ASCII_UPPER_G = /[A-Z]/g;
|
|
796
|
+
function canonicalAttrName(name) {
|
|
797
|
+
return ASCII_UPPER.test(name) ? name.replace(ASCII_UPPER_G, (ch) => String.fromCharCode(ch.charCodeAt(0) + 32)) : name;
|
|
798
|
+
}
|
|
794
799
|
function isEventHandlerAttr(name) {
|
|
795
800
|
if (name.length < 3) return false;
|
|
796
801
|
const lower = name.toLowerCase();
|
|
@@ -802,6 +807,9 @@ function sanitizeUrl(url) {
|
|
|
802
807
|
const probe = stripControlChars(url).trim();
|
|
803
808
|
if (!probe) return "";
|
|
804
809
|
const output2 = url.replace(OUTER_TRIM, "");
|
|
810
|
+
if (probe.length >= 2 && (probe[0] === "\\" || probe[0] === "/") && (probe[1] === "\\" || probe[1] === "/") && (probe[0] === "\\" || probe[1] === "\\")) {
|
|
811
|
+
return "";
|
|
812
|
+
}
|
|
805
813
|
const lower = probe.toLowerCase();
|
|
806
814
|
let schemeEnd = -1;
|
|
807
815
|
for (let i2 = 0; i2 < lower.length; i2++) {
|
|
@@ -818,19 +826,58 @@ function sanitizeUrl(url) {
|
|
|
818
826
|
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
819
827
|
return output2;
|
|
820
828
|
}
|
|
821
|
-
var SRCSET_DESCRIPTOR = /^\
|
|
829
|
+
var SRCSET_DESCRIPTOR = /^\d+(\.\d+)?[wx]$/;
|
|
830
|
+
function isSrcsetWhitespace(ch) {
|
|
831
|
+
return ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f";
|
|
832
|
+
}
|
|
822
833
|
function sanitizeSrcset(value) {
|
|
823
|
-
const
|
|
834
|
+
const input2 = String(value);
|
|
824
835
|
const out = [];
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
if (
|
|
830
|
-
|
|
831
|
-
|
|
836
|
+
let i2 = 0;
|
|
837
|
+
const n = input2.length;
|
|
838
|
+
while (i2 < n) {
|
|
839
|
+
while (i2 < n && (isSrcsetWhitespace(input2[i2]) || input2[i2] === ",")) i2++;
|
|
840
|
+
if (i2 >= n) break;
|
|
841
|
+
const urlStart = i2;
|
|
842
|
+
while (i2 < n && !isSrcsetWhitespace(input2[i2])) i2++;
|
|
843
|
+
let url = input2.slice(urlStart, i2);
|
|
844
|
+
const descriptors = [];
|
|
845
|
+
if (url.endsWith(",")) {
|
|
846
|
+
url = url.replace(/,+$/, "");
|
|
847
|
+
} else {
|
|
848
|
+
let current = "";
|
|
849
|
+
let inParens = false;
|
|
850
|
+
while (i2 < n) {
|
|
851
|
+
const ch = input2[i2];
|
|
852
|
+
if (inParens) {
|
|
853
|
+
current += ch;
|
|
854
|
+
if (ch === ")") inParens = false;
|
|
855
|
+
i2++;
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
if (isSrcsetWhitespace(ch)) {
|
|
859
|
+
if (current) descriptors.push(current);
|
|
860
|
+
current = "";
|
|
861
|
+
i2++;
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
if (ch === ",") {
|
|
865
|
+
i2++;
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
if (ch === "(") inParens = true;
|
|
869
|
+
current += ch;
|
|
870
|
+
i2++;
|
|
871
|
+
}
|
|
872
|
+
if (current) descriptors.push(current);
|
|
873
|
+
}
|
|
874
|
+
if (url === "") continue;
|
|
875
|
+
if (descriptors.length > 1) continue;
|
|
876
|
+
if (descriptors.length === 1 && !SRCSET_DESCRIPTOR.test(descriptors[0])) continue;
|
|
877
|
+
const safe = sanitizeUrl(url);
|
|
832
878
|
if (!safe) continue;
|
|
833
|
-
|
|
879
|
+
if (safe.startsWith(",") || safe.endsWith(",")) continue;
|
|
880
|
+
out.push(descriptors.length === 1 ? `${safe} ${descriptors[0]}` : safe);
|
|
834
881
|
}
|
|
835
882
|
return out.join(", ");
|
|
836
883
|
}
|
|
@@ -889,8 +936,16 @@ var BLOCKED_CSS_NEEDLES = [
|
|
|
889
936
|
"behavior:",
|
|
890
937
|
"@import",
|
|
891
938
|
"image-set(",
|
|
892
|
-
"filter:progid"
|
|
939
|
+
"filter:progid",
|
|
940
|
+
// CSS Images 4 `image("…")` and CSS Values 5 `src("…")` take a URL as a
|
|
941
|
+
// plain STRING, so they fetch without ever spelling `url(`. Support is thin
|
|
942
|
+
// today, which is exactly when a blocklist should get ahead of it.
|
|
943
|
+
"image(",
|
|
944
|
+
"src("
|
|
893
945
|
];
|
|
946
|
+
var CSS_REASON_MOZ_BINDING = 4;
|
|
947
|
+
var CSS_REASON_BEHAVIOR = 5;
|
|
948
|
+
var CSS_REASON_PROGID = 8;
|
|
894
949
|
function describeElement(el) {
|
|
895
950
|
if (!el) return "an element";
|
|
896
951
|
let out = el.tagName.toLowerCase();
|
|
@@ -914,7 +969,9 @@ function warnDroppedDeclaration(value, reason, ctx) {
|
|
|
914
969
|
"behavior: loads and runs a remote HTC script",
|
|
915
970
|
"@import pulls in a remote stylesheet",
|
|
916
971
|
"image-set() fetches remote images, the same exfiltration channel as url()",
|
|
917
|
-
"filter:progid activates legacy scriptable filters"
|
|
972
|
+
"filter:progid activates legacy scriptable filters",
|
|
973
|
+
"image() fetches its string argument as a URL, the same exfiltration channel as url()",
|
|
974
|
+
"src() fetches its string argument as a URL, the same exfiltration channel as url()"
|
|
918
975
|
];
|
|
919
976
|
const declaration = ctx?.property ? `${ctx.property}: ${value}` : value;
|
|
920
977
|
const where = describeElement(ctx?.element);
|
|
@@ -929,27 +986,110 @@ function warnDroppedDeclaration(value, reason, ctx) {
|
|
|
929
986
|
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.`;
|
|
930
987
|
});
|
|
931
988
|
}
|
|
989
|
+
function normalizeCssForScan(value) {
|
|
990
|
+
const normalized = value.includes("\\") ? decodeCssEscapes(value) : value;
|
|
991
|
+
return normalized.toLowerCase().replace(/\s+/g, "");
|
|
992
|
+
}
|
|
932
993
|
function blockedCssReason(value) {
|
|
933
994
|
if (!CSS_DANGER_GATE.test(value)) return -1;
|
|
934
|
-
const
|
|
935
|
-
const lower = normalized.toLowerCase().replace(/\s+/g, "");
|
|
995
|
+
const lower = normalizeCssForScan(value);
|
|
936
996
|
for (let i2 = 0; i2 < BLOCKED_CSS_NEEDLES.length; i2++) {
|
|
937
997
|
if (lower.includes(BLOCKED_CSS_NEEDLES[i2])) return i2;
|
|
938
998
|
}
|
|
939
999
|
return -1;
|
|
940
1000
|
}
|
|
941
|
-
function
|
|
942
|
-
const reason =
|
|
1001
|
+
function sanitizeCSSDeclaration(property, value, context2) {
|
|
1002
|
+
const reason = blockedDeclarationReason(property, value);
|
|
943
1003
|
if (reason === -1) return value;
|
|
944
|
-
warnDroppedDeclaration(value, reason, context2);
|
|
1004
|
+
warnDroppedDeclaration(value, reason, { property, element: context2?.element });
|
|
945
1005
|
return "";
|
|
946
1006
|
}
|
|
1007
|
+
function blockedDeclarationReason(property, value) {
|
|
1008
|
+
const reason = blockedCssReason(value);
|
|
1009
|
+
if (reason !== -1) return reason;
|
|
1010
|
+
const name = canonicalAttrName(property);
|
|
1011
|
+
if (name === "behavior") return CSS_REASON_BEHAVIOR;
|
|
1012
|
+
if (name === "-moz-binding") return CSS_REASON_MOZ_BINDING;
|
|
1013
|
+
if ((name === "filter" || name === "-ms-filter") && normalizeCssForScan(value).includes("progid:")) {
|
|
1014
|
+
return CSS_REASON_PROGID;
|
|
1015
|
+
}
|
|
1016
|
+
return -1;
|
|
1017
|
+
}
|
|
1018
|
+
function parseStyleDeclarations(css) {
|
|
1019
|
+
const chunks = [];
|
|
1020
|
+
let buf = "";
|
|
1021
|
+
let depth = 0;
|
|
1022
|
+
let quote2 = "";
|
|
1023
|
+
for (let i2 = 0; i2 < css.length; i2++) {
|
|
1024
|
+
const ch = css[i2];
|
|
1025
|
+
if (quote2) {
|
|
1026
|
+
buf += ch;
|
|
1027
|
+
if (ch === "\\" && i2 + 1 < css.length) buf += css[++i2];
|
|
1028
|
+
else if (ch === quote2) quote2 = "";
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (ch === "\\") {
|
|
1032
|
+
buf += ch;
|
|
1033
|
+
if (i2 + 1 < css.length) buf += css[++i2];
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
if (ch === "/" && css[i2 + 1] === "*") {
|
|
1037
|
+
const end = css.indexOf("*/", i2 + 2);
|
|
1038
|
+
if (end === -1) return null;
|
|
1039
|
+
i2 = end + 1;
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
if (ch === '"' || ch === "'") quote2 = ch;
|
|
1043
|
+
else if (ch === "(" || ch === "[") depth++;
|
|
1044
|
+
else if (ch === ")" || ch === "]") {
|
|
1045
|
+
if (--depth < 0) return null;
|
|
1046
|
+
} else if (ch === "{" || ch === "}") return null;
|
|
1047
|
+
else if (ch === ";" && depth === 0) {
|
|
1048
|
+
chunks.push(buf);
|
|
1049
|
+
buf = "";
|
|
1050
|
+
continue;
|
|
1051
|
+
}
|
|
1052
|
+
buf += ch;
|
|
1053
|
+
}
|
|
1054
|
+
if (quote2 || depth !== 0) return null;
|
|
1055
|
+
chunks.push(buf);
|
|
1056
|
+
const out = [];
|
|
1057
|
+
for (const chunk of chunks) {
|
|
1058
|
+
const colon = chunk.indexOf(":");
|
|
1059
|
+
if (colon === -1) continue;
|
|
1060
|
+
const rawName = chunk.slice(0, colon).trim();
|
|
1061
|
+
if (!/^(--[\w-]+|-?[a-zA-Z_][\w-]*)$/.test(rawName)) continue;
|
|
1062
|
+
let value = chunk.slice(colon + 1).trim();
|
|
1063
|
+
const bang = /!\s*important\s*$/i.exec(value);
|
|
1064
|
+
if (bang) value = value.slice(0, bang.index).trim();
|
|
1065
|
+
if (value === "") continue;
|
|
1066
|
+
const property = rawName.startsWith("--") ? rawName : canonicalAttrName(rawName);
|
|
1067
|
+
out.push([property, value, bang !== null]);
|
|
1068
|
+
}
|
|
1069
|
+
return out;
|
|
1070
|
+
}
|
|
1071
|
+
function sanitizeStyleDeclarationList(cssText, context2) {
|
|
1072
|
+
const input2 = String(cssText);
|
|
1073
|
+
const declarations = parseStyleDeclarations(input2);
|
|
1074
|
+
if (declarations === null) {
|
|
1075
|
+
if (blockedCssReason(input2) !== -1) warnDroppedDeclaration(input2, blockedCssReason(input2), context2);
|
|
1076
|
+
return "";
|
|
1077
|
+
}
|
|
1078
|
+
const kept = [];
|
|
1079
|
+
for (const [property, value, important] of declarations) {
|
|
1080
|
+
const reason = blockedDeclarationReason(property, value);
|
|
1081
|
+
if (reason !== -1) {
|
|
1082
|
+
warnDroppedDeclaration(value, reason, { property, element: context2?.element });
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
kept.push(`${property}: ${value}${important ? " !important" : ""}`);
|
|
1086
|
+
}
|
|
1087
|
+
return kept.join("; ");
|
|
1088
|
+
}
|
|
947
1089
|
function sanitizeStyleAttribute(cssText, context2) {
|
|
948
1090
|
const input2 = String(cssText);
|
|
949
1091
|
if (input2.trim() === "") return "";
|
|
950
|
-
if (typeof document === "undefined")
|
|
951
|
-
return sanitizeCSSValue(input2, context2) === "" ? "" : input2;
|
|
952
|
-
}
|
|
1092
|
+
if (typeof document === "undefined") return sanitizeStyleDeclarationList(input2, context2);
|
|
953
1093
|
const probe = document.createElement("div");
|
|
954
1094
|
try {
|
|
955
1095
|
probe.style.cssText = input2;
|
|
@@ -960,8 +1100,7 @@ function sanitizeStyleAttribute(cssText, context2) {
|
|
|
960
1100
|
for (let i2 = 0; i2 < probe.style.length; i2++) {
|
|
961
1101
|
const property = probe.style[i2];
|
|
962
1102
|
const value = probe.style.getPropertyValue(property);
|
|
963
|
-
|
|
964
|
-
if (reason === -1) reason = blockedCssReason(`${property}:${value}`);
|
|
1103
|
+
const reason = blockedDeclarationReason(property, value);
|
|
965
1104
|
if (reason !== -1) {
|
|
966
1105
|
warnDroppedDeclaration(value, reason, { property, element: context2?.element });
|
|
967
1106
|
continue;
|
|
@@ -996,6 +1135,10 @@ function isHtmlContentAttribute(name) {
|
|
|
996
1135
|
function isUrlAttribute(attr) {
|
|
997
1136
|
return URL_ATTRIBUTES.has(attr.toLowerCase());
|
|
998
1137
|
}
|
|
1138
|
+
function isPolicyAttribute(name) {
|
|
1139
|
+
const lower = name.toLowerCase();
|
|
1140
|
+
return lower === "style" || URL_ATTRIBUTES.has(lower);
|
|
1141
|
+
}
|
|
999
1142
|
function sanitizeAttributeString(attr, value, context2) {
|
|
1000
1143
|
const lower = attr.toLowerCase();
|
|
1001
1144
|
if (lower === "srcset") return sanitizeSrcset(value);
|
|
@@ -1003,6 +1146,11 @@ function sanitizeAttributeString(attr, value, context2) {
|
|
|
1003
1146
|
if (lower === "style") return sanitizeStyleAttribute(value, context2);
|
|
1004
1147
|
return value;
|
|
1005
1148
|
}
|
|
1149
|
+
function resolveAttributeValue(attr, value, context2) {
|
|
1150
|
+
if (!isPolicyAttribute(attr)) return value;
|
|
1151
|
+
const safe = sanitizeAttributeString(attr, value, context2);
|
|
1152
|
+
return safe === "" ? null : safe;
|
|
1153
|
+
}
|
|
1006
1154
|
|
|
1007
1155
|
// src/build/staticAnalysis.ts
|
|
1008
1156
|
var STATIC_TAGS = /* @__PURE__ */ new Set([
|
|
@@ -1456,6 +1604,11 @@ function generateBody(roots, h) {
|
|
|
1456
1604
|
const q2 = jsStringLiteral;
|
|
1457
1605
|
const P = h.prefix;
|
|
1458
1606
|
function genElement(el) {
|
|
1607
|
+
const tag = el.tag.toLowerCase();
|
|
1608
|
+
if (tag === "meta" || tag === "link") return null;
|
|
1609
|
+
for (const attr of el.attrs) {
|
|
1610
|
+
if ((attr.t === 0 || attr.t === 4) && attr.name.toLowerCase() === "srcdoc") return null;
|
|
1611
|
+
}
|
|
1459
1612
|
const v = `e${n++}`;
|
|
1460
1613
|
h.tags.add(el.tag);
|
|
1461
1614
|
if (el.svg) h.svg = true;
|
|
@@ -1547,6 +1700,9 @@ function helperSource(h) {
|
|
|
1547
1700
|
out.push(
|
|
1548
1701
|
`function ${P}on(el, name, handler) {
|
|
1549
1702
|
if (typeof handler === "function") el.addEventListener(name, handler);
|
|
1703
|
+
else if (typeof __SIBU_DEV__ !== "undefined" && __SIBU_DEV__) {
|
|
1704
|
+
console.warn(\`[SibuJS] html: on:\${name} handler is not a function (got \${typeof handler}). Event listener was not attached.\`);
|
|
1705
|
+
}
|
|
1550
1706
|
}`
|
|
1551
1707
|
);
|
|
1552
1708
|
}
|
|
@@ -1554,7 +1710,10 @@ function helperSource(h) {
|
|
|
1554
1710
|
out.push(
|
|
1555
1711
|
`function ${P}child(el, value) {
|
|
1556
1712
|
if (typeof value === "function") {
|
|
1557
|
-
|
|
1713
|
+
const frag = ${P}Fragment([value]);
|
|
1714
|
+
const ph = frag.firstChild;
|
|
1715
|
+
el.appendChild(frag);
|
|
1716
|
+
${P}registerDisposer(el, () => ${P}dispose(ph));
|
|
1558
1717
|
} else if (value instanceof Node) {
|
|
1559
1718
|
el.appendChild(value);
|
|
1560
1719
|
} else if (Array.isArray(value)) {
|
|
@@ -1574,13 +1733,22 @@ function helperSource(h) {
|
|
|
1574
1733
|
function importSource(h) {
|
|
1575
1734
|
const P = h.prefix;
|
|
1576
1735
|
const core = [];
|
|
1577
|
-
if (h.used.has("child")) core.push(`Fragment as ${P}Fragment`);
|
|
1578
|
-
if (h.used.has("attr")) core.push(`registerDisposer as ${P}registerDisposer`);
|
|
1736
|
+
if (h.used.has("child")) core.push(`Fragment as ${P}Fragment`, `dispose as ${P}dispose`);
|
|
1737
|
+
if (h.used.has("attr") || h.used.has("child")) core.push(`registerDisposer as ${P}registerDisposer`);
|
|
1738
|
+
if (h.used.has("run")) core.push(`__renderParsedTemplate as ${P}run`);
|
|
1579
1739
|
const lines = [];
|
|
1580
1740
|
if (core.length > 0) lines.push(`import { ${core.join(", ")} } from "sibujs";`);
|
|
1581
1741
|
if (h.used.has("attr")) lines.push(`import { bindAttrs as ${P}bindAttrs } from "sibujs/ui";`);
|
|
1582
1742
|
return lines.join("\n");
|
|
1583
1743
|
}
|
|
1744
|
+
function collectTags(children, h) {
|
|
1745
|
+
for (const child of children) {
|
|
1746
|
+
if (child.t !== 0) continue;
|
|
1747
|
+
h.tags.add(child.el.tag);
|
|
1748
|
+
if (child.el.svg) h.svg = true;
|
|
1749
|
+
collectTags(child.el.children, h);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1584
1752
|
function planHtmlTemplates(code2) {
|
|
1585
1753
|
const plan = {
|
|
1586
1754
|
edits: [],
|
|
@@ -1608,24 +1776,44 @@ function planHtmlTemplates(code2) {
|
|
|
1608
1776
|
const strings = [];
|
|
1609
1777
|
for (const qs of tmpl.quasis) {
|
|
1610
1778
|
const cooked = cookEscapes(code2.slice(qs.start, qs.end));
|
|
1611
|
-
if (cooked === null)
|
|
1779
|
+
if (cooked === null) {
|
|
1780
|
+
if (tmpl.quasis.length === 1) return null;
|
|
1781
|
+
strings.push("undefined");
|
|
1782
|
+
continue;
|
|
1783
|
+
}
|
|
1612
1784
|
strings.push(cooked);
|
|
1613
1785
|
}
|
|
1786
|
+
const name = `${h.prefix}t${functions.length}`;
|
|
1787
|
+
const params = tmpl.exprs.map((_, i2) => `v${i2}`).join(", ");
|
|
1614
1788
|
let roots;
|
|
1615
1789
|
try {
|
|
1616
1790
|
roots = parseTemplate(strings);
|
|
1617
1791
|
} catch (err) {
|
|
1618
|
-
if (err instanceof RuntimeParseError)
|
|
1792
|
+
if (err instanceof RuntimeParseError) {
|
|
1793
|
+
const message = `html: dynamic \${...} expressions are not allowed inside <${err.message}> (raw-text context). Build the content separately and append it as a Node.`;
|
|
1794
|
+
functions.push(`function ${name}(${params}) {
|
|
1795
|
+
throw new Error(${jsStringLiteral(message)});
|
|
1796
|
+
}`);
|
|
1797
|
+
return name;
|
|
1798
|
+
}
|
|
1619
1799
|
throw err;
|
|
1620
1800
|
}
|
|
1621
1801
|
const scratch = { prefix: h.prefix, used: /* @__PURE__ */ new Set(), tags: /* @__PURE__ */ new Set(), svg: false };
|
|
1622
1802
|
const body2 = generateBody(roots, scratch);
|
|
1623
|
-
if (body2 === null)
|
|
1803
|
+
if (body2 === null) {
|
|
1804
|
+
const tree = JSON.stringify(roots).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1805
|
+
h.used.add("run");
|
|
1806
|
+
collectTags(roots, h);
|
|
1807
|
+
functions.push(
|
|
1808
|
+
`function ${name}(${params}) {
|
|
1809
|
+
return ${h.prefix}run(${name}.tree || (${name}.tree = ${tree}), [${params}]);
|
|
1810
|
+
}`
|
|
1811
|
+
);
|
|
1812
|
+
return name;
|
|
1813
|
+
}
|
|
1624
1814
|
for (const u2 of scratch.used) h.used.add(u2);
|
|
1625
1815
|
for (const t of scratch.tags) h.tags.add(t);
|
|
1626
1816
|
if (scratch.svg) h.svg = true;
|
|
1627
|
-
const name = `${h.prefix}t${functions.length}`;
|
|
1628
|
-
const params = tmpl.exprs.map((_, i2) => `v${i2}`).join(", ");
|
|
1629
1817
|
functions.push(`function ${name}(${params}) {
|
|
1630
1818
|
${body2}
|
|
1631
1819
|
}`);
|
|
@@ -1903,6 +2091,11 @@ function sibuWebpackPlugin(options = {}) {
|
|
|
1903
2091
|
return {
|
|
1904
2092
|
name: "SibuWebpackPlugin",
|
|
1905
2093
|
apply(compiler) {
|
|
2094
|
+
if (options.pureAnnotations === true) {
|
|
2095
|
+
console.warn(
|
|
2096
|
+
'[SibuWebpackPlugin] `pureAnnotations` is not applied by the plugin: webpack needs a loader file. Create sibu-pure-loader.cjs containing `module.exports = require("sibujs/build").createPureAnnotationsLoader();` and add a module rule `{ test: /\\.[cm]?[jt]sx?$/, exclude: /node_modules/, use: "./sibu-pure-loader.cjs" }`.'
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
1906
2099
|
compiler.hooks?.compilation?.tap("SibuWebpackPlugin", (compilation) => {
|
|
1907
2100
|
const comp = compilation;
|
|
1908
2101
|
if (comp.hooks?.optimizeModules) {
|
|
@@ -2079,8 +2272,9 @@ __export(index_exports, {
|
|
|
2079
2272
|
Loading: () => Loading,
|
|
2080
2273
|
MAX_DRAIN_TEARDOWNS: () => MAX_DRAIN_TEARDOWNS,
|
|
2081
2274
|
Portal: () => Portal,
|
|
2082
|
-
SVG_NS: () =>
|
|
2275
|
+
SVG_NS: () => SVG_NS4,
|
|
2083
2276
|
Suspense: () => Suspense,
|
|
2277
|
+
__renderParsedTemplate: () => __renderParsedTemplate,
|
|
2084
2278
|
__resetIdCounter: () => __resetIdCounter,
|
|
2085
2279
|
a: () => a,
|
|
2086
2280
|
abbr: () => abbr,
|
|
@@ -2552,26 +2746,227 @@ function checkLeaks(warnThreshold = 0) {
|
|
|
2552
2746
|
return activeBindingCount;
|
|
2553
2747
|
}
|
|
2554
2748
|
|
|
2555
|
-
// src/utils/
|
|
2749
|
+
// src/utils/metaRefresh.ts
|
|
2750
|
+
function isAsciiWhitespace(ch) {
|
|
2751
|
+
return ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f";
|
|
2752
|
+
}
|
|
2753
|
+
function trimAsciiWhitespace(value) {
|
|
2754
|
+
let start = 0;
|
|
2755
|
+
let end = value.length;
|
|
2756
|
+
while (start < end && isAsciiWhitespace(value[start])) start++;
|
|
2757
|
+
while (end > start && isAsciiWhitespace(value[end - 1])) end--;
|
|
2758
|
+
return value.slice(start, end);
|
|
2759
|
+
}
|
|
2760
|
+
var forbidden = (reason) => ({ kind: "forbidden", reason });
|
|
2761
|
+
function parseMetaRefreshContent(content) {
|
|
2762
|
+
const raw = trimAsciiWhitespace(stripControlChars(content));
|
|
2763
|
+
if (raw === "") return forbidden(DEV ? "empty content" : "");
|
|
2764
|
+
let i2 = 0;
|
|
2765
|
+
while (i2 < raw.length && raw[i2] >= "0" && raw[i2] <= "9") i2++;
|
|
2766
|
+
if (i2 === 0) return forbidden(DEV ? "missing or non-numeric delay" : "");
|
|
2767
|
+
const delay = Number.parseInt(raw.slice(0, i2), 10);
|
|
2768
|
+
if (!Number.isFinite(delay)) return forbidden(DEV ? "unparseable delay" : "");
|
|
2769
|
+
while (i2 < raw.length && isAsciiWhitespace(raw[i2])) i2++;
|
|
2770
|
+
if (i2 === raw.length) return { kind: "delay-only", delay };
|
|
2771
|
+
if (raw[i2] !== ";" && raw[i2] !== ",") return forbidden(DEV ? "unexpected text after delay" : "");
|
|
2772
|
+
i2++;
|
|
2773
|
+
while (i2 < raw.length && isAsciiWhitespace(raw[i2])) i2++;
|
|
2774
|
+
const keyStart = i2;
|
|
2775
|
+
while (i2 < raw.length && !isAsciiWhitespace(raw[i2]) && raw[i2] !== "=") i2++;
|
|
2776
|
+
const key = raw.slice(keyStart, i2).toLowerCase();
|
|
2777
|
+
if (key !== "url") return forbidden(DEV ? `unsupported refresh key ${JSON.stringify(key)}` : "");
|
|
2778
|
+
while (i2 < raw.length && isAsciiWhitespace(raw[i2])) i2++;
|
|
2779
|
+
if (raw[i2] !== "=") return forbidden(DEV ? "missing '=' after url" : "");
|
|
2780
|
+
i2++;
|
|
2781
|
+
while (i2 < raw.length && isAsciiWhitespace(raw[i2])) i2++;
|
|
2782
|
+
let destination;
|
|
2783
|
+
const quote2 = raw[i2];
|
|
2784
|
+
if (quote2 === '"' || quote2 === "'") {
|
|
2785
|
+
const close = raw.indexOf(quote2, i2 + 1);
|
|
2786
|
+
if (close === -1) return forbidden(DEV ? "unterminated quoted destination" : "");
|
|
2787
|
+
destination = raw.slice(i2 + 1, close);
|
|
2788
|
+
const rest = trimAsciiWhitespace(raw.slice(close + 1));
|
|
2789
|
+
if (rest !== "") return forbidden(DEV ? "trailing text after quoted destination" : "");
|
|
2790
|
+
} else {
|
|
2791
|
+
destination = trimAsciiWhitespace(raw.slice(i2));
|
|
2792
|
+
if (/[;,]/.test(destination)) return forbidden(DEV ? "multiple refresh assignments" : "");
|
|
2793
|
+
}
|
|
2794
|
+
if (destination === "") return forbidden(DEV ? "empty destination" : "");
|
|
2795
|
+
const sanitizedDestination = sanitizeUrl(destination);
|
|
2796
|
+
if (sanitizedDestination === "") return forbidden(DEV ? "destination uses a disallowed protocol" : "");
|
|
2797
|
+
return { kind: "allowed", delay, destination, sanitizedDestination };
|
|
2798
|
+
}
|
|
2799
|
+
function resolveMetaRefreshPolicy(attributes) {
|
|
2800
|
+
let httpEquiv;
|
|
2801
|
+
let content;
|
|
2802
|
+
let duplicateName;
|
|
2803
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2804
|
+
for (const [key, value] of attributes) {
|
|
2805
|
+
const canonical = canonicalAttrName(key);
|
|
2806
|
+
if (seen.has(canonical)) duplicateName = canonical;
|
|
2807
|
+
seen.add(canonical);
|
|
2808
|
+
if (canonical === "http-equiv") httpEquiv = value;
|
|
2809
|
+
else if (canonical === "content") content = value;
|
|
2810
|
+
}
|
|
2811
|
+
if (duplicateName !== void 0) {
|
|
2812
|
+
return forbidden(DEV ? `duplicate case-insensitive attribute ${JSON.stringify(duplicateName)}` : "");
|
|
2813
|
+
}
|
|
2814
|
+
if (typeof httpEquiv !== "string") return { kind: "not-refresh" };
|
|
2815
|
+
if (trimAsciiWhitespace(stripControlChars(httpEquiv)).toLowerCase() !== "refresh") {
|
|
2816
|
+
return { kind: "not-refresh" };
|
|
2817
|
+
}
|
|
2818
|
+
if (typeof content !== "string") return { kind: "not-refresh" };
|
|
2819
|
+
return parseMetaRefreshContent(content);
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
// src/utils/elementPolicy.ts
|
|
2556
2823
|
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
2557
2824
|
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
2825
|
+
var BLOCKED_ELEMENTS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
2826
|
+
function canonicalTagName(tag) {
|
|
2827
|
+
return canonicalAttrName(tag);
|
|
2828
|
+
}
|
|
2829
|
+
function isBlockedElement(tag) {
|
|
2830
|
+
return BLOCKED_ELEMENTS.has(canonicalTagName(tag));
|
|
2831
|
+
}
|
|
2832
|
+
var CODE_TEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
2833
|
+
function isCodeTextElement(tag) {
|
|
2834
|
+
return CODE_TEXT_ELEMENTS.has(canonicalTagName(tag));
|
|
2835
|
+
}
|
|
2836
|
+
var ContextualRefusal = {
|
|
2837
|
+
None: 0,
|
|
2838
|
+
/** The element would carry a refresh directive the shared policy forbids. */
|
|
2839
|
+
MetaRefreshForbidden: 1,
|
|
2840
|
+
/** A `<meta>` with a reactive binding may not carry any refresh directive. */
|
|
2841
|
+
MetaRefreshReactive: 2,
|
|
2842
|
+
/** A runtime value may not choose which program a `<script>` runs. */
|
|
2843
|
+
ScriptSource: 3,
|
|
2844
|
+
/** An SVG animation may not target a URL, handler or document attribute. */
|
|
2845
|
+
AnimationTarget: 4,
|
|
2846
|
+
/** A runtime-written `href` may not become an applied stylesheet. */
|
|
2847
|
+
StylesheetSource: 5
|
|
2848
|
+
};
|
|
2849
|
+
var SCRIPT_SOURCE_ATTRIBUTES = /* @__PURE__ */ new Set(["src", "href", "xlink:href", "type", "language"]);
|
|
2850
|
+
var SVG_ANIMATION_ELEMENTS = /* @__PURE__ */ new Set(["animate", "set", "animateMotion", "animateTransform", "animateColor"]);
|
|
2851
|
+
var reactiveMetaElements = /* @__PURE__ */ new WeakSet();
|
|
2852
|
+
function isHtmlNamespace(el) {
|
|
2853
|
+
return el.namespaceURI === HTML_NS || el.namespaceURI === null;
|
|
2854
|
+
}
|
|
2855
|
+
function metaSnapshot(el, canonical, value) {
|
|
2856
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
2857
|
+
const attrs = el.attributes;
|
|
2858
|
+
for (let i2 = 0; i2 < attrs.length; i2++) {
|
|
2859
|
+
const attr = attrs[i2];
|
|
2860
|
+
if (attr.name === canonical) continue;
|
|
2861
|
+
snapshot.set(attr.name, attr.value);
|
|
2862
|
+
}
|
|
2863
|
+
if (canonical !== null && value !== null) snapshot.set(canonical, value);
|
|
2864
|
+
return snapshot;
|
|
2865
|
+
}
|
|
2866
|
+
function claimReactiveMeta(el) {
|
|
2867
|
+
if (reactiveMetaElements.has(el)) return;
|
|
2868
|
+
reactiveMetaElements.add(el);
|
|
2869
|
+
if (el.getAttribute("content") === null) return;
|
|
2870
|
+
if (resolveMetaRefreshPolicy(metaSnapshot(el, null, null)).kind !== "not-refresh") {
|
|
2871
|
+
el.removeAttribute("content");
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
function metaRefusal(el, name, value, origin) {
|
|
2875
|
+
if (!isHtmlNamespace(el)) return ContextualRefusal.None;
|
|
2876
|
+
const canonical = canonicalAttrName(name);
|
|
2877
|
+
if (canonical !== "http-equiv" && canonical !== "content") return ContextualRefusal.None;
|
|
2878
|
+
if (origin === "reactive") claimReactiveMeta(el);
|
|
2879
|
+
if (value === null) return ContextualRefusal.None;
|
|
2880
|
+
if (canonical === "content" && !el.hasAttribute("http-equiv")) return ContextualRefusal.None;
|
|
2881
|
+
const decision = resolveMetaRefreshPolicy(metaSnapshot(el, canonical, value));
|
|
2882
|
+
if (decision.kind === "forbidden") return ContextualRefusal.MetaRefreshForbidden;
|
|
2883
|
+
if (decision.kind !== "not-refresh" && reactiveMetaElements.has(el)) return ContextualRefusal.MetaRefreshReactive;
|
|
2884
|
+
return ContextualRefusal.None;
|
|
2885
|
+
}
|
|
2886
|
+
function animationRefusal(name, value) {
|
|
2887
|
+
if (value === null || canonicalAttrName(name) !== "attributename") return ContextualRefusal.None;
|
|
2888
|
+
const target = stripControlChars(value);
|
|
2889
|
+
return isUrlAttribute(target) || isEventHandlerAttr(target) || isHtmlContentAttribute(target) ? ContextualRefusal.AnimationTarget : ContextualRefusal.None;
|
|
2890
|
+
}
|
|
2891
|
+
var runtimeHrefLinks = /* @__PURE__ */ new WeakSet();
|
|
2892
|
+
function relHasStylesheet(rel) {
|
|
2893
|
+
if (rel === null) return false;
|
|
2894
|
+
const lower = canonicalAttrName(rel);
|
|
2895
|
+
if (!lower.includes("stylesheet")) return false;
|
|
2896
|
+
const tokens = lower.split(/[\t\n\f\r ]+/);
|
|
2897
|
+
for (let i2 = 0; i2 < tokens.length; i2++) if (tokens[i2] === "stylesheet") return true;
|
|
2898
|
+
return false;
|
|
2899
|
+
}
|
|
2900
|
+
function stylesheetRefusal(el, name, value, origin) {
|
|
2901
|
+
if (!isHtmlNamespace(el)) return ContextualRefusal.None;
|
|
2902
|
+
const canonical = canonicalAttrName(name);
|
|
2903
|
+
if (canonical === "href") {
|
|
2904
|
+
if (origin === "static" || value === null) return ContextualRefusal.None;
|
|
2905
|
+
if (relHasStylesheet(el.getAttribute("rel"))) return ContextualRefusal.StylesheetSource;
|
|
2906
|
+
runtimeHrefLinks.add(el);
|
|
2907
|
+
return ContextualRefusal.None;
|
|
2908
|
+
}
|
|
2909
|
+
if (canonical === "rel") {
|
|
2910
|
+
if (!relHasStylesheet(value)) return ContextualRefusal.None;
|
|
2911
|
+
return runtimeHrefLinks.has(el) && el.hasAttribute("href") ? ContextualRefusal.StylesheetSource : ContextualRefusal.None;
|
|
2912
|
+
}
|
|
2913
|
+
return ContextualRefusal.None;
|
|
2914
|
+
}
|
|
2915
|
+
function contextualAttributeRefusal(el, name, value, origin) {
|
|
2916
|
+
const local = el.localName;
|
|
2917
|
+
if (local === "meta") return metaRefusal(el, name, value, origin);
|
|
2918
|
+
if (local === "link") return stylesheetRefusal(el, name, value, origin);
|
|
2919
|
+
if (local === "script") {
|
|
2920
|
+
if (origin === "static" || value === null) return ContextualRefusal.None;
|
|
2921
|
+
return SCRIPT_SOURCE_ATTRIBUTES.has(canonicalAttrName(name)) ? ContextualRefusal.ScriptSource : ContextualRefusal.None;
|
|
2922
|
+
}
|
|
2923
|
+
if (SVG_ANIMATION_ELEMENTS.has(local) && el.namespaceURI === SVG_NS2) return animationRefusal(name, value);
|
|
2924
|
+
return ContextualRefusal.None;
|
|
2925
|
+
}
|
|
2926
|
+
function settleAttributeProvenance(el, name, origin) {
|
|
2927
|
+
if (el.localName !== "link" || canonicalAttrName(name) !== "href") return;
|
|
2928
|
+
if (origin !== "static" && el.hasAttribute("href")) runtimeHrefLinks.add(el);
|
|
2929
|
+
else runtimeHrefLinks.delete(el);
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
// src/utils/setSafeAttribute.ts
|
|
2933
|
+
var HTML_NS2 = "http://www.w3.org/1999/xhtml";
|
|
2934
|
+
var SVG_NS3 = "http://www.w3.org/2000/svg";
|
|
2558
2935
|
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
2559
2936
|
var XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
2560
2937
|
var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selected"]);
|
|
2561
2938
|
function isHtmlElement(el) {
|
|
2562
|
-
return el.namespaceURI === null || el.namespaceURI ===
|
|
2939
|
+
return el.namespaceURI === null || el.namespaceURI === HTML_NS2;
|
|
2940
|
+
}
|
|
2941
|
+
function warnContextualRefusal(label2, name, refusal) {
|
|
2942
|
+
devWarnLazy(() => {
|
|
2943
|
+
const reasons = [
|
|
2944
|
+
"",
|
|
2945
|
+
'the element would become a <meta http-equiv="refresh"> directive the shared refresh policy forbids (a destination outside the URL allowlist, or a directive too malformed to read unambiguously)',
|
|
2946
|
+
"a <meta> whose http-equiv or content is reactive may never carry a refresh directive: a browser schedules the navigation as soon as the directive is valid, and nothing can withdraw it when the state changes back",
|
|
2947
|
+
"a runtime value may not choose the program a <script> runs; name the script in static template source, or load it through Head({ script }) as an explicit trust decision",
|
|
2948
|
+
"an SVG animation may not target a URL, event-handler or nested-document attribute; its to / values would be written into that attribute without passing the URL policy",
|
|
2949
|
+
'a runtime-chosen href may not become an applied <link rel="stylesheet">: a well-formed URL is not a trusted stylesheet. Name the stylesheet in static template source, or load a runtime-chosen one through Head({ link }) as an explicit trust decision'
|
|
2950
|
+
];
|
|
2951
|
+
return `${label2}: refusing "${name}" in this element's context \u2014 ${reasons[refusal]}. The write was not performed.`;
|
|
2952
|
+
});
|
|
2563
2953
|
}
|
|
2564
2954
|
function setProp(el, key, val) {
|
|
2565
2955
|
el[key] = val;
|
|
2566
2956
|
}
|
|
2567
2957
|
function namespaceFor(el, name) {
|
|
2568
|
-
if (el.namespaceURI !==
|
|
2958
|
+
if (el.namespaceURI !== SVG_NS3) return null;
|
|
2569
2959
|
const lower = name.toLowerCase();
|
|
2570
2960
|
if (lower.startsWith("xlink:")) return XLINK_NS;
|
|
2571
2961
|
if (lower.startsWith("xml:")) return XML_NS;
|
|
2572
2962
|
return null;
|
|
2573
2963
|
}
|
|
2574
2964
|
function setSafeAttribute(el, name, value, options = {}) {
|
|
2965
|
+
const written = commitSafeAttribute(el, name, value, options);
|
|
2966
|
+
if (el.localName === "link") settleAttributeProvenance(el, name, options.reactive ? "reactive" : "runtime");
|
|
2967
|
+
return written;
|
|
2968
|
+
}
|
|
2969
|
+
function commitSafeAttribute(el, name, value, options) {
|
|
2575
2970
|
const ns = namespaceFor(el, name);
|
|
2576
2971
|
const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
|
|
2577
2972
|
if (isEventHandlerAttr(name)) {
|
|
@@ -2584,6 +2979,14 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
2584
2979
|
else el.removeAttribute(name);
|
|
2585
2980
|
return false;
|
|
2586
2981
|
}
|
|
2982
|
+
const pending = value == null || value === false ? null : value === true ? "" : String(value);
|
|
2983
|
+
const refusal = contextualAttributeRefusal(el, name, pending, options.reactive ? "reactive" : "runtime");
|
|
2984
|
+
if (refusal !== ContextualRefusal.None) {
|
|
2985
|
+
warnContextualRefusal(options.label ?? "setSafeAttribute", name, refusal);
|
|
2986
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
2987
|
+
else el.removeAttribute(name);
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2587
2990
|
if (value == null) {
|
|
2588
2991
|
if (ns) el.removeAttributeNS(ns, localName);
|
|
2589
2992
|
else el.removeAttribute(name);
|
|
@@ -2627,13 +3030,32 @@ function setSafeAttribute(el, name, value, options = {}) {
|
|
|
2627
3030
|
setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
|
|
2628
3031
|
return true;
|
|
2629
3032
|
}
|
|
2630
|
-
const safe =
|
|
3033
|
+
const safe = str === "" ? "" : resolveAttributeValue(name, str, { element: el });
|
|
3034
|
+
if (safe === null) {
|
|
3035
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
3036
|
+
else el.removeAttribute(name);
|
|
3037
|
+
return true;
|
|
3038
|
+
}
|
|
2631
3039
|
const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
|
|
2632
3040
|
if (current === safe) return true;
|
|
2633
3041
|
if (ns) el.setAttributeNS(ns, name, safe);
|
|
2634
3042
|
else el.setAttribute(name, safe);
|
|
2635
3043
|
return true;
|
|
2636
3044
|
}
|
|
3045
|
+
function setTrustedAttribute(el, name, value) {
|
|
3046
|
+
if (isHtmlContentAttribute(name)) {
|
|
3047
|
+
if (DEV) devWarn(`html: refusing static attribute "${name}" \u2014 the browser parses it as a nested document.`);
|
|
3048
|
+
return false;
|
|
3049
|
+
}
|
|
3050
|
+
const refusal = contextualAttributeRefusal(el, name, value, "static");
|
|
3051
|
+
if (refusal !== ContextualRefusal.None) {
|
|
3052
|
+
warnContextualRefusal("html (static attribute)", name, refusal);
|
|
3053
|
+
return false;
|
|
3054
|
+
}
|
|
3055
|
+
el.setAttribute(name, value);
|
|
3056
|
+
if (el.localName === "link") settleAttributeProvenance(el, name, "static");
|
|
3057
|
+
return true;
|
|
3058
|
+
}
|
|
2637
3059
|
|
|
2638
3060
|
// src/reactivity/track-core.ts
|
|
2639
3061
|
var POOL_MAX = 4096;
|
|
@@ -3126,7 +3548,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
3126
3548
|
}
|
|
3127
3549
|
|
|
3128
3550
|
// src/reactivity/track.ts
|
|
3129
|
-
var _runtimeVersion = true ? "4.
|
|
3551
|
+
var _runtimeVersion = true ? "4.9.0" : "dev";
|
|
3130
3552
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
3131
3553
|
function resolveReactiveApi() {
|
|
3132
3554
|
const g2 = globalThis;
|
|
@@ -3197,7 +3619,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
3197
3619
|
reportError(err, { phase: "binding", name: `bindAttribute("${attr}")`, node: el });
|
|
3198
3620
|
return;
|
|
3199
3621
|
}
|
|
3200
|
-
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")
|
|
3622
|
+
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")`, reactive: true });
|
|
3201
3623
|
}
|
|
3202
3624
|
return reactiveBinding2(commit, el);
|
|
3203
3625
|
}
|
|
@@ -3222,7 +3644,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
3222
3644
|
el.removeAttribute(prevName);
|
|
3223
3645
|
prevName = null;
|
|
3224
3646
|
}
|
|
3225
|
-
if (!setSafeAttribute(el, name, value, { label: "bindDynamic" })) return;
|
|
3647
|
+
if (!setSafeAttribute(el, name, value, { label: "bindDynamic", reactive: true })) return;
|
|
3226
3648
|
prevName = name;
|
|
3227
3649
|
}
|
|
3228
3650
|
const teardown = reactiveBinding2(commit, el);
|
|
@@ -3403,11 +3825,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
3403
3825
|
}
|
|
3404
3826
|
|
|
3405
3827
|
// src/core/rendering/tagFactory.ts
|
|
3406
|
-
var
|
|
3407
|
-
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
3408
|
-
function isBlockedTag(tag) {
|
|
3409
|
-
return BLOCKED_TAGS.has(tag.toLowerCase());
|
|
3410
|
-
}
|
|
3828
|
+
var SVG_NS4 = "http://www.w3.org/2000/svg";
|
|
3411
3829
|
var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
3412
3830
|
"config",
|
|
3413
3831
|
"location",
|
|
@@ -3452,11 +3870,12 @@ function applyStyle(el, style2) {
|
|
|
3452
3870
|
}
|
|
3453
3871
|
const next = [];
|
|
3454
3872
|
for (const prop in value) {
|
|
3873
|
+
if (!Object.hasOwn(value, prop)) continue;
|
|
3455
3874
|
const val = value[prop];
|
|
3456
3875
|
if (val == null) continue;
|
|
3457
3876
|
const name = toKebab(prop);
|
|
3458
3877
|
next.push(name);
|
|
3459
|
-
decl.setProperty(name,
|
|
3878
|
+
decl.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
|
|
3460
3879
|
}
|
|
3461
3880
|
for (let i2 = 0; i2 < written.length; i2++) {
|
|
3462
3881
|
if (next.indexOf(written[i2]) === -1) decl.removeProperty(written[i2]);
|
|
@@ -3472,16 +3891,17 @@ function applyStyle(el, style2) {
|
|
|
3472
3891
|
}
|
|
3473
3892
|
const htmlEl = el;
|
|
3474
3893
|
for (const prop in style2) {
|
|
3894
|
+
if (!Object.hasOwn(style2, prop)) continue;
|
|
3475
3895
|
const val = style2[prop];
|
|
3476
3896
|
const name = toKebab(prop);
|
|
3477
3897
|
if (typeof val === "function") {
|
|
3478
3898
|
const getter = val;
|
|
3479
3899
|
const teardown = reactiveBinding2(() => {
|
|
3480
|
-
htmlEl.style.setProperty(name,
|
|
3900
|
+
htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(getter()), { element: el }));
|
|
3481
3901
|
}, el);
|
|
3482
3902
|
registerDisposer(el, teardown);
|
|
3483
3903
|
} else {
|
|
3484
|
-
htmlEl.style.setProperty(name,
|
|
3904
|
+
htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
|
|
3485
3905
|
}
|
|
3486
3906
|
}
|
|
3487
3907
|
}
|
|
@@ -3503,6 +3923,7 @@ function applyClass(el, cls) {
|
|
|
3503
3923
|
let hasReactive = false;
|
|
3504
3924
|
let result = "";
|
|
3505
3925
|
for (const name in obj) {
|
|
3926
|
+
if (!Object.hasOwn(obj, name)) continue;
|
|
3506
3927
|
const val = obj[name];
|
|
3507
3928
|
if (typeof val === "function") {
|
|
3508
3929
|
hasReactive = true;
|
|
@@ -3514,6 +3935,7 @@ function applyClass(el, cls) {
|
|
|
3514
3935
|
const update = () => {
|
|
3515
3936
|
let r = "";
|
|
3516
3937
|
for (const name in obj) {
|
|
3938
|
+
if (!Object.hasOwn(obj, name)) continue;
|
|
3517
3939
|
const val = obj[name];
|
|
3518
3940
|
const active = typeof val === "function" ? val() : val;
|
|
3519
3941
|
if (active) r = r ? `${r} ${name}` : name;
|
|
@@ -3577,7 +3999,7 @@ function appendChildren(el, nodes) {
|
|
|
3577
3999
|
}
|
|
3578
4000
|
}
|
|
3579
4001
|
function tagFactory(tag, ns) {
|
|
3580
|
-
const blocked =
|
|
4002
|
+
const blocked = isBlockedElement(tag);
|
|
3581
4003
|
return (first, second) => {
|
|
3582
4004
|
if (blocked) {
|
|
3583
4005
|
throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
|
|
@@ -3640,6 +4062,7 @@ function tagFactory(tag, ns) {
|
|
|
3640
4062
|
const pOn = props.on;
|
|
3641
4063
|
if (pOn) {
|
|
3642
4064
|
for (const ev in pOn) {
|
|
4065
|
+
if (!Object.hasOwn(pOn, ev)) continue;
|
|
3643
4066
|
const handler = pOn[ev];
|
|
3644
4067
|
if (typeof handler === "function") {
|
|
3645
4068
|
el.addEventListener(ev, handler);
|
|
@@ -3666,6 +4089,7 @@ function tagFactory(tag, ns) {
|
|
|
3666
4089
|
continue;
|
|
3667
4090
|
// already handled above / below
|
|
3668
4091
|
default: {
|
|
4092
|
+
if (!Object.hasOwn(props, key)) continue;
|
|
3669
4093
|
const value = props[key];
|
|
3670
4094
|
if (value == null) continue;
|
|
3671
4095
|
if (isEventHandlerAttr(key)) continue;
|
|
@@ -3755,7 +4179,7 @@ var param = tagFactory("param");
|
|
|
3755
4179
|
var picture = tagFactory("picture");
|
|
3756
4180
|
var portal = tagFactory("portal");
|
|
3757
4181
|
var source = tagFactory("source");
|
|
3758
|
-
var svg = tagFactory("svg",
|
|
4182
|
+
var svg = tagFactory("svg", SVG_NS4);
|
|
3759
4183
|
var math = tagFactory("math");
|
|
3760
4184
|
var canvas = tagFactory("canvas");
|
|
3761
4185
|
var noscript = tagFactory("noscript");
|
|
@@ -3796,26 +4220,26 @@ var base = tagFactory("base");
|
|
|
3796
4220
|
var link = tagFactory("link");
|
|
3797
4221
|
var meta = tagFactory("meta");
|
|
3798
4222
|
var style = tagFactory("style");
|
|
3799
|
-
var circle = tagFactory("circle",
|
|
3800
|
-
var ellipse = tagFactory("ellipse",
|
|
3801
|
-
var g = tagFactory("g",
|
|
3802
|
-
var line = tagFactory("line",
|
|
3803
|
-
var path = tagFactory("path",
|
|
3804
|
-
var polygon = tagFactory("polygon",
|
|
3805
|
-
var polyline = tagFactory("polyline",
|
|
3806
|
-
var rect = tagFactory("rect",
|
|
3807
|
-
var text = tagFactory("text",
|
|
3808
|
-
var tspan = tagFactory("tspan",
|
|
3809
|
-
var defs = tagFactory("defs",
|
|
3810
|
-
var clipPath = tagFactory("clipPath",
|
|
3811
|
-
var mask = tagFactory("mask",
|
|
3812
|
-
var pattern = tagFactory("pattern",
|
|
3813
|
-
var linearGradient = tagFactory("linearGradient",
|
|
3814
|
-
var radialGradient = tagFactory("radialGradient",
|
|
3815
|
-
var stop = tagFactory("stop",
|
|
3816
|
-
var use = tagFactory("use",
|
|
3817
|
-
var symbol = tagFactory("symbol",
|
|
3818
|
-
var marker = tagFactory("marker",
|
|
4223
|
+
var circle = tagFactory("circle", SVG_NS4);
|
|
4224
|
+
var ellipse = tagFactory("ellipse", SVG_NS4);
|
|
4225
|
+
var g = tagFactory("g", SVG_NS4);
|
|
4226
|
+
var line = tagFactory("line", SVG_NS4);
|
|
4227
|
+
var path = tagFactory("path", SVG_NS4);
|
|
4228
|
+
var polygon = tagFactory("polygon", SVG_NS4);
|
|
4229
|
+
var polyline = tagFactory("polyline", SVG_NS4);
|
|
4230
|
+
var rect = tagFactory("rect", SVG_NS4);
|
|
4231
|
+
var text = tagFactory("text", SVG_NS4);
|
|
4232
|
+
var tspan = tagFactory("tspan", SVG_NS4);
|
|
4233
|
+
var defs = tagFactory("defs", SVG_NS4);
|
|
4234
|
+
var clipPath = tagFactory("clipPath", SVG_NS4);
|
|
4235
|
+
var mask = tagFactory("mask", SVG_NS4);
|
|
4236
|
+
var pattern = tagFactory("pattern", SVG_NS4);
|
|
4237
|
+
var linearGradient = tagFactory("linearGradient", SVG_NS4);
|
|
4238
|
+
var radialGradient = tagFactory("radialGradient", SVG_NS4);
|
|
4239
|
+
var stop = tagFactory("stop", SVG_NS4);
|
|
4240
|
+
var use = tagFactory("use", SVG_NS4);
|
|
4241
|
+
var symbol = tagFactory("symbol", SVG_NS4);
|
|
4242
|
+
var marker = tagFactory("marker", SVG_NS4);
|
|
3819
4243
|
var center = tagFactory("center");
|
|
3820
4244
|
var font = tagFactory("font");
|
|
3821
4245
|
var marquee = tagFactory("marquee");
|
|
@@ -5393,37 +5817,44 @@ function action(element, action2, param2) {
|
|
|
5393
5817
|
}
|
|
5394
5818
|
}
|
|
5395
5819
|
var clickOutside = (element, callback) => {
|
|
5820
|
+
const doc = element.ownerDocument;
|
|
5396
5821
|
const handler = (e) => {
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
}
|
|
5822
|
+
const target = e.target;
|
|
5823
|
+
if (!(typeof target?.nodeType === "number" && element.contains(target))) callback();
|
|
5400
5824
|
};
|
|
5401
|
-
|
|
5402
|
-
return () =>
|
|
5825
|
+
doc.addEventListener("pointerdown", handler, true);
|
|
5826
|
+
return () => doc.removeEventListener("pointerdown", handler, true);
|
|
5403
5827
|
};
|
|
5828
|
+
var PRESS_END_EVENTS = ["pointerup", "pointerleave", "pointercancel"];
|
|
5404
5829
|
var longPress = (element, options) => {
|
|
5405
5830
|
const duration = options.duration ?? 500;
|
|
5406
5831
|
let timer = null;
|
|
5407
|
-
|
|
5408
|
-
timer = setTimeout(() => {
|
|
5409
|
-
options.callback();
|
|
5410
|
-
timer = null;
|
|
5411
|
-
}, duration);
|
|
5412
|
-
};
|
|
5832
|
+
let owner;
|
|
5413
5833
|
const cancel = () => {
|
|
5414
5834
|
if (timer !== null) {
|
|
5415
5835
|
clearTimeout(timer);
|
|
5416
5836
|
timer = null;
|
|
5417
5837
|
}
|
|
5418
5838
|
};
|
|
5839
|
+
const start = (e) => {
|
|
5840
|
+
const id = e.pointerId;
|
|
5841
|
+
if (timer !== null && id !== owner) return;
|
|
5842
|
+
cancel();
|
|
5843
|
+
owner = id;
|
|
5844
|
+
timer = setTimeout(() => {
|
|
5845
|
+
timer = null;
|
|
5846
|
+
options.callback();
|
|
5847
|
+
}, duration);
|
|
5848
|
+
};
|
|
5849
|
+
const end = (e) => {
|
|
5850
|
+
if (timer !== null && e.pointerId === owner) cancel();
|
|
5851
|
+
};
|
|
5419
5852
|
element.addEventListener("pointerdown", start);
|
|
5420
|
-
element.addEventListener(
|
|
5421
|
-
element.addEventListener("pointerleave", cancel);
|
|
5853
|
+
for (const type of PRESS_END_EVENTS) element.addEventListener(type, end);
|
|
5422
5854
|
return () => {
|
|
5423
5855
|
cancel();
|
|
5424
5856
|
element.removeEventListener("pointerdown", start);
|
|
5425
|
-
element.removeEventListener(
|
|
5426
|
-
element.removeEventListener("pointerleave", cancel);
|
|
5857
|
+
for (const type of PRESS_END_EVENTS) element.removeEventListener(type, end);
|
|
5427
5858
|
};
|
|
5428
5859
|
};
|
|
5429
5860
|
var copyOnClick = (element, getText) => {
|
|
@@ -5457,10 +5888,11 @@ var trapFocus = (element) => {
|
|
|
5457
5888
|
if (elements.length === 0) return;
|
|
5458
5889
|
const first = elements[0];
|
|
5459
5890
|
const last = elements[elements.length - 1];
|
|
5460
|
-
|
|
5891
|
+
const active = element.ownerDocument.activeElement;
|
|
5892
|
+
if (e.shiftKey && active === first) {
|
|
5461
5893
|
e.preventDefault();
|
|
5462
5894
|
last.focus();
|
|
5463
|
-
} else if (!e.shiftKey &&
|
|
5895
|
+
} else if (!e.shiftKey && active === last) {
|
|
5464
5896
|
e.preventDefault();
|
|
5465
5897
|
first.focus();
|
|
5466
5898
|
}
|
|
@@ -5629,6 +6061,10 @@ function attachBranch(parent, anchor, branch, attachedOnce, where) {
|
|
|
5629
6061
|
parent.insertBefore(node, anchor.nextSibling);
|
|
5630
6062
|
return { node, owned };
|
|
5631
6063
|
}
|
|
6064
|
+
function releaseBranchNode(node, owned) {
|
|
6065
|
+
if (owned) dispose(node);
|
|
6066
|
+
node.parentNode?.removeChild(node);
|
|
6067
|
+
}
|
|
5632
6068
|
function when(condition, thenBranch, elseBranch) {
|
|
5633
6069
|
const anchor = document.createComment("when");
|
|
5634
6070
|
let currentNode = null;
|
|
@@ -5646,8 +6082,7 @@ function when(condition, thenBranch, elseBranch) {
|
|
|
5646
6082
|
lastCondition = show2;
|
|
5647
6083
|
const focused = currentNode ? captureFocusWithin([currentNode]) : null;
|
|
5648
6084
|
if (currentNode?.parentNode) {
|
|
5649
|
-
|
|
5650
|
-
currentNode.parentNode.removeChild(currentNode);
|
|
6085
|
+
releaseBranchNode(currentNode, currentNodeOwned);
|
|
5651
6086
|
currentNode = null;
|
|
5652
6087
|
}
|
|
5653
6088
|
const branch = show2 ? thenBranch : elseBranch !== void 0 ? elseBranch : null;
|
|
@@ -5661,6 +6096,8 @@ function when(condition, thenBranch, elseBranch) {
|
|
|
5661
6096
|
registerDisposer(anchor, () => {
|
|
5662
6097
|
disposed = true;
|
|
5663
6098
|
stopBinding();
|
|
6099
|
+
if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
|
|
6100
|
+
currentNode = null;
|
|
5664
6101
|
});
|
|
5665
6102
|
if (!initialized) {
|
|
5666
6103
|
queueMicrotask(() => {
|
|
@@ -5686,8 +6123,7 @@ function match(value, cases, fallback) {
|
|
|
5686
6123
|
lastKey = key;
|
|
5687
6124
|
const focused = currentNode ? captureFocusWithin([currentNode]) : null;
|
|
5688
6125
|
if (currentNode?.parentNode) {
|
|
5689
|
-
|
|
5690
|
-
currentNode.parentNode.removeChild(currentNode);
|
|
6126
|
+
releaseBranchNode(currentNode, currentNodeOwned);
|
|
5691
6127
|
currentNode = null;
|
|
5692
6128
|
}
|
|
5693
6129
|
const branch = Object.hasOwn(cases, key) ? cases[key] : fallback;
|
|
@@ -5701,6 +6137,8 @@ function match(value, cases, fallback) {
|
|
|
5701
6137
|
registerDisposer(anchor, () => {
|
|
5702
6138
|
disposed = true;
|
|
5703
6139
|
stopBinding();
|
|
6140
|
+
if (currentNode) releaseBranchNode(currentNode, currentNodeOwned);
|
|
6141
|
+
currentNode = null;
|
|
5704
6142
|
});
|
|
5705
6143
|
if (!initialized) {
|
|
5706
6144
|
queueMicrotask(() => {
|
|
@@ -6043,7 +6481,6 @@ function appendChild(frag, child) {
|
|
|
6043
6481
|
}
|
|
6044
6482
|
|
|
6045
6483
|
// src/core/rendering/htm.ts
|
|
6046
|
-
var RAW_TEXT_TAGS2 = /* @__PURE__ */ new Set(["script", "style"]);
|
|
6047
6484
|
var VOID_ELEMENTS3 = /* @__PURE__ */ new Set([
|
|
6048
6485
|
"area",
|
|
6049
6486
|
"base",
|
|
@@ -6266,7 +6703,7 @@ function parseTemplate2(strings) {
|
|
|
6266
6703
|
children.push({ t: 0, el: { tag, svg: SVG_TAGS2.has(tag), attrs, children: [] } });
|
|
6267
6704
|
} else {
|
|
6268
6705
|
const inner = parseChildren();
|
|
6269
|
-
if (
|
|
6706
|
+
if (isCodeTextElement(tag)) {
|
|
6270
6707
|
for (let i2 = 0; i2 < inner.length; i2++) {
|
|
6271
6708
|
if (inner[i2].t === 2) {
|
|
6272
6709
|
throw new Error(
|
|
@@ -6292,12 +6729,12 @@ function parseTemplate2(strings) {
|
|
|
6292
6729
|
return parseChildren();
|
|
6293
6730
|
}
|
|
6294
6731
|
function executeElement(tmpl, values) {
|
|
6295
|
-
const el = tmpl.svg ? document.createElementNS(
|
|
6732
|
+
const el = tmpl.svg ? document.createElementNS(SVG_NS4, tmpl.tag) : document.createElement(tmpl.tag);
|
|
6296
6733
|
for (let i2 = 0; i2 < tmpl.attrs.length; i2++) {
|
|
6297
6734
|
const attr = tmpl.attrs[i2];
|
|
6298
6735
|
switch (attr.t) {
|
|
6299
6736
|
case 0:
|
|
6300
|
-
el
|
|
6737
|
+
setTrustedAttribute(el, attr.name, attr.value);
|
|
6301
6738
|
break;
|
|
6302
6739
|
case 1: {
|
|
6303
6740
|
const name = attr.name;
|
|
@@ -6330,7 +6767,7 @@ function executeElement(tmpl, values) {
|
|
|
6330
6767
|
break;
|
|
6331
6768
|
}
|
|
6332
6769
|
case 4:
|
|
6333
|
-
el
|
|
6770
|
+
setTrustedAttribute(el, attr.name, "");
|
|
6334
6771
|
break;
|
|
6335
6772
|
}
|
|
6336
6773
|
}
|
|
@@ -6375,6 +6812,12 @@ function html2(strings, ...values) {
|
|
|
6375
6812
|
tmpl = parseTemplate2(strings);
|
|
6376
6813
|
cache.set(strings, tmpl);
|
|
6377
6814
|
}
|
|
6815
|
+
return renderTemplate(tmpl, values);
|
|
6816
|
+
}
|
|
6817
|
+
function __renderParsedTemplate(tree, values) {
|
|
6818
|
+
return renderTemplate(tree, values);
|
|
6819
|
+
}
|
|
6820
|
+
function renderTemplate(tmpl, values) {
|
|
6378
6821
|
if (tmpl.length === 1 && tmpl[0].t === 0) {
|
|
6379
6822
|
return executeElement(tmpl[0].el, values);
|
|
6380
6823
|
}
|
|
@@ -6450,7 +6893,7 @@ function KeepAlive(activeKey, cases, options) {
|
|
|
6450
6893
|
return;
|
|
6451
6894
|
}
|
|
6452
6895
|
node = factory();
|
|
6453
|
-
if (node
|
|
6896
|
+
if (node.nodeType === 11) {
|
|
6454
6897
|
const wrapper = document.createElement("div");
|
|
6455
6898
|
wrapper.style.display = "contents";
|
|
6456
6899
|
wrapper.appendChild(node);
|
|
@@ -7463,7 +7906,7 @@ function enhance(target, setup) {
|
|
|
7463
7906
|
bindNode(el, () => {
|
|
7464
7907
|
const v = value();
|
|
7465
7908
|
const next = v == null ? null : String(v);
|
|
7466
|
-
setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
|
|
7909
|
+
setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()", reactive: true });
|
|
7467
7910
|
})
|
|
7468
7911
|
);
|
|
7469
7912
|
});
|