@getforma/core 1.1.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-MIOMT2CB.js → chunk-AJP4OVCN.js} +29 -9
- package/dist/chunk-AJP4OVCN.js.map +1 -0
- package/dist/{chunk-XLVBYXOU.js → chunk-ETPJTPYD.js} +6 -3
- package/dist/chunk-ETPJTPYD.js.map +1 -0
- package/dist/{chunk-JRQNDXX7.cjs → chunk-FBM7V4NE.cjs} +68 -47
- package/dist/chunk-FBM7V4NE.cjs.map +1 -0
- package/dist/{chunk-W7OUWVRA.cjs → chunk-H7MDUHS5.cjs} +6 -2
- package/dist/chunk-H7MDUHS5.cjs.map +1 -0
- package/dist/{chunk-2Y5US35K.cjs → chunk-KUXNZ5MG.cjs} +12 -12
- package/dist/{chunk-2Y5US35K.cjs.map → chunk-KUXNZ5MG.cjs.map} +1 -1
- package/dist/{chunk-INNOI6TG.js → chunk-Y3A2EVVS.js} +3 -3
- package/dist/{chunk-INNOI6TG.js.map → chunk-Y3A2EVVS.js.map} +1 -1
- 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 +245 -61
- package/dist/formajs.global.js.map +1 -1
- package/dist/http.cjs +11 -11
- package/dist/http.js +2 -2
- package/dist/index.cjs +307 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +248 -88
- 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 +198 -103
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +174 -79
- package/dist/runtime.js.map +1 -1
- package/dist/server.cjs +7 -7
- package/dist/server.js +2 -2
- package/dist/tc39-compat.cjs +3 -3
- package/dist/tc39-compat.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-JRQNDXX7.cjs.map +0 -1
- package/dist/chunk-MIOMT2CB.js.map +0 -1
- package/dist/chunk-W7OUWVRA.cjs.map +0 -1
- package/dist/chunk-XLVBYXOU.js.map +0 -1
|
@@ -788,14 +788,18 @@ var FormaRuntime = (() => {
|
|
|
788
788
|
}
|
|
789
789
|
const oldKeyMap = /* @__PURE__ */ new Map();
|
|
790
790
|
for (let i = 0; i < oldLen; i++) {
|
|
791
|
-
|
|
791
|
+
const k = keyFn(oldItems[i]);
|
|
792
|
+
const bucket = oldKeyMap.get(k);
|
|
793
|
+
if (bucket) bucket.push(i);
|
|
794
|
+
else oldKeyMap.set(k, [i]);
|
|
792
795
|
}
|
|
793
796
|
const oldIndices = new Array(newLen);
|
|
794
797
|
const oldUsed = new Uint8Array(oldLen);
|
|
795
798
|
for (let i = 0; i < newLen; i++) {
|
|
796
799
|
const key = keyFn(newItems[i]);
|
|
797
|
-
const
|
|
798
|
-
if (
|
|
800
|
+
const bucket = oldKeyMap.get(key);
|
|
801
|
+
if (bucket && bucket.length > 0) {
|
|
802
|
+
const oldIdx = bucket.shift();
|
|
799
803
|
oldIndices[i] = oldIdx;
|
|
800
804
|
oldUsed[oldIdx] = 1;
|
|
801
805
|
} else {
|
|
@@ -1144,12 +1148,12 @@ var FormaRuntime = (() => {
|
|
|
1144
1148
|
return null;
|
|
1145
1149
|
}
|
|
1146
1150
|
function createReconciler(config) {
|
|
1147
|
-
|
|
1151
|
+
const lastHtmlByContainer = /* @__PURE__ */ new WeakMap();
|
|
1148
1152
|
return function reconcile2(container, html) {
|
|
1149
1153
|
const trimmed = html.trim();
|
|
1150
1154
|
if (!trimmed) return;
|
|
1151
|
-
if (
|
|
1152
|
-
|
|
1155
|
+
if (lastHtmlByContainer.get(container) === trimmed && container.hasChildNodes()) return;
|
|
1156
|
+
lastHtmlByContainer.set(container, trimmed);
|
|
1153
1157
|
config.disconnectObserver();
|
|
1154
1158
|
try {
|
|
1155
1159
|
if (!container.hasChildNodes() || container.children.length === 0) {
|
|
@@ -1464,9 +1468,97 @@ var FormaRuntime = (() => {
|
|
|
1464
1468
|
var RE_NULLISH = /^(.+?)\s*\?\?\s*(.+)$/;
|
|
1465
1469
|
var RE_AND = /^(.+?)\s*&&\s*(.+)$/;
|
|
1466
1470
|
var RE_OR = /^(.+?)\s*\|\|\s*(.+)$/;
|
|
1467
|
-
var
|
|
1468
|
-
|
|
1469
|
-
|
|
1471
|
+
var UNARY_PRECEDERS = "+-*/%<>=!&|^~(,[{?:";
|
|
1472
|
+
function matchBinaryOp(expr, ops) {
|
|
1473
|
+
const SQ = String.fromCharCode(39);
|
|
1474
|
+
const DQ = String.fromCharCode(34);
|
|
1475
|
+
const BT = String.fromCharCode(96);
|
|
1476
|
+
const BS = String.fromCharCode(92);
|
|
1477
|
+
let depth = 0;
|
|
1478
|
+
let inSingle = false, inDouble = false, inTemplate = false, escaped = false;
|
|
1479
|
+
let prevSig = "";
|
|
1480
|
+
let bestIdx = -1;
|
|
1481
|
+
let bestOp = "";
|
|
1482
|
+
for (let i = 0; i < expr.length; i++) {
|
|
1483
|
+
const ch = expr[i];
|
|
1484
|
+
if (escaped) {
|
|
1485
|
+
escaped = false;
|
|
1486
|
+
continue;
|
|
1487
|
+
}
|
|
1488
|
+
if (ch === BS && (inSingle || inDouble || inTemplate)) {
|
|
1489
|
+
escaped = true;
|
|
1490
|
+
continue;
|
|
1491
|
+
}
|
|
1492
|
+
if (inSingle) {
|
|
1493
|
+
if (ch === SQ) {
|
|
1494
|
+
inSingle = false;
|
|
1495
|
+
prevSig = DQ;
|
|
1496
|
+
}
|
|
1497
|
+
continue;
|
|
1498
|
+
}
|
|
1499
|
+
if (inDouble) {
|
|
1500
|
+
if (ch === DQ) {
|
|
1501
|
+
inDouble = false;
|
|
1502
|
+
prevSig = DQ;
|
|
1503
|
+
}
|
|
1504
|
+
continue;
|
|
1505
|
+
}
|
|
1506
|
+
if (inTemplate) {
|
|
1507
|
+
if (ch === BT) {
|
|
1508
|
+
inTemplate = false;
|
|
1509
|
+
prevSig = DQ;
|
|
1510
|
+
}
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
if (ch === SQ) {
|
|
1514
|
+
inSingle = true;
|
|
1515
|
+
continue;
|
|
1516
|
+
}
|
|
1517
|
+
if (ch === DQ) {
|
|
1518
|
+
inDouble = true;
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
if (ch === BT) {
|
|
1522
|
+
inTemplate = true;
|
|
1523
|
+
continue;
|
|
1524
|
+
}
|
|
1525
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
1526
|
+
depth++;
|
|
1527
|
+
prevSig = ch;
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
1531
|
+
if (depth > 0) depth--;
|
|
1532
|
+
prevSig = ch;
|
|
1533
|
+
continue;
|
|
1534
|
+
}
|
|
1535
|
+
if (depth !== 0) continue;
|
|
1536
|
+
if (ch === " " || ch === " " || ch === "\n") continue;
|
|
1537
|
+
if (i > 0) {
|
|
1538
|
+
let matchedOp = "";
|
|
1539
|
+
for (const op of ops) {
|
|
1540
|
+
if (expr.startsWith(op, i)) {
|
|
1541
|
+
matchedOp = op;
|
|
1542
|
+
break;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (matchedOp) {
|
|
1546
|
+
const isPlusMinus = matchedOp === "+" || matchedOp === "-";
|
|
1547
|
+
const unary = isPlusMinus && (prevSig === "" || UNARY_PRECEDERS.includes(prevSig));
|
|
1548
|
+
if (!unary) {
|
|
1549
|
+
bestIdx = i;
|
|
1550
|
+
bestOp = matchedOp;
|
|
1551
|
+
}
|
|
1552
|
+
i += matchedOp.length - 1;
|
|
1553
|
+
prevSig = matchedOp[matchedOp.length - 1];
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
prevSig = ch;
|
|
1558
|
+
}
|
|
1559
|
+
if (bestIdx === -1) return null;
|
|
1560
|
+
return { left: expr.slice(0, bestIdx).trim(), op: bestOp, right: expr.slice(bestIdx + bestOp.length).trim() };
|
|
1561
|
+
}
|
|
1470
1562
|
var RE_TEMPLATE_LIT = /^`([^`]*)`$/;
|
|
1471
1563
|
var RE_TEMPLATE_INTERP = /\$\{([^}]+)\}/g;
|
|
1472
1564
|
var RE_GROUP_METHOD_CALL = /^\((.+)\)\.(\w+)\((.*)\)$/;
|
|
@@ -2461,12 +2553,12 @@ var FormaRuntime = (() => {
|
|
|
2461
2553
|
return () => left() && right();
|
|
2462
2554
|
}
|
|
2463
2555
|
}
|
|
2464
|
-
const compMatch = expr
|
|
2556
|
+
const compMatch = matchBinaryOp(expr, ["===", "!==", "==", "!=", ">=", "<=", ">", "<"]);
|
|
2465
2557
|
if (compMatch) {
|
|
2466
|
-
const left = parseExpression(compMatch
|
|
2467
|
-
const right = parseExpression(compMatch
|
|
2558
|
+
const left = parseExpression(compMatch.left, scope);
|
|
2559
|
+
const right = parseExpression(compMatch.right, scope);
|
|
2468
2560
|
if (left && right) {
|
|
2469
|
-
const op = compMatch
|
|
2561
|
+
const op = compMatch.op;
|
|
2470
2562
|
return () => {
|
|
2471
2563
|
const l = left(), r = right();
|
|
2472
2564
|
switch (op) {
|
|
@@ -2490,12 +2582,12 @@ var FormaRuntime = (() => {
|
|
|
2490
2582
|
};
|
|
2491
2583
|
}
|
|
2492
2584
|
}
|
|
2493
|
-
const addMatch = expr
|
|
2585
|
+
const addMatch = matchBinaryOp(expr, ["+", "-"]);
|
|
2494
2586
|
if (addMatch) {
|
|
2495
|
-
const left = parseExpression(addMatch
|
|
2496
|
-
const right = parseExpression(addMatch
|
|
2587
|
+
const left = parseExpression(addMatch.left, scope);
|
|
2588
|
+
const right = parseExpression(addMatch.right, scope);
|
|
2497
2589
|
if (left && right) {
|
|
2498
|
-
const op = addMatch
|
|
2590
|
+
const op = addMatch.op;
|
|
2499
2591
|
return () => {
|
|
2500
2592
|
const l = left(), r = right();
|
|
2501
2593
|
if (op === "+") return l + r;
|
|
@@ -2503,12 +2595,12 @@ var FormaRuntime = (() => {
|
|
|
2503
2595
|
};
|
|
2504
2596
|
}
|
|
2505
2597
|
}
|
|
2506
|
-
const mulMatch = expr
|
|
2598
|
+
const mulMatch = matchBinaryOp(expr, ["*", "/", "%"]);
|
|
2507
2599
|
if (mulMatch) {
|
|
2508
|
-
const left = parseExpression(mulMatch
|
|
2509
|
-
const right = parseExpression(mulMatch
|
|
2600
|
+
const left = parseExpression(mulMatch.left, scope);
|
|
2601
|
+
const right = parseExpression(mulMatch.right, scope);
|
|
2510
2602
|
if (left && right) {
|
|
2511
|
-
const op = mulMatch
|
|
2603
|
+
const op = mulMatch.op;
|
|
2512
2604
|
return () => {
|
|
2513
2605
|
const l = left(), r = right();
|
|
2514
2606
|
switch (op) {
|
|
@@ -3003,25 +3095,61 @@ var FormaRuntime = (() => {
|
|
|
3003
3095
|
const modelExpr = !known || known.has("data-model") ? el.getAttribute("data-model") : null;
|
|
3004
3096
|
if (modelExpr) {
|
|
3005
3097
|
const prop = modelExpr.replace(RE_STRIP_BRACES, "").trim();
|
|
3006
|
-
|
|
3007
|
-
|
|
3098
|
+
let getter = scope.getters[prop];
|
|
3099
|
+
let setter = scope.setters[prop];
|
|
3100
|
+
if ((!getter || !setter) && prop.includes(".")) {
|
|
3101
|
+
getter = buildEvaluator(prop, scope);
|
|
3102
|
+
const lastDot = prop.lastIndexOf(".");
|
|
3103
|
+
const basePath = prop.slice(0, lastDot);
|
|
3104
|
+
const key = prop.slice(lastDot + 1);
|
|
3105
|
+
const baseGet = buildEvaluator(basePath, scope);
|
|
3106
|
+
setter = (v) => {
|
|
3107
|
+
const base = baseGet();
|
|
3108
|
+
if (base != null && typeof base === "object") base[key] = v;
|
|
3109
|
+
};
|
|
3110
|
+
}
|
|
3008
3111
|
if (getter && setter) {
|
|
3009
3112
|
const input = el;
|
|
3113
|
+
const tag = input.tagName;
|
|
3010
3114
|
const dispose = internalEffect(() => {
|
|
3011
3115
|
const val = getter();
|
|
3012
|
-
|
|
3116
|
+
const type = input.type;
|
|
3117
|
+
if (type === "checkbox") {
|
|
3013
3118
|
input.checked = !!val;
|
|
3119
|
+
const indetExpr = el.getAttribute("data-model-indeterminate");
|
|
3120
|
+
if (indetExpr) {
|
|
3121
|
+
const indetGetter = scope.getters[indetExpr.replace(RE_STRIP_BRACES, "").trim()];
|
|
3122
|
+
if (indetGetter) input.indeterminate = !!indetGetter();
|
|
3123
|
+
}
|
|
3124
|
+
} else if (type === "radio") {
|
|
3125
|
+
input.checked = String(val) === input.value;
|
|
3126
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
3127
|
+
const sel = input;
|
|
3128
|
+
const arr = Array.isArray(val) ? val.map(String) : [];
|
|
3129
|
+
for (const opt of Array.from(sel.options)) opt.selected = arr.includes(opt.value);
|
|
3014
3130
|
} else {
|
|
3015
3131
|
input.value = String(val ?? "");
|
|
3016
3132
|
}
|
|
3017
3133
|
});
|
|
3018
3134
|
disposers.push(dispose);
|
|
3019
|
-
const event = input.type === "checkbox" ? "change" : "input";
|
|
3135
|
+
const event = input.type === "checkbox" || input.type === "radio" || tag === "SELECT" ? "change" : "input";
|
|
3020
3136
|
const onModelInput = () => {
|
|
3021
|
-
|
|
3137
|
+
const type = input.type;
|
|
3138
|
+
if (type === "checkbox") {
|
|
3022
3139
|
setter(input.checked);
|
|
3023
|
-
} else if (
|
|
3024
|
-
setter(
|
|
3140
|
+
} else if (type === "radio") {
|
|
3141
|
+
if (input.checked) setter(input.value);
|
|
3142
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
3143
|
+
const sel = input;
|
|
3144
|
+
setter(Array.from(sel.selectedOptions).map((o) => o.value));
|
|
3145
|
+
} else if (type === "number" || type === "range") {
|
|
3146
|
+
const raw = input.value;
|
|
3147
|
+
if (raw === "") {
|
|
3148
|
+
setter(null);
|
|
3149
|
+
} else {
|
|
3150
|
+
const n = Number(raw);
|
|
3151
|
+
if (!Number.isNaN(n)) setter(n);
|
|
3152
|
+
}
|
|
3025
3153
|
} else {
|
|
3026
3154
|
setter(input.value);
|
|
3027
3155
|
}
|
|
@@ -3214,59 +3342,30 @@ var FormaRuntime = (() => {
|
|
|
3214
3342
|
}
|
|
3215
3343
|
}
|
|
3216
3344
|
const prevNodes = new Set(oldNodes);
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
for (const n of prevNodes) {
|
|
3238
|
-
if (!nextNodes.has(n)) {
|
|
3239
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
3240
|
-
disposeCloneBindings2(n);
|
|
3241
|
-
}
|
|
3242
|
-
}
|
|
3243
|
-
oldItems = result.items;
|
|
3244
|
-
oldNodes = result.nodes;
|
|
3245
|
-
} else {
|
|
3246
|
-
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
3247
|
-
const oldWrapped = oldItems;
|
|
3248
|
-
const result = reconcileList(
|
|
3249
|
-
el,
|
|
3250
|
-
oldWrapped,
|
|
3251
|
-
wrapped,
|
|
3252
|
-
oldNodes,
|
|
3253
|
-
(w) => w.__idx,
|
|
3254
|
-
(w) => createBoundClone2(w.__item, w.__idx),
|
|
3255
|
-
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
3256
|
-
void 0,
|
|
3257
|
-
// beforeNode
|
|
3258
|
-
listHooks
|
|
3259
|
-
);
|
|
3260
|
-
const nextNodes = new Set(result.nodes);
|
|
3261
|
-
for (const n of prevNodes) {
|
|
3262
|
-
if (!nextNodes.has(n)) {
|
|
3263
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
3264
|
-
disposeCloneBindings2(n);
|
|
3265
|
-
}
|
|
3345
|
+
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
3346
|
+
const oldWrapped = oldItems;
|
|
3347
|
+
const keyFn = keyProp ? (w) => String(w.__item?.[keyProp] ?? "") : (w) => w.__idx;
|
|
3348
|
+
const result = reconcileList(
|
|
3349
|
+
el,
|
|
3350
|
+
oldWrapped,
|
|
3351
|
+
wrapped,
|
|
3352
|
+
oldNodes,
|
|
3353
|
+
keyFn,
|
|
3354
|
+
(w) => createBoundClone2(w.__item, w.__idx),
|
|
3355
|
+
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
3356
|
+
void 0,
|
|
3357
|
+
// beforeNode
|
|
3358
|
+
listHooks
|
|
3359
|
+
);
|
|
3360
|
+
const nextNodes = new Set(result.nodes);
|
|
3361
|
+
for (const n of prevNodes) {
|
|
3362
|
+
if (!nextNodes.has(n)) {
|
|
3363
|
+
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
3364
|
+
disposeCloneBindings2(n);
|
|
3266
3365
|
}
|
|
3267
|
-
oldItems = result.items;
|
|
3268
|
-
oldNodes = result.nodes;
|
|
3269
3366
|
}
|
|
3367
|
+
oldItems = result.items;
|
|
3368
|
+
oldNodes = result.nodes;
|
|
3270
3369
|
});
|
|
3271
3370
|
disposers.push(dispose);
|
|
3272
3371
|
}
|