@getforma/core 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-YRNYOZF3.js → chunk-AJP4OVCN.js} +27 -7
- package/dist/chunk-AJP4OVCN.js.map +1 -0
- package/dist/{chunk-E3FV2VSU.cjs → chunk-FBM7V4NE.cjs} +27 -6
- package/dist/chunk-FBM7V4NE.cjs.map +1 -0
- package/dist/forma-runtime-csp.js +178 -79
- package/dist/forma-runtime.js +178 -79
- package/dist/formajs-runtime-hardened.global.js +178 -79
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +178 -79
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/formajs.global.js +69 -9
- package/dist/formajs.global.js.map +1 -1
- package/dist/index.cjs +59 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +46 -7
- package/dist/index.js.map +1 -1
- package/dist/runtime-hardened.cjs +178 -79
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.js +178 -79
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +172 -77
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +172 -77
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-E3FV2VSU.cjs.map +0 -1
- package/dist/chunk-YRNYOZF3.js.map +0 -1
|
@@ -241,14 +241,18 @@ function reconcileList(parent, oldItems, newItems, oldNodes, keyFn, createFn, up
|
|
|
241
241
|
}
|
|
242
242
|
const oldKeyMap = /* @__PURE__ */ new Map();
|
|
243
243
|
for (let i = 0; i < oldLen; i++) {
|
|
244
|
-
|
|
244
|
+
const k = keyFn(oldItems[i]);
|
|
245
|
+
const bucket = oldKeyMap.get(k);
|
|
246
|
+
if (bucket) bucket.push(i);
|
|
247
|
+
else oldKeyMap.set(k, [i]);
|
|
245
248
|
}
|
|
246
249
|
const oldIndices = new Array(newLen);
|
|
247
250
|
const oldUsed = new Uint8Array(oldLen);
|
|
248
251
|
for (let i = 0; i < newLen; i++) {
|
|
249
252
|
const key = keyFn(newItems[i]);
|
|
250
|
-
const
|
|
251
|
-
if (
|
|
253
|
+
const bucket = oldKeyMap.get(key);
|
|
254
|
+
if (bucket && bucket.length > 0) {
|
|
255
|
+
const oldIdx = bucket.shift();
|
|
252
256
|
oldIndices[i] = oldIdx;
|
|
253
257
|
oldUsed[oldIdx] = 1;
|
|
254
258
|
} else {
|
|
@@ -597,12 +601,12 @@ function findInsertionPoint(parent, newChild, newChildren) {
|
|
|
597
601
|
return null;
|
|
598
602
|
}
|
|
599
603
|
function createReconciler(config) {
|
|
600
|
-
|
|
604
|
+
const lastHtmlByContainer = /* @__PURE__ */ new WeakMap();
|
|
601
605
|
return function reconcile2(container, html) {
|
|
602
606
|
const trimmed = html.trim();
|
|
603
607
|
if (!trimmed) return;
|
|
604
|
-
if (
|
|
605
|
-
|
|
608
|
+
if (lastHtmlByContainer.get(container) === trimmed && container.hasChildNodes()) return;
|
|
609
|
+
lastHtmlByContainer.set(container, trimmed);
|
|
606
610
|
config.disconnectObserver();
|
|
607
611
|
try {
|
|
608
612
|
if (!container.hasChildNodes() || container.children.length === 0) {
|
|
@@ -916,9 +920,97 @@ var RE_TERNARY = /^(.+?)\s*\?\s*(.+?)\s*:\s*(.+)$/;
|
|
|
916
920
|
var RE_NULLISH = /^(.+?)\s*\?\?\s*(.+)$/;
|
|
917
921
|
var RE_AND = /^(.+?)\s*&&\s*(.+)$/;
|
|
918
922
|
var RE_OR = /^(.+?)\s*\|\|\s*(.+)$/;
|
|
919
|
-
var
|
|
920
|
-
|
|
921
|
-
|
|
923
|
+
var UNARY_PRECEDERS = "+-*/%<>=!&|^~(,[{?:";
|
|
924
|
+
function matchBinaryOp(expr, ops) {
|
|
925
|
+
const SQ = String.fromCharCode(39);
|
|
926
|
+
const DQ = String.fromCharCode(34);
|
|
927
|
+
const BT = String.fromCharCode(96);
|
|
928
|
+
const BS = String.fromCharCode(92);
|
|
929
|
+
let depth = 0;
|
|
930
|
+
let inSingle = false, inDouble = false, inTemplate = false, escaped = false;
|
|
931
|
+
let prevSig = "";
|
|
932
|
+
let bestIdx = -1;
|
|
933
|
+
let bestOp = "";
|
|
934
|
+
for (let i = 0; i < expr.length; i++) {
|
|
935
|
+
const ch = expr[i];
|
|
936
|
+
if (escaped) {
|
|
937
|
+
escaped = false;
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
if (ch === BS && (inSingle || inDouble || inTemplate)) {
|
|
941
|
+
escaped = true;
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
if (inSingle) {
|
|
945
|
+
if (ch === SQ) {
|
|
946
|
+
inSingle = false;
|
|
947
|
+
prevSig = DQ;
|
|
948
|
+
}
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
if (inDouble) {
|
|
952
|
+
if (ch === DQ) {
|
|
953
|
+
inDouble = false;
|
|
954
|
+
prevSig = DQ;
|
|
955
|
+
}
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
if (inTemplate) {
|
|
959
|
+
if (ch === BT) {
|
|
960
|
+
inTemplate = false;
|
|
961
|
+
prevSig = DQ;
|
|
962
|
+
}
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
965
|
+
if (ch === SQ) {
|
|
966
|
+
inSingle = true;
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
if (ch === DQ) {
|
|
970
|
+
inDouble = true;
|
|
971
|
+
continue;
|
|
972
|
+
}
|
|
973
|
+
if (ch === BT) {
|
|
974
|
+
inTemplate = true;
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
978
|
+
depth++;
|
|
979
|
+
prevSig = ch;
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
982
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
983
|
+
if (depth > 0) depth--;
|
|
984
|
+
prevSig = ch;
|
|
985
|
+
continue;
|
|
986
|
+
}
|
|
987
|
+
if (depth !== 0) continue;
|
|
988
|
+
if (ch === " " || ch === " " || ch === "\n") continue;
|
|
989
|
+
if (i > 0) {
|
|
990
|
+
let matchedOp = "";
|
|
991
|
+
for (const op of ops) {
|
|
992
|
+
if (expr.startsWith(op, i)) {
|
|
993
|
+
matchedOp = op;
|
|
994
|
+
break;
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
if (matchedOp) {
|
|
998
|
+
const isPlusMinus = matchedOp === "+" || matchedOp === "-";
|
|
999
|
+
const unary = isPlusMinus && (prevSig === "" || UNARY_PRECEDERS.includes(prevSig));
|
|
1000
|
+
if (!unary) {
|
|
1001
|
+
bestIdx = i;
|
|
1002
|
+
bestOp = matchedOp;
|
|
1003
|
+
}
|
|
1004
|
+
i += matchedOp.length - 1;
|
|
1005
|
+
prevSig = matchedOp[matchedOp.length - 1];
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
prevSig = ch;
|
|
1010
|
+
}
|
|
1011
|
+
if (bestIdx === -1) return null;
|
|
1012
|
+
return { left: expr.slice(0, bestIdx).trim(), op: bestOp, right: expr.slice(bestIdx + bestOp.length).trim() };
|
|
1013
|
+
}
|
|
922
1014
|
var RE_TEMPLATE_LIT = /^`([^`]*)`$/;
|
|
923
1015
|
var RE_TEMPLATE_INTERP = /\$\{([^}]+)\}/g;
|
|
924
1016
|
var RE_GROUP_METHOD_CALL = /^\((.+)\)\.(\w+)\((.*)\)$/;
|
|
@@ -1875,12 +1967,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1875
1967
|
return () => left() && right();
|
|
1876
1968
|
}
|
|
1877
1969
|
}
|
|
1878
|
-
const compMatch = expr
|
|
1970
|
+
const compMatch = matchBinaryOp(expr, ["===", "!==", "==", "!=", ">=", "<=", ">", "<"]);
|
|
1879
1971
|
if (compMatch) {
|
|
1880
|
-
const left = parseExpression(compMatch
|
|
1881
|
-
const right = parseExpression(compMatch
|
|
1972
|
+
const left = parseExpression(compMatch.left, scope);
|
|
1973
|
+
const right = parseExpression(compMatch.right, scope);
|
|
1882
1974
|
if (left && right) {
|
|
1883
|
-
const op = compMatch
|
|
1975
|
+
const op = compMatch.op;
|
|
1884
1976
|
return () => {
|
|
1885
1977
|
const l = left(), r = right();
|
|
1886
1978
|
switch (op) {
|
|
@@ -1904,12 +1996,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1904
1996
|
};
|
|
1905
1997
|
}
|
|
1906
1998
|
}
|
|
1907
|
-
const addMatch = expr
|
|
1999
|
+
const addMatch = matchBinaryOp(expr, ["+", "-"]);
|
|
1908
2000
|
if (addMatch) {
|
|
1909
|
-
const left = parseExpression(addMatch
|
|
1910
|
-
const right = parseExpression(addMatch
|
|
2001
|
+
const left = parseExpression(addMatch.left, scope);
|
|
2002
|
+
const right = parseExpression(addMatch.right, scope);
|
|
1911
2003
|
if (left && right) {
|
|
1912
|
-
const op = addMatch
|
|
2004
|
+
const op = addMatch.op;
|
|
1913
2005
|
return () => {
|
|
1914
2006
|
const l = left(), r = right();
|
|
1915
2007
|
if (op === "+") return l + r;
|
|
@@ -1917,12 +2009,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1917
2009
|
};
|
|
1918
2010
|
}
|
|
1919
2011
|
}
|
|
1920
|
-
const mulMatch = expr
|
|
2012
|
+
const mulMatch = matchBinaryOp(expr, ["*", "/", "%"]);
|
|
1921
2013
|
if (mulMatch) {
|
|
1922
|
-
const left = parseExpression(mulMatch
|
|
1923
|
-
const right = parseExpression(mulMatch
|
|
2014
|
+
const left = parseExpression(mulMatch.left, scope);
|
|
2015
|
+
const right = parseExpression(mulMatch.right, scope);
|
|
1924
2016
|
if (left && right) {
|
|
1925
|
-
const op = mulMatch
|
|
2017
|
+
const op = mulMatch.op;
|
|
1926
2018
|
return () => {
|
|
1927
2019
|
const l = left(), r = right();
|
|
1928
2020
|
switch (op) {
|
|
@@ -2347,25 +2439,61 @@ function bindElement(el, scope, disposers) {
|
|
|
2347
2439
|
const modelExpr = !known || known.has("data-model") ? el.getAttribute("data-model") : null;
|
|
2348
2440
|
if (modelExpr) {
|
|
2349
2441
|
const prop = modelExpr.replace(RE_STRIP_BRACES, "").trim();
|
|
2350
|
-
|
|
2351
|
-
|
|
2442
|
+
let getter = scope.getters[prop];
|
|
2443
|
+
let setter = scope.setters[prop];
|
|
2444
|
+
if ((!getter || !setter) && prop.includes(".")) {
|
|
2445
|
+
getter = buildEvaluator(prop, scope);
|
|
2446
|
+
const lastDot = prop.lastIndexOf(".");
|
|
2447
|
+
const basePath = prop.slice(0, lastDot);
|
|
2448
|
+
const key = prop.slice(lastDot + 1);
|
|
2449
|
+
const baseGet = buildEvaluator(basePath, scope);
|
|
2450
|
+
setter = (v) => {
|
|
2451
|
+
const base = baseGet();
|
|
2452
|
+
if (base != null && typeof base === "object") base[key] = v;
|
|
2453
|
+
};
|
|
2454
|
+
}
|
|
2352
2455
|
if (getter && setter) {
|
|
2353
2456
|
const input = el;
|
|
2457
|
+
const tag = input.tagName;
|
|
2354
2458
|
const dispose = internalEffect(() => {
|
|
2355
2459
|
const val = getter();
|
|
2356
|
-
|
|
2460
|
+
const type = input.type;
|
|
2461
|
+
if (type === "checkbox") {
|
|
2357
2462
|
input.checked = !!val;
|
|
2463
|
+
const indetExpr = el.getAttribute("data-model-indeterminate");
|
|
2464
|
+
if (indetExpr) {
|
|
2465
|
+
const indetGetter = scope.getters[indetExpr.replace(RE_STRIP_BRACES, "").trim()];
|
|
2466
|
+
if (indetGetter) input.indeterminate = !!indetGetter();
|
|
2467
|
+
}
|
|
2468
|
+
} else if (type === "radio") {
|
|
2469
|
+
input.checked = String(val) === input.value;
|
|
2470
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2471
|
+
const sel = input;
|
|
2472
|
+
const arr = Array.isArray(val) ? val.map(String) : [];
|
|
2473
|
+
for (const opt of Array.from(sel.options)) opt.selected = arr.includes(opt.value);
|
|
2358
2474
|
} else {
|
|
2359
2475
|
input.value = String(val ?? "");
|
|
2360
2476
|
}
|
|
2361
2477
|
});
|
|
2362
2478
|
disposers.push(dispose);
|
|
2363
|
-
const event = input.type === "checkbox" ? "change" : "input";
|
|
2479
|
+
const event = input.type === "checkbox" || input.type === "radio" || tag === "SELECT" ? "change" : "input";
|
|
2364
2480
|
const onModelInput = () => {
|
|
2365
|
-
|
|
2481
|
+
const type = input.type;
|
|
2482
|
+
if (type === "checkbox") {
|
|
2366
2483
|
setter(input.checked);
|
|
2367
|
-
} else if (
|
|
2368
|
-
setter(
|
|
2484
|
+
} else if (type === "radio") {
|
|
2485
|
+
if (input.checked) setter(input.value);
|
|
2486
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2487
|
+
const sel = input;
|
|
2488
|
+
setter(Array.from(sel.selectedOptions).map((o) => o.value));
|
|
2489
|
+
} else if (type === "number" || type === "range") {
|
|
2490
|
+
const raw = input.value;
|
|
2491
|
+
if (raw === "") {
|
|
2492
|
+
setter(null);
|
|
2493
|
+
} else {
|
|
2494
|
+
const n = Number(raw);
|
|
2495
|
+
if (!Number.isNaN(n)) setter(n);
|
|
2496
|
+
}
|
|
2369
2497
|
} else {
|
|
2370
2498
|
setter(input.value);
|
|
2371
2499
|
}
|
|
@@ -2557,59 +2685,30 @@ function bindElement(el, scope, disposers) {
|
|
|
2557
2685
|
}
|
|
2558
2686
|
}
|
|
2559
2687
|
const prevNodes = new Set(oldNodes);
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
for (const n of prevNodes) {
|
|
2581
|
-
if (!nextNodes.has(n)) {
|
|
2582
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2583
|
-
disposeCloneBindings2(n);
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
|
-
oldItems = result.items;
|
|
2587
|
-
oldNodes = result.nodes;
|
|
2588
|
-
} else {
|
|
2589
|
-
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2590
|
-
const oldWrapped = oldItems;
|
|
2591
|
-
const result = reconcileList(
|
|
2592
|
-
el,
|
|
2593
|
-
oldWrapped,
|
|
2594
|
-
wrapped,
|
|
2595
|
-
oldNodes,
|
|
2596
|
-
(w) => w.__idx,
|
|
2597
|
-
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2598
|
-
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2599
|
-
void 0,
|
|
2600
|
-
// beforeNode
|
|
2601
|
-
listHooks
|
|
2602
|
-
);
|
|
2603
|
-
const nextNodes = new Set(result.nodes);
|
|
2604
|
-
for (const n of prevNodes) {
|
|
2605
|
-
if (!nextNodes.has(n)) {
|
|
2606
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2607
|
-
disposeCloneBindings2(n);
|
|
2608
|
-
}
|
|
2688
|
+
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2689
|
+
const oldWrapped = oldItems;
|
|
2690
|
+
const keyFn = keyProp ? (w) => String(w.__item?.[keyProp] ?? "") : (w) => w.__idx;
|
|
2691
|
+
const result = reconcileList(
|
|
2692
|
+
el,
|
|
2693
|
+
oldWrapped,
|
|
2694
|
+
wrapped,
|
|
2695
|
+
oldNodes,
|
|
2696
|
+
keyFn,
|
|
2697
|
+
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2698
|
+
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2699
|
+
void 0,
|
|
2700
|
+
// beforeNode
|
|
2701
|
+
listHooks
|
|
2702
|
+
);
|
|
2703
|
+
const nextNodes = new Set(result.nodes);
|
|
2704
|
+
for (const n of prevNodes) {
|
|
2705
|
+
if (!nextNodes.has(n)) {
|
|
2706
|
+
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2707
|
+
disposeCloneBindings2(n);
|
|
2609
2708
|
}
|
|
2610
|
-
oldItems = result.items;
|
|
2611
|
-
oldNodes = result.nodes;
|
|
2612
2709
|
}
|
|
2710
|
+
oldItems = result.items;
|
|
2711
|
+
oldNodes = result.nodes;
|
|
2613
2712
|
});
|
|
2614
2713
|
disposers.push(dispose);
|
|
2615
2714
|
}
|