@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
package/dist/runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reconcileList } from './chunk-
|
|
1
|
+
import { reconcileList } from './chunk-AJP4OVCN.js';
|
|
2
2
|
import { isEventHandlerAttr, isUrlAttr, isDangerousUrl } from './chunk-2QQBKQIF.js';
|
|
3
3
|
import { internalEffect, batch } from './chunk-Y3A2EVVS.js';
|
|
4
4
|
import { createSignal, createComputed } from './chunk-ETPJTPYD.js';
|
|
@@ -273,12 +273,12 @@ function findInsertionPoint(parent, newChild, newChildren) {
|
|
|
273
273
|
return null;
|
|
274
274
|
}
|
|
275
275
|
function createReconciler(config) {
|
|
276
|
-
|
|
276
|
+
const lastHtmlByContainer = /* @__PURE__ */ new WeakMap();
|
|
277
277
|
return function reconcile2(container, html) {
|
|
278
278
|
const trimmed = html.trim();
|
|
279
279
|
if (!trimmed) return;
|
|
280
|
-
if (
|
|
281
|
-
|
|
280
|
+
if (lastHtmlByContainer.get(container) === trimmed && container.hasChildNodes()) return;
|
|
281
|
+
lastHtmlByContainer.set(container, trimmed);
|
|
282
282
|
config.disconnectObserver();
|
|
283
283
|
try {
|
|
284
284
|
if (!container.hasChildNodes() || container.children.length === 0) {
|
|
@@ -569,9 +569,97 @@ var RE_TERNARY = /^(.+?)\s*\?\s*(.+?)\s*:\s*(.+)$/;
|
|
|
569
569
|
var RE_NULLISH = /^(.+?)\s*\?\?\s*(.+)$/;
|
|
570
570
|
var RE_AND = /^(.+?)\s*&&\s*(.+)$/;
|
|
571
571
|
var RE_OR = /^(.+?)\s*\|\|\s*(.+)$/;
|
|
572
|
-
var
|
|
573
|
-
|
|
574
|
-
|
|
572
|
+
var UNARY_PRECEDERS = "+-*/%<>=!&|^~(,[{?:";
|
|
573
|
+
function matchBinaryOp(expr, ops) {
|
|
574
|
+
const SQ = String.fromCharCode(39);
|
|
575
|
+
const DQ = String.fromCharCode(34);
|
|
576
|
+
const BT = String.fromCharCode(96);
|
|
577
|
+
const BS = String.fromCharCode(92);
|
|
578
|
+
let depth = 0;
|
|
579
|
+
let inSingle = false, inDouble = false, inTemplate = false, escaped = false;
|
|
580
|
+
let prevSig = "";
|
|
581
|
+
let bestIdx = -1;
|
|
582
|
+
let bestOp = "";
|
|
583
|
+
for (let i = 0; i < expr.length; i++) {
|
|
584
|
+
const ch = expr[i];
|
|
585
|
+
if (escaped) {
|
|
586
|
+
escaped = false;
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
if (ch === BS && (inSingle || inDouble || inTemplate)) {
|
|
590
|
+
escaped = true;
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
if (inSingle) {
|
|
594
|
+
if (ch === SQ) {
|
|
595
|
+
inSingle = false;
|
|
596
|
+
prevSig = DQ;
|
|
597
|
+
}
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
if (inDouble) {
|
|
601
|
+
if (ch === DQ) {
|
|
602
|
+
inDouble = false;
|
|
603
|
+
prevSig = DQ;
|
|
604
|
+
}
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
if (inTemplate) {
|
|
608
|
+
if (ch === BT) {
|
|
609
|
+
inTemplate = false;
|
|
610
|
+
prevSig = DQ;
|
|
611
|
+
}
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
if (ch === SQ) {
|
|
615
|
+
inSingle = true;
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (ch === DQ) {
|
|
619
|
+
inDouble = true;
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
if (ch === BT) {
|
|
623
|
+
inTemplate = true;
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
627
|
+
depth++;
|
|
628
|
+
prevSig = ch;
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
632
|
+
if (depth > 0) depth--;
|
|
633
|
+
prevSig = ch;
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (depth !== 0) continue;
|
|
637
|
+
if (ch === " " || ch === " " || ch === "\n") continue;
|
|
638
|
+
if (i > 0) {
|
|
639
|
+
let matchedOp = "";
|
|
640
|
+
for (const op of ops) {
|
|
641
|
+
if (expr.startsWith(op, i)) {
|
|
642
|
+
matchedOp = op;
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (matchedOp) {
|
|
647
|
+
const isPlusMinus = matchedOp === "+" || matchedOp === "-";
|
|
648
|
+
const unary = isPlusMinus && (prevSig === "" || UNARY_PRECEDERS.includes(prevSig));
|
|
649
|
+
if (!unary) {
|
|
650
|
+
bestIdx = i;
|
|
651
|
+
bestOp = matchedOp;
|
|
652
|
+
}
|
|
653
|
+
i += matchedOp.length - 1;
|
|
654
|
+
prevSig = matchedOp[matchedOp.length - 1];
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
prevSig = ch;
|
|
659
|
+
}
|
|
660
|
+
if (bestIdx === -1) return null;
|
|
661
|
+
return { left: expr.slice(0, bestIdx).trim(), op: bestOp, right: expr.slice(bestIdx + bestOp.length).trim() };
|
|
662
|
+
}
|
|
575
663
|
var RE_TEMPLATE_LIT = /^`([^`]*)`$/;
|
|
576
664
|
var RE_TEMPLATE_INTERP = /\$\{([^}]+)\}/g;
|
|
577
665
|
var RE_GROUP_METHOD_CALL = /^\((.+)\)\.(\w+)\((.*)\)$/;
|
|
@@ -1566,12 +1654,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1566
1654
|
return () => left() && right();
|
|
1567
1655
|
}
|
|
1568
1656
|
}
|
|
1569
|
-
const compMatch = expr
|
|
1657
|
+
const compMatch = matchBinaryOp(expr, ["===", "!==", "==", "!=", ">=", "<=", ">", "<"]);
|
|
1570
1658
|
if (compMatch) {
|
|
1571
|
-
const left = parseExpression(compMatch
|
|
1572
|
-
const right = parseExpression(compMatch
|
|
1659
|
+
const left = parseExpression(compMatch.left, scope);
|
|
1660
|
+
const right = parseExpression(compMatch.right, scope);
|
|
1573
1661
|
if (left && right) {
|
|
1574
|
-
const op = compMatch
|
|
1662
|
+
const op = compMatch.op;
|
|
1575
1663
|
return () => {
|
|
1576
1664
|
const l = left(), r = right();
|
|
1577
1665
|
switch (op) {
|
|
@@ -1595,12 +1683,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1595
1683
|
};
|
|
1596
1684
|
}
|
|
1597
1685
|
}
|
|
1598
|
-
const addMatch = expr
|
|
1686
|
+
const addMatch = matchBinaryOp(expr, ["+", "-"]);
|
|
1599
1687
|
if (addMatch) {
|
|
1600
|
-
const left = parseExpression(addMatch
|
|
1601
|
-
const right = parseExpression(addMatch
|
|
1688
|
+
const left = parseExpression(addMatch.left, scope);
|
|
1689
|
+
const right = parseExpression(addMatch.right, scope);
|
|
1602
1690
|
if (left && right) {
|
|
1603
|
-
const op = addMatch
|
|
1691
|
+
const op = addMatch.op;
|
|
1604
1692
|
return () => {
|
|
1605
1693
|
const l = left(), r = right();
|
|
1606
1694
|
if (op === "+") return l + r;
|
|
@@ -1608,12 +1696,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1608
1696
|
};
|
|
1609
1697
|
}
|
|
1610
1698
|
}
|
|
1611
|
-
const mulMatch = expr
|
|
1699
|
+
const mulMatch = matchBinaryOp(expr, ["*", "/", "%"]);
|
|
1612
1700
|
if (mulMatch) {
|
|
1613
|
-
const left = parseExpression(mulMatch
|
|
1614
|
-
const right = parseExpression(mulMatch
|
|
1701
|
+
const left = parseExpression(mulMatch.left, scope);
|
|
1702
|
+
const right = parseExpression(mulMatch.right, scope);
|
|
1615
1703
|
if (left && right) {
|
|
1616
|
-
const op = mulMatch
|
|
1704
|
+
const op = mulMatch.op;
|
|
1617
1705
|
return () => {
|
|
1618
1706
|
const l = left(), r = right();
|
|
1619
1707
|
switch (op) {
|
|
@@ -2108,25 +2196,61 @@ function bindElement(el, scope, disposers) {
|
|
|
2108
2196
|
const modelExpr = !known || known.has("data-model") ? el.getAttribute("data-model") : null;
|
|
2109
2197
|
if (modelExpr) {
|
|
2110
2198
|
const prop = modelExpr.replace(RE_STRIP_BRACES, "").trim();
|
|
2111
|
-
|
|
2112
|
-
|
|
2199
|
+
let getter = scope.getters[prop];
|
|
2200
|
+
let setter = scope.setters[prop];
|
|
2201
|
+
if ((!getter || !setter) && prop.includes(".")) {
|
|
2202
|
+
getter = buildEvaluator(prop, scope);
|
|
2203
|
+
const lastDot = prop.lastIndexOf(".");
|
|
2204
|
+
const basePath = prop.slice(0, lastDot);
|
|
2205
|
+
const key = prop.slice(lastDot + 1);
|
|
2206
|
+
const baseGet = buildEvaluator(basePath, scope);
|
|
2207
|
+
setter = (v) => {
|
|
2208
|
+
const base = baseGet();
|
|
2209
|
+
if (base != null && typeof base === "object") base[key] = v;
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2113
2212
|
if (getter && setter) {
|
|
2114
2213
|
const input = el;
|
|
2214
|
+
const tag = input.tagName;
|
|
2115
2215
|
const dispose = internalEffect(() => {
|
|
2116
2216
|
const val = getter();
|
|
2117
|
-
|
|
2217
|
+
const type = input.type;
|
|
2218
|
+
if (type === "checkbox") {
|
|
2118
2219
|
input.checked = !!val;
|
|
2220
|
+
const indetExpr = el.getAttribute("data-model-indeterminate");
|
|
2221
|
+
if (indetExpr) {
|
|
2222
|
+
const indetGetter = scope.getters[indetExpr.replace(RE_STRIP_BRACES, "").trim()];
|
|
2223
|
+
if (indetGetter) input.indeterminate = !!indetGetter();
|
|
2224
|
+
}
|
|
2225
|
+
} else if (type === "radio") {
|
|
2226
|
+
input.checked = String(val) === input.value;
|
|
2227
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2228
|
+
const sel = input;
|
|
2229
|
+
const arr = Array.isArray(val) ? val.map(String) : [];
|
|
2230
|
+
for (const opt of Array.from(sel.options)) opt.selected = arr.includes(opt.value);
|
|
2119
2231
|
} else {
|
|
2120
2232
|
input.value = String(val ?? "");
|
|
2121
2233
|
}
|
|
2122
2234
|
});
|
|
2123
2235
|
disposers.push(dispose);
|
|
2124
|
-
const event = input.type === "checkbox" ? "change" : "input";
|
|
2236
|
+
const event = input.type === "checkbox" || input.type === "radio" || tag === "SELECT" ? "change" : "input";
|
|
2125
2237
|
const onModelInput = () => {
|
|
2126
|
-
|
|
2238
|
+
const type = input.type;
|
|
2239
|
+
if (type === "checkbox") {
|
|
2127
2240
|
setter(input.checked);
|
|
2128
|
-
} else if (
|
|
2129
|
-
setter(
|
|
2241
|
+
} else if (type === "radio") {
|
|
2242
|
+
if (input.checked) setter(input.value);
|
|
2243
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2244
|
+
const sel = input;
|
|
2245
|
+
setter(Array.from(sel.selectedOptions).map((o) => o.value));
|
|
2246
|
+
} else if (type === "number" || type === "range") {
|
|
2247
|
+
const raw = input.value;
|
|
2248
|
+
if (raw === "") {
|
|
2249
|
+
setter(null);
|
|
2250
|
+
} else {
|
|
2251
|
+
const n = Number(raw);
|
|
2252
|
+
if (!Number.isNaN(n)) setter(n);
|
|
2253
|
+
}
|
|
2130
2254
|
} else {
|
|
2131
2255
|
setter(input.value);
|
|
2132
2256
|
}
|
|
@@ -2318,59 +2442,30 @@ function bindElement(el, scope, disposers) {
|
|
|
2318
2442
|
}
|
|
2319
2443
|
}
|
|
2320
2444
|
const prevNodes = new Set(oldNodes);
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
for (const n of prevNodes) {
|
|
2342
|
-
if (!nextNodes.has(n)) {
|
|
2343
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2344
|
-
disposeCloneBindings2(n);
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
oldItems = result.items;
|
|
2348
|
-
oldNodes = result.nodes;
|
|
2349
|
-
} else {
|
|
2350
|
-
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2351
|
-
const oldWrapped = oldItems;
|
|
2352
|
-
const result = reconcileList(
|
|
2353
|
-
el,
|
|
2354
|
-
oldWrapped,
|
|
2355
|
-
wrapped,
|
|
2356
|
-
oldNodes,
|
|
2357
|
-
(w) => w.__idx,
|
|
2358
|
-
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2359
|
-
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2360
|
-
void 0,
|
|
2361
|
-
// beforeNode
|
|
2362
|
-
listHooks
|
|
2363
|
-
);
|
|
2364
|
-
const nextNodes = new Set(result.nodes);
|
|
2365
|
-
for (const n of prevNodes) {
|
|
2366
|
-
if (!nextNodes.has(n)) {
|
|
2367
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2368
|
-
disposeCloneBindings2(n);
|
|
2369
|
-
}
|
|
2445
|
+
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2446
|
+
const oldWrapped = oldItems;
|
|
2447
|
+
const keyFn = keyProp ? (w) => String(w.__item?.[keyProp] ?? "") : (w) => w.__idx;
|
|
2448
|
+
const result = reconcileList(
|
|
2449
|
+
el,
|
|
2450
|
+
oldWrapped,
|
|
2451
|
+
wrapped,
|
|
2452
|
+
oldNodes,
|
|
2453
|
+
keyFn,
|
|
2454
|
+
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2455
|
+
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2456
|
+
void 0,
|
|
2457
|
+
// beforeNode
|
|
2458
|
+
listHooks
|
|
2459
|
+
);
|
|
2460
|
+
const nextNodes = new Set(result.nodes);
|
|
2461
|
+
for (const n of prevNodes) {
|
|
2462
|
+
if (!nextNodes.has(n)) {
|
|
2463
|
+
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2464
|
+
disposeCloneBindings2(n);
|
|
2370
2465
|
}
|
|
2371
|
-
oldItems = result.items;
|
|
2372
|
-
oldNodes = result.nodes;
|
|
2373
2466
|
}
|
|
2467
|
+
oldItems = result.items;
|
|
2468
|
+
oldNodes = result.nodes;
|
|
2374
2469
|
});
|
|
2375
2470
|
disposers.push(dispose);
|
|
2376
2471
|
}
|