@wildwinter/expr-editor 0.14.1 → 0.15.1
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/index.cjs +61 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +60 -10
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -98,6 +98,7 @@ var normaliseRef = (ref, defaultScope) => {
|
|
|
98
98
|
const prefix = `@${defaultScope.toLowerCase()}.`;
|
|
99
99
|
return low.startsWith(prefix) ? `@${low.slice(prefix.length)}` : low;
|
|
100
100
|
};
|
|
101
|
+
var flagChangeSrc = (targetRef, sign, flag) => `set_flags(${targetRef}, ${sign}${flag})`;
|
|
101
102
|
function advancedRef(node, defaultScope) {
|
|
102
103
|
if (node.kind !== "call" || node.name !== "advance" || node.args.length !== 1) return null;
|
|
103
104
|
const arg = node.args[0];
|
|
@@ -296,6 +297,7 @@ var propertyTip = (e) => {
|
|
|
296
297
|
return lines.length ? lines.join("\n") : void 0;
|
|
297
298
|
};
|
|
298
299
|
var refOf = (e, defaultScope) => e.scope === defaultScope ? `@${e.name}` : `@${e.scope}.${e.name}`;
|
|
300
|
+
var targetRefOf = (e) => `@${e.scope}.${e.name}`;
|
|
299
301
|
var displayName = (e, defaultScope) => e.scope === defaultScope ? e.name : `${e.scope}.${e.name}`;
|
|
300
302
|
function filterCatalogue(entries, filter = {}) {
|
|
301
303
|
return entries.filter(
|
|
@@ -383,8 +385,14 @@ function openPopover(anchor, render, opts = {}) {
|
|
|
383
385
|
container.append(pop);
|
|
384
386
|
const a = anchor.getBoundingClientRect();
|
|
385
387
|
const ph = pop.getBoundingClientRect();
|
|
386
|
-
|
|
387
|
-
|
|
388
|
+
const GAP = 4;
|
|
389
|
+
const EDGE = 8;
|
|
390
|
+
const below = window.innerHeight - EDGE - (a.bottom + GAP);
|
|
391
|
+
const above = a.top - GAP - EDGE;
|
|
392
|
+
const flip = ph.height > below && above > below;
|
|
393
|
+
const room = flip ? above : below;
|
|
394
|
+
const top = flip ? a.top - Math.min(ph.height, above) - GAP : a.bottom + GAP;
|
|
395
|
+
if (ph.height > room) pop.style.maxHeight = `${Math.max(96, Math.round(room))}px`;
|
|
388
396
|
let left = a.left;
|
|
389
397
|
if (left + ph.width > window.innerWidth - 8) left = Math.max(8, window.innerWidth - 8 - ph.width);
|
|
390
398
|
if (container === document.body) {
|
|
@@ -1084,7 +1092,7 @@ function seedClause(ctx) {
|
|
|
1084
1092
|
function clauseMenu(ctx, anchor, onPick) {
|
|
1085
1093
|
ctx.openPopover(anchor, (close) => {
|
|
1086
1094
|
const wrap = el("div", "exed-menu");
|
|
1087
|
-
wrap.append(el("div", "exed-menu-head", ["Add a
|
|
1095
|
+
wrap.append(el("div", "exed-menu-head", ["Add a condition"]));
|
|
1088
1096
|
const add = (label, hint, make, disabled = false) => {
|
|
1089
1097
|
const b = button(`exed-opt${disabled ? " disabled" : ""}`, "", () => {
|
|
1090
1098
|
if (disabled) return;
|
|
@@ -1383,7 +1391,9 @@ function valueWizard(opts) {
|
|
|
1383
1391
|
host.append(body);
|
|
1384
1392
|
const choices = opts.expectedChoices?.length ? opts.expectedChoices : opts.expectedEnumValues;
|
|
1385
1393
|
const isStage = opts.expectedType === "quality";
|
|
1386
|
-
|
|
1394
|
+
const flagsReady = opts.expectedType === "flags" && opts.expectedRef !== void 0;
|
|
1395
|
+
let kind = opts.expectedType === "number" ? "number" : opts.expectedType === "string" ? "text" : opts.expectedType === "boolean" ? "bool" : (opts.expectedType === "enum" || opts.expectedType === "quality") && choices?.length ? "enum" : flagsReady ? "flags" : "menu";
|
|
1396
|
+
let flagSign = "+";
|
|
1387
1397
|
const draw = () => {
|
|
1388
1398
|
body.replaceChildren();
|
|
1389
1399
|
const other = () => button("exed-vwiz-other", "\u21A9 a different kind", () => {
|
|
@@ -1392,6 +1402,10 @@ function valueWizard(opts) {
|
|
|
1392
1402
|
});
|
|
1393
1403
|
switch (kind) {
|
|
1394
1404
|
case "menu":
|
|
1405
|
+
if (flagsReady) body.append(optBtn("Set or clear a flag\u2026", () => {
|
|
1406
|
+
kind = "flags";
|
|
1407
|
+
draw();
|
|
1408
|
+
}));
|
|
1395
1409
|
body.append(optBtn("A property\u2026", () => {
|
|
1396
1410
|
kind = "property";
|
|
1397
1411
|
draw();
|
|
@@ -1413,6 +1427,33 @@ function valueWizard(opts) {
|
|
|
1413
1427
|
draw();
|
|
1414
1428
|
}));
|
|
1415
1429
|
break;
|
|
1430
|
+
case "flags": {
|
|
1431
|
+
const flags = opts.expectedFlags ?? [];
|
|
1432
|
+
if (!flags.length) body.append(el("div", "exed-hint", ["This property declares no flag values yet."]));
|
|
1433
|
+
else {
|
|
1434
|
+
const signRow = el("div", "exed-field-row");
|
|
1435
|
+
signRow.append(
|
|
1436
|
+
button(`exed-opt${flagSign === "+" ? " sel" : ""}`, "\uFF0B set", () => {
|
|
1437
|
+
flagSign = "+";
|
|
1438
|
+
draw();
|
|
1439
|
+
}),
|
|
1440
|
+
button(`exed-opt${flagSign === "-" ? " sel" : ""}`, "\uFF0D clear", () => {
|
|
1441
|
+
flagSign = "-";
|
|
1442
|
+
draw();
|
|
1443
|
+
})
|
|
1444
|
+
);
|
|
1445
|
+
body.append(signRow);
|
|
1446
|
+
body.append(el("div", "exed-vwiz-note", [flagSign === "+" ? "Set a flag:" : "Clear a flag:"]));
|
|
1447
|
+
const list = el("div", "exed-picker-list");
|
|
1448
|
+
for (const f of flags) list.append(optBtn(`${flagSign} ${f}`, () => opts.onCommit(flagChangeSrc(opts.expectedRef, flagSign, f))));
|
|
1449
|
+
body.append(list);
|
|
1450
|
+
}
|
|
1451
|
+
body.append(button("exed-vwiz-other", "\u21A9 a different kind (replaces every flag)", () => {
|
|
1452
|
+
kind = "menu";
|
|
1453
|
+
draw();
|
|
1454
|
+
}));
|
|
1455
|
+
break;
|
|
1456
|
+
}
|
|
1416
1457
|
case "property":
|
|
1417
1458
|
body.append(propertyPicker(pickCtx, { onPick: (e) => opts.onCommit(refOf(e, opts.defaultScope)) }));
|
|
1418
1459
|
body.append(other());
|
|
@@ -1451,6 +1492,10 @@ function isSelfAdvance(eff, defaultScope, dialect) {
|
|
|
1451
1492
|
return false;
|
|
1452
1493
|
}
|
|
1453
1494
|
}
|
|
1495
|
+
function entryForTarget(catalogue, target, defaultScope) {
|
|
1496
|
+
const want = normaliseRef(target, defaultScope);
|
|
1497
|
+
return catalogue.find((e) => normaliseRef(`@${e.scope}.${e.name}`, defaultScope) === want);
|
|
1498
|
+
}
|
|
1454
1499
|
var clone = (list) => list.map((e) => e.kind === "set" ? { ...e } : { ...e, args: [...e.args] });
|
|
1455
1500
|
var addSet = (list, target, value) => [...clone(list), { kind: "set", target, value }];
|
|
1456
1501
|
var addEmit = (list, event) => [...clone(list), { kind: "emit", event, args: [] }];
|
|
@@ -1539,6 +1584,11 @@ function mountEffectsEditor(host, opts) {
|
|
|
1539
1584
|
// choicesOf, never a raw field: a quality's ladder lives in `stages`, and reading `enumValues`
|
|
1540
1585
|
// here told the wizard the type and withheld the values.
|
|
1541
1586
|
...choicesOf(expected) ? { expectedChoices: choicesOf(expected) } : {},
|
|
1587
|
+
// The flags step needs the target itself: its declared flags, and the
|
|
1588
|
+
// qualified ref its set_flags(...) is written against. choicesOf stays
|
|
1589
|
+
// out of it deliberately - flags are not a pick-one list, and a pinned
|
|
1590
|
+
// test holds it to that.
|
|
1591
|
+
...expected?.type === "flags" ? { expectedRef: targetRefOf(expected), expectedFlags: expected.enumValues ?? [] } : {},
|
|
1542
1592
|
onCommit: (src) => {
|
|
1543
1593
|
onCommit(src);
|
|
1544
1594
|
close();
|
|
@@ -1546,7 +1596,7 @@ function mountEffectsEditor(host, opts) {
|
|
|
1546
1596
|
onCancel: close
|
|
1547
1597
|
}), { container: opts.popoverContainer });
|
|
1548
1598
|
};
|
|
1549
|
-
const targetType = (target) => opts.catalogue
|
|
1599
|
+
const targetType = (target) => entryForTarget(opts.catalogue, target, defaultScope)?.type;
|
|
1550
1600
|
const valueDisplay = (value, onChange, type, selfAdvanceRef) => {
|
|
1551
1601
|
const sub = el("div", "exed-effect-value");
|
|
1552
1602
|
const addTerm = type === "number" ? "arithmetic" : type === "boolean" ? "boolean" : void 0;
|
|
@@ -1613,10 +1663,10 @@ function mountEffectsEditor(host, opts) {
|
|
|
1613
1663
|
const row = el("div", "exed-effect exed-effect-set");
|
|
1614
1664
|
const targetBtn = button("exed-pill exed-pill-prop", eff.target || "(pick property)", (e) => {
|
|
1615
1665
|
pickTarget(e.currentTarget, void 0, (entry) => {
|
|
1616
|
-
commit(updateAt(effects, i, { target:
|
|
1666
|
+
commit(updateAt(effects, i, { target: targetRefOf(entry), value: initialValueFor(entry, defaultScope).src }));
|
|
1617
1667
|
});
|
|
1618
1668
|
}, "change the target property");
|
|
1619
|
-
const targetEntry = opts.catalogue
|
|
1669
|
+
const targetEntry = entryForTarget(opts.catalogue, eff.target, defaultScope);
|
|
1620
1670
|
const tip = propertyTip(targetEntry);
|
|
1621
1671
|
if (tip) targetBtn.title = tip;
|
|
1622
1672
|
if (targetEntry && opts.propertyActions) {
|
|
@@ -1720,10 +1770,10 @@ function mountEffectsEditor(host, opts) {
|
|
|
1720
1770
|
pickTarget(anchor, void 0, (entry) => {
|
|
1721
1771
|
const { src, ask } = initialValueFor(entry, defaultScope);
|
|
1722
1772
|
if (!ask) {
|
|
1723
|
-
commit(addSet(effects,
|
|
1773
|
+
commit(addSet(effects, targetRefOf(entry), src));
|
|
1724
1774
|
return;
|
|
1725
1775
|
}
|
|
1726
|
-
openValueWizard(anchor, entry, (chosen) => commit(addSet(effects,
|
|
1776
|
+
openValueWizard(anchor, entry, (chosen) => commit(addSet(effects, targetRefOf(entry), chosen)));
|
|
1727
1777
|
});
|
|
1728
1778
|
}));
|
|
1729
1779
|
if (opts.allowEmit !== false) {
|
|
@@ -1852,6 +1902,7 @@ exports.filterCatalogue = filterCatalogue;
|
|
|
1852
1902
|
exports.findChoicePeer = findChoicePeer;
|
|
1853
1903
|
exports.findEnumPeer = findEnumPeer;
|
|
1854
1904
|
exports.firstEmptyLeafPath = firstEmptyLeafPath;
|
|
1905
|
+
exports.flagChangeSrc = flagChangeSrc;
|
|
1855
1906
|
exports.flagDelta = flagDelta;
|
|
1856
1907
|
exports.flipContainerOp = flipContainerOp;
|
|
1857
1908
|
exports.formatNumber = formatNumber;
|
|
@@ -1889,6 +1940,7 @@ exports.seedValueSrc = seedValueSrc;
|
|
|
1889
1940
|
exports.setArgAt = setArgAt;
|
|
1890
1941
|
exports.setNodeAt = setNodeAt;
|
|
1891
1942
|
exports.strLit = strLit;
|
|
1943
|
+
exports.targetRefOf = targetRefOf;
|
|
1892
1944
|
exports.toggleContainerNot = toggleContainerNot;
|
|
1893
1945
|
exports.toggleNotAt = toggleNotAt;
|
|
1894
1946
|
exports.updateAt = updateAt;
|