@lark.js/mvc 0.0.7 → 0.0.9

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 CHANGED
@@ -40,23 +40,28 @@ __export(index_exports, {
40
40
  Updater: () => Updater,
41
41
  VIEW_EVENT_METHOD_REGEXP: () => VIEW_EVENT_METHOD_REGEXP,
42
42
  View: () => View,
43
+ applyDomOps: () => applyDomOps,
43
44
  applyIdUpdates: () => applyIdUpdates,
44
45
  applyStyle: () => applyStyle,
45
- applyVdomOps: () => applyVdomOps,
46
46
  assign: () => assign,
47
47
  bindStore: () => bindStore,
48
- compileTemplate: () => compileTemplate,
49
48
  computed: () => computed,
50
49
  create: () => create,
51
- createVdomRef: () => createVdomRef,
50
+ createDomRef: () => createDomRef,
52
51
  defineStore: () => defineStore,
53
52
  defineView: () => defineView,
53
+ domGetCompareKey: () => domGetCompareKey,
54
+ domGetNode: () => domGetNode,
55
+ domSetAttributes: () => domSetAttributes,
56
+ domSetChildNodes: () => domSetChildNodes,
57
+ domSetNode: () => domSetNode,
58
+ domSpecialDiff: () => domSpecialDiff,
59
+ domUnmountFrames: () => domUnmountFrames,
54
60
  encodeHTML: () => encodeHTML,
55
61
  encodeQ: () => encodeQ,
56
62
  encodeSafe: () => encodeSafe,
57
63
  encodeURIExtra: () => encodeURIExtra,
58
64
  ensureElementId: () => ensureElementId,
59
- extractGlobalVars: () => extractGlobalVars,
60
65
  frameworkConfig: () => config,
61
66
  funcWithTry: () => funcWithTry,
62
67
  generateId: () => generateId,
@@ -89,14 +94,7 @@ __export(index_exports, {
89
94
  translateData: () => translateData,
90
95
  unmark: () => unmark,
91
96
  use: () => use,
92
- useUrlState: () => useUrlState,
93
- vdomGetCompareKey: () => vdomGetCompareKey,
94
- vdomGetNode: () => vdomGetNode,
95
- vdomSetAttributes: () => vdomSetAttributes,
96
- vdomSetChildNodes: () => vdomSetChildNodes,
97
- vdomSetNode: () => vdomSetNode,
98
- vdomSpecialDiff: () => vdomSpecialDiff,
99
- vdomUnmountFrames: () => vdomUnmountFrames
97
+ useUrlState: () => useUrlState
100
98
  });
101
99
  module.exports = __toCommonJS(index_exports);
102
100
 
@@ -108,14 +106,6 @@ var RouterEvents = {
108
106
  CHANGED: "changed",
109
107
  PAGE_UNLOAD: "page_unload"
110
108
  };
111
- var LarkInnerKeys = {
112
- /** Attribute name: ldk (static key for skipping VDOM diff) */
113
- DIFF_KEY: "ldk",
114
- /** Attribute name: lak (static attribute key) */
115
- ATTR_KEY: "lak",
116
- /** Attribute name: lvk (view key for assign) */
117
- VIEW_KEY: "lvk"
118
- };
119
109
  var LARK_VIEW = "v-lark";
120
110
  var EVENT_METHOD_REGEXP = new RegExp(
121
111
  `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
@@ -897,6 +887,9 @@ function attachViewAndPath(loc) {
897
887
  if (!loc.view) {
898
888
  const rawPath = routeMode === "history" ? loc.query["path"] || loc.hash["path"] : loc.hash["path"];
899
889
  let path = rawPath || cachedDefaultPath || "/";
890
+ if (!cachedRoutes[path] && path === "/" && cachedDefaultPath && cachedDefaultPath !== "/") {
891
+ path = cachedDefaultPath;
892
+ }
900
893
  if (cachedRewrite) {
901
894
  path = cachedRewrite(
902
895
  path,
@@ -965,6 +958,10 @@ function getChanged(oldLoc, newLoc) {
965
958
  function updateBrowserUrl(path, replace) {
966
959
  if (routeMode === "history") {
967
960
  const url = path || "/";
961
+ const currentUrl = window.location.pathname + window.location.search;
962
+ if (url === currentUrl) {
963
+ return;
964
+ }
968
965
  if (replace) {
969
966
  window.history.replaceState(null, "", url);
970
967
  } else {
@@ -986,6 +983,9 @@ function updateUrl(path, params, loc, replace, silentFlag, lQuery) {
986
983
  if (path !== currentSrc) {
987
984
  silent = silentFlag ? 1 : 0;
988
985
  updateBrowserUrl(path, replace);
986
+ if (routeMode === "history" && Router.notify) {
987
+ Router.notify();
988
+ }
989
989
  }
990
990
  }
991
991
  var Router = {
@@ -1465,7 +1465,7 @@ var EventDelegator = {
1465
1465
  }
1466
1466
  };
1467
1467
 
1468
- // src/vdom.ts
1468
+ // src/dom.ts
1469
1469
  var wrapMeta = {
1470
1470
  option: [1, "<select multiple>"],
1471
1471
  thead: [1, "<table>"],
@@ -1485,12 +1485,12 @@ var VDoc = document.implementation.createHTMLDocument("");
1485
1485
  var VBase = VDoc.createElement("base");
1486
1486
  VBase.href = document.location.href;
1487
1487
  VDoc.head.appendChild(VBase);
1488
- var VDomSpecials = {
1488
+ var DomSpecials = {
1489
1489
  INPUT: ["value", "checked"],
1490
1490
  TEXTAREA: ["value"],
1491
1491
  OPTION: ["selected"]
1492
1492
  };
1493
- function vdomUnmountFrames(frame, node) {
1493
+ function domUnmountFrames(frame, node) {
1494
1494
  if (!(node instanceof Element)) return;
1495
1495
  const id = node.getAttribute("id");
1496
1496
  if (!id) return;
@@ -1499,7 +1499,7 @@ function vdomUnmountFrames(frame, node) {
1499
1499
  frame.unmountFrame(id);
1500
1500
  }
1501
1501
  }
1502
- function vdomGetNode(html, refNode) {
1502
+ function domGetNode(html, refNode) {
1503
1503
  const tmp = VDoc.createElement("div");
1504
1504
  const ns = refNode.namespaceURI;
1505
1505
  let tag;
@@ -1520,16 +1520,13 @@ function vdomGetNode(html, refNode) {
1520
1520
  }
1521
1521
  return tmp;
1522
1522
  }
1523
- function vdomGetCompareKey(node) {
1523
+ function domGetCompareKey(node) {
1524
1524
  if (node.nodeType !== 1) return void 0;
1525
1525
  const el = node;
1526
1526
  if (el.compareKeyCached) {
1527
1527
  return el.cachedCompareKey;
1528
1528
  }
1529
1529
  let key = el.autoId ? "" : el.getAttribute("id") || void 0;
1530
- if (!key) {
1531
- key = el.getAttribute(LarkInnerKeys.DIFF_KEY) || void 0;
1532
- }
1533
1530
  if (!key) {
1534
1531
  const larkView = el.getAttribute(LARK_VIEW);
1535
1532
  if (larkView) {
@@ -1540,8 +1537,8 @@ function vdomGetCompareKey(node) {
1540
1537
  el.cachedCompareKey = key || "";
1541
1538
  return key;
1542
1539
  }
1543
- function vdomSpecialDiff(oldNode, newNode) {
1544
- const specials = VDomSpecials[oldNode.nodeName];
1540
+ function domSpecialDiff(oldNode, newNode) {
1541
+ const specials = DomSpecials[oldNode.nodeName];
1545
1542
  if (!specials) return 0;
1546
1543
  const oldEl = oldNode;
1547
1544
  const newEl = newNode;
@@ -1554,7 +1551,7 @@ function vdomSpecialDiff(oldNode, newNode) {
1554
1551
  }
1555
1552
  return result;
1556
1553
  }
1557
- function vdomSetAttributes(oldNode, newNode, ref, keepId) {
1554
+ function domSetAttributes(oldNode, newNode, ref, keepId) {
1558
1555
  const oldEl = oldNode;
1559
1556
  Reflect.deleteProperty(oldEl, "compareKeyCached");
1560
1557
  const oldAttrs = oldNode.attributes;
@@ -1586,7 +1583,7 @@ function vdomSetAttributes(oldNode, newNode, ref, keepId) {
1586
1583
  }
1587
1584
  }
1588
1585
  }
1589
- function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1586
+ function domSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1590
1587
  let oldNode = oldParent.lastChild;
1591
1588
  let newNode = newParent.firstChild;
1592
1589
  let extra = 0;
@@ -1594,7 +1591,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1594
1591
  const newKeyedNodes = /* @__PURE__ */ new Map();
1595
1592
  while (oldNode) {
1596
1593
  extra++;
1597
- const nodeKey = vdomGetCompareKey(oldNode);
1594
+ const nodeKey = domGetCompareKey(oldNode);
1598
1595
  if (nodeKey) {
1599
1596
  let bucket = keyedNodes.get(nodeKey);
1600
1597
  if (!bucket) {
@@ -1606,7 +1603,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1606
1603
  oldNode = oldNode.previousSibling;
1607
1604
  }
1608
1605
  while (newNode) {
1609
- const nodeKey = vdomGetCompareKey(newNode);
1606
+ const nodeKey = domGetCompareKey(newNode);
1610
1607
  if (nodeKey) {
1611
1608
  newKeyedNodes.set(nodeKey, (newKeyedNodes.get(nodeKey) ?? 0) + 1);
1612
1609
  }
@@ -1618,7 +1615,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1618
1615
  extra--;
1619
1616
  const tempNew = newNode;
1620
1617
  newNode = newNode.nextSibling;
1621
- const nodeKey = vdomGetCompareKey(tempNew);
1618
+ const nodeKey = domGetCompareKey(tempNew);
1622
1619
  let foundNode = nodeKey ? keyedNodes.get(nodeKey) : void 0;
1623
1620
  if (foundNode && (foundNode = foundNode.slice()) && foundNode.length) {
1624
1621
  const matched = foundNode.pop();
@@ -1633,17 +1630,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1633
1630
  const c = newKeyedNodes.get(nodeKey);
1634
1631
  if (c) newKeyedNodes.set(nodeKey, c - 1);
1635
1632
  }
1636
- vdomSetNode(matched, tempNew, oldParent, ref, frame, keys_);
1633
+ domSetNode(matched, tempNew, oldParent, ref, frame, keys_);
1637
1634
  } else if (oldNode) {
1638
1635
  const tempOld2 = oldNode;
1639
- const oldKey = vdomGetCompareKey(tempOld2);
1636
+ const oldKey = domGetCompareKey(tempOld2);
1640
1637
  if (oldKey && keyedNodes.has(oldKey) && newKeyedNodes.get(oldKey)) {
1641
1638
  extra++;
1642
1639
  ref.hasChanged = 1;
1643
1640
  ref.domOps.push([8, oldParent, tempNew, tempOld2]);
1644
1641
  } else {
1645
1642
  oldNode = oldNode.nextSibling;
1646
- vdomSetNode(tempOld2, tempNew, oldParent, ref, frame, keys_);
1643
+ domSetNode(tempOld2, tempNew, oldParent, ref, frame, keys_);
1647
1644
  }
1648
1645
  } else {
1649
1646
  ref.hasChanged = 1;
@@ -1653,29 +1650,23 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1653
1650
  let tempOld = oldParent.lastChild;
1654
1651
  while (extra-- > 0) {
1655
1652
  if (tempOld) {
1656
- vdomUnmountFrames(frame, tempOld);
1653
+ domUnmountFrames(frame, tempOld);
1657
1654
  ref.domOps.push([2, oldParent, tempOld]);
1658
1655
  tempOld = tempOld.previousSibling;
1659
1656
  ref.hasChanged = 1;
1660
1657
  }
1661
1658
  }
1662
1659
  }
1663
- function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1660
+ function domSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1664
1661
  const oldAsEl = oldNode instanceof Element ? oldNode : null;
1665
1662
  const newAsEl = newNode instanceof Element ? newNode : null;
1666
- const hasViewKey = !!oldAsEl?.hasAttribute(LarkInnerKeys.VIEW_KEY);
1667
1663
  const equalAsNodes = oldAsEl !== null && newAsEl !== null && oldAsEl.isEqualNode && oldAsEl.isEqualNode(newAsEl);
1668
- if (vdomSpecialDiff(oldNode, newNode) || hasViewKey || !equalAsNodes) {
1664
+ if (domSpecialDiff(oldNode, newNode) || !equalAsNodes) {
1669
1665
  if (oldNode.nodeType === newNode.nodeType && oldNode.nodeName === newNode.nodeName) {
1670
1666
  if (oldAsEl !== null && newAsEl !== null) {
1671
1667
  const oldEl = oldAsEl;
1672
1668
  const newEl = newAsEl;
1673
- const staticKey = newEl.getAttribute(LarkInnerKeys.DIFF_KEY);
1674
- if (staticKey && staticKey === oldEl.getAttribute(LarkInnerKeys.DIFF_KEY)) {
1675
- return;
1676
- }
1677
1669
  const newLarkView = newEl.getAttribute(LARK_VIEW);
1678
- const updateAttribute = !newEl.getAttribute(LarkInnerKeys.ATTR_KEY) || newEl.getAttribute(LarkInnerKeys.ATTR_KEY) !== oldEl.getAttribute(LarkInnerKeys.ATTR_KEY);
1679
1670
  let updateChildren = true;
1680
1671
  if (newLarkView) {
1681
1672
  const oldFrameId = oldEl.getAttribute("id") || "";
@@ -1686,11 +1677,9 @@ function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1686
1677
  updateChildren = false;
1687
1678
  }
1688
1679
  }
1689
- if (updateAttribute) {
1690
- vdomSetAttributes(oldEl, newEl, ref, !!newLarkView);
1691
- }
1680
+ domSetAttributes(oldEl, newEl, ref, !!newLarkView);
1692
1681
  if (updateChildren) {
1693
- vdomSetChildNodes(oldEl, newEl, ref, frame, keys_);
1682
+ domSetChildNodes(oldEl, newEl, ref, frame, keys_);
1694
1683
  }
1695
1684
  } else if (oldNode.nodeValue !== newNode.nodeValue) {
1696
1685
  ref.hasChanged = 1;
@@ -1698,12 +1687,12 @@ function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1698
1687
  }
1699
1688
  } else {
1700
1689
  ref.hasChanged = 1;
1701
- vdomUnmountFrames(frame, oldNode);
1690
+ domUnmountFrames(frame, oldNode);
1702
1691
  ref.domOps.push([4, oldParent, newNode, oldNode]);
1703
1692
  }
1704
1693
  }
1705
1694
  }
1706
- function createVdomRef() {
1695
+ function createDomRef() {
1707
1696
  return {
1708
1697
  idUpdates: [],
1709
1698
  views: [],
@@ -1711,7 +1700,7 @@ function createVdomRef() {
1711
1700
  hasChanged: 0
1712
1701
  };
1713
1702
  }
1714
- function applyVdomOps(ops) {
1703
+ function applyDomOps(ops) {
1715
1704
  for (const op of ops) {
1716
1705
  switch (op[0]) {
1717
1706
  case 1:
@@ -1850,11 +1839,11 @@ var Updater = class {
1850
1839
  return this;
1851
1840
  }
1852
1841
  /**
1853
- * Detect changes and trigger VDOM re-render.
1842
+ * Detect changes and trigger DOM re-render.
1854
1843
  *
1855
1844
  * The core rendering pipeline:
1856
1845
  * 1. Set data if provided
1857
- * 2. If changed, run VDOM diff (template → new DOM → diff against old DOM)
1846
+ * 2. If changed, run DOM diff (template → new DOM → diff against old DOM)
1858
1847
  * 3. Apply DOM operations
1859
1848
  * 4. Apply ID updates
1860
1849
  * 5. Call endUpdate on views that need re-rendering
@@ -1899,11 +1888,11 @@ var Updater = class {
1899
1888
  updaterRef,
1900
1889
  encodeQ
1901
1890
  );
1902
- const newDom = vdomGetNode(html, node);
1903
- const ref = createVdomRef();
1904
- vdomSetChildNodes(node, newDom, ref, frame, keys2);
1891
+ const newDom = domGetNode(html, node);
1892
+ const ref = createDomRef();
1893
+ domSetChildNodes(node, newDom, ref, frame, keys2);
1905
1894
  applyIdUpdates(ref.idUpdates);
1906
- applyVdomOps(ref.domOps);
1895
+ applyDomOps(ref.domOps);
1907
1896
  for (const v of ref.views) {
1908
1897
  if (v.render) {
1909
1898
  funcWithTry(v.render, [], v, noop);
@@ -2253,28 +2242,28 @@ var View = class _View {
2253
2242
  // ============================================================
2254
2243
  // Static public methods
2255
2244
  // ============================================================
2256
- /** Collected ctors from mixins */
2257
- static ctors;
2245
+ /** Collected makes from mixins */
2246
+ static makes;
2258
2247
  /**
2259
2248
  * Prepare a View subclass by scanning its prototype for event method patterns.
2260
2249
  * Pattern: `$?name<eventType1,eventType2>(&modifiers)`
2261
2250
  *
2262
- * Only runs once per View subclass (guarded by ctors marker).
2251
+ * Only runs once per View subclass (guarded by makes marker).
2263
2252
  * Called from Frame.mountView before creating the view instance.
2264
2253
  */
2265
2254
  static prepare(oView) {
2266
- if (oView.ctors) {
2267
- return oView.ctors;
2255
+ if (oView.makes) {
2256
+ return oView.makes;
2268
2257
  }
2269
- const ctors = [];
2270
- oView.ctors = ctors;
2258
+ const makes = [];
2259
+ oView.makes = makes;
2271
2260
  const proto = oView.prototype;
2272
2261
  const eventsObject = {};
2273
2262
  const eventsList = [];
2274
2263
  const selectorObject = {};
2275
2264
  const mixins = proto["mixins"];
2276
2265
  if (mixins && Array.isArray(mixins)) {
2277
- _View.mergeMixins(mixins, oView, ctors);
2266
+ _View.mergeMixins(mixins, oView, makes);
2278
2267
  }
2279
2268
  for (const p in proto) {
2280
2269
  if (!hasOwnProperty(proto, p)) continue;
@@ -2344,7 +2333,7 @@ var View = class _View {
2344
2333
  proto["$globalEvtList"] = eventsList;
2345
2334
  proto["$selMap"] = selectorObject;
2346
2335
  proto["$assignFn"] = proto["assign"];
2347
- return ctors;
2336
+ return makes;
2348
2337
  }
2349
2338
  /**
2350
2339
  * Bind or unbind event delegation for a view instance.
@@ -2469,7 +2458,7 @@ var View = class _View {
2469
2458
  /**
2470
2459
  * Merge an array of mixin objects into the view prototype.
2471
2460
  */
2472
- static mergeMixins(mixins, viewClass, ctors) {
2461
+ static mergeMixins(mixins, viewClass, makes) {
2473
2462
  const proto = viewClass.prototype;
2474
2463
  const temp = {};
2475
2464
  for (const node of mixins) {
@@ -2480,7 +2469,7 @@ var View = class _View {
2480
2469
  const mixinFn = fn;
2481
2470
  const exist = temp[p];
2482
2471
  if (p === "make") {
2483
- ctors.push(mixinFn);
2472
+ makes.push(mixinFn);
2484
2473
  continue;
2485
2474
  }
2486
2475
  if (VIEW_EVENT_METHOD_REGEXP.test(p)) {
@@ -2531,9 +2520,9 @@ var View = class _View {
2531
2520
  static extend(props, statics) {
2532
2521
  const definedProps = props ?? {};
2533
2522
  const make = definedProps["make"];
2534
- const ctors = [];
2523
+ const makes = [];
2535
2524
  if (typeof make === "function") {
2536
- ctors.push(make);
2525
+ makes.push(make);
2537
2526
  }
2538
2527
  const ParentView = this;
2539
2528
  const ChildView = class extends ParentView {
@@ -2555,7 +2544,7 @@ var View = class _View {
2555
2544
  deep: !this.template
2556
2545
  }
2557
2546
  ];
2558
- const concatCtors = ctors.concat(mixinCtors || []);
2547
+ const concatCtors = makes.concat(mixinCtors || []);
2559
2548
  if (concatCtors.length) {
2560
2549
  funcWithTry(concatCtors, params, this, noop);
2561
2550
  }
@@ -2581,7 +2570,7 @@ var View = class _View {
2581
2570
  * Merge mixins into View prototype.
2582
2571
  */
2583
2572
  static merge(...mixins) {
2584
- const existingCtors = this.ctors || [];
2573
+ const existingCtors = this.makes || [];
2585
2574
  _View.mergeMixins(mixins, this, existingCtors);
2586
2575
  return this;
2587
2576
  }
@@ -3325,13 +3314,13 @@ var Service = class {
3325
3314
  * References per-type static state from the current class.
3326
3315
  */
3327
3316
  get internals() {
3328
- const ctor = this.constructor;
3317
+ const constructor = this.constructor;
3329
3318
  return {
3330
- metaList: ctor._metaList,
3331
- payloadCache: ctor._payloadCache,
3332
- pendingCacheKeys: ctor._pendingCacheKeys,
3333
- syncFn: ctor._syncFn,
3334
- staticEmitter: ctor._staticEmitter
3319
+ metaList: constructor._metaList,
3320
+ payloadCache: constructor._payloadCache,
3321
+ pendingCacheKeys: constructor._pendingCacheKeys,
3322
+ syncFn: constructor._syncFn,
3323
+ staticEmitter: constructor._staticEmitter
3335
3324
  };
3336
3325
  }
3337
3326
  /**
@@ -4326,755 +4315,6 @@ function bindStore(view, store, selector) {
4326
4315
  return off;
4327
4316
  }
4328
4317
  var defineStore = create;
4329
-
4330
- // src/compiler.ts
4331
- var import_parser = require("@babel/parser");
4332
- var SPLITTER2 = String.fromCharCode(30);
4333
- var VIEW_ID_PLACEHOLDER = String.fromCharCode(31);
4334
- function jsObjectToUrlParams(paramsStr) {
4335
- const trimmed = paramsStr.trim();
4336
- if (!/^[{[]/.test(trimmed) && /=/.test(trimmed)) {
4337
- return trimmed;
4338
- }
4339
- const objMatch = trimmed.match(/^\{(.*)\}$/s);
4340
- if (objMatch) {
4341
- const inner = objMatch[1];
4342
- const pairs = [];
4343
- const pairRegExp = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|([^,}]+))/g;
4344
- let m;
4345
- while ((m = pairRegExp.exec(inner)) !== null) {
4346
- const key = m[1];
4347
- const value = m[2] ?? m[3] ?? m[4]?.trim() ?? "";
4348
- pairs.push(`${key}=${value}`);
4349
- }
4350
- return pairs.join("&");
4351
- }
4352
- return trimmed;
4353
- }
4354
- function protectComments(source) {
4355
- const comments = [];
4356
- const protectedSource = source.replace(/<!--[\s\S]*?-->/g, (match) => {
4357
- comments.push(match);
4358
- return `__lark_comment_${comments.length - 1}__`;
4359
- });
4360
- return { protectedSource, comments };
4361
- }
4362
- function restoreComments(source, comments) {
4363
- return source.replace(/__lark_comment_(\d+)__/g, (_, index) => {
4364
- return comments[parseInt(index, 10)];
4365
- });
4366
- }
4367
- function processViewEvents(source) {
4368
- return source.replace(
4369
- /@(\w+)="([^"]+)"/g,
4370
- (fullAttr, eventName, attrValue) => {
4371
- const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
4372
- if (!eventMatch) return fullAttr;
4373
- const handlerName = eventMatch[1];
4374
- const paramsStr = eventMatch[2].trim();
4375
- if (!paramsStr) {
4376
- return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4377
- }
4378
- const urlParams = jsObjectToUrlParams(paramsStr);
4379
- return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4380
- }
4381
- );
4382
- }
4383
- function addLineMarkers(source) {
4384
- const lines = source.split(/\r\n?|\n/);
4385
- const result = [];
4386
- let lineNo = 0;
4387
- const openTag = "{{";
4388
- for (const line of lines) {
4389
- const parts = line.split(openTag);
4390
- if (parts.length > 1) {
4391
- const reconstructed = parts.map((part, i) => {
4392
- if (i === 0) return part;
4393
- return openTag + SPLITTER2 + ++lineNo + part;
4394
- }).join("");
4395
- result.push(reconstructed);
4396
- } else {
4397
- result.push(line);
4398
- }
4399
- }
4400
- return result.join("\n");
4401
- }
4402
- function extractArtInfo(art) {
4403
- const m = art.match(new RegExp(`^${SPLITTER2}(\\d+)([\\s\\S]+)`));
4404
- if (m) {
4405
- let code = m[2].trimStart();
4406
- if (code.startsWith("if(")) {
4407
- code = code.substring(0, 2) + " " + code.substring(2);
4408
- } else if (code.startsWith("for(")) {
4409
- code = code.substring(0, 3) + " " + code.substring(3);
4410
- }
4411
- return { line: parseInt(m[1], 10), art: code };
4412
- }
4413
- return null;
4414
- }
4415
- function convertArtSyntax(source, debug) {
4416
- const markedSource = debug ? addLineMarkers(source) : source;
4417
- const openTag = "{{";
4418
- const parts = markedSource.split(openTag);
4419
- const result = [parts[0]];
4420
- const blockStack = [];
4421
- for (let i = 1; i < parts.length; i++) {
4422
- const part = parts[i];
4423
- const closeIdx = findCloseBrace(part);
4424
- if (closeIdx === -1) {
4425
- result.push(openTag + part);
4426
- continue;
4427
- }
4428
- const code = part.substring(0, closeIdx);
4429
- const rest = part.substring(closeIdx + 2);
4430
- let lineNo = -1;
4431
- let cleanCode = code;
4432
- if (debug) {
4433
- const info = extractArtInfo(code);
4434
- if (info) {
4435
- lineNo = info.line;
4436
- cleanCode = info.art;
4437
- }
4438
- } else {
4439
- cleanCode = code.trim();
4440
- }
4441
- const converted = convertArtExpression(
4442
- cleanCode,
4443
- debug,
4444
- lineNo,
4445
- blockStack
4446
- );
4447
- result.push(converted);
4448
- result.push(rest);
4449
- }
4450
- if (blockStack.length > 0) {
4451
- const unclosed = blockStack.map((b) => `"${b.ctrl}" at line ${b.line}`).join(", ");
4452
- throw new Error(`[@lark.js/mvc error] unclosed block(s): ${unclosed}`);
4453
- }
4454
- return result.join("");
4455
- }
4456
- function findCloseBrace(str) {
4457
- let leftCount = 0;
4458
- let rightCount = 0;
4459
- let maybeCount = 0;
4460
- let maybeAt = -1;
4461
- for (let i = 0; i < str.length; i++) {
4462
- const c = str.charAt(i);
4463
- if (c !== "}") {
4464
- if (maybeCount >= 2 && maybeAt === -1) {
4465
- maybeAt = i;
4466
- }
4467
- maybeCount = 0;
4468
- rightCount = 0;
4469
- }
4470
- if (c === "{") {
4471
- leftCount++;
4472
- } else if (c === "}") {
4473
- maybeCount++;
4474
- if (!leftCount) {
4475
- rightCount++;
4476
- if (rightCount === 2) {
4477
- return i - 1;
4478
- }
4479
- } else {
4480
- leftCount--;
4481
- }
4482
- }
4483
- }
4484
- if (!leftCount && maybeCount >= 2 && maybeAt === -1) {
4485
- maybeAt = str.length - 2;
4486
- }
4487
- if (maybeAt > -1) {
4488
- return maybeAt - 2;
4489
- }
4490
- return -1;
4491
- }
4492
- function trimOuterParens(expr) {
4493
- expr = expr.trim();
4494
- while (expr.startsWith("(") && expr.endsWith(")")) {
4495
- let depth = 0;
4496
- let matched = true;
4497
- for (let i = 0; i < expr.length - 1; i++) {
4498
- const c = expr.charAt(i);
4499
- if (c === "(") depth++;
4500
- else if (c === ")") depth--;
4501
- if (depth === 0 && i < expr.length - 1) {
4502
- matched = false;
4503
- break;
4504
- }
4505
- }
4506
- if (!matched) break;
4507
- expr = expr.substring(1, expr.length - 1).trim();
4508
- }
4509
- return expr;
4510
- }
4511
- function convertArtExpression(code, debug, lineNo, blockStack = []) {
4512
- code = code.trim();
4513
- const debugPrefix = debug && lineNo > -1 ? `<%'${lineNo}${code.replace(/\\|'/g, "\\$&").replace(/\r\n?|\n/g, "\\n")}'%>` : "";
4514
- const ifForMatch = code.match(/^\s*(if|for)\s*\(/);
4515
- if (ifForMatch) {
4516
- const keyword2 = ifForMatch[1];
4517
- const expr = code.substring(ifForMatch[0].length);
4518
- if (keyword2 === "if") {
4519
- blockStack.push({ ctrl: "if", line: lineNo });
4520
- const rawExpr = expr.replace(/\)\s*$/, "");
4521
- const cleanExpr = trimOuterParens(rawExpr);
4522
- return `${debugPrefix}<%if(${cleanExpr}){%>`;
4523
- }
4524
- blockStack.push({ ctrl: "for", line: lineNo });
4525
- const forExpr = expr.replace(/\)\s*$/, "");
4526
- return `${debugPrefix}<%for(${forExpr}){%>`;
4527
- }
4528
- const tokens = code.split(/\s+/);
4529
- const keyword = tokens.shift() ?? "";
4530
- switch (keyword) {
4531
- case "if": {
4532
- blockStack.push({ ctrl: "if", line: lineNo });
4533
- const rawExpr = tokens.join(" ").trim();
4534
- const expr = trimOuterParens(rawExpr);
4535
- return `${debugPrefix}<%if(${expr}){%>`;
4536
- }
4537
- case "else": {
4538
- if (tokens[0] === "if") {
4539
- tokens.shift();
4540
- const rawExpr = tokens.join(" ").trim();
4541
- const expr = trimOuterParens(rawExpr);
4542
- return `${debugPrefix}<%}else if(${expr}){%>`;
4543
- }
4544
- return `${debugPrefix}<%}else{%>`;
4545
- }
4546
- case "forOf": {
4547
- blockStack.push({ ctrl: "forOf", line: lineNo });
4548
- const object = tokens[0];
4549
- if (tokens.length > 1 && tokens[1] !== "as") {
4550
- throw new Error(
4551
- `[@lark.js/mvc error] bad forOf syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forOf list as item [index]}}`
4552
- );
4553
- }
4554
- const restTokens = tokens.slice(2);
4555
- const asValue = restTokens.join(" ");
4556
- const asExpr = parseAsExpr(asValue);
4557
- const index = asExpr.key || "_i";
4558
- const refObj = /[.[\]]/.test(object) ? `_art_obj_${object.replace(/[^\w]/g, "_")}` : object;
4559
- const refExpr = /[.[\]]/.test(object) ? `,${refObj}=${object}` : "";
4560
- const refObjCount = "_l";
4561
- const valueDecl = asExpr.vars ? `let ${asExpr.vars}=${refObj}[${index}]` : "";
4562
- let firstAndLast = "";
4563
- let lastCount = "";
4564
- if (asExpr.first) {
4565
- firstAndLast += `let ${asExpr.first}=${index}===0;`;
4566
- }
4567
- if (asExpr.last) {
4568
- lastCount = `,_lc=${refObjCount}-1`;
4569
- firstAndLast += `let ${asExpr.last}=${index}===_lc;`;
4570
- }
4571
- return `${debugPrefix}<%for(let ${index}=0${refExpr},${refObjCount}=${refObj}.length${lastCount};${index}<${refObjCount};${index}++){${firstAndLast}${valueDecl}%>`;
4572
- }
4573
- case "forIn": {
4574
- blockStack.push({ ctrl: "forIn", line: lineNo });
4575
- const object = tokens[0];
4576
- if (tokens.length > 1 && tokens[1] !== "as") {
4577
- throw new Error(
4578
- `[@lark.js/mvc error] bad forIn syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{for-in obj as val [key]}}`
4579
- );
4580
- }
4581
- const restTokens2 = tokens.slice(2);
4582
- const asValue2 = restTokens2.join(" ");
4583
- const asExpr2 = parseAsExpr(asValue2);
4584
- const key1 = asExpr2.key || "_k";
4585
- const refObj2 = /[.[\]]/.test(object) ? `_art_obj_${object.replace(/[^\w]/g, "_")}` : object;
4586
- const refExpr2 = /[.[\]]/.test(object) ? `let ${refObj2}=${object};` : "";
4587
- const valueDecl2 = asExpr2.vars ? `let ${asExpr2.vars}=${refObj2}[${key1}]` : "";
4588
- return `${debugPrefix}<%${refExpr2}for(let ${key1} in ${refObj2}){${valueDecl2}%>`;
4589
- }
4590
- case "for": {
4591
- blockStack.push({ ctrl: "for", line: lineNo });
4592
- const expr = tokens.join(" ").trim();
4593
- return `${debugPrefix}<%for(${expr}){%>`;
4594
- }
4595
- case "set":
4596
- return `${debugPrefix}<%let ${tokens.join(" ")};%>`;
4597
- case "/if":
4598
- case "/forOf":
4599
- case "/forIn":
4600
- case "/for": {
4601
- const expectedCtrl = keyword.substring(1);
4602
- const last = blockStack.pop();
4603
- if (!last) {
4604
- throw new Error(
4605
- `[@lark.js/mvc error] unexpected {{${code}}}: no matching open block`
4606
- );
4607
- }
4608
- if (last.ctrl !== expectedCtrl) {
4609
- throw new Error(
4610
- `[@lark.js/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4611
- );
4612
- }
4613
- return `${debugPrefix}<%}%>`;
4614
- }
4615
- default:
4616
- return `${debugPrefix}<%${code}%>`;
4617
- }
4618
- }
4619
- function parseAsExpr(expr) {
4620
- expr = expr.trim();
4621
- if (!expr) {
4622
- return { vars: "", key: "", last: "", first: "", bad: false };
4623
- }
4624
- if (expr.startsWith("{") || expr.startsWith("[")) {
4625
- const stack = [];
4626
- let vars = "";
4627
- let key = "";
4628
- let last = "";
4629
- let first = "";
4630
- let pos = 0;
4631
- let bad = false;
4632
- for (const c of expr) {
4633
- if (pos === 0) vars += c;
4634
- else if (pos === 1) key += c;
4635
- else if (pos === 2) last += c;
4636
- else if (pos === 3) first += c;
4637
- if (c === "{" || c === "[") stack.push(c);
4638
- else if (c === "}") {
4639
- if (stack[stack.length - 1] === "{") stack.pop();
4640
- else {
4641
- bad = true;
4642
- break;
4643
- }
4644
- } else if (c === "]") {
4645
- if (stack[stack.length - 1] === "[") stack.pop();
4646
- else {
4647
- bad = true;
4648
- break;
4649
- }
4650
- } else if (c === " " && !stack.length) {
4651
- pos++;
4652
- }
4653
- }
4654
- return {
4655
- vars: vars.trim(),
4656
- key: key.trim(),
4657
- last: last.trim(),
4658
- first: first.trim(),
4659
- bad: bad || stack.length > 0
4660
- };
4661
- }
4662
- const parts = expr.split(/\s+/);
4663
- return {
4664
- vars: parts[0] || "",
4665
- key: parts[1] || "",
4666
- last: parts[2] || "",
4667
- first: parts[3] || "",
4668
- bad: false
4669
- };
4670
- }
4671
- function compileToFunction(source, debug, file) {
4672
- const matcher = /<%([@=!:])?([\s\S]*?)%>|$/g;
4673
- let index = 0;
4674
- let funcSource = `$out+='`;
4675
- let hasAtRule = false;
4676
- const escapeSlashRegExp = /\\|'/g;
4677
- const escapeBreakReturnRegExp = /\r|\n/g;
4678
- source.replace(matcher, (match, operate, content, offset) => {
4679
- funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
4680
- index = offset + match.length;
4681
- if (debug) {
4682
- let expr = source.substring(
4683
- index - match.length + 2 + (operate ? 1 : 0),
4684
- index - 2
4685
- );
4686
- const x11 = String.fromCharCode(17);
4687
- const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
4688
- const artM = expr.match(artRegExp);
4689
- let art = "";
4690
- let line = -1;
4691
- if (artM) {
4692
- expr = expr.replace(artRegExp, "");
4693
- art = artM[2];
4694
- line = parseInt(artM[1], 10);
4695
- } else {
4696
- expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
4697
- }
4698
- if (operate === "@") {
4699
- hasAtRule = true;
4700
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$refFn($refAlt,${content}))+'`;
4701
- } else if (operate === "=" || operate === ":") {
4702
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$encHtml(${content}))+'`;
4703
- } else if (operate === "!") {
4704
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
4705
- content = `$strSafe(${content})`;
4706
- }
4707
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
4708
- } else if (content) {
4709
- if (line > -1) {
4710
- funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
4711
- content = "";
4712
- } else {
4713
- funcSource += `';`;
4714
- }
4715
- if (funcSource.endsWith(`+'';`)) {
4716
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
4717
- }
4718
- if (expr) {
4719
- funcSource += `$dbgExpr='<%${expr}%>';`;
4720
- }
4721
- funcSource += content + `;$out+='`;
4722
- }
4723
- } else {
4724
- if (operate === "@") {
4725
- hasAtRule = true;
4726
- funcSource += `'+$refFn($refAlt,${content})+'`;
4727
- } else if (operate === "=" || operate === ":") {
4728
- funcSource += `'+$encHtml(${content})+'`;
4729
- } else if (operate === "!") {
4730
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
4731
- content = `$strSafe(${content})`;
4732
- }
4733
- funcSource += `'+${content}+'`;
4734
- } else if (content) {
4735
- funcSource += `';`;
4736
- if (funcSource.endsWith(`+'';`)) {
4737
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
4738
- }
4739
- funcSource += `${content};$out+='`;
4740
- }
4741
- }
4742
- return match;
4743
- });
4744
- funcSource += `';`;
4745
- funcSource = funcSource.replace(/\$out\+='';/g, "");
4746
- funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
4747
- if (debug) {
4748
- const filePart = file ? `\\r\\n\\tat file:${file}` : "";
4749
- funcSource = `let $dbgExpr,$dbgArt,$dbgLine;try{${funcSource}}catch(ex){let msg='render view error:'+(ex.message||ex);if($dbgArt)msg+='\\r\\n\\tsrc art:{{'+$dbgArt+'}}\\r\\n\\tat line:'+$dbgLine;msg+='\\r\\n\\t'+($dbgArt?'translate to:':'expr:');msg+=$dbgExpr+'${filePart}';throw msg;}`;
4750
- }
4751
- const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
4752
- funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
4753
- void hasAtRule;
4754
- const refFallback = "if(!$refAlt)$refAlt=$data;";
4755
- const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
4756
- return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
4757
- }
4758
- function compileTemplate(source, options = {}) {
4759
- const { debug = false, globalVars = [], file } = options;
4760
- const { protectedSource, comments } = protectComments(source);
4761
- const converted = convertArtSyntax(protectedSource, debug);
4762
- const viewEventProcessed = processViewEvents(converted);
4763
- const finalSource = restoreComments(viewEventProcessed, comments);
4764
- const funcBody = compileToFunction(finalSource, debug, file);
4765
- const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
4766
- const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
4767
- return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
4768
- export default function(data, viewId, refData) {
4769
- let $data = data || {},
4770
- $viewId = viewId || '';
4771
- return (${funcWithVars})($data, $viewId, refData,
4772
- __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
4773
- );
4774
- }`;
4775
- }
4776
- function extractGlobalVars(source) {
4777
- const { protectedSource, comments: _comments } = protectComments(source);
4778
- const viewEventProcessed = processViewEvents(protectedSource);
4779
- const converted = convertArtSyntax(viewEventProcessed, false);
4780
- const template = restoreComments(converted, _comments);
4781
- const templateCmdRegExp = /<%([@=!:])?([\s\S]*?)%>|$/g;
4782
- const fnParts = [];
4783
- const htmlStore = {};
4784
- let htmlIndex = 0;
4785
- let lastIndex = 0;
4786
- const htmlKey = String.fromCharCode(5);
4787
- template.replace(
4788
- templateCmdRegExp,
4789
- (match, operate, content, offset) => {
4790
- const start = operate ? 3 : 2;
4791
- const htmlText = template.substring(lastIndex, offset + start);
4792
- const key = htmlKey + htmlIndex++ + htmlKey;
4793
- htmlStore[key] = htmlText;
4794
- lastIndex = offset + match.length - 2;
4795
- if (operate && content.trim()) {
4796
- fnParts.push(';"' + key + '";', "[" + content + "]");
4797
- } else {
4798
- fnParts.push(';"' + key + '";', content || "");
4799
- }
4800
- return match;
4801
- }
4802
- );
4803
- let fn = fnParts.join("");
4804
- fn = `(function(){${fn}})`;
4805
- let ast;
4806
- try {
4807
- ast = (0, import_parser.parse)(fn, {
4808
- sourceType: "script",
4809
- allowReturnOutsideFunction: true,
4810
- allowAwaitOutsideFunction: true
4811
- });
4812
- } catch {
4813
- return fallbackExtractVariables(source);
4814
- }
4815
- const globalExists = { ...BUILTIN_GLOBALS };
4816
- const globalVars = /* @__PURE__ */ Object.create(null);
4817
- const fnRange = [];
4818
- walkAst(ast, {
4819
- VariableDeclarator(node) {
4820
- if (node.id.type === "Identifier") {
4821
- const name = node.id.name;
4822
- globalExists[name] = node.init ? 3 : 2;
4823
- }
4824
- },
4825
- FunctionDeclaration(node) {
4826
- if (node.id) {
4827
- globalExists[node.id.name] = 3;
4828
- }
4829
- fnRange.push(node);
4830
- },
4831
- FunctionExpression(node) {
4832
- fnRange.push(node);
4833
- },
4834
- ArrowFunctionExpression(node) {
4835
- fnRange.push(node);
4836
- },
4837
- CallExpression(node) {
4838
- if (node.callee.type === "Identifier") {
4839
- globalExists[node.callee.name] = 1;
4840
- }
4841
- }
4842
- });
4843
- const functionParams = /* @__PURE__ */ Object.create(null);
4844
- for (const fnNode of fnRange) {
4845
- const params = "params" in fnNode ? fnNode.params : [];
4846
- for (const p of params) {
4847
- if (p.type === "Identifier") {
4848
- functionParams[p.name] = 1;
4849
- } else if (p.type === "AssignmentPattern" && p.left.type === "Identifier") {
4850
- functionParams[p.left.name] = 1;
4851
- } else if (p.type === "RestElement" && p.argument.type === "Identifier") {
4852
- functionParams[p.argument.name] = 1;
4853
- }
4854
- }
4855
- }
4856
- walkAst(ast, {
4857
- Identifier(node) {
4858
- const name = node.name;
4859
- if (globalExists[name]) return;
4860
- if (functionParams[name]) return;
4861
- globalVars[name] = 1;
4862
- },
4863
- AssignmentExpression(node) {
4864
- if (node.left.type === "Identifier") {
4865
- const name = node.left.name;
4866
- if (!globalExists[name] || globalExists[name] === 1) {
4867
- globalExists[name] = (globalExists[name] || 0) + 1;
4868
- }
4869
- }
4870
- }
4871
- });
4872
- return Object.keys(globalVars);
4873
- }
4874
- function fallbackExtractVariables(source) {
4875
- const vars = /* @__PURE__ */ new Set();
4876
- const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4877
- let m;
4878
- while ((m = outputRegExp.exec(source)) !== null) {
4879
- vars.add(m[1]);
4880
- }
4881
- const eachRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
4882
- while ((m = eachRegExp.exec(source)) !== null) {
4883
- vars.add(m[1]);
4884
- }
4885
- const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4886
- while ((m = ifRegExp.exec(source)) !== null) {
4887
- vars.add(m[1]);
4888
- }
4889
- return Array.from(vars).filter((v) => !BUILTIN_GLOBAL_SET.has(v));
4890
- }
4891
- function walkAst(ast, visitors) {
4892
- function visit(node) {
4893
- const type = node.type;
4894
- if (visitors[type]) {
4895
- visitors[type](node);
4896
- }
4897
- const bag = node;
4898
- for (const key of Object.keys(node)) {
4899
- if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
4900
- continue;
4901
- if (type === "MemberExpression" && key === "property") {
4902
- const me = node;
4903
- if (!me.computed) continue;
4904
- }
4905
- if (type === "ObjectProperty" && key === "key") {
4906
- const op = node;
4907
- if (!op.computed) continue;
4908
- }
4909
- if (type === "ObjectMethod" && key === "key") {
4910
- const om = node;
4911
- if (!om.computed) continue;
4912
- }
4913
- const child = bag[key];
4914
- if (Array.isArray(child)) {
4915
- for (const item of child) {
4916
- if (isAstNode(item)) visit(item);
4917
- }
4918
- } else if (isAstNode(child)) {
4919
- visit(child);
4920
- }
4921
- }
4922
- }
4923
- visit(ast);
4924
- }
4925
- function isAstNode(v) {
4926
- return !!v && typeof v === "object" && typeof v.type === "string";
4927
- }
4928
- var BUILTIN_GLOBALS = {
4929
- // ─── Template runtime helpers (injected by compileToFunction) ───────
4930
- //
4931
- // These variables appear in the generated template function signature
4932
- // or body. They must be excluded from extractGlobalVars() so that
4933
- // they are not mistaken for user data variables and destructured from $data.
4934
- // SPLITTER character constant (same as \x1e), used as namespace separator
4935
- // for refData keys, event attribute encoding, and internal data structures.
4936
- // Declared as: let $splitter='\x1e'
4937
- $splitter: 1,
4938
- // Data — the data object passed from Updater to the template function.
4939
- // User variables are destructured from $data at the top of the function:
4940
- // let {name, age} = $data;
4941
- // This is the first parameter of the generated arrow function.
4942
- $data: 1,
4943
- // Null-safe toString: v => '' + (v == null ? '' : v)
4944
- // Converts null/undefined to empty string, otherwise calls toString().
4945
- // Wraps every {{!raw}} output to prevent "null" / "undefined" rendering.
4946
- $strSafe: 1,
4947
- // HTML entity encoder: v => $strSafe(v).replace(/[&<>"'`]/g, entityMap)
4948
- // Encodes &, <, >, ", ', ` to HTML entities (&amp; &lt; etc.)
4949
- // Applied to all {{=escaped}} and {{:binding}} outputs.
4950
- $encHtml: 1,
4951
- // HTML entity map — internal object used by $encHtml:
4952
- // {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
4953
- // Not a standalone function; referenced inside $encHtml's closure.
4954
- $entMap: 1,
4955
- // HTML entity RegExp — internal regexp used by $encHtml:
4956
- // /[&<>"'`]/g
4957
- $entReg: 1,
4958
- // HTML entity replacer function — internal helper used by $encHtml:
4959
- // m => '&' + $entMap[m] + ';'
4960
- // Maps matched character to its entity string.
4961
- $entFn: 1,
4962
- // Output buffer — the string accumulator for rendered HTML.
4963
- // All template output is appended via $out += '...'.
4964
- // Declared as: let $out = ''
4965
- $out: 1,
4966
- // Reference lookup: (refData, value) => key
4967
- // Finds or allocates a SPLITTER-prefixed key in refData for a given
4968
- // object reference. Used by {{@ref}} operator for passing object
4969
- // references to child views via v-lark attributes.
4970
- $refFn: 1,
4971
- // URI encoder: v => encodeURIComponent($strSafe(v)).replace(/[!')(*]/g, extraMap)
4972
- // Extends encodeURIComponent with encoding of ! ' ( ) *.
4973
- // Applied to values in @event URL parameters and {{!uri}} contexts.
4974
- $encUri: 1,
4975
- // URI encode map — internal object used by $encUri:
4976
- // {'!':'%21','\'':'%27','(':'%28',')':'%29','*':'%2A'}
4977
- $uriMap: 1,
4978
- // URI encode replacer — internal helper used by $encUri:
4979
- // m => $uriMap[m]
4980
- $uriFn: 1,
4981
- // URI encode regexp — internal regexp used by $encUri:
4982
- // /[!')(*]/g
4983
- $uriReg: 1,
4984
- // Quote encoder: v => $strSafe(v).replace(/['"\\]/g, '\\$&')
4985
- // Escapes quotes and backslashes for safe embedding in HTML attribute
4986
- // values (e.g. data-json='...').
4987
- $encQuote: 1,
4988
- // Quote encode regexp — internal regexp used by $encQuote:
4989
- // /['"\\]/g
4990
- $qReg: 1,
4991
- // View ID — the unique identifier of the owning View instance.
4992
- // Injected into @event attribute values at render time so that
4993
- // EventDelegator can dispatch events to the correct View handler.
4994
- // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
4995
- $viewId: 1,
4996
- // Debug: current expression text — stores the template expression being
4997
- // evaluated, for error reporting. Only present in debug mode.
4998
- // e.g. $dbgExpr='<%=user.name%>'
4999
- $dbgExpr: 1,
5000
- // Debug: original art syntax — stores the {{}} template syntax before
5001
- // conversion, for error reporting. Only present in debug mode.
5002
- // e.g. $dbgArt='{{=user.name}}'
5003
- $dbgArt: 1,
5004
- // Debug: source line number — tracks the current line in the template
5005
- // source, for error reporting. Only present in debug mode.
5006
- $dbgLine: 1,
5007
- // RefData alias — fallback reference lookup table.
5008
- // Defaults to $data when no explicit $refAlt is provided.
5009
- // Ensures $refFn() does not crash when @ operator is used without refData.
5010
- $refAlt: 1,
5011
- // Temporary variable — used by the compiler for intermediate
5012
- // expression results in generated code (e.g. loop variables,
5013
- // conditional branches). Declared as: let $tmp
5014
- $tmp: 1,
5015
- // JS literals
5016
- undefined: 1,
5017
- null: 1,
5018
- true: 1,
5019
- false: 1,
5020
- NaN: 1,
5021
- Infinity: 1,
5022
- // JS built-in globals
5023
- window: 1,
5024
- self: 1,
5025
- globalThis: 1,
5026
- document: 1,
5027
- console: 1,
5028
- JSON: 1,
5029
- Math: 1,
5030
- Intl: 1,
5031
- Promise: 1,
5032
- Symbol: 1,
5033
- Number: 1,
5034
- String: 1,
5035
- Boolean: 1,
5036
- Array: 1,
5037
- Object: 1,
5038
- Date: 1,
5039
- RegExp: 1,
5040
- Error: 1,
5041
- TypeError: 1,
5042
- RangeError: 1,
5043
- SyntaxError: 1,
5044
- Map: 1,
5045
- Set: 1,
5046
- WeakMap: 1,
5047
- WeakSet: 1,
5048
- Proxy: 1,
5049
- Reflect: 1,
5050
- ArrayBuffer: 1,
5051
- DataView: 1,
5052
- Float32Array: 1,
5053
- Float64Array: 1,
5054
- Int8Array: 1,
5055
- Int16Array: 1,
5056
- Int32Array: 1,
5057
- Uint8Array: 1,
5058
- Uint16Array: 1,
5059
- Uint32Array: 1,
5060
- Uint8ClampedArray: 1,
5061
- // Functions
5062
- parseInt: 1,
5063
- parseFloat: 1,
5064
- isNaN: 1,
5065
- isFinite: 1,
5066
- encodeURIComponent: 1,
5067
- decodeURIComponent: 1,
5068
- encodeURI: 1,
5069
- decodeURI: 1,
5070
- // Babel helpers
5071
- arguments: 1,
5072
- this: 1,
5073
- require: 1,
5074
- // Lark framework
5075
- Lark: 1
5076
- };
5077
- var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5078
4318
  // Annotate the CommonJS export names for ESM import in node:
