@jxsuite/runtime 6.3.0 → 7.1.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/runtime.js +862 -119
- package/dist/runtime.js.map +11 -10
- package/package.json +4 -4
- package/src/body-eraser.ts +70 -6
- package/src/css.ts +32 -9
- package/src/expression.ts +140 -7
- package/src/runtime.ts +1271 -127
- package/src/types.ts +58 -3
package/dist/runtime.js
CHANGED
|
@@ -29,21 +29,11 @@ var cacheStringFunction = (fn) => {
|
|
|
29
29
|
return hit || (cache[str] = fn(str));
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
|
-
var
|
|
33
|
-
var camelize = cacheStringFunction((str) => {
|
|
34
|
-
return str.replace(camelizeRE, (c) => c.slice(1).toUpperCase());
|
|
35
|
-
});
|
|
36
|
-
var hyphenateRE = /\B([A-Z])/g;
|
|
37
|
-
var hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase());
|
|
38
|
-
var capitalize = cacheStringFunction((str) => {
|
|
32
|
+
var capitalize = /* @__PURE__ */ cacheStringFunction((str) => {
|
|
39
33
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
40
34
|
});
|
|
41
|
-
var toHandlerKey = cacheStringFunction((str) => {
|
|
42
|
-
const s = str ? `on${capitalize(str)}` : ``;
|
|
43
|
-
return s;
|
|
44
|
-
});
|
|
45
35
|
var hasChanged = (value, oldValue) => !Object.is(value, oldValue);
|
|
46
|
-
var specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,playsinline,readonly`;
|
|
36
|
+
var specialBooleanAttrs = `itemscope,allowfullscreen,disablepictureinpicture,disableremoteplayback,formnovalidate,ismap,nomodule,novalidate,playsinline,readonly`;
|
|
47
37
|
var isBooleanAttr = /* @__PURE__ */ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`);
|
|
48
38
|
|
|
49
39
|
// ../../node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js
|
|
@@ -179,7 +169,11 @@ function effectScope(detached) {
|
|
|
179
169
|
}
|
|
180
170
|
function onScopeDispose(fn, failSilently = false) {
|
|
181
171
|
if (activeEffectScope) {
|
|
182
|
-
activeEffectScope.
|
|
172
|
+
if (activeEffectScope.active) {
|
|
173
|
+
activeEffectScope.cleanups.push(fn);
|
|
174
|
+
} else {
|
|
175
|
+
fn();
|
|
176
|
+
}
|
|
183
177
|
} else if (!failSilently) {
|
|
184
178
|
warn(`onScopeDispose() is called when there is no active effect scope to be associated with.`);
|
|
185
179
|
}
|
|
@@ -907,7 +901,7 @@ function noTracking(self2, method, args = []) {
|
|
|
907
901
|
return res;
|
|
908
902
|
}
|
|
909
903
|
var isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);
|
|
910
|
-
var builtInSymbols = new Set(/* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol));
|
|
904
|
+
var builtInSymbols = /* @__PURE__ */ new Set(/* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol));
|
|
911
905
|
function hasOwnProperty2(key) {
|
|
912
906
|
if (!isSymbol(key))
|
|
913
907
|
key = String(key);
|
|
@@ -1511,7 +1505,91 @@ function maskCode(body) {
|
|
|
1511
1505
|
}
|
|
1512
1506
|
var masked = new Map;
|
|
1513
1507
|
var MASKED_LIMIT = 2048;
|
|
1514
|
-
function
|
|
1508
|
+
function templateExpressions(template) {
|
|
1509
|
+
if (!template.includes("${")) {
|
|
1510
|
+
return NO_EXPRESSIONS;
|
|
1511
|
+
}
|
|
1512
|
+
const known = scanned.get(template);
|
|
1513
|
+
if (known !== undefined) {
|
|
1514
|
+
return known;
|
|
1515
|
+
}
|
|
1516
|
+
const found = [];
|
|
1517
|
+
let from = 0;
|
|
1518
|
+
while (from < template.length) {
|
|
1519
|
+
const spans = [];
|
|
1520
|
+
scanCode(template.slice(from), spans);
|
|
1521
|
+
let unclosed = -1;
|
|
1522
|
+
for (let i = 0;i < spans.length; i += 2) {
|
|
1523
|
+
const start = from + (spans[i] ?? 0);
|
|
1524
|
+
const end = spans[i + 1] ?? -1;
|
|
1525
|
+
if (end === -1) {
|
|
1526
|
+
unclosed = start;
|
|
1527
|
+
break;
|
|
1528
|
+
}
|
|
1529
|
+
found.push(expressionAt(template, start, from + end));
|
|
1530
|
+
}
|
|
1531
|
+
if (unclosed === -1) {
|
|
1532
|
+
break;
|
|
1533
|
+
}
|
|
1534
|
+
const end = closeByBraceDepth(template, unclosed);
|
|
1535
|
+
if (end === -1) {
|
|
1536
|
+
from = unclosed + 2;
|
|
1537
|
+
} else {
|
|
1538
|
+
found.push(expressionAt(template, unclosed, end));
|
|
1539
|
+
from = end;
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
if (scanned.size >= MASKED_LIMIT) {
|
|
1543
|
+
scanned.clear();
|
|
1544
|
+
}
|
|
1545
|
+
scanned.set(template, found);
|
|
1546
|
+
return found;
|
|
1547
|
+
}
|
|
1548
|
+
var NO_EXPRESSIONS = [];
|
|
1549
|
+
var scanned = new Map;
|
|
1550
|
+
function expressionAt(template, start, end) {
|
|
1551
|
+
return { end, expr: template.slice(start + 2, end - 1), start };
|
|
1552
|
+
}
|
|
1553
|
+
function closeByBraceDepth(template, start) {
|
|
1554
|
+
let depth = 0;
|
|
1555
|
+
for (let at = start + 1;at < template.length; at += 1) {
|
|
1556
|
+
const char = template.charAt(at);
|
|
1557
|
+
if (char === "{") {
|
|
1558
|
+
depth += 1;
|
|
1559
|
+
} else if (char === "}") {
|
|
1560
|
+
depth -= 1;
|
|
1561
|
+
if (depth === 0) {
|
|
1562
|
+
return at + 1;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
return -1;
|
|
1567
|
+
}
|
|
1568
|
+
var BEFORE_OPERAND = new Set("(,=:[!&|?{;+-*%<>~^");
|
|
1569
|
+
function endsUpdateOperator(body, before, at) {
|
|
1570
|
+
return (before === "+" || before === "-") && body.charAt(at - 1) === before;
|
|
1571
|
+
}
|
|
1572
|
+
function regexLiteralEnd(body, at) {
|
|
1573
|
+
let inClass = false;
|
|
1574
|
+
for (let i = at + 1;i < body.length; i += 1) {
|
|
1575
|
+
const char = body.charAt(i);
|
|
1576
|
+
if (char === `
|
|
1577
|
+
`) {
|
|
1578
|
+
return -1;
|
|
1579
|
+
}
|
|
1580
|
+
if (char === "\\") {
|
|
1581
|
+
i += 1;
|
|
1582
|
+
} else if (char === "[") {
|
|
1583
|
+
inClass = true;
|
|
1584
|
+
} else if (char === "]") {
|
|
1585
|
+
inClass = false;
|
|
1586
|
+
} else if (char === "/" && !inClass) {
|
|
1587
|
+
return i + 1;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return -1;
|
|
1591
|
+
}
|
|
1592
|
+
function scanCode(body, spans) {
|
|
1515
1593
|
const out = body.split("");
|
|
1516
1594
|
const blank = (at) => {
|
|
1517
1595
|
if (out[at] !== undefined && out[at] !== `
|
|
@@ -1520,7 +1598,9 @@ function scanCode(body) {
|
|
|
1520
1598
|
}
|
|
1521
1599
|
};
|
|
1522
1600
|
const substitutions = [];
|
|
1523
|
-
let inTemplate =
|
|
1601
|
+
let inTemplate = spans !== undefined;
|
|
1602
|
+
let before = "";
|
|
1603
|
+
let beforeAt = -1;
|
|
1524
1604
|
let at = 0;
|
|
1525
1605
|
while (at < body.length) {
|
|
1526
1606
|
const char = body.charAt(at);
|
|
@@ -1529,12 +1609,17 @@ function scanCode(body) {
|
|
|
1529
1609
|
blank(at);
|
|
1530
1610
|
blank(at + 1);
|
|
1531
1611
|
at += 2;
|
|
1532
|
-
} else if (char === "`") {
|
|
1612
|
+
} else if (char === "`" && !(spans && substitutions.length === 0)) {
|
|
1533
1613
|
inTemplate = false;
|
|
1614
|
+
before = char;
|
|
1534
1615
|
at += 1;
|
|
1535
1616
|
} else if (char === "$" && body.charAt(at + 1) === "{") {
|
|
1617
|
+
if (substitutions.length === 0) {
|
|
1618
|
+
spans?.push(at, -1);
|
|
1619
|
+
}
|
|
1536
1620
|
substitutions.push(0);
|
|
1537
1621
|
inTemplate = false;
|
|
1622
|
+
before = "{";
|
|
1538
1623
|
at += 2;
|
|
1539
1624
|
} else {
|
|
1540
1625
|
blank(at);
|
|
@@ -1563,10 +1648,18 @@ function scanCode(body) {
|
|
|
1563
1648
|
blank(at);
|
|
1564
1649
|
at += 1;
|
|
1565
1650
|
}
|
|
1651
|
+
before = char;
|
|
1566
1652
|
at += 1;
|
|
1567
1653
|
} else if (char === "`") {
|
|
1568
1654
|
inTemplate = true;
|
|
1569
1655
|
at += 1;
|
|
1656
|
+
} else if (spans && char === "/" && BEFORE_OPERAND.has(before) && !endsUpdateOperator(body, before, beforeAt) && regexLiteralEnd(body, at) > 0) {
|
|
1657
|
+
const stop = regexLiteralEnd(body, at);
|
|
1658
|
+
for (at += 1;at < stop - 1; at += 1) {
|
|
1659
|
+
blank(at);
|
|
1660
|
+
}
|
|
1661
|
+
before = "/";
|
|
1662
|
+
at = stop;
|
|
1570
1663
|
} else {
|
|
1571
1664
|
const open = substitutions.length - 1;
|
|
1572
1665
|
if (open >= 0 && char === "{") {
|
|
@@ -1575,10 +1668,17 @@ function scanCode(body) {
|
|
|
1575
1668
|
if (substitutions[open] === 0) {
|
|
1576
1669
|
substitutions.pop();
|
|
1577
1670
|
inTemplate = true;
|
|
1671
|
+
if (spans && substitutions.length === 0) {
|
|
1672
|
+
spans[spans.length - 1] = at + 1;
|
|
1673
|
+
}
|
|
1578
1674
|
} else {
|
|
1579
1675
|
substitutions[open] = (substitutions[open] ?? 1) - 1;
|
|
1580
1676
|
}
|
|
1581
1677
|
}
|
|
1678
|
+
if (char.trim() !== "") {
|
|
1679
|
+
before = char;
|
|
1680
|
+
beforeAt = at;
|
|
1681
|
+
}
|
|
1582
1682
|
at += 1;
|
|
1583
1683
|
}
|
|
1584
1684
|
}
|
|
@@ -1793,6 +1893,13 @@ function cssRuleText(conditions, selector, declarations) {
|
|
|
1793
1893
|
}
|
|
1794
1894
|
return text;
|
|
1795
1895
|
}
|
|
1896
|
+
function commentedRuleText(rule) {
|
|
1897
|
+
if (rule.description === undefined) {
|
|
1898
|
+
return rule.text;
|
|
1899
|
+
}
|
|
1900
|
+
return `/* ${rule.description.replaceAll("*/", "* /")} */
|
|
1901
|
+
${rule.text}`;
|
|
1902
|
+
}
|
|
1796
1903
|
function cssKeyframesText(conditions, name, blocks) {
|
|
1797
1904
|
const body = blocks.map(({ selector, declarations }) => `${selector} { ${declarations.map(([property, value]) => `${property}: ${value}`).join("; ")} }`).join(" ");
|
|
1798
1905
|
let text = `@keyframes ${name} { ${body} }`;
|
|
@@ -1872,6 +1979,7 @@ function buildStyleRules(style, options = {}) {
|
|
|
1872
1979
|
}
|
|
1873
1980
|
return declarations;
|
|
1874
1981
|
};
|
|
1982
|
+
const describedBy = (description) => isString2(description) && description !== "" ? { description } : {};
|
|
1875
1983
|
const emit = (conditions, selector, declarations, target, description) => {
|
|
1876
1984
|
if (declarations.length === 0) {
|
|
1877
1985
|
return;
|
|
@@ -1893,10 +2001,7 @@ function buildStyleRules(style, options = {}) {
|
|
|
1893
2001
|
target,
|
|
1894
2002
|
key: hashCss(text)
|
|
1895
2003
|
};
|
|
1896
|
-
|
|
1897
|
-
rule.description = description;
|
|
1898
|
-
}
|
|
1899
|
-
rules.push(rule);
|
|
2004
|
+
rules.push({ ...rule, ...describedBy(description) });
|
|
1900
2005
|
};
|
|
1901
2006
|
const emitKeyframes = (atKey, block, conditions) => {
|
|
1902
2007
|
const name = atKey.slice("@keyframes".length).trim();
|
|
@@ -1924,7 +2029,8 @@ function buildStyleRules(style, options = {}) {
|
|
|
1924
2029
|
key: hashCss(text),
|
|
1925
2030
|
selector: null,
|
|
1926
2031
|
target: "unscoped",
|
|
1927
|
-
text
|
|
2032
|
+
text,
|
|
2033
|
+
...describedBy(block["$description"])
|
|
1928
2034
|
});
|
|
1929
2035
|
};
|
|
1930
2036
|
const walkAt = (atKey, block, selector, conditions, target) => {
|
|
@@ -2225,12 +2331,77 @@ function withPageLocale(path, args, state) {
|
|
|
2225
2331
|
filled[index] = locale;
|
|
2226
2332
|
return filled;
|
|
2227
2333
|
}
|
|
2334
|
+
function windowRoot() {
|
|
2335
|
+
const root = globalThis.window;
|
|
2336
|
+
return root ?? globalThis;
|
|
2337
|
+
}
|
|
2228
2338
|
function isBlessedGlobal(ref) {
|
|
2229
2339
|
return ref.startsWith("window#/") && BLESSED_GLOBALS.has(ref.slice("window#/".length));
|
|
2230
2340
|
}
|
|
2231
2341
|
function isMutating(op) {
|
|
2232
2342
|
return MUTATING_OPS.has(op);
|
|
2233
2343
|
}
|
|
2344
|
+
function operandMutates(operand) {
|
|
2345
|
+
if (Array.isArray(operand)) {
|
|
2346
|
+
return operand.some((item) => operandMutates(item));
|
|
2347
|
+
}
|
|
2348
|
+
if (operand === undefined || !isNodeOperand(operand)) {
|
|
2349
|
+
return false;
|
|
2350
|
+
}
|
|
2351
|
+
return isMutating(operand.operator) || [operand.target, operand.value, operand.initial, operand.default].some((part) => operandMutates(part)) || Object.values(operand.cases ?? {}).some((part) => operandMutates(part));
|
|
2352
|
+
}
|
|
2353
|
+
function isPureNamedFormula(def) {
|
|
2354
|
+
return isNamedFormulaDef(def) && !operandMutates(def.$expression);
|
|
2355
|
+
}
|
|
2356
|
+
var OUTSIDE_SCOPE_REF = /^(?:\$args\/|\$reduce\/|\$map\/|window#\/|document#\/|event#\/)/;
|
|
2357
|
+
function collectScopeReads(operand, into) {
|
|
2358
|
+
if (Array.isArray(operand)) {
|
|
2359
|
+
for (const item of operand) {
|
|
2360
|
+
collectScopeReads(item, into);
|
|
2361
|
+
}
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
if (operand === undefined || !isNonNullObject(operand)) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
if (isRefOperand(operand)) {
|
|
2368
|
+
if (!OUTSIDE_SCOPE_REF.test(operand.$ref)) {
|
|
2369
|
+
const path = operand.$ref.replace(/^(?:#\/state\/|parent#\/)/, "");
|
|
2370
|
+
into.add(refSegments(path)[0] ?? "");
|
|
2371
|
+
}
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
if (isNodeOperand(operand)) {
|
|
2375
|
+
const parts = [operand.target, operand.value, operand.initial, operand.default];
|
|
2376
|
+
for (const part of [...parts, ...Object.values(operand.cases ?? {})]) {
|
|
2377
|
+
collectScopeReads(part, into);
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
function formulaScopeReads(def) {
|
|
2382
|
+
const reads = new Set;
|
|
2383
|
+
collectScopeReads(def.$expression, reads);
|
|
2384
|
+
return [...reads];
|
|
2385
|
+
}
|
|
2386
|
+
function inheritableFormulas(projectState) {
|
|
2387
|
+
const candidates = new Map;
|
|
2388
|
+
for (const [key, def] of Object.entries(projectState ?? {})) {
|
|
2389
|
+
if (!key.startsWith("$") && isPureNamedFormula(def)) {
|
|
2390
|
+
candidates.set(key, def);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
let settled = false;
|
|
2394
|
+
while (!settled) {
|
|
2395
|
+
settled = true;
|
|
2396
|
+
for (const [key, def] of candidates) {
|
|
2397
|
+
if (formulaScopeReads(def).some((read) => !candidates.has(read))) {
|
|
2398
|
+
candidates.delete(key);
|
|
2399
|
+
settled = false;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
return Object.fromEntries(candidates);
|
|
2404
|
+
}
|
|
2234
2405
|
var MAX_CALL_DEPTH = 64;
|
|
2235
2406
|
var MAX_REPORT_DEPTH = 64;
|
|
2236
2407
|
function subTrace(trace, seg) {
|
|
@@ -2324,7 +2495,7 @@ function resolveExprRef(ref, state, event, iterCtx) {
|
|
|
2324
2495
|
return readPath(state, ref.slice("parent#/".length));
|
|
2325
2496
|
}
|
|
2326
2497
|
if (ref.startsWith("window#/")) {
|
|
2327
|
-
return readPath(
|
|
2498
|
+
return readPath(windowRoot(), ref.slice("window#/".length));
|
|
2328
2499
|
}
|
|
2329
2500
|
if (ref.startsWith("document#/")) {
|
|
2330
2501
|
return readPath(globalThis.document, ref.slice("document#/".length));
|
|
@@ -2440,9 +2611,10 @@ function evaluateNode(node, state, event, iterCtx, trace) {
|
|
|
2440
2611
|
if (helper) {
|
|
2441
2612
|
return helper(...withPageLocale(globalPath, argValues, state));
|
|
2442
2613
|
}
|
|
2443
|
-
const
|
|
2614
|
+
const root = windowRoot();
|
|
2615
|
+
const fn = readPath(root, globalPath);
|
|
2444
2616
|
const lastSlash = globalPath.lastIndexOf("/");
|
|
2445
|
-
const thisArg = lastSlash === -1 ?
|
|
2617
|
+
const thisArg = lastSlash === -1 ? root : readPath(root, globalPath.slice(0, lastSlash));
|
|
2446
2618
|
return fn.apply(thisArg, argValues);
|
|
2447
2619
|
}
|
|
2448
2620
|
const callee = resolveExprRef(calleeRef, state, event, iterCtx);
|
|
@@ -2796,6 +2968,7 @@ async function runStatements(statements, state, event, opts = {}) {
|
|
|
2796
2968
|
|
|
2797
2969
|
// src/body-eraser.ts
|
|
2798
2970
|
var eraser = null;
|
|
2971
|
+
var moduleLoader = null;
|
|
2799
2972
|
var loader = null;
|
|
2800
2973
|
var loading = null;
|
|
2801
2974
|
var erased = new Map;
|
|
@@ -2806,6 +2979,35 @@ function setBodyEraser(fn) {
|
|
|
2806
2979
|
loading = null;
|
|
2807
2980
|
}
|
|
2808
2981
|
}
|
|
2982
|
+
function setModuleLoader(fn) {
|
|
2983
|
+
moduleLoader = fn;
|
|
2984
|
+
if (!fn) {
|
|
2985
|
+
loading = null;
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
function canLoadModules() {
|
|
2989
|
+
return moduleLoader !== null || loader !== null;
|
|
2990
|
+
}
|
|
2991
|
+
function fetchEraser(load) {
|
|
2992
|
+
loading ??= load().then((module) => {
|
|
2993
|
+
if (loader !== load) {
|
|
2994
|
+
return;
|
|
2995
|
+
}
|
|
2996
|
+
if (!eraser) {
|
|
2997
|
+
setBodyEraser(module.eraseBody);
|
|
2998
|
+
}
|
|
2999
|
+
if (!moduleLoader && module.loadModule) {
|
|
3000
|
+
setModuleLoader(module.loadModule);
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3003
|
+
return loading;
|
|
3004
|
+
}
|
|
3005
|
+
async function moduleLoaderFor() {
|
|
3006
|
+
if (!moduleLoader && loader) {
|
|
3007
|
+
await fetchEraser(loader);
|
|
3008
|
+
}
|
|
3009
|
+
return moduleLoader;
|
|
3010
|
+
}
|
|
2809
3011
|
function setBodyEraserLoader(load) {
|
|
2810
3012
|
loader = load;
|
|
2811
3013
|
loading = null;
|
|
@@ -2864,12 +3066,7 @@ async function prepareBodies(doc) {
|
|
|
2864
3066
|
if (!bodiesOf(tree).some((body) => bodyNeedsEraser(body))) {
|
|
2865
3067
|
return;
|
|
2866
3068
|
}
|
|
2867
|
-
|
|
2868
|
-
if (loader === load) {
|
|
2869
|
-
setBodyEraser(module.eraseBody);
|
|
2870
|
-
}
|
|
2871
|
-
});
|
|
2872
|
-
await loading;
|
|
3069
|
+
await fetchEraser(load);
|
|
2873
3070
|
}
|
|
2874
3071
|
function javaScriptOf(body, where) {
|
|
2875
3072
|
if (!eraser) {
|
|
@@ -2899,6 +3096,75 @@ function compileBody(params, body, where) {
|
|
|
2899
3096
|
}
|
|
2900
3097
|
}
|
|
2901
3098
|
|
|
3099
|
+
// ../schema/src/document-scripts.ts
|
|
3100
|
+
var SCRIPT_SPECIFIER_PREFIX = "jx-script:";
|
|
3101
|
+
var CLIENT_SCRIPT_REF = "#client";
|
|
3102
|
+
var SERVER_SCRIPT_REF = "#server";
|
|
3103
|
+
var TYPESCRIPT_PATH = /\.[cm]?ts$/iu;
|
|
3104
|
+
function isTypeScriptPath(pathname) {
|
|
3105
|
+
return TYPESCRIPT_PATH.test(pathname);
|
|
3106
|
+
}
|
|
3107
|
+
function scriptRefSide(src) {
|
|
3108
|
+
if (src === CLIENT_SCRIPT_REF) {
|
|
3109
|
+
return "client";
|
|
3110
|
+
}
|
|
3111
|
+
if (src === SERVER_SCRIPT_REF) {
|
|
3112
|
+
return "server";
|
|
3113
|
+
}
|
|
3114
|
+
return null;
|
|
3115
|
+
}
|
|
3116
|
+
function normalizedPath(path) {
|
|
3117
|
+
return path.replaceAll("\\", "/").replace(/^(?:\.\/)+/, "");
|
|
3118
|
+
}
|
|
3119
|
+
function scriptSpecifier(path, side) {
|
|
3120
|
+
return `${SCRIPT_SPECIFIER_PREFIX}${normalizedPath(path)}#${side}`;
|
|
3121
|
+
}
|
|
3122
|
+
function isScriptSpecifier(src) {
|
|
3123
|
+
return src.startsWith(SCRIPT_SPECIFIER_PREFIX);
|
|
3124
|
+
}
|
|
3125
|
+
function parseScriptSpecifier(src) {
|
|
3126
|
+
if (!isScriptSpecifier(src)) {
|
|
3127
|
+
return null;
|
|
3128
|
+
}
|
|
3129
|
+
const rest = src.slice(SCRIPT_SPECIFIER_PREFIX.length);
|
|
3130
|
+
const hash = rest.lastIndexOf("#");
|
|
3131
|
+
if (hash <= 0) {
|
|
3132
|
+
return null;
|
|
3133
|
+
}
|
|
3134
|
+
const side = rest.slice(hash + 1);
|
|
3135
|
+
if (side !== "client" && side !== "server") {
|
|
3136
|
+
return null;
|
|
3137
|
+
}
|
|
3138
|
+
return { path: rest.slice(0, hash), side };
|
|
3139
|
+
}
|
|
3140
|
+
function qualifiedValue(value, path) {
|
|
3141
|
+
if (Array.isArray(value)) {
|
|
3142
|
+
const items = value.map((item) => qualifiedValue(item, path));
|
|
3143
|
+
return items.some((item, index) => item !== value[index]) ? items : value;
|
|
3144
|
+
}
|
|
3145
|
+
if (!isJsonObject(value)) {
|
|
3146
|
+
return value;
|
|
3147
|
+
}
|
|
3148
|
+
let copy = null;
|
|
3149
|
+
for (const [key, member] of Object.entries(value)) {
|
|
3150
|
+
let next = member;
|
|
3151
|
+
if (key === "$src" && isString2(member)) {
|
|
3152
|
+
const side = scriptRefSide(member);
|
|
3153
|
+
next = side === null ? member : scriptSpecifier(path, side);
|
|
3154
|
+
} else if (key !== "$script") {
|
|
3155
|
+
next = qualifiedValue(member, path);
|
|
3156
|
+
}
|
|
3157
|
+
if (next !== member) {
|
|
3158
|
+
copy ??= { ...value };
|
|
3159
|
+
copy[key] = next;
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
return copy === null ? value : copy;
|
|
3163
|
+
}
|
|
3164
|
+
function qualifyScripts(doc, path) {
|
|
3165
|
+
return qualifiedValue(doc, path);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
2902
3168
|
// src/cookie.ts
|
|
2903
3169
|
var HOST_PREFIX = "__Host-";
|
|
2904
3170
|
var SECURE_PREFIX = "__Secure-";
|
|
@@ -2980,10 +3246,11 @@ function assertHostScope(scope) {
|
|
|
2980
3246
|
}
|
|
2981
3247
|
}
|
|
2982
3248
|
}
|
|
2983
|
-
async function mount(
|
|
3249
|
+
async function mount(source, target, options = {}) {
|
|
2984
3250
|
const hostScope = options.scope ? hostScopeOf(options.scope) : {};
|
|
2985
3251
|
assertHostScope(hostScope);
|
|
2986
3252
|
const base = options.base ? new URL(options.base, location.href).href : location.href;
|
|
3253
|
+
const doc = inlineDocument(source, base);
|
|
2987
3254
|
const ctx = {
|
|
2988
3255
|
base,
|
|
2989
3256
|
media: options.media ?? doc.$media ?? null,
|
|
@@ -3019,6 +3286,15 @@ async function mount(doc, target, options = {}) {
|
|
|
3019
3286
|
if (options.onNodeMoved) {
|
|
3020
3287
|
renderOptions.onNodeMoved = options.onNodeMoved;
|
|
3021
3288
|
}
|
|
3289
|
+
if (options.rowLimit !== undefined) {
|
|
3290
|
+
renderOptions.rowLimit = options.rowLimit;
|
|
3291
|
+
}
|
|
3292
|
+
if (options.emptyRow) {
|
|
3293
|
+
renderOptions.emptyRow = options.emptyRow;
|
|
3294
|
+
}
|
|
3295
|
+
if (options.onListReconciled) {
|
|
3296
|
+
renderOptions.onListReconciled = options.onListReconciled;
|
|
3297
|
+
}
|
|
3022
3298
|
const { result: root, stop } = runScoped(() => renderNode(doc, scope, renderOptions));
|
|
3023
3299
|
ctx.root = root;
|
|
3024
3300
|
let mounted = false;
|
|
@@ -3065,7 +3341,7 @@ async function resolve(source, ctx) {
|
|
|
3065
3341
|
}
|
|
3066
3342
|
const served = ctx?.resolver?.(source);
|
|
3067
3343
|
if (served) {
|
|
3068
|
-
return served;
|
|
3344
|
+
return withOwnScripts(await served, source);
|
|
3069
3345
|
}
|
|
3070
3346
|
if (_resolveCache.has(source)) {
|
|
3071
3347
|
return _resolveCache.get(source);
|
|
@@ -3086,7 +3362,8 @@ async function resolve(source, ctx) {
|
|
|
3086
3362
|
}
|
|
3087
3363
|
return await res.json();
|
|
3088
3364
|
});
|
|
3089
|
-
const p = fetched.then(async (
|
|
3365
|
+
const p = fetched.then(async (read) => {
|
|
3366
|
+
const doc = withOwnScripts(read, source);
|
|
3090
3367
|
await prepareBodies(doc);
|
|
3091
3368
|
return doc;
|
|
3092
3369
|
});
|
|
@@ -3119,6 +3396,10 @@ var _autoRequestConfig = { skip: false };
|
|
|
3119
3396
|
function setSkipAutoRequests(v) {
|
|
3120
3397
|
_autoRequestConfig.skip = v;
|
|
3121
3398
|
}
|
|
3399
|
+
var _remoteLookupHandler = null;
|
|
3400
|
+
function setRemoteLookupHandler(handler) {
|
|
3401
|
+
_remoteLookupHandler = handler;
|
|
3402
|
+
}
|
|
3122
3403
|
var _resolveToken = null;
|
|
3123
3404
|
function setResolveToken(token) {
|
|
3124
3405
|
_resolveToken = token || null;
|
|
@@ -3175,8 +3456,20 @@ function setCanvasDelinkCommands(on) {
|
|
|
3175
3456
|
_canvasDelinkCommands = on;
|
|
3176
3457
|
}
|
|
3177
3458
|
var _canvasInsideStampedHost = false;
|
|
3459
|
+
function insideStampedHost(inside, fn) {
|
|
3460
|
+
const was = _canvasInsideStampedHost;
|
|
3461
|
+
_canvasInsideStampedHost = inside;
|
|
3462
|
+
try {
|
|
3463
|
+
return fn();
|
|
3464
|
+
} finally {
|
|
3465
|
+
_canvasInsideStampedHost = was;
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3178
3468
|
function canvasStamped(el) {
|
|
3179
|
-
return _canvasInsideStampedHost || el
|
|
3469
|
+
return _canvasInsideStampedHost || carriesCanvasStamp(el);
|
|
3470
|
+
}
|
|
3471
|
+
function carriesCanvasStamp(el) {
|
|
3472
|
+
return el.dataset.jxPath !== undefined || el.dataset.jxEchoPath !== undefined;
|
|
3180
3473
|
}
|
|
3181
3474
|
function canvasAttrName(el, key) {
|
|
3182
3475
|
if (_canvasDelinkAnchors && key === "href" && (el.tagName === "A" || el.tagName === "AREA")) {
|
|
@@ -3274,7 +3567,8 @@ function boundPropKey(key, val, state) {
|
|
|
3274
3567
|
}
|
|
3275
3568
|
return sub;
|
|
3276
3569
|
}
|
|
3277
|
-
async function buildScope(
|
|
3570
|
+
async function buildScope(source, parentScope = {}, base = location.href, ctx) {
|
|
3571
|
+
const doc = inlineDocument(source, base);
|
|
3278
3572
|
const dispatchRoot = () => ctx?.root ?? null;
|
|
3279
3573
|
const raw = {};
|
|
3280
3574
|
const defs = doc.state ?? {};
|
|
@@ -3488,6 +3782,7 @@ function bindTemplate(source, run, fallback) {
|
|
|
3488
3782
|
run();
|
|
3489
3783
|
heldTemplateErrors.delete(run);
|
|
3490
3784
|
} catch (error) {
|
|
3785
|
+
_templateThrows += 1;
|
|
3491
3786
|
const thrown = error instanceof Error ? error : new Error(String(error));
|
|
3492
3787
|
if (_templateErrorHandler) {
|
|
3493
3788
|
_templateErrorHandler(thrown, source);
|
|
@@ -3500,6 +3795,8 @@ function bindTemplate(source, run, fallback) {
|
|
|
3500
3795
|
}
|
|
3501
3796
|
});
|
|
3502
3797
|
}
|
|
3798
|
+
var _templateThrows = 0;
|
|
3799
|
+
var _listRedraws = 0;
|
|
3503
3800
|
function rowContext(state) {
|
|
3504
3801
|
return state.$map;
|
|
3505
3802
|
}
|
|
@@ -3507,19 +3804,8 @@ function isSingleExpression(str) {
|
|
|
3507
3804
|
if (!str.startsWith("${") || !str.endsWith("}")) {
|
|
3508
3805
|
return false;
|
|
3509
3806
|
}
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
const c = str[i];
|
|
3513
|
-
if (c === "{") {
|
|
3514
|
-
depth += 1;
|
|
3515
|
-
} else if (c === "}") {
|
|
3516
|
-
depth -= 1;
|
|
3517
|
-
if (depth === 0) {
|
|
3518
|
-
return i === str.length - 1;
|
|
3519
|
-
}
|
|
3520
|
-
}
|
|
3521
|
-
}
|
|
3522
|
-
return false;
|
|
3807
|
+
const [only, ...more] = templateExpressions(str);
|
|
3808
|
+
return only !== undefined && more.length === 0 && only.start === 0 && only.end === str.length;
|
|
3523
3809
|
}
|
|
3524
3810
|
function evaluateValueTemplate(str, state) {
|
|
3525
3811
|
if (!isSingleExpression(str)) {
|
|
@@ -3532,6 +3818,9 @@ function evaluateValueTemplate(str, state) {
|
|
|
3532
3818
|
}
|
|
3533
3819
|
return fn(...templateArgs(state));
|
|
3534
3820
|
}
|
|
3821
|
+
function evaluateTemplateValue(str, scope) {
|
|
3822
|
+
return evaluateValueTemplate(str, scope);
|
|
3823
|
+
}
|
|
3535
3824
|
var _npmModuleResolver = null;
|
|
3536
3825
|
function setNpmModuleResolver(resolver) {
|
|
3537
3826
|
_npmModuleResolver = resolver;
|
|
@@ -3542,6 +3831,13 @@ async function importSource(src, base) {
|
|
|
3542
3831
|
const specifier = src.slice(NPM_SCHEME.length);
|
|
3543
3832
|
return importModule(_npmModuleResolver?.(specifier) ?? specifier);
|
|
3544
3833
|
}
|
|
3834
|
+
const typed = typeScriptSource(src, base);
|
|
3835
|
+
if (typed !== null && (canLoadModules() || isScriptSpecifier(src))) {
|
|
3836
|
+
const loaded = await importTypeScript(typed, src, base);
|
|
3837
|
+
if (loaded) {
|
|
3838
|
+
return loaded;
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3545
3841
|
if (base) {
|
|
3546
3842
|
try {
|
|
3547
3843
|
return await importModule(new URL(src, base).href);
|
|
@@ -3551,6 +3847,70 @@ async function importSource(src, base) {
|
|
|
3551
3847
|
}
|
|
3552
3848
|
return importModule(src);
|
|
3553
3849
|
}
|
|
3850
|
+
var FETCHED_SCHEMES = new Set(["http:", "https:"]);
|
|
3851
|
+
function typeScriptSource(src, base) {
|
|
3852
|
+
if (isScriptSpecifier(src)) {
|
|
3853
|
+
return src;
|
|
3854
|
+
}
|
|
3855
|
+
if (scriptRefSide(src) !== null) {
|
|
3856
|
+
throw new Error(`Jx: $src "${src}" names the script of the document it is written in, and that document ` + `has no $script`);
|
|
3857
|
+
}
|
|
3858
|
+
const from = base ?? location.href;
|
|
3859
|
+
if (!URL.canParse(src, from)) {
|
|
3860
|
+
return null;
|
|
3861
|
+
}
|
|
3862
|
+
const url = new URL(src, from);
|
|
3863
|
+
return FETCHED_SCHEMES.has(url.protocol) && isTypeScriptPath(url.pathname) ? url.href : null;
|
|
3864
|
+
}
|
|
3865
|
+
async function importTypeScript(specifier, src, base) {
|
|
3866
|
+
const load = await moduleLoaderFor();
|
|
3867
|
+
if (load) {
|
|
3868
|
+
const module = await load(specifier, {
|
|
3869
|
+
base,
|
|
3870
|
+
resolveNpm: _npmModuleResolver,
|
|
3871
|
+
text: _documentScripts.get(src)
|
|
3872
|
+
});
|
|
3873
|
+
return module;
|
|
3874
|
+
}
|
|
3875
|
+
if (isScriptSpecifier(src)) {
|
|
3876
|
+
throw new Error(`Jx: ${parseScriptSpecifier(src)?.path ?? src} has a script, and this page has nothing ` + `that can load one. Give it a module loader with setModuleLoader(loadModule), loadModule ` + `from @jxsuite/erase/browser, or let setBodyEraserLoader fetch that file when it is needed.`);
|
|
3877
|
+
}
|
|
3878
|
+
return null;
|
|
3879
|
+
}
|
|
3880
|
+
var _documentScripts = new Map;
|
|
3881
|
+
function withOwnScripts(doc, source) {
|
|
3882
|
+
if (!doc.$script) {
|
|
3883
|
+
return doc;
|
|
3884
|
+
}
|
|
3885
|
+
const address = URL.canParse(source, location.href) ? new URL(source, location.href).href : source;
|
|
3886
|
+
const { client } = doc.$script;
|
|
3887
|
+
const specifier = scriptSpecifier(address, "client");
|
|
3888
|
+
if (isString2(client) && _documentScripts.get(specifier) !== client) {
|
|
3889
|
+
if (_documentScripts.has(specifier) && !_hostSeeded.has(specifier)) {
|
|
3890
|
+
_moduleCache.delete(specifier);
|
|
3891
|
+
}
|
|
3892
|
+
_documentScripts.set(specifier, client);
|
|
3893
|
+
}
|
|
3894
|
+
const own = qualifyScripts(doc, address);
|
|
3895
|
+
_addressed.set(own, own);
|
|
3896
|
+
return own;
|
|
3897
|
+
}
|
|
3898
|
+
var _addressed = new WeakMap;
|
|
3899
|
+
var _inlineCount = 0;
|
|
3900
|
+
function inlineDocument(doc, base) {
|
|
3901
|
+
if (!doc.$script) {
|
|
3902
|
+
return doc;
|
|
3903
|
+
}
|
|
3904
|
+
let own = _addressed.get(doc);
|
|
3905
|
+
if (!own) {
|
|
3906
|
+
_inlineCount += 1;
|
|
3907
|
+
const address = new URL(base, location.href);
|
|
3908
|
+
address.hash = `jx-inline-${_inlineCount}`;
|
|
3909
|
+
own = withOwnScripts(doc, address.href);
|
|
3910
|
+
_addressed.set(doc, own);
|
|
3911
|
+
}
|
|
3912
|
+
return own;
|
|
3913
|
+
}
|
|
3554
3914
|
function importModule(specifier) {
|
|
3555
3915
|
return import(specifier);
|
|
3556
3916
|
}
|
|
@@ -3594,6 +3954,28 @@ function seededModule(src) {
|
|
|
3594
3954
|
_moduleLoaders.set(src, load);
|
|
3595
3955
|
return load;
|
|
3596
3956
|
}
|
|
3957
|
+
function acquireModule(src, base) {
|
|
3958
|
+
const seeded = seededModule(src);
|
|
3959
|
+
if (seeded) {
|
|
3960
|
+
return seeded;
|
|
3961
|
+
}
|
|
3962
|
+
const loading = importSource(src, base);
|
|
3963
|
+
loading.then((mod) => {
|
|
3964
|
+
_moduleCache.set(src, mod);
|
|
3965
|
+
}, () => {});
|
|
3966
|
+
return loading;
|
|
3967
|
+
}
|
|
3968
|
+
function exportedFunction(def, key, src, mod) {
|
|
3969
|
+
const exportName = def.$export ?? key;
|
|
3970
|
+
const candidate = mod[exportName] ?? mod.default?.[exportName];
|
|
3971
|
+
if (!isFunction2(candidate)) {
|
|
3972
|
+
throw new TypeError(`Jx: export "${exportName}" not found or not a function in "${src}"`);
|
|
3973
|
+
}
|
|
3974
|
+
return candidate;
|
|
3975
|
+
}
|
|
3976
|
+
async function importFunctionExport(def, key, src, base) {
|
|
3977
|
+
return exportedFunction(def, key, src, await acquireModule(src, base));
|
|
3978
|
+
}
|
|
3597
3979
|
async function resolveFunction(def, state, key, role, base) {
|
|
3598
3980
|
if (!def.body && !def.$src) {
|
|
3599
3981
|
const params = handlerParamNames(def);
|
|
@@ -3612,27 +3994,25 @@ async function resolveFunction(def, state, key, role, base) {
|
|
|
3612
3994
|
configurable: true,
|
|
3613
3995
|
value: def.name ?? key
|
|
3614
3996
|
});
|
|
3997
|
+
} else if (def.$lazy === true && def.$src) {
|
|
3998
|
+
const { $src: src } = def;
|
|
3999
|
+
if (role === "computed") {
|
|
4000
|
+
throw new Error(`Jx: "${key}" declares "$lazy": true but is used as a computed value, not called. A lazily loaded function resolves to a promise; a computed must resolve now. Remove "$lazy", or call ${key}() from a handler instead of binding its value.`);
|
|
4001
|
+
}
|
|
4002
|
+
let loaded;
|
|
4003
|
+
const load = () => loaded ??= importFunctionExport(def, key, src, base);
|
|
4004
|
+
fn = (...args) => load().then((target) => target(...args));
|
|
4005
|
+
Object.defineProperty(fn, "name", {
|
|
4006
|
+
configurable: true,
|
|
4007
|
+
value: def.name ?? key
|
|
4008
|
+
});
|
|
4009
|
+
return fn;
|
|
3615
4010
|
} else {
|
|
3616
|
-
|
|
3617
|
-
if (!src) {
|
|
4011
|
+
if (!def.$src) {
|
|
3618
4012
|
throw new Error(`Jx: '${key}' has neither body nor $src`);
|
|
3619
4013
|
}
|
|
3620
|
-
const
|
|
3621
|
-
|
|
3622
|
-
const seeded = seededModule(src);
|
|
3623
|
-
if (seeded instanceof Promise) {
|
|
3624
|
-
mod = await seeded;
|
|
3625
|
-
} else if (seeded) {
|
|
3626
|
-
mod = seeded;
|
|
3627
|
-
} else {
|
|
3628
|
-
mod = await importSource(src, base);
|
|
3629
|
-
_moduleCache.set(src, mod);
|
|
3630
|
-
}
|
|
3631
|
-
const candidate = mod[exportName] ?? mod.default?.[exportName];
|
|
3632
|
-
if (!isFunction2(candidate)) {
|
|
3633
|
-
throw new TypeError(`Jx: export "${exportName}" not found or not a function in "${src}"`);
|
|
3634
|
-
}
|
|
3635
|
-
fn = candidate;
|
|
4014
|
+
const acquired = acquireModule(def.$src, base);
|
|
4015
|
+
fn = exportedFunction(def, key, def.$src, acquired instanceof Promise ? await acquired : acquired);
|
|
3636
4016
|
}
|
|
3637
4017
|
if (role === "computed") {
|
|
3638
4018
|
return computed(() => fn(state));
|
|
@@ -3653,6 +4033,7 @@ var RESERVED_KEYS = new Set([
|
|
|
3653
4033
|
"$prototype",
|
|
3654
4034
|
"$src",
|
|
3655
4035
|
"$export",
|
|
4036
|
+
"$script",
|
|
3656
4037
|
"$media",
|
|
3657
4038
|
"$map",
|
|
3658
4039
|
"timing",
|
|
@@ -3787,6 +4168,8 @@ function renderNode(def, state, options) {
|
|
|
3787
4168
|
const childOpts = options || childNs ? { ...options, _ns: childNs, _path: [...path, "children", i] } : undefined;
|
|
3788
4169
|
if (isMappedArray(child)) {
|
|
3789
4170
|
renderMappedArrayInto(el, child, localState, childOpts);
|
|
4171
|
+
} else if (isString2(child) && isSingleExpression(child)) {
|
|
4172
|
+
renderTemplatedChild(el, child, localState, childOpts);
|
|
3790
4173
|
} else {
|
|
3791
4174
|
el.append(renderNode(child, localState, childOpts));
|
|
3792
4175
|
}
|
|
@@ -3801,7 +4184,6 @@ function renderNode(def, state, options) {
|
|
|
3801
4184
|
return el;
|
|
3802
4185
|
}
|
|
3803
4186
|
function renderComputedChildren(el, template, state, options) {
|
|
3804
|
-
const path = options._path ?? [];
|
|
3805
4187
|
let live = null;
|
|
3806
4188
|
const retire = () => {
|
|
3807
4189
|
el.replaceChildren();
|
|
@@ -3814,21 +4196,62 @@ function renderComputedChildren(el, template, state, options) {
|
|
|
3814
4196
|
if (!Array.isArray(nodes)) {
|
|
3815
4197
|
return;
|
|
3816
4198
|
}
|
|
3817
|
-
|
|
3818
|
-
live
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
scope.run(() => {
|
|
3822
|
-
for (const [i, child] of nodes.entries()) {
|
|
3823
|
-
el.append(renderNode(child, state, { ...options, _path: [...path, i] }));
|
|
3824
|
-
}
|
|
3825
|
-
});
|
|
3826
|
-
} finally {
|
|
3827
|
-
resetTracking();
|
|
3828
|
-
}
|
|
4199
|
+
live = effectScope(true);
|
|
4200
|
+
drawTemplateNodes(live, nodes, state, options, (node) => {
|
|
4201
|
+
el.append(node);
|
|
4202
|
+
});
|
|
3829
4203
|
}, retire);
|
|
3830
4204
|
onScopeDispose(() => live?.stop(), true);
|
|
3831
4205
|
}
|
|
4206
|
+
function drawTemplateNodes(scope, nodes, state, options, place) {
|
|
4207
|
+
const path = options?._path ?? [];
|
|
4208
|
+
const members = [...nodes];
|
|
4209
|
+
pauseTracking();
|
|
4210
|
+
try {
|
|
4211
|
+
scope.run(() => {
|
|
4212
|
+
for (const [i, child] of members.entries()) {
|
|
4213
|
+
place(renderNode(child, state, options ? { ...options, _path: [...path, i] } : undefined));
|
|
4214
|
+
}
|
|
4215
|
+
});
|
|
4216
|
+
} finally {
|
|
4217
|
+
resetTracking();
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
function renderTemplatedChild(parent, template, state, options) {
|
|
4221
|
+
const anchor = document.createTextNode(template);
|
|
4222
|
+
parent.append(anchor);
|
|
4223
|
+
let live = null;
|
|
4224
|
+
let drawn = [];
|
|
4225
|
+
const retire = () => {
|
|
4226
|
+
for (const node of drawn) {
|
|
4227
|
+
node.remove();
|
|
4228
|
+
}
|
|
4229
|
+
drawn = [];
|
|
4230
|
+
live?.stop();
|
|
4231
|
+
live = null;
|
|
4232
|
+
};
|
|
4233
|
+
bindTemplate(template, () => {
|
|
4234
|
+
const value = evaluateValueTemplate(template, state);
|
|
4235
|
+
retire();
|
|
4236
|
+
if (!Array.isArray(value)) {
|
|
4237
|
+
anchor.textContent = templateText(value);
|
|
4238
|
+
return;
|
|
4239
|
+
}
|
|
4240
|
+
anchor.textContent = "";
|
|
4241
|
+
live = effectScope(true);
|
|
4242
|
+
drawTemplateNodes(live, value, state, options, (node) => {
|
|
4243
|
+
drawn.push(node);
|
|
4244
|
+
anchor.before(node);
|
|
4245
|
+
});
|
|
4246
|
+
}, () => {
|
|
4247
|
+
retire();
|
|
4248
|
+
anchor.textContent = "";
|
|
4249
|
+
});
|
|
4250
|
+
onScopeDispose(() => live?.stop(), true);
|
|
4251
|
+
}
|
|
4252
|
+
function templateText(value) {
|
|
4253
|
+
return `${value}`;
|
|
4254
|
+
}
|
|
3832
4255
|
function applyProperties(el, def, state) {
|
|
3833
4256
|
for (const [key, val] of Object.entries(def)) {
|
|
3834
4257
|
if (RESERVED_KEYS.has(key)) {
|
|
@@ -4202,10 +4625,14 @@ function applyStyleInto(el, styleDef, mediaQueries, state, live) {
|
|
|
4202
4625
|
const scope = effectScope();
|
|
4203
4626
|
scope.run(() => {
|
|
4204
4627
|
for (const { name, value } of sources) {
|
|
4205
|
-
|
|
4206
|
-
const resolved = isRef2(value) ? resolveRef(value.$ref, state) : evaluateTemplate(value, state);
|
|
4628
|
+
const write = (resolved) => {
|
|
4207
4629
|
el.style.setProperty(name, canvasStyleValue(String(resolved ?? "")));
|
|
4208
|
-
}
|
|
4630
|
+
};
|
|
4631
|
+
if (isRef2(value)) {
|
|
4632
|
+
effect(() => write(resolveRef(value.$ref, state)));
|
|
4633
|
+
} else {
|
|
4634
|
+
bindTemplate(value, () => write(evaluateTemplate(value, state)));
|
|
4635
|
+
}
|
|
4209
4636
|
}
|
|
4210
4637
|
});
|
|
4211
4638
|
entry.stop = () => scope.stop();
|
|
@@ -4259,6 +4686,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4259
4686
|
const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef, key: keyRef } = arrayDef;
|
|
4260
4687
|
const keyPointer = isRef2(keyRef) ? keyRef.$ref : null;
|
|
4261
4688
|
const instancePath = _instancePath;
|
|
4689
|
+
const insideStamped = _canvasInsideStampedHost;
|
|
4262
4690
|
let warned = false;
|
|
4263
4691
|
const warnOnce = (message) => {
|
|
4264
4692
|
if (!warned) {
|
|
@@ -4280,7 +4708,9 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4280
4708
|
const scope = effectScope(true);
|
|
4281
4709
|
const childOpts = options ? { ...options, _path: [...path, "map", index] } : undefined;
|
|
4282
4710
|
const node = scope.run(() => renderNode(mapDef, child, childOpts));
|
|
4283
|
-
|
|
4711
|
+
const row = { key, map, node, scope };
|
|
4712
|
+
listRows.set(node, row);
|
|
4713
|
+
return row;
|
|
4284
4714
|
};
|
|
4285
4715
|
const reconcile = (list, keys) => {
|
|
4286
4716
|
const previous = new Map;
|
|
@@ -4335,8 +4765,17 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4335
4765
|
items = [...unsorted].toSorted(compare);
|
|
4336
4766
|
}
|
|
4337
4767
|
}
|
|
4338
|
-
|
|
4339
|
-
const
|
|
4768
|
+
let list = Array.isArray(items) && mapDef ? items : [];
|
|
4769
|
+
const count = list.length;
|
|
4770
|
+
const placeholder = count === 0 && mapDef ? options?.emptyRow?.(arrayDef, path) : undefined;
|
|
4771
|
+
if (placeholder !== undefined) {
|
|
4772
|
+
list = [placeholder];
|
|
4773
|
+
}
|
|
4774
|
+
const limit = options?.rowLimit;
|
|
4775
|
+
if (isNumber(limit) && limit >= 0 && list.length > limit) {
|
|
4776
|
+
list = list.slice(0, Math.floor(limit));
|
|
4777
|
+
}
|
|
4778
|
+
const keys = placeholder === undefined ? list.map((item, index) => mappedRowKey(keyPointer, item, index, warnOnce)) : list.map(() => EMPTY_ROW_KEY);
|
|
4340
4779
|
const seen = new Set;
|
|
4341
4780
|
for (let i = 0;i < keys.length; i++) {
|
|
4342
4781
|
if (seen.has(keys[i])) {
|
|
@@ -4348,7 +4787,13 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4348
4787
|
}
|
|
4349
4788
|
pauseTracking();
|
|
4350
4789
|
try {
|
|
4351
|
-
underInstancePath(reexpand(instancePath), () => reconcile(list, keys));
|
|
4790
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => reconcile(list, keys)));
|
|
4791
|
+
options?.onListReconciled?.(path, {
|
|
4792
|
+
count,
|
|
4793
|
+
empty: count === 0,
|
|
4794
|
+
nodes: rows.map((row) => row.node),
|
|
4795
|
+
rendered: rows.length
|
|
4796
|
+
});
|
|
4352
4797
|
} finally {
|
|
4353
4798
|
resetTracking();
|
|
4354
4799
|
}
|
|
@@ -4357,6 +4802,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4357
4802
|
let stopped = false;
|
|
4358
4803
|
const runner = effect(update, {
|
|
4359
4804
|
scheduler: () => {
|
|
4805
|
+
_listRedraws += 1;
|
|
4360
4806
|
if (queued) {
|
|
4361
4807
|
return;
|
|
4362
4808
|
}
|
|
@@ -4377,6 +4823,21 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
4377
4823
|
rows = [];
|
|
4378
4824
|
}, true);
|
|
4379
4825
|
}
|
|
4826
|
+
var EMPTY_ROW_KEY = Object.freeze({ emptyRow: true });
|
|
4827
|
+
var listRows = new WeakMap;
|
|
4828
|
+
function replaceListRow(current, next, stop) {
|
|
4829
|
+
const row = listRows.get(current);
|
|
4830
|
+
if (!row || row.node !== current) {
|
|
4831
|
+
return false;
|
|
4832
|
+
}
|
|
4833
|
+
row.node.replaceWith(next);
|
|
4834
|
+
row.scope.stop();
|
|
4835
|
+
listRows.delete(current);
|
|
4836
|
+
row.node = next;
|
|
4837
|
+
row.scope = { stop: () => stop?.() };
|
|
4838
|
+
listRows.set(next, row);
|
|
4839
|
+
return true;
|
|
4840
|
+
}
|
|
4380
4841
|
function mappedRowKey(pointer, item, index, warnOnce) {
|
|
4381
4842
|
if (pointer === null) {
|
|
4382
4843
|
return index;
|
|
@@ -4413,6 +4874,7 @@ function renderSwitch(def, state, options) {
|
|
|
4413
4874
|
const path = options?._path ?? [];
|
|
4414
4875
|
const container = document.createElement(resolveTagName(def.tagName, state));
|
|
4415
4876
|
const instancePath = _instancePath;
|
|
4877
|
+
const insideStamped = _canvasInsideStampedHost;
|
|
4416
4878
|
if (options?.onNodeCreated) {
|
|
4417
4879
|
options.onNodeCreated(container, path, def, state);
|
|
4418
4880
|
}
|
|
@@ -4455,18 +4917,18 @@ function renderSwitch(def, state, options) {
|
|
|
4455
4917
|
if (gen !== generation) {
|
|
4456
4918
|
return;
|
|
4457
4919
|
}
|
|
4458
|
-
const childScope = await buildScope(doc, {}, href, options?._ctx);
|
|
4920
|
+
const childScope = await buildScope(withProjectFormulas(doc), {}, href, options?._ctx);
|
|
4459
4921
|
if (gen !== generation) {
|
|
4460
4922
|
return;
|
|
4461
4923
|
}
|
|
4462
4924
|
container.replaceChildren();
|
|
4463
|
-
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(doc, childScope, childOpts))));
|
|
4925
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => scope.run(() => container.append(renderNode(doc, childScope, childOpts)))));
|
|
4464
4926
|
}).catch((error) => console.error("Jx $switch: failed to load external case", caseDef.$ref, error));
|
|
4465
4927
|
return;
|
|
4466
4928
|
}
|
|
4467
4929
|
pauseTracking();
|
|
4468
4930
|
try {
|
|
4469
|
-
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(caseDef, state, childOpts))));
|
|
4931
|
+
underInstancePath(reexpand(instancePath), () => insideStampedHost(insideStamped, () => scope.run(() => container.append(renderNode(caseDef, state, childOpts)))));
|
|
4470
4932
|
} finally {
|
|
4471
4933
|
resetTracking();
|
|
4472
4934
|
}
|
|
@@ -4502,18 +4964,46 @@ async function resolvePrototype(def, state, key, base, ctx) {
|
|
|
4502
4964
|
clearTimeout(debounceTimer);
|
|
4503
4965
|
}
|
|
4504
4966
|
});
|
|
4967
|
+
const request = (signal) => fetch(url, {
|
|
4968
|
+
method: def.method ?? "GET",
|
|
4969
|
+
...signal && { signal },
|
|
4970
|
+
...def.headers && { headers: def.headers },
|
|
4971
|
+
...def.body && {
|
|
4972
|
+
body: isNonNullObject(def.body) ? JSON.stringify(def.body) : def.body
|
|
4973
|
+
}
|
|
4974
|
+
}).then((r) => r.ok ? r.json() : Promise.reject(r.statusText));
|
|
4505
4975
|
const doFetch = () => {
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4976
|
+
const handler = _remoteLookupHandler;
|
|
4977
|
+
let lookup;
|
|
4978
|
+
if (handler) {
|
|
4979
|
+
const answer = handler({
|
|
4980
|
+
key,
|
|
4981
|
+
kind: "request",
|
|
4982
|
+
request: {
|
|
4983
|
+
method: def.method ?? "GET",
|
|
4984
|
+
url,
|
|
4985
|
+
...def.headers && { headers: def.headers },
|
|
4986
|
+
...def.body !== undefined && { body: def.body }
|
|
4987
|
+
},
|
|
4988
|
+
scope: state
|
|
4989
|
+
}, () => request());
|
|
4990
|
+
if (answer === null) {
|
|
4991
|
+
return;
|
|
4992
|
+
}
|
|
4993
|
+
if (!(answer instanceof Promise)) {
|
|
4994
|
+
s.value = answer.value;
|
|
4995
|
+
return;
|
|
4996
|
+
}
|
|
4997
|
+
lookup = answer;
|
|
4998
|
+
} else {
|
|
4999
|
+
lookup = request(controller.signal);
|
|
5000
|
+
}
|
|
5001
|
+
holdTemplateErrorsFor(lookup.then((d) => {
|
|
5002
|
+
if (!controller.signal.aborted) {
|
|
5003
|
+
s.value = d;
|
|
4512
5004
|
}
|
|
4513
|
-
}).then((r) => r.ok ? r.json() : Promise.reject(r.statusText)).then((d) => {
|
|
4514
|
-
s.value = d;
|
|
4515
5005
|
}).catch((error) => {
|
|
4516
|
-
if (!(error instanceof Error && error.name === "AbortError")) {
|
|
5006
|
+
if (!controller.signal.aborted && !(error instanceof Error && error.name === "AbortError")) {
|
|
4517
5007
|
s.value = { error: String(error) };
|
|
4518
5008
|
}
|
|
4519
5009
|
}));
|
|
@@ -4864,24 +5354,46 @@ async function resolveViaDevProxy(def, state, key, base) {
|
|
|
4864
5354
|
}
|
|
4865
5355
|
return s;
|
|
4866
5356
|
}
|
|
4867
|
-
function latestServerCall(s, invoke, label) {
|
|
5357
|
+
function latestServerCall(s, invoke, label, describe) {
|
|
4868
5358
|
let seq = 0;
|
|
4869
5359
|
return (args) => {
|
|
4870
5360
|
seq += 1;
|
|
4871
5361
|
const n = seq;
|
|
4872
|
-
|
|
5362
|
+
const run = () => new Promise((settle) => {
|
|
4873
5363
|
settle(invoke(args));
|
|
4874
|
-
})
|
|
5364
|
+
});
|
|
5365
|
+
const answer = _remoteLookupHandler ? _remoteLookupHandler(describe(args), run) : run();
|
|
5366
|
+
if (answer === null) {
|
|
5367
|
+
return;
|
|
5368
|
+
}
|
|
5369
|
+
if (!(answer instanceof Promise)) {
|
|
5370
|
+
s.value = answer.value;
|
|
5371
|
+
return;
|
|
5372
|
+
}
|
|
5373
|
+
holdTemplateErrorsFor(answer.then((result) => {
|
|
4875
5374
|
if (n === seq) {
|
|
4876
5375
|
s.value = result;
|
|
4877
5376
|
}
|
|
4878
5377
|
}).catch((error) => {
|
|
4879
|
-
if (n === seq) {
|
|
5378
|
+
if (n === seq && !(error instanceof Error && error.name === "AbortError")) {
|
|
4880
5379
|
console.error(label, error);
|
|
4881
5380
|
}
|
|
4882
5381
|
}));
|
|
4883
5382
|
};
|
|
4884
5383
|
}
|
|
5384
|
+
function serverLookup(def, state, key, args, base) {
|
|
5385
|
+
return {
|
|
5386
|
+
key,
|
|
5387
|
+
kind: "server",
|
|
5388
|
+
request: {
|
|
5389
|
+
$export: def.$export,
|
|
5390
|
+
$src: def.$src,
|
|
5391
|
+
arguments: args,
|
|
5392
|
+
...base !== undefined && { $base: base }
|
|
5393
|
+
},
|
|
5394
|
+
scope: state
|
|
5395
|
+
};
|
|
5396
|
+
}
|
|
4885
5397
|
async function resolveServerFunction(def, state, key, base) {
|
|
4886
5398
|
const src = def.$src;
|
|
4887
5399
|
const exportName = def.$export;
|
|
@@ -4909,7 +5421,7 @@ async function resolveServerFunction(def, state, key, base) {
|
|
|
4909
5421
|
};
|
|
4910
5422
|
const s = ref(null);
|
|
4911
5423
|
if (hasReactiveArg) {
|
|
4912
|
-
const call = latestServerCall(s, fn, "Jx server function:");
|
|
5424
|
+
const call = latestServerCall(s, fn, "Jx server function:", (args) => serverLookup(def, state, key, args, base));
|
|
4913
5425
|
effect(() => {
|
|
4914
5426
|
const args = resolveArgs();
|
|
4915
5427
|
onEffectCleanup(() => {});
|
|
@@ -4946,7 +5458,7 @@ async function resolveServerFunctionViaProxy(def, state, key, base) {
|
|
|
4946
5458
|
return r.json();
|
|
4947
5459
|
});
|
|
4948
5460
|
const s = ref(null);
|
|
4949
|
-
const call = latestServerCall(s, doResolve, "Jx server proxy:");
|
|
5461
|
+
const call = latestServerCall(s, doResolve, "Jx server proxy:", (args) => serverLookup(def, state, key, args, base));
|
|
4950
5462
|
if (hasReactiveArg) {
|
|
4951
5463
|
effect(() => {
|
|
4952
5464
|
const args = resolveArgs();
|
|
@@ -4988,6 +5500,9 @@ function isSignal(v) {
|
|
|
4988
5500
|
}
|
|
4989
5501
|
function absorbAttribute(state, name, value, defaults) {
|
|
4990
5502
|
const camelKey = name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
5503
|
+
if (defaults?.has(camelKey) && defaults.get(camelKey) === undefined) {
|
|
5504
|
+
return;
|
|
5505
|
+
}
|
|
4991
5506
|
const current = state[camelKey];
|
|
4992
5507
|
if (isBoolean(current)) {
|
|
4993
5508
|
state[camelKey] = value !== null && value !== "false";
|
|
@@ -5003,12 +5518,20 @@ function absorbAttribute(state, name, value, defaults) {
|
|
|
5003
5518
|
function declaredDefaults(def) {
|
|
5004
5519
|
const out = new Map;
|
|
5005
5520
|
for (const [key, entry] of Object.entries(def.state ?? {})) {
|
|
5006
|
-
if (
|
|
5521
|
+
if (isString2(entry) && isTemplateString(entry)) {
|
|
5522
|
+
out.set(key, undefined);
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5525
|
+
if (isNonNullObject(entry) && !Array.isArray(entry)) {
|
|
5007
5526
|
if ("default" in entry) {
|
|
5008
5527
|
out.set(key, entry.default);
|
|
5009
5528
|
continue;
|
|
5010
5529
|
}
|
|
5011
5530
|
if (COMPUTED_STATE_KEYS.some((marker) => (marker in entry))) {
|
|
5531
|
+
out.set(key, undefined);
|
|
5532
|
+
continue;
|
|
5533
|
+
}
|
|
5534
|
+
if (hasSchemaKeywords(entry)) {
|
|
5012
5535
|
continue;
|
|
5013
5536
|
}
|
|
5014
5537
|
}
|
|
@@ -5089,6 +5612,23 @@ async function redefineElement(doc, baseUrl) {
|
|
|
5089
5612
|
}
|
|
5090
5613
|
_elementDefs.set(tagName, { base, doc });
|
|
5091
5614
|
}
|
|
5615
|
+
var _projectFormulas = {};
|
|
5616
|
+
var _withFormulas = new WeakMap;
|
|
5617
|
+
function setProjectFormulas(projectState) {
|
|
5618
|
+
_projectFormulas = inheritableFormulas(projectState);
|
|
5619
|
+
_withFormulas = new WeakMap;
|
|
5620
|
+
}
|
|
5621
|
+
function withProjectFormulas(doc) {
|
|
5622
|
+
const cached = _withFormulas.get(doc);
|
|
5623
|
+
if (cached) {
|
|
5624
|
+
return cached;
|
|
5625
|
+
}
|
|
5626
|
+
const own = doc.state ?? {};
|
|
5627
|
+
const added = Object.entries(_projectFormulas).filter(([key]) => !(key in own));
|
|
5628
|
+
const merged = added.length > 0 ? { ...doc, state: { ...Object.fromEntries(added), ...own } } : doc;
|
|
5629
|
+
_withFormulas.set(doc, merged);
|
|
5630
|
+
return merged;
|
|
5631
|
+
}
|
|
5092
5632
|
function setRootMedia(map) {
|
|
5093
5633
|
_rootMedia = map ?? {};
|
|
5094
5634
|
}
|
|
@@ -5235,7 +5775,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5235
5775
|
_definedSources.add(base);
|
|
5236
5776
|
source_ = await resolve(source);
|
|
5237
5777
|
} else {
|
|
5238
|
-
source_ = source;
|
|
5778
|
+
source_ = inlineDocument(source, new URL(base ?? location.href, location.href).href);
|
|
5239
5779
|
}
|
|
5240
5780
|
base ??= location.href;
|
|
5241
5781
|
const { tagName } = source_;
|
|
@@ -5252,6 +5792,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5252
5792
|
const initialDef = source_;
|
|
5253
5793
|
const initialBase = base;
|
|
5254
5794
|
const observedAttrs = initialDef.observedAttributes ?? [];
|
|
5795
|
+
_observedAttributes.set(tagName, observedAttrs);
|
|
5255
5796
|
const ElementClass = class extends HTMLElement {
|
|
5256
5797
|
_jxInitialized = false;
|
|
5257
5798
|
_state = null;
|
|
@@ -5269,12 +5810,14 @@ async function defineElement(source, baseUrl) {
|
|
|
5269
5810
|
const enclosingPath = _instancePath;
|
|
5270
5811
|
const supplied = {};
|
|
5271
5812
|
const live = _elementDefs.get(tagName) ?? { base: initialBase, doc: initialDef };
|
|
5272
|
-
|
|
5813
|
+
_connectedDefs.set(this, live.doc);
|
|
5814
|
+
const def = withProjectFormulas(live.doc);
|
|
5273
5815
|
const defBase = live.base;
|
|
5274
5816
|
const state = await buildScope(def, {}, defBase, { base: defBase, media: null, root: this });
|
|
5817
|
+
const connectDefaults = declaredDefaults(def);
|
|
5275
5818
|
for (const attr of observedAttrs) {
|
|
5276
5819
|
if (this.hasAttribute(attr)) {
|
|
5277
|
-
absorbAttribute(state, attr, this.getAttribute(attr));
|
|
5820
|
+
absorbAttribute(state, attr, this.getAttribute(attr), connectDefaults);
|
|
5278
5821
|
supplied[attr] = this.getAttribute(attr);
|
|
5279
5822
|
}
|
|
5280
5823
|
}
|
|
@@ -5326,10 +5869,14 @@ async function defineElement(source, baseUrl) {
|
|
|
5326
5869
|
reportUnrendered(this, tagName, error instanceof Error ? error : new Error(String(error)));
|
|
5327
5870
|
return;
|
|
5328
5871
|
}
|
|
5872
|
+
const declared = live.doc.state ?? {};
|
|
5329
5873
|
for (const key of Object.keys(def.state ?? {})) {
|
|
5330
5874
|
if (isPrivateStateKey(key)) {
|
|
5331
5875
|
continue;
|
|
5332
5876
|
}
|
|
5877
|
+
if (!(key in declared) && !(key in supplied)) {
|
|
5878
|
+
continue;
|
|
5879
|
+
}
|
|
5333
5880
|
const native = nativeSetter(this, key);
|
|
5334
5881
|
Object.defineProperty(this, key, {
|
|
5335
5882
|
configurable: true,
|
|
@@ -5355,7 +5902,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5355
5902
|
const children = Array.isArray(def.children) ? def.children : [];
|
|
5356
5903
|
const draw = () => {
|
|
5357
5904
|
const wasInside = _canvasInsideStampedHost;
|
|
5358
|
-
_canvasInsideStampedHost ||= this
|
|
5905
|
+
_canvasInsideStampedHost ||= carriesCanvasStamp(this);
|
|
5359
5906
|
let failure = null;
|
|
5360
5907
|
try {
|
|
5361
5908
|
underInstancePath(ownPath, () => {
|
|
@@ -5384,7 +5931,7 @@ async function defineElement(source, baseUrl) {
|
|
|
5384
5931
|
return;
|
|
5385
5932
|
}
|
|
5386
5933
|
reportUnrendered(this, tagName, failure);
|
|
5387
|
-
const inputs =
|
|
5934
|
+
const inputs = Object.keys(def.state ?? {}).filter((key) => !isPrivateStateKey(key) && !(connectDefaults.has(key) && connectDefaults.get(key) === undefined));
|
|
5388
5935
|
let lastMessage = failure.message;
|
|
5389
5936
|
let queued = false;
|
|
5390
5937
|
const watch = effect(() => {
|
|
@@ -5445,6 +5992,195 @@ async function defineElement(source, baseUrl) {
|
|
|
5445
5992
|
};
|
|
5446
5993
|
customElements.define(tagName, ElementClass);
|
|
5447
5994
|
}
|
|
5995
|
+
function writeInstanceProp(el, key, resolved) {
|
|
5996
|
+
const value = isString2(resolved) ? canvasAssetValue(el.tagName, key, resolved) : resolved;
|
|
5997
|
+
elementProperties(el)[key] = value;
|
|
5998
|
+
const instanceState = instanceStateOf(el);
|
|
5999
|
+
if (instanceState && key in HTMLElement.prototype && Object.hasOwn(toRaw(instanceState), key)) {
|
|
6000
|
+
instanceState[key] = value;
|
|
6001
|
+
}
|
|
6002
|
+
}
|
|
6003
|
+
var _observedAttributes = new Map;
|
|
6004
|
+
var _connectedDefs = new WeakMap;
|
|
6005
|
+
function drawnByCurrent(el) {
|
|
6006
|
+
const drawn = _connectedDefs.get(el);
|
|
6007
|
+
return drawn !== undefined && drawn === _elementDefs.get(el.localName)?.doc;
|
|
6008
|
+
}
|
|
6009
|
+
function producedElsewhere(entry) {
|
|
6010
|
+
if (!isJsonObject(entry)) {
|
|
6011
|
+
return false;
|
|
6012
|
+
}
|
|
6013
|
+
const { $prototype: prototype } = entry;
|
|
6014
|
+
if (prototype !== undefined) {
|
|
6015
|
+
return prototype !== "Function";
|
|
6016
|
+
}
|
|
6017
|
+
return "$src" in entry || "timing" in entry;
|
|
6018
|
+
}
|
|
6019
|
+
function isScalarProp(value) {
|
|
6020
|
+
return isString2(value) && !isTemplateString(value) || isNumber(value) || isBoolean(value);
|
|
6021
|
+
}
|
|
6022
|
+
var VERBATIM_PROPS = new Set(["id", "lang", "role", "slot", "title"]);
|
|
6023
|
+
function isBoundProp(value) {
|
|
6024
|
+
return isRef2(value) || isTemplateString(value);
|
|
6025
|
+
}
|
|
6026
|
+
function rendersOnce(def, drawing = new Set) {
|
|
6027
|
+
const declared = def.state ?? {};
|
|
6028
|
+
if ("onMount" in declared || Object.values(declared).some((entry) => producedElsewhere(entry))) {
|
|
6029
|
+
return true;
|
|
6030
|
+
}
|
|
6031
|
+
drawing.add(def);
|
|
6032
|
+
const walk = (value, isRoot, redrawn) => {
|
|
6033
|
+
if (Array.isArray(value)) {
|
|
6034
|
+
return value.some((item) => walk(item, false, redrawn));
|
|
6035
|
+
}
|
|
6036
|
+
if (!isNonNullObject(value)) {
|
|
6037
|
+
return false;
|
|
6038
|
+
}
|
|
6039
|
+
const node = Object.fromEntries(Object.entries(value));
|
|
6040
|
+
const { attributes, tagName } = node;
|
|
6041
|
+
if (tagName !== undefined && !isString2(tagName)) {
|
|
6042
|
+
return true;
|
|
6043
|
+
}
|
|
6044
|
+
const attrs = isJsonObject(attributes) ? attributes : {};
|
|
6045
|
+
if (tagName === "slot" && (redrawn || isBoundProp(attrs.name) || isBoundProp(node.name) || isBoundProp(node.textContent) || node.$switch !== undefined)) {
|
|
6046
|
+
return true;
|
|
6047
|
+
}
|
|
6048
|
+
if (isBoundProp(node.innerHTML) || !isRoot && isBoundProp(node.children)) {
|
|
6049
|
+
return true;
|
|
6050
|
+
}
|
|
6051
|
+
const isInstance = !isRoot && isString2(tagName) && tagName.includes("-");
|
|
6052
|
+
const inner = isInstance ? _elementDefs.get(tagName)?.doc : undefined;
|
|
6053
|
+
if (isInstance && handsOverOnce(node, attrs, inner)) {
|
|
6054
|
+
return true;
|
|
6055
|
+
}
|
|
6056
|
+
if (inner && (drawing.has(inner) || rendersOnce(inner, drawing))) {
|
|
6057
|
+
return true;
|
|
6058
|
+
}
|
|
6059
|
+
for (const [key, entry] of Object.entries(node)) {
|
|
6060
|
+
if (isRoot && (key === "state" || key === "$props")) {
|
|
6061
|
+
continue;
|
|
6062
|
+
}
|
|
6063
|
+
if (key === "$props") {
|
|
6064
|
+
if (!isInstance && isJsonObject(entry) && Object.values(entry).some((v) => isRef2(v))) {
|
|
6065
|
+
return true;
|
|
6066
|
+
}
|
|
6067
|
+
continue;
|
|
6068
|
+
}
|
|
6069
|
+
if ((key === "id" || key.startsWith("$") && !RESERVED_KEYS.has(key)) && isRef2(entry)) {
|
|
6070
|
+
return true;
|
|
6071
|
+
}
|
|
6072
|
+
const drawn = key === "cases" && isJsonObject(entry) ? Object.values(entry) : entry;
|
|
6073
|
+
if (walk(drawn, false, redrawn || key === "cases" || key === "map")) {
|
|
6074
|
+
return true;
|
|
6075
|
+
}
|
|
6076
|
+
}
|
|
6077
|
+
return false;
|
|
6078
|
+
};
|
|
6079
|
+
const answer = walk(def, true, false);
|
|
6080
|
+
drawing.delete(def);
|
|
6081
|
+
return answer;
|
|
6082
|
+
}
|
|
6083
|
+
function handsOverOnce(node, attrs, inner) {
|
|
6084
|
+
if (isBoundProp(node.textContent)) {
|
|
6085
|
+
return true;
|
|
6086
|
+
}
|
|
6087
|
+
const kids = Array.isArray(node.children) ? node.children : [];
|
|
6088
|
+
if (kids.some((kid) => isBoundProp(kid) || isMappedArray(kid) || isJsonObject(kid) && (isBoundProp(kid.slot) || isJsonObject(kid.attributes) && isBoundProp(kid.attributes.slot)))) {
|
|
6089
|
+
return true;
|
|
6090
|
+
}
|
|
6091
|
+
const coerced = (given) => Object.entries(given).some(([key, value]) => isBoundProp(value) && (key in HTMLElement.prototype) && key !== "textContent");
|
|
6092
|
+
if (coerced(node) || isJsonObject(node.$props) && coerced(node.$props)) {
|
|
6093
|
+
return true;
|
|
6094
|
+
}
|
|
6095
|
+
const observed = isString2(node.tagName) ? _observedAttributes.get(node.tagName) ?? [] : [];
|
|
6096
|
+
return Object.entries(attrs).some(([name, given]) => {
|
|
6097
|
+
if (!isBoundProp(given)) {
|
|
6098
|
+
return false;
|
|
6099
|
+
}
|
|
6100
|
+
if (name.startsWith("props.")) {
|
|
6101
|
+
return true;
|
|
6102
|
+
}
|
|
6103
|
+
const prop = name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
6104
|
+
return !inner || prop in (inner.state ?? {}) && !observed.includes(name);
|
|
6105
|
+
});
|
|
6106
|
+
}
|
|
6107
|
+
function mountedFromProps(host, state) {
|
|
6108
|
+
if (isScopeHook(state.onMount) || !drawnByCurrent(host)) {
|
|
6109
|
+
return true;
|
|
6110
|
+
}
|
|
6111
|
+
for (const inner of host.querySelectorAll("*")) {
|
|
6112
|
+
const innerState = instanceStateOf(inner);
|
|
6113
|
+
if (!innerState || !isScopeHook(innerState.onMount) && drawnByCurrent(inner)) {
|
|
6114
|
+
continue;
|
|
6115
|
+
}
|
|
6116
|
+
let owner = inner;
|
|
6117
|
+
while (owner && owner !== host && owner.dataset.jxPath === undefined) {
|
|
6118
|
+
owner = owner.parentElement;
|
|
6119
|
+
}
|
|
6120
|
+
if (owner === host) {
|
|
6121
|
+
return true;
|
|
6122
|
+
}
|
|
6123
|
+
}
|
|
6124
|
+
return false;
|
|
6125
|
+
}
|
|
6126
|
+
function updateInstanceProps(el, before, after) {
|
|
6127
|
+
const state = instanceStateOf(el);
|
|
6128
|
+
const registered = _elementDefs.get(el.localName)?.doc;
|
|
6129
|
+
if (!state || !registered) {
|
|
6130
|
+
return false;
|
|
6131
|
+
}
|
|
6132
|
+
const def = withProjectFormulas(registered);
|
|
6133
|
+
const defaults = declaredDefaults(def);
|
|
6134
|
+
const declared = def.state ?? {};
|
|
6135
|
+
const observed = _observedAttributes.get(el.localName) ?? [];
|
|
6136
|
+
const writes = [];
|
|
6137
|
+
for (const key of new Set([...Object.keys(before ?? {}), ...Object.keys(after ?? {})])) {
|
|
6138
|
+
const was = before?.[key];
|
|
6139
|
+
const now = after?.[key];
|
|
6140
|
+
if (isPrivateStateKey(key) || JSON.stringify(was) === JSON.stringify(now)) {
|
|
6141
|
+
continue;
|
|
6142
|
+
}
|
|
6143
|
+
if (was !== undefined && !isScalarProp(was) || now !== undefined && !isScalarProp(now) || producedElsewhere(declared[key]) || key in declared && !isScalarProp(toRaw(state)[key]) || key === "_state" || key === "_jxInitialized") {
|
|
6144
|
+
return false;
|
|
6145
|
+
}
|
|
6146
|
+
if (key in HTMLElement.prototype && !(VERBATIM_PROPS.has(key) && (key in declared) && isString2(now))) {
|
|
6147
|
+
return false;
|
|
6148
|
+
}
|
|
6149
|
+
if (now !== undefined) {
|
|
6150
|
+
writes.push(() => {
|
|
6151
|
+
writeInstanceProp(el, key, now);
|
|
6152
|
+
});
|
|
6153
|
+
continue;
|
|
6154
|
+
}
|
|
6155
|
+
if (!(key in declared)) {
|
|
6156
|
+
writes.push(() => {
|
|
6157
|
+
Reflect.deleteProperty(el, key);
|
|
6158
|
+
});
|
|
6159
|
+
continue;
|
|
6160
|
+
}
|
|
6161
|
+
const fallback = defaults.get(key);
|
|
6162
|
+
const attribute = key.replaceAll(/[A-Z]/gu, (c) => `-${c.toLowerCase()}`);
|
|
6163
|
+
if (!isScalarProp(fallback) || observed.includes(attribute) && el.hasAttribute(attribute)) {
|
|
6164
|
+
return false;
|
|
6165
|
+
}
|
|
6166
|
+
writes.push(() => {
|
|
6167
|
+
state[key] = fallback;
|
|
6168
|
+
});
|
|
6169
|
+
}
|
|
6170
|
+
if (writes.length === 0 || mountedFromProps(el, state) || rendersOnce(def)) {
|
|
6171
|
+
return false;
|
|
6172
|
+
}
|
|
6173
|
+
const thrown = _templateThrows;
|
|
6174
|
+
const redraws = _listRedraws;
|
|
6175
|
+
try {
|
|
6176
|
+
for (const write of writes) {
|
|
6177
|
+
write();
|
|
6178
|
+
}
|
|
6179
|
+
} catch {
|
|
6180
|
+
return false;
|
|
6181
|
+
}
|
|
6182
|
+
return _templateThrows === thrown && _listRedraws === redraws;
|
|
6183
|
+
}
|
|
5448
6184
|
function renderCustomElementWithProps(def, state, options, path) {
|
|
5449
6185
|
const el = document.createElement(resolveTagName(def.tagName, state));
|
|
5450
6186
|
if (options?.onNodeCreated) {
|
|
@@ -5455,12 +6191,7 @@ function renderCustomElementWithProps(def, state, options, path) {
|
|
|
5455
6191
|
continue;
|
|
5456
6192
|
}
|
|
5457
6193
|
const write = (resolved) => {
|
|
5458
|
-
|
|
5459
|
-
elementProperties(el)[key] = value;
|
|
5460
|
-
const instanceState = instanceStateOf(el);
|
|
5461
|
-
if (instanceState && key in HTMLElement.prototype && Object.hasOwn(toRaw(instanceState), key)) {
|
|
5462
|
-
instanceState[key] = value;
|
|
5463
|
-
}
|
|
6194
|
+
writeInstanceProp(el, key, resolved);
|
|
5464
6195
|
};
|
|
5465
6196
|
if (isRef2(val)) {
|
|
5466
6197
|
const refVal = val;
|
|
@@ -5488,6 +6219,8 @@ function renderCustomElementWithProps(def, state, options, path) {
|
|
|
5488
6219
|
const childOpts = options && path ? { ...options, _path: [...path, "children", i] } : undefined;
|
|
5489
6220
|
if (isMappedArray(child)) {
|
|
5490
6221
|
renderMappedArrayInto(el, child, state, childOpts);
|
|
6222
|
+
} else if (isString2(child) && isSingleExpression(child)) {
|
|
6223
|
+
renderTemplatedChild(el, child, state, childOpts);
|
|
5491
6224
|
} else {
|
|
5492
6225
|
el.append(renderNode(child, state, childOpts));
|
|
5493
6226
|
}
|
|
@@ -5595,6 +6328,7 @@ export {
|
|
|
5595
6328
|
SLOT_WHITESPACE,
|
|
5596
6329
|
SUPPORTED_SCHEMA_VERSION,
|
|
5597
6330
|
_resetPrivatePropWarnings,
|
|
6331
|
+
absorbAttribute,
|
|
5598
6332
|
applyStyle,
|
|
5599
6333
|
bodyNeedsEraser,
|
|
5600
6334
|
booleanAttrValue,
|
|
@@ -5603,15 +6337,19 @@ export {
|
|
|
5603
6337
|
camelToKebab,
|
|
5604
6338
|
canvasStyleValue,
|
|
5605
6339
|
captureSlotted,
|
|
6340
|
+
commentedRuleText,
|
|
5606
6341
|
cssPropertyName,
|
|
5607
6342
|
cssRuleText,
|
|
6343
|
+
declaredDefaults,
|
|
5608
6344
|
defineElement,
|
|
5609
6345
|
distributeSlots,
|
|
5610
6346
|
documentStyleText,
|
|
5611
6347
|
elementDefinition,
|
|
5612
6348
|
enumeratedAttrNames,
|
|
6349
|
+
evaluateTemplateValue,
|
|
5613
6350
|
hasSchemaKeywords,
|
|
5614
6351
|
hashCss,
|
|
6352
|
+
instanceSupplies,
|
|
5615
6353
|
isDeclarationAtRule,
|
|
5616
6354
|
isKeyframesAtRule,
|
|
5617
6355
|
isNestedSelectorKey,
|
|
@@ -5628,6 +6366,7 @@ export {
|
|
|
5628
6366
|
redefineElement,
|
|
5629
6367
|
releaseElementStyles,
|
|
5630
6368
|
renderNode,
|
|
6369
|
+
replaceListRow,
|
|
5631
6370
|
resetDocumentStyles,
|
|
5632
6371
|
resolve,
|
|
5633
6372
|
resolveAtQuery,
|
|
@@ -5645,7 +6384,10 @@ export {
|
|
|
5645
6384
|
setCanvasDelinkPopovers,
|
|
5646
6385
|
setCanvasViewportTranspose,
|
|
5647
6386
|
setDocumentParser,
|
|
6387
|
+
setModuleLoader,
|
|
5648
6388
|
setNpmModuleResolver,
|
|
6389
|
+
setProjectFormulas,
|
|
6390
|
+
setRemoteLookupHandler,
|
|
5649
6391
|
setResolveToken,
|
|
5650
6392
|
setRootMedia,
|
|
5651
6393
|
setSkipAutoRequests,
|
|
@@ -5657,8 +6399,9 @@ export {
|
|
|
5657
6399
|
toCSSText,
|
|
5658
6400
|
transposeCanvasOverlaySelector,
|
|
5659
6401
|
transposeCanvasPopoverSelector,
|
|
5660
|
-
transposeCanvasUnits
|
|
6402
|
+
transposeCanvasUnits,
|
|
6403
|
+
updateInstanceProps
|
|
5661
6404
|
};
|
|
5662
6405
|
|
|
5663
|
-
//# debugId=
|
|
6406
|
+
//# debugId=00BEC97E8AE119E064756E2164756E21
|
|
5664
6407
|
//# sourceMappingURL=runtime.js.map
|