@lokascript/compilation-service 3.1.0 → 3.2.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/CHANGELOG.md +168 -0
- package/dist/{chunk-TVK2OFIB.js → chunk-QQLDIJOC.js} +3 -3
- package/dist/{chunk-5CZBYL6A.js → chunk-XOAPC6M5.js} +58 -7
- package/dist/chunk-XOAPC6M5.js.map +1 -0
- package/dist/{core-parser-adapter-W5UPZR4X-AIVYD5RA.js → core-parser-adapter-W5UPZR4X-7CPPQMOH.js} +2 -2
- package/dist/{dist-HDVJKXUX.js → dist-BDTQTYGC.js} +414 -230
- package/dist/dist-BDTQTYGC.js.map +1 -0
- package/dist/{dist-GFKFJKU6.js → dist-SO754VTX.js} +1087 -484
- package/dist/dist-SO754VTX.js.map +1 -0
- package/dist/http.cjs +1555 -717
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.js +1 -1
- package/dist/index.cjs +1555 -717
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{multilingual-VYI3FTN7.js → multilingual-TCFUREGW.js} +1 -1
- package/dist/multilingual-TCFUREGW.js.map +1 -0
- package/dist/{service-IyB2DZOm.d.cts → service-Da54XrEI.d.cts} +14 -0
- package/dist/{service-IyB2DZOm.d.ts → service-Da54XrEI.d.ts} +14 -0
- package/package.json +9 -9
- package/dist/chunk-5CZBYL6A.js.map +0 -1
- package/dist/dist-GFKFJKU6.js.map +0 -1
- package/dist/dist-HDVJKXUX.js.map +0 -1
- package/dist/multilingual-VYI3FTN7.js.map +0 -1
- /package/dist/{chunk-TVK2OFIB.js.map → chunk-QQLDIJOC.js.map} +0 -0
- /package/dist/{core-parser-adapter-W5UPZR4X-AIVYD5RA.js.map → core-parser-adapter-W5UPZR4X-7CPPQMOH.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CoreParserAdapter,
|
|
3
3
|
createCoreParserAdapter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QQLDIJOC.js";
|
|
5
5
|
import {
|
|
6
6
|
SemanticParserAdapter,
|
|
7
7
|
createSemanticAdapter
|
|
@@ -427,6 +427,13 @@ var AnalysisVisitor = class {
|
|
|
427
427
|
}
|
|
428
428
|
visitCommand(node) {
|
|
429
429
|
this.commandsUsed.add(node.name);
|
|
430
|
+
if (["set", "increment", "decrement", "default"].includes(node.name)) {
|
|
431
|
+
const target = node.roles?.destination ?? node.roles?.patient ?? node.args?.[0];
|
|
432
|
+
const name = target?.type === "identifier" ? target.value : void 0;
|
|
433
|
+
if (name && /^[A-Za-z_]\w*$/.test(name)) {
|
|
434
|
+
this.registerVariable(name, "local", "write");
|
|
435
|
+
}
|
|
436
|
+
}
|
|
430
437
|
switch (node.name) {
|
|
431
438
|
case "fetch":
|
|
432
439
|
this.hasAsync = true;
|
|
@@ -508,32 +515,37 @@ var AnalysisVisitor = class {
|
|
|
508
515
|
if (node.whileCondition) {
|
|
509
516
|
this.visit(node.whileCondition);
|
|
510
517
|
}
|
|
511
|
-
|
|
512
|
-
this.
|
|
518
|
+
if (node.untilEvent !== void 0) {
|
|
519
|
+
this.hasAsync = true;
|
|
520
|
+
this.runtimeHelpers.add("wait");
|
|
521
|
+
if (node.untilEventTarget) this.visit(node.untilEventTarget);
|
|
513
522
|
}
|
|
523
|
+
this.visitLoopBody(node);
|
|
514
524
|
this.exitNesting();
|
|
515
525
|
}
|
|
516
526
|
visitForEach(node) {
|
|
517
527
|
this.hasLoops = true;
|
|
518
528
|
this.enterNesting();
|
|
519
529
|
this.registerVariable(node.itemName, "local", "write");
|
|
520
|
-
if (node.indexName) {
|
|
521
|
-
this.registerVariable(node.indexName, "local", "write");
|
|
522
|
-
}
|
|
523
530
|
this.visit(node.collection);
|
|
524
|
-
|
|
525
|
-
this.visit(child);
|
|
526
|
-
}
|
|
531
|
+
this.visitLoopBody(node);
|
|
527
532
|
this.exitNesting();
|
|
528
533
|
}
|
|
529
534
|
visitWhile(node) {
|
|
530
535
|
this.hasLoops = true;
|
|
531
536
|
this.enterNesting();
|
|
532
537
|
this.visit(node.condition);
|
|
533
|
-
|
|
538
|
+
this.visitLoopBody(node);
|
|
539
|
+
this.exitNesting();
|
|
540
|
+
}
|
|
541
|
+
/** The parts every loop form shares: its `index` local, body, and `else`. */
|
|
542
|
+
visitLoopBody(node) {
|
|
543
|
+
if (node.indexName) {
|
|
544
|
+
this.registerVariable(node.indexName, "local", "write");
|
|
545
|
+
}
|
|
546
|
+
for (const child of [...node.body, ...node.elseBody ?? []]) {
|
|
534
547
|
this.visit(child);
|
|
535
548
|
}
|
|
536
|
-
this.exitNesting();
|
|
537
549
|
}
|
|
538
550
|
visitVariable(node, access) {
|
|
539
551
|
const name = node.name.startsWith(":") || node.name.startsWith("$") ? node.name.slice(1) : node.name;
|
|
@@ -686,11 +698,15 @@ function analyze(ast) {
|
|
|
686
698
|
const analyzer = new Analyzer();
|
|
687
699
|
return analyzer.analyze(ast);
|
|
688
700
|
}
|
|
689
|
-
var
|
|
701
|
+
var TARGET_SLOTS = /* @__PURE__ */ new Map([
|
|
702
|
+
["add", "to"],
|
|
703
|
+
["remove", "from"],
|
|
704
|
+
["toggle", "on"]
|
|
705
|
+
]);
|
|
690
706
|
function extractClassOp(node) {
|
|
691
707
|
if (node.type !== "command") return null;
|
|
692
708
|
const cmd = node;
|
|
693
|
-
if (!
|
|
709
|
+
if (!TARGET_SLOTS.has(cmd.name)) return null;
|
|
694
710
|
const args = cmd.args ?? [];
|
|
695
711
|
if (args.length === 0) return null;
|
|
696
712
|
const arg = args[0];
|
|
@@ -699,48 +715,32 @@ function extractClassOp(node) {
|
|
|
699
715
|
if (!selector.startsWith(".")) return null;
|
|
700
716
|
const className = selector.slice(1);
|
|
701
717
|
if (!className) return null;
|
|
702
|
-
return {
|
|
703
|
-
command: cmd.name,
|
|
704
|
-
className,
|
|
705
|
-
hasExplicitTarget: !!cmd.target
|
|
706
|
-
};
|
|
718
|
+
return { command: cmd.name, className };
|
|
707
719
|
}
|
|
708
|
-
function
|
|
709
|
-
if (
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
if (!cmdA.target && !cmdB.target) return true;
|
|
713
|
-
if (cmdA.target && cmdB.target) {
|
|
714
|
-
return getTargetKey(cmdA.target) === getTargetKey(cmdB.target);
|
|
715
|
-
}
|
|
716
|
-
return false;
|
|
720
|
+
function classTarget(cmd) {
|
|
721
|
+
if (cmd.target) return cmd.target;
|
|
722
|
+
const slot = cmd.modifiers?.[TARGET_SLOTS.get(cmd.name)];
|
|
723
|
+
return slot && typeof slot === "object" && "type" in slot ? slot : void 0;
|
|
717
724
|
}
|
|
718
|
-
function
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (target.type === "
|
|
723
|
-
return
|
|
725
|
+
function batchTargetKey(cmd) {
|
|
726
|
+
const target = classTarget(cmd);
|
|
727
|
+
if (!target) return "me";
|
|
728
|
+
if (target.type === "identifier" && target.value === "me") return "me";
|
|
729
|
+
if (target.type === "selector" && /^#[\w-]+$/.test(target.value)) {
|
|
730
|
+
return target.value;
|
|
724
731
|
}
|
|
725
732
|
return null;
|
|
726
733
|
}
|
|
727
|
-
function resolveTarget(
|
|
728
|
-
|
|
729
|
-
if (cmd.target.type === "selector") {
|
|
730
|
-
const sel = cmd.target.value;
|
|
731
|
-
if (sel.startsWith("#") && !sel.includes(" ") && !sel.includes(".")) {
|
|
732
|
-
return `document.getElementById('${sel.slice(1)}')`;
|
|
733
|
-
}
|
|
734
|
-
return `document.querySelector('${sel}')`;
|
|
735
|
-
}
|
|
736
|
-
if (cmd.target.type === "identifier") {
|
|
737
|
-
const val = cmd.target.value;
|
|
738
|
-
if (val === "me") return "_ctx.me";
|
|
739
|
-
return val;
|
|
740
|
-
}
|
|
741
|
-
return "_ctx.me";
|
|
734
|
+
function resolveTarget(key) {
|
|
735
|
+
return key === "me" ? "_ctx.me" : `document.getElementById('${key.slice(1)}')`;
|
|
742
736
|
}
|
|
743
|
-
function
|
|
737
|
+
function reordersClass(run, op) {
|
|
738
|
+
return run.some((node) => {
|
|
739
|
+
const other = extractClassOp(node);
|
|
740
|
+
return other.command !== op.command && other.className === op.className;
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
function createBatchNode(run, targetKey) {
|
|
744
744
|
const adds = [];
|
|
745
745
|
const removes = [];
|
|
746
746
|
const toggles = [];
|
|
@@ -758,10 +758,9 @@ function createBatchNode(run) {
|
|
|
758
758
|
break;
|
|
759
759
|
}
|
|
760
760
|
}
|
|
761
|
-
const target = resolveTarget(run[0]);
|
|
762
761
|
return {
|
|
763
762
|
type: "batchedClassOps",
|
|
764
|
-
target,
|
|
763
|
+
target: resolveTarget(targetKey),
|
|
765
764
|
adds,
|
|
766
765
|
removes,
|
|
767
766
|
toggles
|
|
@@ -770,9 +769,10 @@ function createBatchNode(run) {
|
|
|
770
769
|
function batchBody(nodes) {
|
|
771
770
|
const result = [];
|
|
772
771
|
let currentRun = [];
|
|
772
|
+
let runKey = "";
|
|
773
773
|
function flushRun() {
|
|
774
774
|
if (currentRun.length >= 2) {
|
|
775
|
-
result.push(createBatchNode(currentRun));
|
|
775
|
+
result.push(createBatchNode(currentRun, runKey));
|
|
776
776
|
} else if (currentRun.length === 1) {
|
|
777
777
|
result.push(currentRun[0]);
|
|
778
778
|
}
|
|
@@ -780,12 +780,14 @@ function batchBody(nodes) {
|
|
|
780
780
|
}
|
|
781
781
|
for (const node of nodes) {
|
|
782
782
|
const op = extractClassOp(node);
|
|
783
|
-
|
|
784
|
-
|
|
783
|
+
const key = op && batchTargetKey(node);
|
|
784
|
+
if (op && key) {
|
|
785
|
+
if (currentRun.length > 0 && key === runKey && !reordersClass(currentRun, op)) {
|
|
785
786
|
currentRun.push(node);
|
|
786
787
|
} else {
|
|
787
788
|
flushRun();
|
|
788
789
|
currentRun = [node];
|
|
790
|
+
runKey = key;
|
|
789
791
|
}
|
|
790
792
|
} else {
|
|
791
793
|
flushRun();
|
|
@@ -1112,6 +1114,9 @@ var LoopUnrollingPass = class {
|
|
|
1112
1114
|
if (this.usesIndex(body)) {
|
|
1113
1115
|
return null;
|
|
1114
1116
|
}
|
|
1117
|
+
if (repeatNode.indexName !== void 0 || repeatNode.elseBody !== void 0) {
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1115
1120
|
const unrolled = [];
|
|
1116
1121
|
for (let i = 0; i < count; i++) {
|
|
1117
1122
|
unrolled.push(...this.cloneBody(body));
|
|
@@ -1431,6 +1436,8 @@ var ExpressionCodegen = class {
|
|
|
1431
1436
|
return this.generateTemplate(node);
|
|
1432
1437
|
case "unary":
|
|
1433
1438
|
return this.generateUnary(node);
|
|
1439
|
+
case "typeCheck":
|
|
1440
|
+
return this.generateTypeCheck(node);
|
|
1434
1441
|
case "conditional":
|
|
1435
1442
|
return this.generateConditional(node);
|
|
1436
1443
|
case "sequence":
|
|
@@ -1505,6 +1512,9 @@ var ExpressionCodegen = class {
|
|
|
1505
1512
|
this.ctx.requireHelper("globals");
|
|
1506
1513
|
return `_rt.globals.get('${varName}')`;
|
|
1507
1514
|
}
|
|
1515
|
+
if (this.ctx.analysis?.variables?.locals?.get(name)?.scope === "local") {
|
|
1516
|
+
return `_ctx.locals.get('${sanitizeIdentifier(name)}')`;
|
|
1517
|
+
}
|
|
1508
1518
|
return sanitizeIdentifier(name);
|
|
1509
1519
|
}
|
|
1510
1520
|
}
|
|
@@ -1538,7 +1548,8 @@ var ExpressionCodegen = class {
|
|
|
1538
1548
|
this.ctx.requireHelper("globals");
|
|
1539
1549
|
return `_rt.globals.get('${varName}')`;
|
|
1540
1550
|
case "element":
|
|
1541
|
-
|
|
1551
|
+
this.ctx.requireHelper("elementVars");
|
|
1552
|
+
return `_rt.elementVars(_ctx.me).get('${varName}')`;
|
|
1542
1553
|
default:
|
|
1543
1554
|
return `_ctx.locals.get('${varName}')`;
|
|
1544
1555
|
}
|
|
@@ -1551,19 +1562,40 @@ var ExpressionCodegen = class {
|
|
|
1551
1562
|
const right = this.generate(node.right);
|
|
1552
1563
|
const op = node.operator;
|
|
1553
1564
|
switch (op) {
|
|
1554
|
-
// Equality
|
|
1565
|
+
// Equality, with core's phrase forms of each (`n is equal to 3`).
|
|
1555
1566
|
case "is":
|
|
1556
1567
|
case "==":
|
|
1568
|
+
case "am":
|
|
1569
|
+
case "equals":
|
|
1570
|
+
case "is equal":
|
|
1571
|
+
case "is equal to":
|
|
1557
1572
|
return `(${left} === ${right})`;
|
|
1558
1573
|
case "is not":
|
|
1559
1574
|
case "!=":
|
|
1575
|
+
case "is not equal":
|
|
1576
|
+
case "is not equal to":
|
|
1560
1577
|
return `(${left} !== ${right})`;
|
|
1561
|
-
|
|
1578
|
+
case "really equals":
|
|
1579
|
+
case "is really":
|
|
1580
|
+
case "is really equal to":
|
|
1581
|
+
return `(${left} === ${right})`;
|
|
1582
|
+
case "is not really":
|
|
1583
|
+
case "is not really equal to":
|
|
1584
|
+
return `(${left} !== ${right})`;
|
|
1585
|
+
// Comparison. Left as is, `(n is greater than 2)` is not JavaScript.
|
|
1562
1586
|
case "<":
|
|
1563
1587
|
case ">":
|
|
1564
1588
|
case "<=":
|
|
1565
1589
|
case ">=":
|
|
1566
1590
|
return `(${left} ${op} ${right})`;
|
|
1591
|
+
case "is less than":
|
|
1592
|
+
return `(${left} < ${right})`;
|
|
1593
|
+
case "is greater than":
|
|
1594
|
+
return `(${left} > ${right})`;
|
|
1595
|
+
case "is less than or equal to":
|
|
1596
|
+
return `(${left} <= ${right})`;
|
|
1597
|
+
case "is greater than or equal to":
|
|
1598
|
+
return `(${left} >= ${right})`;
|
|
1567
1599
|
// Arithmetic
|
|
1568
1600
|
case "+":
|
|
1569
1601
|
case "-":
|
|
@@ -1571,6 +1603,9 @@ var ExpressionCodegen = class {
|
|
|
1571
1603
|
case "/":
|
|
1572
1604
|
case "%":
|
|
1573
1605
|
return `(${left} ${op} ${right})`;
|
|
1606
|
+
// Hyperscript's word for `%`; left as is, `(n mod 2)` is not JavaScript.
|
|
1607
|
+
case "mod":
|
|
1608
|
+
return `(${left} % ${right})`;
|
|
1574
1609
|
// Logical
|
|
1575
1610
|
case "and":
|
|
1576
1611
|
case "&&":
|
|
@@ -1580,15 +1615,49 @@ var ExpressionCodegen = class {
|
|
|
1580
1615
|
return `(${left} || ${right})`;
|
|
1581
1616
|
// String/collection operators
|
|
1582
1617
|
case "contains":
|
|
1618
|
+
case "contain":
|
|
1619
|
+
case "includes":
|
|
1620
|
+
case "include":
|
|
1583
1621
|
this.ctx.requireHelper("contains");
|
|
1584
1622
|
return `_rt.contains(${left}, ${right})`;
|
|
1623
|
+
case "does not contain":
|
|
1624
|
+
case "do not contain":
|
|
1625
|
+
case "does not contains":
|
|
1626
|
+
case "does not include":
|
|
1627
|
+
this.ctx.requireHelper("contains");
|
|
1628
|
+
return `!_rt.contains(${left}, ${right})`;
|
|
1629
|
+
// `matches` tests a selector, so a selector operand stays a string: the
|
|
1630
|
+
// element it would query is not a selector (`_rt.matches(el, el)`).
|
|
1585
1631
|
case "matches":
|
|
1632
|
+
case "match":
|
|
1633
|
+
this.ctx.requireHelper("matches");
|
|
1634
|
+
return `_rt.matches(${left}, ${this.selectorText(node.right, right)})`;
|
|
1635
|
+
case "does not match":
|
|
1636
|
+
case "do not match":
|
|
1586
1637
|
this.ctx.requireHelper("matches");
|
|
1587
|
-
return
|
|
1638
|
+
return `!_rt.matches(${left}, ${this.selectorText(node.right, right)})`;
|
|
1639
|
+
// Membership, `n is in [1, 3]`: the right side contains the left.
|
|
1640
|
+
case "is in":
|
|
1641
|
+
case "am in":
|
|
1642
|
+
this.ctx.requireHelper("contains");
|
|
1643
|
+
return `_rt.contains(${right}, ${left})`;
|
|
1644
|
+
case "is not in":
|
|
1645
|
+
case "am not in":
|
|
1646
|
+
this.ctx.requireHelper("contains");
|
|
1647
|
+
return `!_rt.contains(${right}, ${left})`;
|
|
1588
1648
|
case "starts with":
|
|
1589
1649
|
return `${left}.startsWith(${right})`;
|
|
1590
1650
|
case "ends with":
|
|
1591
1651
|
return `${left}.endsWith(${right})`;
|
|
1652
|
+
// A scoped query, `<li/> in #list`: the matches inside the scope, as
|
|
1653
|
+
// both engines read it. JavaScript's `in` (the default below) tests a
|
|
1654
|
+
// property KEY, so `(document.querySelector('li') in …)` matched nothing.
|
|
1655
|
+
case "in":
|
|
1656
|
+
if (node.left.type === "selector") {
|
|
1657
|
+
const query = sanitizeSelector(node.left.value);
|
|
1658
|
+
return `${right}.querySelectorAll('${query}')`;
|
|
1659
|
+
}
|
|
1660
|
+
return `(${left} ${op} ${right})`;
|
|
1592
1661
|
// Class check
|
|
1593
1662
|
case "has":
|
|
1594
1663
|
if (node.right.type === "selector") {
|
|
@@ -1616,13 +1685,18 @@ var ExpressionCodegen = class {
|
|
|
1616
1685
|
return `(${left} ${op} ${right})`;
|
|
1617
1686
|
}
|
|
1618
1687
|
}
|
|
1688
|
+
/** A selector operand as its quoted text; any other operand as generated. */
|
|
1689
|
+
selectorText(node, generated) {
|
|
1690
|
+
return node.type === "selector" ? `'${sanitizeSelector(node.value)}'` : generated;
|
|
1691
|
+
}
|
|
1619
1692
|
// ===========================================================================
|
|
1620
1693
|
// MEMBER EXPRESSIONS
|
|
1621
1694
|
// ===========================================================================
|
|
1622
1695
|
generateMember(node) {
|
|
1623
1696
|
const object = this.generate(node.object);
|
|
1624
|
-
|
|
1625
|
-
|
|
1697
|
+
const property = node.property;
|
|
1698
|
+
const prop = typeof property === "string" ? property : !node.computed && property.type === "identifier" ? property.value ?? property.name : void 0;
|
|
1699
|
+
if (prop !== void 0) {
|
|
1626
1700
|
if (prop.startsWith("*")) {
|
|
1627
1701
|
const styleProp = prop.slice(1);
|
|
1628
1702
|
return `${object}.style.${styleProp}`;
|
|
@@ -1804,6 +1878,12 @@ var ExpressionCodegen = class {
|
|
|
1804
1878
|
// ===========================================================================
|
|
1805
1879
|
// UNARY EXPRESSIONS
|
|
1806
1880
|
// ===========================================================================
|
|
1881
|
+
/** `x is a Number`, as both engines test it: see the runtime's `typeCheck`. */
|
|
1882
|
+
generateTypeCheck(node) {
|
|
1883
|
+
this.ctx.requireHelper("typeCheck");
|
|
1884
|
+
const test = `_rt.typeCheck(${this.generate(node.value)}, ${JSON.stringify(node.typeName)}, ${node.nullOk})`;
|
|
1885
|
+
return node.negated ? `!${test}` : test;
|
|
1886
|
+
}
|
|
1807
1887
|
generateUnary(node) {
|
|
1808
1888
|
const operand = this.generate(node.operand);
|
|
1809
1889
|
switch (node.operator) {
|
|
@@ -1816,6 +1896,22 @@ var ExpressionCodegen = class {
|
|
|
1816
1896
|
return `+${operand}`;
|
|
1817
1897
|
case "no":
|
|
1818
1898
|
return `!${operand}`;
|
|
1899
|
+
// Core's postfix tests. Left as is, `exists#d1` is not JavaScript.
|
|
1900
|
+
case "exists":
|
|
1901
|
+
case "some":
|
|
1902
|
+
this.ctx.requireHelper("exists");
|
|
1903
|
+
return `_rt.exists(${operand})`;
|
|
1904
|
+
case "does not exist":
|
|
1905
|
+
this.ctx.requireHelper("exists");
|
|
1906
|
+
return `!_rt.exists(${operand})`;
|
|
1907
|
+
case "is empty":
|
|
1908
|
+
this.ctx.requireHelper("isEmpty");
|
|
1909
|
+
return `_rt.isEmpty(${operand})`;
|
|
1910
|
+
case "is not empty":
|
|
1911
|
+
this.ctx.requireHelper("isEmpty");
|
|
1912
|
+
return `!_rt.isEmpty(${operand})`;
|
|
1913
|
+
case "beep!":
|
|
1914
|
+
return `((v) => (console.log('%c[beep]', 'color: orange; font-weight: bold', v), v))(${operand})`;
|
|
1819
1915
|
default:
|
|
1820
1916
|
return `${node.operator}${operand}`;
|
|
1821
1917
|
}
|
|
@@ -1834,6 +1930,30 @@ function generateExpression(node, ctx) {
|
|
|
1834
1930
|
const codegen = new ExpressionCodegen(ctx);
|
|
1835
1931
|
return codegen.generate(node);
|
|
1836
1932
|
}
|
|
1933
|
+
var isNode = (value) => typeof value === "object" && value !== null && "type" in value;
|
|
1934
|
+
function commandTarget(node, ...slots) {
|
|
1935
|
+
if (node.target) return node.target;
|
|
1936
|
+
for (const slot of slots) {
|
|
1937
|
+
const found = slot === "arg" ? node.args?.[0] : node.modifiers?.[slot];
|
|
1938
|
+
if (isNode(found)) return found;
|
|
1939
|
+
}
|
|
1940
|
+
return void 0;
|
|
1941
|
+
}
|
|
1942
|
+
function isScopedQuery(node) {
|
|
1943
|
+
const binary = node;
|
|
1944
|
+
return binary?.type === "binary" && binary.operator === "in" && binary.left.type === "selector";
|
|
1945
|
+
}
|
|
1946
|
+
function allMatches(node, ctx) {
|
|
1947
|
+
if (isScopedQuery(node)) return ctx.generateExpression(node);
|
|
1948
|
+
if (node?.type !== "selector") return null;
|
|
1949
|
+
const selector = node.value;
|
|
1950
|
+
return /^#[\w-]+$/.test(selector) ? null : `document.querySelectorAll('${sanitizeSelector(selector)}')`;
|
|
1951
|
+
}
|
|
1952
|
+
function forEachTarget(node, ctx, op) {
|
|
1953
|
+
const all = allMatches(node, ctx);
|
|
1954
|
+
if (all) return `${all}.forEach(el => ${op("el")})`;
|
|
1955
|
+
return op(node ? ctx.generateExpression(node) : "_ctx.me");
|
|
1956
|
+
}
|
|
1837
1957
|
var ToggleCodegen = class {
|
|
1838
1958
|
constructor() {
|
|
1839
1959
|
this.command = "toggle";
|
|
@@ -1841,22 +1961,15 @@ var ToggleCodegen = class {
|
|
|
1841
1961
|
generate(node, ctx) {
|
|
1842
1962
|
const args = node.args ?? [];
|
|
1843
1963
|
if (args.length === 0) return null;
|
|
1844
|
-
const
|
|
1964
|
+
const targetNode = commandTarget(node, "on");
|
|
1845
1965
|
const arg = args[0];
|
|
1846
1966
|
if (arg.type === "selector") {
|
|
1847
1967
|
const selector = arg.value;
|
|
1848
1968
|
if (selector.startsWith(".")) {
|
|
1849
1969
|
const className = sanitizeClassName(selector.slice(1));
|
|
1850
1970
|
if (!className) return null;
|
|
1851
|
-
if (target === "_ctx.me") {
|
|
1852
|
-
return {
|
|
1853
|
-
code: `_ctx.me.classList.toggle('${className}')`,
|
|
1854
|
-
async: false,
|
|
1855
|
-
sideEffects: true
|
|
1856
|
-
};
|
|
1857
|
-
}
|
|
1858
1971
|
return {
|
|
1859
|
-
code:
|
|
1972
|
+
code: forEachTarget(targetNode, ctx, (el) => `${el}.classList.toggle('${className}')`),
|
|
1860
1973
|
async: false,
|
|
1861
1974
|
sideEffects: true
|
|
1862
1975
|
};
|
|
@@ -1868,7 +1981,11 @@ var ToggleCodegen = class {
|
|
|
1868
1981
|
const attrName = value.slice(1);
|
|
1869
1982
|
ctx.requireHelper("toggleAttr");
|
|
1870
1983
|
return {
|
|
1871
|
-
code:
|
|
1984
|
+
code: forEachTarget(
|
|
1985
|
+
targetNode,
|
|
1986
|
+
ctx,
|
|
1987
|
+
(el) => `_rt.toggleAttr(${el}, '${sanitizeSelector(attrName)}')`
|
|
1988
|
+
),
|
|
1872
1989
|
async: false,
|
|
1873
1990
|
sideEffects: true
|
|
1874
1991
|
};
|
|
@@ -1876,7 +1993,11 @@ var ToggleCodegen = class {
|
|
|
1876
1993
|
}
|
|
1877
1994
|
ctx.requireHelper("toggle");
|
|
1878
1995
|
return {
|
|
1879
|
-
code:
|
|
1996
|
+
code: forEachTarget(
|
|
1997
|
+
targetNode,
|
|
1998
|
+
ctx,
|
|
1999
|
+
(el) => `_rt.toggle(${ctx.generateExpression(arg)}, ${el})`
|
|
2000
|
+
),
|
|
1880
2001
|
async: false,
|
|
1881
2002
|
sideEffects: true
|
|
1882
2003
|
};
|
|
@@ -1897,15 +2018,8 @@ var AddCodegen = class {
|
|
|
1897
2018
|
if (selector.startsWith(".")) {
|
|
1898
2019
|
const className = sanitizeClassName(selector.slice(1));
|
|
1899
2020
|
if (!className) return null;
|
|
1900
|
-
if (target === "_ctx.me") {
|
|
1901
|
-
return {
|
|
1902
|
-
code: `_ctx.me.classList.add('${className}')`,
|
|
1903
|
-
async: false,
|
|
1904
|
-
sideEffects: true
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
2021
|
return {
|
|
1908
|
-
code: `${
|
|
2022
|
+
code: forEachTarget(targetSlot, ctx, (el) => `${el}.classList.add('${className}')`),
|
|
1909
2023
|
async: false,
|
|
1910
2024
|
sideEffects: true
|
|
1911
2025
|
};
|
|
@@ -1928,7 +2042,11 @@ var AddCodegen = class {
|
|
|
1928
2042
|
}
|
|
1929
2043
|
ctx.requireHelper("addClass");
|
|
1930
2044
|
return {
|
|
1931
|
-
code:
|
|
2045
|
+
code: forEachTarget(
|
|
2046
|
+
targetSlot,
|
|
2047
|
+
ctx,
|
|
2048
|
+
(el) => `_rt.addClass(${el}, ${ctx.generateExpression(arg)})`
|
|
2049
|
+
),
|
|
1932
2050
|
async: false,
|
|
1933
2051
|
sideEffects: true
|
|
1934
2052
|
};
|
|
@@ -1942,23 +2060,29 @@ var RemoveCodegen = class {
|
|
|
1942
2060
|
const args = node.args ?? [];
|
|
1943
2061
|
if (args.length === 0) {
|
|
1944
2062
|
const targetSlot2 = node.target ?? node.modifiers?.from;
|
|
1945
|
-
const target2 = targetSlot2 ? ctx.generateExpression(targetSlot2) : "_ctx.me";
|
|
1946
2063
|
return {
|
|
1947
|
-
code: `${
|
|
2064
|
+
code: forEachTarget(targetSlot2, ctx, (el) => `${el}.remove()`),
|
|
1948
2065
|
async: false,
|
|
1949
2066
|
sideEffects: true
|
|
1950
2067
|
};
|
|
1951
2068
|
}
|
|
1952
2069
|
const targetSlot = node.target ?? node.modifiers?.from;
|
|
1953
|
-
const target = targetSlot ? ctx.generateExpression(targetSlot) : "_ctx.me";
|
|
1954
2070
|
const arg = args[0];
|
|
2071
|
+
const isElement = arg.type === "selector" ? !/^[.@]/.test(arg.value) : arg.type === "identifier" && !String(arg.value ?? "").startsWith("@") || arg.type === "variable" || isScopedQuery(arg);
|
|
2072
|
+
if (!targetSlot && isElement) {
|
|
2073
|
+
return {
|
|
2074
|
+
code: forEachTarget(arg, ctx, (el) => `${el}.remove()`),
|
|
2075
|
+
async: false,
|
|
2076
|
+
sideEffects: true
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
1955
2079
|
if (arg.type === "selector") {
|
|
1956
2080
|
const selector = arg.value;
|
|
1957
2081
|
if (selector.startsWith(".")) {
|
|
1958
2082
|
const className = sanitizeClassName(selector.slice(1));
|
|
1959
2083
|
if (!className) return null;
|
|
1960
2084
|
return {
|
|
1961
|
-
code: `${
|
|
2085
|
+
code: forEachTarget(targetSlot, ctx, (el) => `${el}.classList.remove('${className}')`),
|
|
1962
2086
|
async: false,
|
|
1963
2087
|
sideEffects: true
|
|
1964
2088
|
};
|
|
@@ -1966,12 +2090,42 @@ var RemoveCodegen = class {
|
|
|
1966
2090
|
}
|
|
1967
2091
|
ctx.requireHelper("removeClass");
|
|
1968
2092
|
return {
|
|
1969
|
-
code:
|
|
2093
|
+
code: forEachTarget(
|
|
2094
|
+
targetSlot,
|
|
2095
|
+
ctx,
|
|
2096
|
+
(el) => `_rt.removeClass(${el}, ${ctx.generateExpression(arg)})`
|
|
2097
|
+
),
|
|
1970
2098
|
async: false,
|
|
1971
2099
|
sideEffects: true
|
|
1972
2100
|
};
|
|
1973
2101
|
}
|
|
1974
2102
|
};
|
|
2103
|
+
function variableStore(node, ctx) {
|
|
2104
|
+
let name;
|
|
2105
|
+
let scope;
|
|
2106
|
+
if (node.type === "variable") {
|
|
2107
|
+
name = node.name;
|
|
2108
|
+
scope = node.scope;
|
|
2109
|
+
} else if (node.type === "identifier") {
|
|
2110
|
+
name = node.value ?? node.name ?? "";
|
|
2111
|
+
if (/^(\$|::)/.test(name)) scope = "global";
|
|
2112
|
+
else if (/^[A-Za-z_]\w*$/.test(name)) scope = "local";
|
|
2113
|
+
else return null;
|
|
2114
|
+
} else {
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
const key = sanitizeIdentifier(name.replace(/^(\$|::|:)/, ""));
|
|
2118
|
+
if (scope === "global") {
|
|
2119
|
+
ctx.requireHelper("globals");
|
|
2120
|
+
return { read: `_rt.globals.get('${key}')`, write: (v) => `_rt.globals.set('${key}', ${v})` };
|
|
2121
|
+
}
|
|
2122
|
+
if (scope === "element") {
|
|
2123
|
+
ctx.requireHelper("elementVars");
|
|
2124
|
+
const store = `_rt.elementVars(_ctx.me)`;
|
|
2125
|
+
return { read: `${store}.get('${key}')`, write: (v) => `${store}.set('${key}', ${v})` };
|
|
2126
|
+
}
|
|
2127
|
+
return { read: `_ctx.locals.get('${key}')`, write: (v) => `_ctx.locals.set('${key}', ${v})` };
|
|
2128
|
+
}
|
|
1975
2129
|
var SetCodegen = class {
|
|
1976
2130
|
constructor() {
|
|
1977
2131
|
this.command = "set";
|
|
@@ -1984,26 +2138,8 @@ var SetCodegen = class {
|
|
|
1984
2138
|
const valueNode = roles?.patient ?? modifiers?.to ?? args[1];
|
|
1985
2139
|
if (!targetNode || !valueNode) return null;
|
|
1986
2140
|
const value = ctx.generateExpression(valueNode);
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
const name = varNode.name.startsWith(":") ? varNode.name.slice(1) : varNode.name;
|
|
1990
|
-
const safeName = sanitizeIdentifier(name);
|
|
1991
|
-
if (varNode.scope === "local") {
|
|
1992
|
-
return {
|
|
1993
|
-
code: `_ctx.locals.set('${safeName}', ${value})`,
|
|
1994
|
-
async: false,
|
|
1995
|
-
sideEffects: true
|
|
1996
|
-
};
|
|
1997
|
-
}
|
|
1998
|
-
if (varNode.scope === "global") {
|
|
1999
|
-
ctx.requireHelper("globals");
|
|
2000
|
-
return {
|
|
2001
|
-
code: `_rt.globals.set('${safeName}', ${value})`,
|
|
2002
|
-
async: false,
|
|
2003
|
-
sideEffects: true
|
|
2004
|
-
};
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2141
|
+
const store = variableStore(targetNode, ctx);
|
|
2142
|
+
if (store) return { code: store.write(value), async: false, sideEffects: true };
|
|
2007
2143
|
if (targetNode.type === "possessive") {
|
|
2008
2144
|
const possessive = targetNode;
|
|
2009
2145
|
const obj = ctx.generateExpression(possessive.object);
|
|
@@ -2052,20 +2188,17 @@ var PutCodegen = class {
|
|
|
2052
2188
|
const contentNode = roles?.patient ?? args[0];
|
|
2053
2189
|
if (!contentNode) return null;
|
|
2054
2190
|
const content = ctx.generateExpression(contentNode);
|
|
2055
|
-
let
|
|
2056
|
-
if (
|
|
2057
|
-
target = ctx.generateExpression(roles.destination);
|
|
2058
|
-
} else if (modifiers) {
|
|
2191
|
+
let targetNode = roles?.destination;
|
|
2192
|
+
if (!targetNode && modifiers) {
|
|
2059
2193
|
for (const key of ["into", "before", "after"]) {
|
|
2060
2194
|
if (modifiers[key] && typeof modifiers[key] === "object") {
|
|
2061
|
-
|
|
2195
|
+
targetNode = modifiers[key];
|
|
2062
2196
|
break;
|
|
2063
2197
|
}
|
|
2064
2198
|
}
|
|
2065
2199
|
}
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
}
|
|
2200
|
+
targetNode ?? (targetNode = node.target);
|
|
2201
|
+
const into = (op) => forEachTarget(targetNode, ctx, op);
|
|
2069
2202
|
let modifier = "into";
|
|
2070
2203
|
if (roles?.method && roles.method.value) {
|
|
2071
2204
|
modifier = String(roles.method.value);
|
|
@@ -2077,39 +2210,39 @@ var PutCodegen = class {
|
|
|
2077
2210
|
switch (modifier) {
|
|
2078
2211
|
case "into":
|
|
2079
2212
|
return {
|
|
2080
|
-
code: `${
|
|
2213
|
+
code: into((el) => `${el}.innerHTML = ${content}`),
|
|
2081
2214
|
async: false,
|
|
2082
2215
|
sideEffects: true
|
|
2083
2216
|
};
|
|
2084
2217
|
case "before":
|
|
2085
2218
|
return {
|
|
2086
|
-
code: `${
|
|
2219
|
+
code: into((el) => `${el}.insertAdjacentHTML('beforebegin', ${content})`),
|
|
2087
2220
|
async: false,
|
|
2088
2221
|
sideEffects: true
|
|
2089
2222
|
};
|
|
2090
2223
|
case "after":
|
|
2091
2224
|
return {
|
|
2092
|
-
code: `${
|
|
2225
|
+
code: into((el) => `${el}.insertAdjacentHTML('afterend', ${content})`),
|
|
2093
2226
|
async: false,
|
|
2094
2227
|
sideEffects: true
|
|
2095
2228
|
};
|
|
2096
2229
|
case "at start of":
|
|
2097
2230
|
case "start":
|
|
2098
2231
|
return {
|
|
2099
|
-
code: `${
|
|
2232
|
+
code: into((el) => `${el}.insertAdjacentHTML('afterbegin', ${content})`),
|
|
2100
2233
|
async: false,
|
|
2101
2234
|
sideEffects: true
|
|
2102
2235
|
};
|
|
2103
2236
|
case "at end of":
|
|
2104
2237
|
case "end":
|
|
2105
2238
|
return {
|
|
2106
|
-
code: `${
|
|
2239
|
+
code: into((el) => `${el}.insertAdjacentHTML('beforeend', ${content})`),
|
|
2107
2240
|
async: false,
|
|
2108
2241
|
sideEffects: true
|
|
2109
2242
|
};
|
|
2110
2243
|
default:
|
|
2111
2244
|
return {
|
|
2112
|
-
code: `${
|
|
2245
|
+
code: into((el) => `${el}.innerHTML = ${content}`),
|
|
2113
2246
|
async: false,
|
|
2114
2247
|
sideEffects: true
|
|
2115
2248
|
};
|
|
@@ -2121,9 +2254,9 @@ var ShowCodegen = class {
|
|
|
2121
2254
|
this.command = "show";
|
|
2122
2255
|
}
|
|
2123
2256
|
generate(node, ctx) {
|
|
2124
|
-
const
|
|
2257
|
+
const targetNode = commandTarget(node, "arg");
|
|
2125
2258
|
return {
|
|
2126
|
-
code: `${
|
|
2259
|
+
code: forEachTarget(targetNode, ctx, (el) => `${el}.style.display = ''`),
|
|
2127
2260
|
async: false,
|
|
2128
2261
|
sideEffects: true
|
|
2129
2262
|
};
|
|
@@ -2134,9 +2267,22 @@ var HideCodegen = class {
|
|
|
2134
2267
|
this.command = "hide";
|
|
2135
2268
|
}
|
|
2136
2269
|
generate(node, ctx) {
|
|
2137
|
-
const
|
|
2270
|
+
const targetNode = commandTarget(node, "arg");
|
|
2271
|
+
return {
|
|
2272
|
+
code: forEachTarget(targetNode, ctx, (el) => `${el}.style.display = 'none'`),
|
|
2273
|
+
async: false,
|
|
2274
|
+
sideEffects: true
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
};
|
|
2278
|
+
var EmptyCodegen = class {
|
|
2279
|
+
constructor() {
|
|
2280
|
+
this.command = "empty";
|
|
2281
|
+
}
|
|
2282
|
+
generate(node, ctx) {
|
|
2283
|
+
const targetNode = commandTarget(node, "arg");
|
|
2138
2284
|
return {
|
|
2139
|
-
code: `${
|
|
2285
|
+
code: forEachTarget(targetNode, ctx, (el) => `${el}.replaceChildren()`),
|
|
2140
2286
|
async: false,
|
|
2141
2287
|
sideEffects: true
|
|
2142
2288
|
};
|
|
@@ -2147,7 +2293,8 @@ var FocusCodegen = class {
|
|
|
2147
2293
|
this.command = "focus";
|
|
2148
2294
|
}
|
|
2149
2295
|
generate(node, ctx) {
|
|
2150
|
-
const
|
|
2296
|
+
const targetNode = commandTarget(node, "arg");
|
|
2297
|
+
const target = targetNode ? ctx.generateExpression(targetNode) : "_ctx.me";
|
|
2151
2298
|
return {
|
|
2152
2299
|
code: `${target}.focus()`,
|
|
2153
2300
|
async: false,
|
|
@@ -2160,7 +2307,8 @@ var BlurCodegen = class {
|
|
|
2160
2307
|
this.command = "blur";
|
|
2161
2308
|
}
|
|
2162
2309
|
generate(node, ctx) {
|
|
2163
|
-
const
|
|
2310
|
+
const targetNode = commandTarget(node, "arg");
|
|
2311
|
+
const target = targetNode ? ctx.generateExpression(targetNode) : "_ctx.me";
|
|
2164
2312
|
return {
|
|
2165
2313
|
code: `${target}.blur()`,
|
|
2166
2314
|
async: false,
|
|
@@ -2281,11 +2429,11 @@ var SendCodegen = class {
|
|
|
2281
2429
|
const args = node.args ?? [];
|
|
2282
2430
|
if (args.length === 0) return null;
|
|
2283
2431
|
const eventName = ctx.generateExpression(args[0]);
|
|
2284
|
-
const
|
|
2432
|
+
const targetNode = commandTarget(node, "on", "to");
|
|
2285
2433
|
const detail = args.length > 1 ? ctx.generateExpression(args[1]) : "undefined";
|
|
2286
2434
|
ctx.requireHelper("send");
|
|
2287
2435
|
return {
|
|
2288
|
-
code: `_rt.send(${
|
|
2436
|
+
code: forEachTarget(targetNode, ctx, (el) => `_rt.send(${el}, ${eventName}, ${detail})`),
|
|
2289
2437
|
async: false,
|
|
2290
2438
|
sideEffects: true
|
|
2291
2439
|
};
|
|
@@ -2303,25 +2451,10 @@ var IncrementCodegen = class {
|
|
|
2303
2451
|
if (!target) return null;
|
|
2304
2452
|
const amountNode = roles?.quantity ?? modifiers?.by ?? args[1];
|
|
2305
2453
|
const amount = amountNode ? ctx.generateExpression(amountNode) : "1";
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
const
|
|
2309
|
-
|
|
2310
|
-
if (varNode.scope === "local") {
|
|
2311
|
-
return {
|
|
2312
|
-
code: `_ctx.locals.set('${safeName}', (_ctx.locals.get('${safeName}') || 0) + ${amount})`,
|
|
2313
|
-
async: false,
|
|
2314
|
-
sideEffects: true
|
|
2315
|
-
};
|
|
2316
|
-
}
|
|
2317
|
-
if (varNode.scope === "global") {
|
|
2318
|
-
ctx.requireHelper("globals");
|
|
2319
|
-
return {
|
|
2320
|
-
code: `_rt.globals.set('${safeName}', (_rt.globals.get('${safeName}') || 0) + ${amount})`,
|
|
2321
|
-
async: false,
|
|
2322
|
-
sideEffects: true
|
|
2323
|
-
};
|
|
2324
|
-
}
|
|
2454
|
+
const store = variableStore(target, ctx);
|
|
2455
|
+
if (store) {
|
|
2456
|
+
const code = store.write(`(Number(${store.read}) || 0) + ${amount}`);
|
|
2457
|
+
return { code, async: false, sideEffects: true };
|
|
2325
2458
|
}
|
|
2326
2459
|
const targetCode = ctx.generateExpression(target);
|
|
2327
2460
|
return {
|
|
@@ -2343,25 +2476,10 @@ var DecrementCodegen = class {
|
|
|
2343
2476
|
if (!target) return null;
|
|
2344
2477
|
const amountNode = roles?.quantity ?? modifiers?.by ?? args[1];
|
|
2345
2478
|
const amount = amountNode ? ctx.generateExpression(amountNode) : "1";
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
const
|
|
2349
|
-
|
|
2350
|
-
if (varNode.scope === "local") {
|
|
2351
|
-
return {
|
|
2352
|
-
code: `_ctx.locals.set('${safeName}', (_ctx.locals.get('${safeName}') || 0) - ${amount})`,
|
|
2353
|
-
async: false,
|
|
2354
|
-
sideEffects: true
|
|
2355
|
-
};
|
|
2356
|
-
}
|
|
2357
|
-
if (varNode.scope === "global") {
|
|
2358
|
-
ctx.requireHelper("globals");
|
|
2359
|
-
return {
|
|
2360
|
-
code: `_rt.globals.set('${safeName}', (_rt.globals.get('${safeName}') || 0) - ${amount})`,
|
|
2361
|
-
async: false,
|
|
2362
|
-
sideEffects: true
|
|
2363
|
-
};
|
|
2364
|
-
}
|
|
2479
|
+
const store = variableStore(target, ctx);
|
|
2480
|
+
if (store) {
|
|
2481
|
+
const code = store.write(`(Number(${store.read}) || 0) - ${amount}`);
|
|
2482
|
+
return { code, async: false, sideEffects: true };
|
|
2365
2483
|
}
|
|
2366
2484
|
const targetCode = ctx.generateExpression(target);
|
|
2367
2485
|
return {
|
|
@@ -2426,17 +2544,37 @@ var CallCodegen = class {
|
|
|
2426
2544
|
};
|
|
2427
2545
|
}
|
|
2428
2546
|
};
|
|
2547
|
+
var SCROLL_BLOCK = {
|
|
2548
|
+
top: "start",
|
|
2549
|
+
middle: "center",
|
|
2550
|
+
bottom: "end",
|
|
2551
|
+
nearest: "nearest"
|
|
2552
|
+
};
|
|
2553
|
+
var SCROLL_INLINE = { left: "start", center: "center", right: "end" };
|
|
2554
|
+
function scrollOptions(modifiers) {
|
|
2555
|
+
const word = (slot) => {
|
|
2556
|
+
const value = modifiers?.[slot]?.value;
|
|
2557
|
+
return typeof value === "string" ? value : void 0;
|
|
2558
|
+
};
|
|
2559
|
+
const position = word("position") ?? "";
|
|
2560
|
+
const options = [];
|
|
2561
|
+
if (SCROLL_BLOCK[position]) options.push(`block: '${SCROLL_BLOCK[position]}'`);
|
|
2562
|
+
if (SCROLL_INLINE[position]) options.push(`inline: '${SCROLL_INLINE[position]}'`);
|
|
2563
|
+
const behavior = modifiers?.smooth ? "smooth" : word("behavior");
|
|
2564
|
+
options.push(
|
|
2565
|
+
`behavior: '${behavior === "smooth" || behavior === "instant" ? behavior : "auto"}'`
|
|
2566
|
+
);
|
|
2567
|
+
return `{ ${options.join(", ")} }`;
|
|
2568
|
+
}
|
|
2429
2569
|
var ScrollCodegen = class {
|
|
2430
2570
|
constructor() {
|
|
2431
2571
|
this.command = "scroll";
|
|
2432
2572
|
}
|
|
2433
2573
|
generate(node, ctx) {
|
|
2434
|
-
const
|
|
2435
|
-
const
|
|
2436
|
-
const smooth = mods?.smooth || mods?.behavior?.value === "smooth";
|
|
2437
|
-
const behavior = smooth ? "'smooth'" : "'auto'";
|
|
2574
|
+
const targetNode = commandTarget(node, "arg", "of");
|
|
2575
|
+
const target = targetNode ? ctx.generateExpression(targetNode) : "_ctx.me";
|
|
2438
2576
|
return {
|
|
2439
|
-
code: `${target}.scrollIntoView(
|
|
2577
|
+
code: `${target}.scrollIntoView(${scrollOptions(node.modifiers)})`,
|
|
2440
2578
|
async: false,
|
|
2441
2579
|
sideEffects: true
|
|
2442
2580
|
};
|
|
@@ -2446,7 +2584,7 @@ var TakeCodegen = class {
|
|
|
2446
2584
|
constructor() {
|
|
2447
2585
|
this.command = "take";
|
|
2448
2586
|
}
|
|
2449
|
-
generate(node,
|
|
2587
|
+
generate(node, ctx) {
|
|
2450
2588
|
const args = node.args ?? [];
|
|
2451
2589
|
if (args.length === 0) return null;
|
|
2452
2590
|
const arg = args[0];
|
|
@@ -2455,6 +2593,19 @@ var TakeCodegen = class {
|
|
|
2455
2593
|
if (!selector.startsWith(".")) return null;
|
|
2456
2594
|
const className = sanitizeClassName(selector.slice(1));
|
|
2457
2595
|
if (!className) return null;
|
|
2596
|
+
const source = commandTarget(node, "from");
|
|
2597
|
+
if (source) {
|
|
2598
|
+
let from = allMatches(source, ctx);
|
|
2599
|
+
if (!from) {
|
|
2600
|
+
ctx.requireHelper("toArray");
|
|
2601
|
+
from = `_rt.toArray(${ctx.generateExpression(source)})`;
|
|
2602
|
+
}
|
|
2603
|
+
return {
|
|
2604
|
+
code: `(() => { ${from}.forEach(el => el.classList.remove('${className}')); _ctx.me.classList.add('${className}'); })()`,
|
|
2605
|
+
async: false,
|
|
2606
|
+
sideEffects: true
|
|
2607
|
+
};
|
|
2608
|
+
}
|
|
2458
2609
|
return {
|
|
2459
2610
|
code: `(() => { const _me = _ctx.me; _me.parentElement?.querySelectorAll('.${className}').forEach(el => el.classList.remove('${className}')); _me.classList.add('${className}'); })()`,
|
|
2460
2611
|
async: false,
|
|
@@ -2486,49 +2637,85 @@ ${elseBody}
|
|
|
2486
2637
|
}
|
|
2487
2638
|
return code;
|
|
2488
2639
|
}
|
|
2640
|
+
function emitLoop(parts) {
|
|
2641
|
+
const pass = [
|
|
2642
|
+
...parts.elseBody !== void 0 ? ["_ran = true;"] : [],
|
|
2643
|
+
...parts.enter ? [parts.enter] : [],
|
|
2644
|
+
...parts.indexName ? [`_ctx.locals.set('${sanitizeIdentifier(parts.indexName)}', _i);`] : [],
|
|
2645
|
+
parts.body
|
|
2646
|
+
].join("\n");
|
|
2647
|
+
const step = parts.step ? `_i++, ${parts.step}` : "_i++";
|
|
2648
|
+
const loop = parts.bottomTested ? (
|
|
2649
|
+
// A `continue` jumps straight to the test, so the counter moves there.
|
|
2650
|
+
`let _i = 0;
|
|
2651
|
+
do {
|
|
2652
|
+
${pass}
|
|
2653
|
+
} while ((${step}, ${parts.test}));`
|
|
2654
|
+
) : `for (let _i = 0; ${parts.test}; ${step}) {
|
|
2655
|
+
${pass}
|
|
2656
|
+
}`;
|
|
2657
|
+
if (parts.elseBody === void 0) return parts.bottomTested ? `{
|
|
2658
|
+
${loop}
|
|
2659
|
+
}` : loop;
|
|
2660
|
+
return `{
|
|
2661
|
+
let _ran = false;
|
|
2662
|
+
${loop}
|
|
2663
|
+
if (!_ran) {
|
|
2664
|
+
${parts.elseBody}
|
|
2665
|
+
}
|
|
2666
|
+
}`;
|
|
2667
|
+
}
|
|
2489
2668
|
function generateRepeat(node, ctx, generateBody) {
|
|
2490
2669
|
const exprCodegen = new ExpressionCodegen(ctx);
|
|
2491
|
-
const
|
|
2670
|
+
const shared = {
|
|
2671
|
+
indexName: node.indexName,
|
|
2672
|
+
body: generateBody(node.body),
|
|
2673
|
+
elseBody: node.elseBody ? generateBody(node.elseBody) : void 0
|
|
2674
|
+
};
|
|
2492
2675
|
if (node.count !== void 0) {
|
|
2493
2676
|
const count = typeof node.count === "number" ? String(node.count) : exprCodegen.generate(node.count);
|
|
2494
|
-
return
|
|
2495
|
-
_ctx.locals.set('index', _i);
|
|
2496
|
-
${body}
|
|
2497
|
-
}`;
|
|
2677
|
+
return emitLoop({ ...shared, test: `_i < ${count}`, indexName: node.indexName ?? "index" });
|
|
2498
2678
|
}
|
|
2499
2679
|
if (node.whileCondition) {
|
|
2500
|
-
|
|
2501
|
-
return `while (${condition}) {
|
|
2502
|
-
${body}
|
|
2503
|
-
}`;
|
|
2680
|
+
return emitLoop({ ...shared, test: exprCodegen.generate(node.whileCondition) });
|
|
2504
2681
|
}
|
|
2505
|
-
|
|
2506
|
-
|
|
2682
|
+
if (node.untilEvent !== void 0) {
|
|
2683
|
+
ctx.requireHelper("wait");
|
|
2684
|
+
const target = node.untilEventTarget ? exprCodegen.generate(node.untilEventTarget) : "_ctx.me";
|
|
2685
|
+
return `{
|
|
2686
|
+
let _fired = false;
|
|
2687
|
+
${target}.addEventListener(${JSON.stringify(node.untilEvent)}, () => { _fired = true; }, { once: true });
|
|
2688
|
+
${emitLoop({ ...shared, test: "!_fired", step: "await _rt.wait(0)" })}
|
|
2507
2689
|
}`;
|
|
2690
|
+
}
|
|
2691
|
+
return emitLoop({ ...shared, test: "true" });
|
|
2508
2692
|
}
|
|
2509
2693
|
function generateForEach(node, ctx, generateBody) {
|
|
2510
2694
|
const exprCodegen = new ExpressionCodegen(ctx);
|
|
2511
|
-
const
|
|
2695
|
+
const source = node.collection;
|
|
2696
|
+
const collection = source.type === "selector" && !String(source.value).startsWith("#") ? `document.querySelectorAll('${sanitizeSelector(String(source.value))}')` : exprCodegen.generate(source);
|
|
2512
2697
|
const itemName = sanitizeIdentifier(node.itemName);
|
|
2513
|
-
const indexName = node.indexName ? sanitizeIdentifier(node.indexName) : "index";
|
|
2514
|
-
const body = generateBody(node.body);
|
|
2515
2698
|
return `{
|
|
2516
2699
|
const _collection = ${collection};
|
|
2517
|
-
const _arr = Array.isArray(_collection) ? _collection : Array.from(_collection);
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
_ctx.locals.set('${
|
|
2521
|
-
|
|
2522
|
-
|
|
2700
|
+
const _arr = _collection == null ? [] : Array.isArray(_collection) ? _collection : Array.from(_collection);
|
|
2701
|
+
${emitLoop({
|
|
2702
|
+
test: "_i < _arr.length",
|
|
2703
|
+
enter: `_ctx.locals.set('${itemName}', _arr[_i]);`,
|
|
2704
|
+
indexName: node.indexName ?? "index",
|
|
2705
|
+
body: generateBody(node.body),
|
|
2706
|
+
elseBody: node.elseBody ? generateBody(node.elseBody) : void 0
|
|
2707
|
+
})}
|
|
2523
2708
|
}`;
|
|
2524
2709
|
}
|
|
2525
2710
|
function generateWhile(node, ctx, generateBody) {
|
|
2526
2711
|
const exprCodegen = new ExpressionCodegen(ctx);
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2712
|
+
return emitLoop({
|
|
2713
|
+
test: exprCodegen.generate(node.condition),
|
|
2714
|
+
bottomTested: node.bottomTested,
|
|
2715
|
+
indexName: node.indexName,
|
|
2716
|
+
body: generateBody(node.body),
|
|
2717
|
+
elseBody: node.elseBody ? generateBody(node.elseBody) : void 0
|
|
2718
|
+
});
|
|
2532
2719
|
}
|
|
2533
2720
|
var UnlessCodegen = class {
|
|
2534
2721
|
constructor() {
|
|
@@ -2571,25 +2758,10 @@ var DefaultCodegen = class {
|
|
|
2571
2758
|
const valueNode = roles?.patient ?? modifiers?.to ?? args[1];
|
|
2572
2759
|
if (!targetNode || !valueNode) return null;
|
|
2573
2760
|
const value = ctx.generateExpression(valueNode);
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
const
|
|
2577
|
-
|
|
2578
|
-
if (varNode.scope === "local") {
|
|
2579
|
-
return {
|
|
2580
|
-
code: `if (_ctx.locals.get('${safeName}') == null) _ctx.locals.set('${safeName}', ${value})`,
|
|
2581
|
-
async: false,
|
|
2582
|
-
sideEffects: true
|
|
2583
|
-
};
|
|
2584
|
-
}
|
|
2585
|
-
if (varNode.scope === "global") {
|
|
2586
|
-
ctx.requireHelper("globals");
|
|
2587
|
-
return {
|
|
2588
|
-
code: `if (_rt.globals.get('${safeName}') == null) _rt.globals.set('${safeName}', ${value})`,
|
|
2589
|
-
async: false,
|
|
2590
|
-
sideEffects: true
|
|
2591
|
-
};
|
|
2592
|
-
}
|
|
2761
|
+
const store = variableStore(targetNode, ctx);
|
|
2762
|
+
if (store) {
|
|
2763
|
+
const code = `if (${store.read} == null) ${store.write(value)}`;
|
|
2764
|
+
return { code, async: false, sideEffects: true };
|
|
2593
2765
|
}
|
|
2594
2766
|
return null;
|
|
2595
2767
|
}
|
|
@@ -2605,6 +2777,15 @@ var GoCodegen = class {
|
|
|
2605
2777
|
if (mods?.back) {
|
|
2606
2778
|
return { code: "history.back()", async: false, sideEffects: true };
|
|
2607
2779
|
}
|
|
2780
|
+
if (mods?.position || mods?.behavior) {
|
|
2781
|
+
const element = roles?.destination ?? args[0];
|
|
2782
|
+
if (!element) return null;
|
|
2783
|
+
return {
|
|
2784
|
+
code: `${ctx.generateExpression(element)}.scrollIntoView(${scrollOptions(mods)})`,
|
|
2785
|
+
async: false,
|
|
2786
|
+
sideEffects: true
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2608
2789
|
const target = mods?.url ?? roles?.destination ?? args[0];
|
|
2609
2790
|
if (!target) return null;
|
|
2610
2791
|
if (target.type === "identifier") {
|
|
@@ -2616,9 +2797,10 @@ var GoCodegen = class {
|
|
|
2616
2797
|
return { code: "history.forward()", async: false, sideEffects: true };
|
|
2617
2798
|
}
|
|
2618
2799
|
}
|
|
2619
|
-
|
|
2800
|
+
ctx.requireHelper("go");
|
|
2801
|
+
const newWindow = mods?.in !== void 0 ? ", true" : "";
|
|
2620
2802
|
return {
|
|
2621
|
-
code: `
|
|
2803
|
+
code: `_rt.go(${ctx.generateExpression(target)}${newWindow})`,
|
|
2622
2804
|
async: false,
|
|
2623
2805
|
sideEffects: true
|
|
2624
2806
|
};
|
|
@@ -2634,7 +2816,8 @@ var AppendCodegen = class {
|
|
|
2634
2816
|
const contentNode = roles?.patient ?? args[0];
|
|
2635
2817
|
if (!contentNode) return null;
|
|
2636
2818
|
const content = ctx.generateExpression(contentNode);
|
|
2637
|
-
const
|
|
2819
|
+
const targetNode = commandTarget(node, "to");
|
|
2820
|
+
const target = targetNode ? ctx.generateExpression(targetNode) : "_ctx.me";
|
|
2638
2821
|
return {
|
|
2639
2822
|
code: `${target}.insertAdjacentHTML('beforeend', ${content})`,
|
|
2640
2823
|
async: false,
|
|
@@ -3013,7 +3196,8 @@ var SettleCodegen = class {
|
|
|
3013
3196
|
this.command = "settle";
|
|
3014
3197
|
}
|
|
3015
3198
|
generate(node, ctx) {
|
|
3016
|
-
const
|
|
3199
|
+
const targetNode = commandTarget(node, "arg");
|
|
3200
|
+
const target = targetNode ? ctx.generateExpression(targetNode) : "_ctx.me";
|
|
3017
3201
|
const mods = node.modifiers;
|
|
3018
3202
|
const timeoutNode = mods?.for;
|
|
3019
3203
|
const timeout = timeoutNode ? ctx.generateExpression(timeoutNode) : "5000";
|
|
@@ -3133,6 +3317,7 @@ var commandCodegens = /* @__PURE__ */ new Map([
|
|
|
3133
3317
|
["put", new PutCodegen()],
|
|
3134
3318
|
["show", new ShowCodegen()],
|
|
3135
3319
|
["hide", new HideCodegen()],
|
|
3320
|
+
["empty", new EmptyCodegen()],
|
|
3136
3321
|
["focus", new FocusCodegen()],
|
|
3137
3322
|
["blur", new BlurCodegen()],
|
|
3138
3323
|
["log", new LogCodegen()],
|
|
@@ -3259,6 +3444,8 @@ var EventHandlerCodegen = class {
|
|
|
3259
3444
|
return generateForEach(node, this.ctx, (nodes) => this.generateBody(nodes));
|
|
3260
3445
|
case "while":
|
|
3261
3446
|
return generateWhile(node, this.ctx, (nodes) => this.generateBody(nodes));
|
|
3447
|
+
case "sequence":
|
|
3448
|
+
return this.generateBody(node.commands);
|
|
3262
3449
|
case "event": {
|
|
3263
3450
|
const nested = node;
|
|
3264
3451
|
return this.generateBody(nested.body ?? []);
|
|
@@ -4131,15 +4318,8 @@ var AOTCompiler = class {
|
|
|
4131
4318
|
* Create a codegen context.
|
|
4132
4319
|
*/
|
|
4133
4320
|
createCodegenContext(handlerId, analysis, options) {
|
|
4134
|
-
const selectorCache = /* @__PURE__ */ new Map();
|
|
4135
4321
|
const requiredHelpers = /* @__PURE__ */ new Set();
|
|
4136
4322
|
let idCounter = 0;
|
|
4137
|
-
for (const info of analysis.expressions.selectors) {
|
|
4138
|
-
if (info.canCache && info.usages.length > 1) {
|
|
4139
|
-
const cacheKey = "_sel_" + sanitizeIdentifier(info.selector).slice(0, 20) + "_" + idCounter++;
|
|
4140
|
-
selectorCache.set(info.selector, cacheKey);
|
|
4141
|
-
}
|
|
4142
|
-
}
|
|
4143
4323
|
const exprCodegenRef = { current: null };
|
|
4144
4324
|
const ctx = {
|
|
4145
4325
|
handlerId,
|
|
@@ -4152,8 +4332,12 @@ var AOTCompiler = class {
|
|
|
4152
4332
|
},
|
|
4153
4333
|
implicitTarget: "_ctx.me",
|
|
4154
4334
|
localVarDeclarations: "",
|
|
4155
|
-
|
|
4156
|
-
|
|
4335
|
+
// A selector is queried each time it is evaluated, as on both engines. The
|
|
4336
|
+
// cache named a variable nothing declared (`_sel__d1_0`: a handler naming
|
|
4337
|
+
// #d1 twice threw), and a declared one goes stale when the handler
|
|
4338
|
+
// replaces the element.
|
|
4339
|
+
canCacheSelector: () => false,
|
|
4340
|
+
getCachedSelector: (selector) => `document.querySelector('${selector}')`,
|
|
4157
4341
|
requireHelper: (name) => {
|
|
4158
4342
|
requiredHelpers.add(name);
|
|
4159
4343
|
},
|
|
@@ -4223,7 +4407,7 @@ async function compileHyperscript(code, options) {
|
|
|
4223
4407
|
async function createMultilingualCompiler() {
|
|
4224
4408
|
const compiler = new AOTCompiler();
|
|
4225
4409
|
try {
|
|
4226
|
-
const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-W5UPZR4X-
|
|
4410
|
+
const { createCoreParserAdapter: createCoreParserAdapter2 } = await import("./core-parser-adapter-W5UPZR4X-7CPPQMOH.js");
|
|
4227
4411
|
compiler.setParser(await createCoreParserAdapter2());
|
|
4228
4412
|
} catch {
|
|
4229
4413
|
}
|
|
@@ -4276,4 +4460,4 @@ export {
|
|
|
4276
4460
|
sanitizeSelector,
|
|
4277
4461
|
scanFiles
|
|
4278
4462
|
};
|
|
4279
|
-
//# sourceMappingURL=dist-
|
|
4463
|
+
//# sourceMappingURL=dist-BDTQTYGC.js.map
|