5079
4319
  0 && (module.exports = {
5080
4320
  CALL_BREAK_TIME,
@@ -5097,23 +4337,28 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5097
4337
  Updater,
5098
4338
  VIEW_EVENT_METHOD_REGEXP,
5099
4339
  View,
4340
+ applyDomOps,
5100
4341
  applyIdUpdates,
5101
4342
  applyStyle,
5102
- applyVdomOps,
5103
4343
  assign,
5104
4344
  bindStore,
5105
- compileTemplate,
5106
4345
  computed,
5107
4346
  create,
5108
- createVdomRef,
4347
+ createDomRef,
5109
4348
  defineStore,
5110
4349
  defineView,
4350
+ domGetCompareKey,
4351
+ domGetNode,
4352
+ domSetAttributes,
4353
+ domSetChildNodes,
4354
+ domSetNode,
4355
+ domSpecialDiff,
4356
+ domUnmountFrames,
5111
4357
  encodeHTML,
5112
4358
  encodeQ,
5113
4359
  encodeSafe,
5114
4360
  encodeURIExtra,
5115
4361
  ensureElementId,
5116
- extractGlobalVars,
5117
4362
  frameworkConfig,
5118
4363
  funcWithTry,
5119
4364
  generateId,
@@ -5146,12 +4391,5 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5146
4391
  translateData,
5147
4392
  unmark,
5148
4393
  use,
5149
- useUrlState,
5150
- vdomGetCompareKey,
5151
- vdomGetNode,
5152
- vdomSetAttributes,
5153
- vdomSetChildNodes,
5154
- vdomSetNode,
5155
- vdomSpecialDiff,
5156
- vdomUnmountFrames
4394
+ useUrlState
5157
4395
  });