@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.js CHANGED
@@ -6,14 +6,6 @@ var RouterEvents = {
6
6
  CHANGED: "changed",
7
7
  PAGE_UNLOAD: "page_unload"
8
8
  };
9
- var LarkInnerKeys = {
10
- /** Attribute name: ldk (static key for skipping VDOM diff) */
11
- DIFF_KEY: "ldk",
12
- /** Attribute name: lak (static attribute key) */
13
- ATTR_KEY: "lak",
14
- /** Attribute name: lvk (view key for assign) */
15
- VIEW_KEY: "lvk"
16
- };
17
9
  var LARK_VIEW = "v-lark";
18
10
  var EVENT_METHOD_REGEXP = new RegExp(
19
11
  `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
@@ -795,6 +787,9 @@ function attachViewAndPath(loc) {
795
787
  if (!loc.view) {
796
788
  const rawPath = routeMode === "history" ? loc.query["path"] || loc.hash["path"] : loc.hash["path"];
797
789
  let path = rawPath || cachedDefaultPath || "/";
790
+ if (!cachedRoutes[path] && path === "/" && cachedDefaultPath && cachedDefaultPath !== "/") {
791
+ path = cachedDefaultPath;
792
+ }
798
793
  if (cachedRewrite) {
799
794
  path = cachedRewrite(
800
795
  path,
@@ -863,6 +858,10 @@ function getChanged(oldLoc, newLoc) {
863
858
  function updateBrowserUrl(path, replace) {
864
859
  if (routeMode === "history") {
865
860
  const url = path || "/";
861
+ const currentUrl = window.location.pathname + window.location.search;
862
+ if (url === currentUrl) {
863
+ return;
864
+ }
866
865
  if (replace) {
867
866
  window.history.replaceState(null, "", url);
868
867
  } else {
@@ -884,6 +883,9 @@ function updateUrl(path, params, loc, replace, silentFlag, lQuery) {
884
883
  if (path !== currentSrc) {
885
884
  silent = silentFlag ? 1 : 0;
886
885
  updateBrowserUrl(path, replace);
886
+ if (routeMode === "history" && Router.notify) {
887
+ Router.notify();
888
+ }
887
889
  }
888
890
  }
889
891
  var Router = {
@@ -1363,7 +1365,7 @@ var EventDelegator = {
1363
1365
  }
1364
1366
  };
1365
1367
 
1366
- // src/vdom.ts
1368
+ // src/dom.ts
1367
1369
  var wrapMeta = {
1368
1370
  option: [1, "<select multiple>"],
1369
1371
  thead: [1, "<table>"],
@@ -1383,12 +1385,12 @@ var VDoc = document.implementation.createHTMLDocument("");
1383
1385
  var VBase = VDoc.createElement("base");
1384
1386
  VBase.href = document.location.href;
1385
1387
  VDoc.head.appendChild(VBase);
1386
- var VDomSpecials = {
1388
+ var DomSpecials = {
1387
1389
  INPUT: ["value", "checked"],
1388
1390
  TEXTAREA: ["value"],
1389
1391
  OPTION: ["selected"]
1390
1392
  };
1391
- function vdomUnmountFrames(frame, node) {
1393
+ function domUnmountFrames(frame, node) {
1392
1394
  if (!(node instanceof Element)) return;
1393
1395
  const id = node.getAttribute("id");
1394
1396
  if (!id) return;
@@ -1397,7 +1399,7 @@ function vdomUnmountFrames(frame, node) {
1397
1399
  frame.unmountFrame(id);
1398
1400
  }
1399
1401
  }
1400
- function vdomGetNode(html, refNode) {
1402
+ function domGetNode(html, refNode) {
1401
1403
  const tmp = VDoc.createElement("div");
1402
1404
  const ns = refNode.namespaceURI;
1403
1405
  let tag;
@@ -1418,16 +1420,13 @@ function vdomGetNode(html, refNode) {
1418
1420
  }
1419
1421
  return tmp;
1420
1422
  }
1421
- function vdomGetCompareKey(node) {
1423
+ function domGetCompareKey(node) {
1422
1424
  if (node.nodeType !== 1) return void 0;
1423
1425
  const el = node;
1424
1426
  if (el.compareKeyCached) {
1425
1427
  return el.cachedCompareKey;
1426
1428
  }
1427
1429
  let key = el.autoId ? "" : el.getAttribute("id") || void 0;
1428
- if (!key) {
1429
- key = el.getAttribute(LarkInnerKeys.DIFF_KEY) || void 0;
1430
- }
1431
1430
  if (!key) {
1432
1431
  const larkView = el.getAttribute(LARK_VIEW);
1433
1432
  if (larkView) {
@@ -1438,8 +1437,8 @@ function vdomGetCompareKey(node) {
1438
1437
  el.cachedCompareKey = key || "";
1439
1438
  return key;
1440
1439
  }
1441
- function vdomSpecialDiff(oldNode, newNode) {
1442
- const specials = VDomSpecials[oldNode.nodeName];
1440
+ function domSpecialDiff(oldNode, newNode) {
1441
+ const specials = DomSpecials[oldNode.nodeName];
1443
1442
  if (!specials) return 0;
1444
1443
  const oldEl = oldNode;
1445
1444
  const newEl = newNode;
@@ -1452,7 +1451,7 @@ function vdomSpecialDiff(oldNode, newNode) {
1452
1451
  }
1453
1452
  return result;
1454
1453
  }
1455
- function vdomSetAttributes(oldNode, newNode, ref, keepId) {
1454
+ function domSetAttributes(oldNode, newNode, ref, keepId) {
1456
1455
  const oldEl = oldNode;
1457
1456
  Reflect.deleteProperty(oldEl, "compareKeyCached");
1458
1457
  const oldAttrs = oldNode.attributes;
@@ -1484,7 +1483,7 @@ function vdomSetAttributes(oldNode, newNode, ref, keepId) {
1484
1483
  }
1485
1484
  }
1486
1485
  }
1487
- function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1486
+ function domSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1488
1487
  let oldNode = oldParent.lastChild;
1489
1488
  let newNode = newParent.firstChild;
1490
1489
  let extra = 0;
@@ -1492,7 +1491,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1492
1491
  const newKeyedNodes = /* @__PURE__ */ new Map();
1493
1492
  while (oldNode) {
1494
1493
  extra++;
1495
- const nodeKey = vdomGetCompareKey(oldNode);
1494
+ const nodeKey = domGetCompareKey(oldNode);
1496
1495
  if (nodeKey) {
1497
1496
  let bucket = keyedNodes.get(nodeKey);
1498
1497
  if (!bucket) {
@@ -1504,7 +1503,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1504
1503
  oldNode = oldNode.previousSibling;
1505
1504
  }
1506
1505
  while (newNode) {
1507
- const nodeKey = vdomGetCompareKey(newNode);
1506
+ const nodeKey = domGetCompareKey(newNode);
1508
1507
  if (nodeKey) {
1509
1508
  newKeyedNodes.set(nodeKey, (newKeyedNodes.get(nodeKey) ?? 0) + 1);
1510
1509
  }
@@ -1516,7 +1515,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1516
1515
  extra--;
1517
1516
  const tempNew = newNode;
1518
1517
  newNode = newNode.nextSibling;
1519
- const nodeKey = vdomGetCompareKey(tempNew);
1518
+ const nodeKey = domGetCompareKey(tempNew);
1520
1519
  let foundNode = nodeKey ? keyedNodes.get(nodeKey) : void 0;
1521
1520
  if (foundNode && (foundNode = foundNode.slice()) && foundNode.length) {
1522
1521
  const matched = foundNode.pop();
@@ -1531,17 +1530,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1531
1530
  const c = newKeyedNodes.get(nodeKey);
1532
1531
  if (c) newKeyedNodes.set(nodeKey, c - 1);
1533
1532
  }
1534
- vdomSetNode(matched, tempNew, oldParent, ref, frame, keys_);
1533
+ domSetNode(matched, tempNew, oldParent, ref, frame, keys_);
1535
1534
  } else if (oldNode) {
1536
1535
  const tempOld2 = oldNode;
1537
- const oldKey = vdomGetCompareKey(tempOld2);
1536
+ const oldKey = domGetCompareKey(tempOld2);
1538
1537
  if (oldKey && keyedNodes.has(oldKey) && newKeyedNodes.get(oldKey)) {
1539
1538
  extra++;
1540
1539
  ref.hasChanged = 1;
1541
1540
  ref.domOps.push([8, oldParent, tempNew, tempOld2]);
1542
1541
  } else {
1543
1542
  oldNode = oldNode.nextSibling;
1544
- vdomSetNode(tempOld2, tempNew, oldParent, ref, frame, keys_);
1543
+ domSetNode(tempOld2, tempNew, oldParent, ref, frame, keys_);
1545
1544
  }
1546
1545
  } else {
1547
1546
  ref.hasChanged = 1;
@@ -1551,29 +1550,23 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1551
1550
  let tempOld = oldParent.lastChild;
1552
1551
  while (extra-- > 0) {
1553
1552
  if (tempOld) {
1554
- vdomUnmountFrames(frame, tempOld);
1553
+ domUnmountFrames(frame, tempOld);
1555
1554
  ref.domOps.push([2, oldParent, tempOld]);
1556
1555
  tempOld = tempOld.previousSibling;
1557
1556
  ref.hasChanged = 1;
1558
1557
  }
1559
1558
  }
1560
1559
  }
1561
- function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1560
+ function domSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1562
1561
  const oldAsEl = oldNode instanceof Element ? oldNode : null;
1563
1562
  const newAsEl = newNode instanceof Element ? newNode : null;
1564
- const hasViewKey = !!oldAsEl?.hasAttribute(LarkInnerKeys.VIEW_KEY);
1565
1563
  const equalAsNodes = oldAsEl !== null && newAsEl !== null && oldAsEl.isEqualNode && oldAsEl.isEqualNode(newAsEl);
1566
- if (vdomSpecialDiff(oldNode, newNode) || hasViewKey || !equalAsNodes) {
1564
+ if (domSpecialDiff(oldNode, newNode) || !equalAsNodes) {
1567
1565
  if (oldNode.nodeType === newNode.nodeType && oldNode.nodeName === newNode.nodeName) {
1568
1566
  if (oldAsEl !== null && newAsEl !== null) {
1569
1567
  const oldEl = oldAsEl;
1570
1568
  const newEl = newAsEl;
1571
- const staticKey = newEl.getAttribute(LarkInnerKeys.DIFF_KEY);
1572
- if (staticKey && staticKey === oldEl.getAttribute(LarkInnerKeys.DIFF_KEY)) {
1573
- return;
1574
- }
1575
1569
  const newLarkView = newEl.getAttribute(LARK_VIEW);
1576
- const updateAttribute = !newEl.getAttribute(LarkInnerKeys.ATTR_KEY) || newEl.getAttribute(LarkInnerKeys.ATTR_KEY) !== oldEl.getAttribute(LarkInnerKeys.ATTR_KEY);
1577
1570
  let updateChildren = true;
1578
1571
  if (newLarkView) {
1579
1572
  const oldFrameId = oldEl.getAttribute("id") || "";
@@ -1584,11 +1577,9 @@ function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1584
1577
  updateChildren = false;
1585
1578
  }
1586
1579
  }
1587
- if (updateAttribute) {
1588
- vdomSetAttributes(oldEl, newEl, ref, !!newLarkView);
1589
- }
1580
+ domSetAttributes(oldEl, newEl, ref, !!newLarkView);
1590
1581
  if (updateChildren) {
1591
- vdomSetChildNodes(oldEl, newEl, ref, frame, keys_);
1582
+ domSetChildNodes(oldEl, newEl, ref, frame, keys_);
1592
1583
  }
1593
1584
  } else if (oldNode.nodeValue !== newNode.nodeValue) {
1594
1585
  ref.hasChanged = 1;
@@ -1596,12 +1587,12 @@ function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1596
1587
  }
1597
1588
  } else {
1598
1589
  ref.hasChanged = 1;
1599
- vdomUnmountFrames(frame, oldNode);
1590
+ domUnmountFrames(frame, oldNode);
1600
1591
  ref.domOps.push([4, oldParent, newNode, oldNode]);
1601
1592
  }
1602
1593
  }
1603
1594
  }
1604
- function createVdomRef() {
1595
+ function createDomRef() {
1605
1596
  return {
1606
1597
  idUpdates: [],
1607
1598
  views: [],
@@ -1609,7 +1600,7 @@ function createVdomRef() {
1609
1600
  hasChanged: 0
1610
1601
  };
1611
1602
  }
1612
- function applyVdomOps(ops) {
1603
+ function applyDomOps(ops) {
1613
1604
  for (const op of ops) {
1614
1605
  switch (op[0]) {
1615
1606
  case 1:
@@ -1748,11 +1739,11 @@ var Updater = class {
1748
1739
  return this;
1749
1740
  }
1750
1741
  /**
1751
- * Detect changes and trigger VDOM re-render.
1742
+ * Detect changes and trigger DOM re-render.
1752
1743
  *
1753
1744
  * The core rendering pipeline:
1754
1745
  * 1. Set data if provided
1755
- * 2. If changed, run VDOM diff (template → new DOM → diff against old DOM)
1746
+ * 2. If changed, run DOM diff (template → new DOM → diff against old DOM)
1756
1747
  * 3. Apply DOM operations
1757
1748
  * 4. Apply ID updates
1758
1749
  * 5. Call endUpdate on views that need re-rendering
@@ -1797,11 +1788,11 @@ var Updater = class {
1797
1788
  updaterRef,
1798
1789
  encodeQ
1799
1790
  );
1800
- const newDom = vdomGetNode(html, node);
1801
- const ref = createVdomRef();
1802
- vdomSetChildNodes(node, newDom, ref, frame, keys2);
1791
+ const newDom = domGetNode(html, node);
1792
+ const ref = createDomRef();
1793
+ domSetChildNodes(node, newDom, ref, frame, keys2);
1803
1794
  applyIdUpdates(ref.idUpdates);
1804
- applyVdomOps(ref.domOps);
1795
+ applyDomOps(ref.domOps);
1805
1796
  for (const v of ref.views) {
1806
1797
  if (v.render) {
1807
1798
  funcWithTry(v.render, [], v, noop);
@@ -2151,28 +2142,28 @@ var View = class _View {
2151
2142
  // ============================================================
2152
2143
  // Static public methods
2153
2144
  // ============================================================
2154
- /** Collected ctors from mixins */
2155
- static ctors;
2145
+ /** Collected makes from mixins */
2146
+ static makes;
2156
2147
  /**
2157
2148
  * Prepare a View subclass by scanning its prototype for event method patterns.
2158
2149
  * Pattern: `$?name<eventType1,eventType2>(&modifiers)`
2159
2150
  *
2160
- * Only runs once per View subclass (guarded by ctors marker).
2151
+ * Only runs once per View subclass (guarded by makes marker).
2161
2152
  * Called from Frame.mountView before creating the view instance.
2162
2153
  */
2163
2154
  static prepare(oView) {
2164
- if (oView.ctors) {
2165
- return oView.ctors;
2155
+ if (oView.makes) {
2156
+ return oView.makes;
2166
2157
  }
2167
- const ctors = [];
2168
- oView.ctors = ctors;
2158
+ const makes = [];
2159
+ oView.makes = makes;
2169
2160
  const proto = oView.prototype;
2170
2161
  const eventsObject = {};
2171
2162
  const eventsList = [];
2172
2163
  const selectorObject = {};
2173
2164
  const mixins = proto["mixins"];
2174
2165
  if (mixins && Array.isArray(mixins)) {
2175
- _View.mergeMixins(mixins, oView, ctors);
2166
+ _View.mergeMixins(mixins, oView, makes);
2176
2167
  }
2177
2168
  for (const p in proto) {
2178
2169
  if (!hasOwnProperty(proto, p)) continue;
@@ -2242,7 +2233,7 @@ var View = class _View {
2242
2233
  proto["$globalEvtList"] = eventsList;
2243
2234
  proto["$selMap"] = selectorObject;
2244
2235
  proto["$assignFn"] = proto["assign"];
2245
- return ctors;
2236
+ return makes;
2246
2237
  }
2247
2238
  /**
2248
2239
  * Bind or unbind event delegation for a view instance.
@@ -2367,7 +2358,7 @@ var View = class _View {
2367
2358
  /**
2368
2359
  * Merge an array of mixin objects into the view prototype.
2369
2360
  */
2370
- static mergeMixins(mixins, viewClass, ctors) {
2361
+ static mergeMixins(mixins, viewClass, makes) {
2371
2362
  const proto = viewClass.prototype;
2372
2363
  const temp = {};
2373
2364
  for (const node of mixins) {
@@ -2378,7 +2369,7 @@ var View = class _View {
2378
2369
  const mixinFn = fn;
2379
2370
  const exist = temp[p];
2380
2371
  if (p === "make") {
2381
- ctors.push(mixinFn);
2372
+ makes.push(mixinFn);
2382
2373
  continue;
2383
2374
  }
2384
2375
  if (VIEW_EVENT_METHOD_REGEXP.test(p)) {
@@ -2429,9 +2420,9 @@ var View = class _View {
2429
2420
  static extend(props, statics) {
2430
2421
  const definedProps = props ?? {};
2431
2422
  const make = definedProps["make"];
2432
- const ctors = [];
2423
+ const makes = [];
2433
2424
  if (typeof make === "function") {
2434
- ctors.push(make);
2425
+ makes.push(make);
2435
2426
  }
2436
2427
  const ParentView = this;
2437
2428
  const ChildView = class extends ParentView {
@@ -2453,7 +2444,7 @@ var View = class _View {
2453
2444
  deep: !this.template
2454
2445
  }
2455
2446
  ];
2456
- const concatCtors = ctors.concat(mixinCtors || []);
2447
+ const concatCtors = makes.concat(mixinCtors || []);
2457
2448
  if (concatCtors.length) {
2458
2449
  funcWithTry(concatCtors, params, this, noop);
2459
2450
  }
@@ -2479,7 +2470,7 @@ var View = class _View {
2479
2470
  * Merge mixins into View prototype.
2480
2471
  */
2481
2472
  static merge(...mixins) {
2482
- const existingCtors = this.ctors || [];
2473
+ const existingCtors = this.makes || [];
2483
2474
  _View.mergeMixins(mixins, this, existingCtors);
2484
2475
  return this;
2485
2476
  }
@@ -3223,13 +3214,13 @@ var Service = class {
3223
3214
  * References per-type static state from the current class.
3224
3215
  */
3225
3216
  get internals() {
3226
- const ctor = this.constructor;
3217
+ const constructor = this.constructor;
3227
3218
  return {
3228
- metaList: ctor._metaList,
3229
- payloadCache: ctor._payloadCache,
3230
- pendingCacheKeys: ctor._pendingCacheKeys,
3231
- syncFn: ctor._syncFn,
3232
- staticEmitter: ctor._staticEmitter
3219
+ metaList: constructor._metaList,
3220
+ payloadCache: constructor._payloadCache,
3221
+ pendingCacheKeys: constructor._pendingCacheKeys,
3222
+ syncFn: constructor._syncFn,
3223
+ staticEmitter: constructor._staticEmitter
3233
3224
  };
3234
3225
  }
3235
3226
  /**
@@ -4224,755 +4215,6 @@ function bindStore(view, store, selector) {
4224
4215
  return off;
4225
4216
  }
4226
4217
  var defineStore = create;
4227
-
4228
- // src/compiler.ts
4229
- import { parse as babelParse } from "@babel/parser";
4230
- var SPLITTER2 = String.fromCharCode(30);
4231
- var VIEW_ID_PLACEHOLDER = String.fromCharCode(31);
4232
- function jsObjectToUrlParams(paramsStr) {
4233
- const trimmed = paramsStr.trim();
4234
- if (!/^[{[]/.test(trimmed) && /=/.test(trimmed)) {
4235
- return trimmed;
4236
- }
4237
- const objMatch = trimmed.match(/^\{(.*)\}$/s);
4238
- if (objMatch) {
4239
- const inner = objMatch[1];
4240
- const pairs = [];
4241
- const pairRegExp = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|([^,}]+))/g;
4242
- let m;
4243
- while ((m = pairRegExp.exec(inner)) !== null) {
4244
- const key = m[1];
4245
- const value = m[2] ?? m[3] ?? m[4]?.trim() ?? "";
4246
- pairs.push(`${key}=${value}`);
4247
- }
4248
- return pairs.join("&");
4249
- }
4250
- return trimmed;
4251
- }
4252
- function protectComments(source) {
4253
- const comments = [];
4254
- const protectedSource = source.replace(/<!--[\s\S]*?-->/g, (match) => {
4255
- comments.push(match);
4256
- return `__lark_comment_${comments.length - 1}__`;
4257
- });
4258
- return { protectedSource, comments };
4259
- }
4260
- function restoreComments(source, comments) {
4261
- return source.replace(/__lark_comment_(\d+)__/g, (_, index) => {
4262
- return comments[parseInt(index, 10)];
4263
- });
4264
- }
4265
- function processViewEvents(source) {
4266
- return source.replace(
4267
- /@(\w+)="([^"]+)"/g,
4268
- (fullAttr, eventName, attrValue) => {
4269
- const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
4270
- if (!eventMatch) return fullAttr;
4271
- const handlerName = eventMatch[1];
4272
- const paramsStr = eventMatch[2].trim();
4273
- if (!paramsStr) {
4274
- return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4275
- }
4276
- const urlParams = jsObjectToUrlParams(paramsStr);
4277
- return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4278
- }
4279
- );
4280
- }
4281
- function addLineMarkers(source) {
4282
- const lines = source.split(/\r\n?|\n/);
4283
- const result = [];
4284
- let lineNo = 0;
4285
- const openTag = "{{";
4286
- for (const line of lines) {
4287
- const parts = line.split(openTag);
4288
- if (parts.length > 1) {
4289
- const reconstructed = parts.map((part, i) => {
4290
- if (i === 0) return part;
4291
- return openTag + SPLITTER2 + ++lineNo + part;
4292
- }).join("");
4293
- result.push(reconstructed);
4294
- } else {
4295
- result.push(line);
4296
- }
4297
- }
4298
- return result.join("\n");
4299
- }
4300
- function extractArtInfo(art) {
4301
- const m = art.match(new RegExp(`^${SPLITTER2}(\\d+)([\\s\\S]+)`));
4302
- if (m) {
4303
- let code = m[2].trimStart();
4304
- if (code.startsWith("if(")) {
4305
- code = code.substring(0, 2) + " " + code.substring(2);
4306
- } else if (code.startsWith("for(")) {
4307
- code = code.substring(0, 3) + " " + code.substring(3);
4308
- }
4309
- return { line: parseInt(m[1], 10), art: code };
4310
- }
4311
- return null;
4312
- }
4313
- function convertArtSyntax(source, debug) {
4314
- const markedSource = debug ? addLineMarkers(source) : source;
4315
- const openTag = "{{";
4316
- const parts = markedSource.split(openTag);
4317
- const result = [parts[0]];
4318
- const blockStack = [];
4319
- for (let i = 1; i < parts.length; i++) {
4320
- const part = parts[i];
4321
- const closeIdx = findCloseBrace(part);
4322
- if (closeIdx === -1) {
4323
- result.push(openTag + part);
4324
- continue;
4325
- }
4326
- const code = part.substring(0, closeIdx);
4327
- const rest = part.substring(closeIdx + 2);
4328
- let lineNo = -1;
4329
- let cleanCode = code;
4330
- if (debug) {
4331
- const info = extractArtInfo(code);
4332
- if (info) {
4333
- lineNo = info.line;
4334
- cleanCode = info.art;
4335
- }
4336
- } else {
4337
- cleanCode = code.trim();
4338
- }
4339
- const converted = convertArtExpression(
4340
- cleanCode,
4341
- debug,
4342
- lineNo,
4343
- blockStack
4344
- );
4345
- result.push(converted);
4346
- result.push(rest);
4347
- }
4348
- if (blockStack.length > 0) {
4349
- const unclosed = blockStack.map((b) => `"${b.ctrl}" at line ${b.line}`).join(", ");
4350
- throw new Error(`[@lark.js/mvc error] unclosed block(s): ${unclosed}`);
4351
- }
4352
- return result.join("");
4353
- }
4354
- function findCloseBrace(str) {
4355
- let leftCount = 0;
4356
- let rightCount = 0;
4357
- let maybeCount = 0;
4358
- let maybeAt = -1;
4359
- for (let i = 0; i < str.length; i++) {
4360
- const c = str.charAt(i);
4361
- if (c !== "}") {
4362
- if (maybeCount >= 2 && maybeAt === -1) {
4363
- maybeAt = i;
4364
- }
4365
- maybeCount = 0;
4366
- rightCount = 0;
4367
- }
4368
- if (c === "{") {
4369
- leftCount++;
4370
- } else if (c === "}") {
4371
- maybeCount++;
4372
- if (!leftCount) {
4373
- rightCount++;
4374
- if (rightCount === 2) {
4375
- return i - 1;
4376
- }
4377
- } else {
4378
- leftCount--;
4379
- }
4380
- }
4381
- }
4382
- if (!leftCount && maybeCount >= 2 && maybeAt === -1) {
4383
- maybeAt = str.length - 2;
4384
- }
4385
- if (maybeAt > -1) {
4386
- return maybeAt - 2;
4387
- }
4388
- return -1;
4389
- }
4390
- function trimOuterParens(expr) {
4391
- expr = expr.trim();
4392
- while (expr.startsWith("(") && expr.endsWith(")")) {
4393
- let depth = 0;
4394
- let matched = true;
4395
- for (let i = 0; i < expr.length - 1; i++) {
4396
- const c = expr.charAt(i);
4397
- if (c === "(") depth++;
4398
- else if (c === ")") depth--;
4399
- if (depth === 0 && i < expr.length - 1) {
4400
- matched = false;
4401
- break;
4402
- }
4403
- }
4404
- if (!matched) break;
4405
- expr = expr.substring(1, expr.length - 1).trim();
4406
- }
4407
- return expr;
4408
- }
4409
- function convertArtExpression(code, debug, lineNo, blockStack = []) {
4410
- code = code.trim();
4411
- const debugPrefix = debug && lineNo > -1 ? `<%'${lineNo}${code.replace(/\\|'/g, "\\$&").replace(/\r\n?|\n/g, "\\n")}'%>` : "";
4412
- const ifForMatch = code.match(/^\s*(if|for)\s*\(/);
4413
- if (ifForMatch) {
4414
- const keyword2 = ifForMatch[1];
4415
- const expr = code.substring(ifForMatch[0].length);
4416
- if (keyword2 === "if") {
4417
- blockStack.push({ ctrl: "if", line: lineNo });
4418
- const rawExpr = expr.replace(/\)\s*$/, "");
4419
- const cleanExpr = trimOuterParens(rawExpr);
4420
- return `${debugPrefix}<%if(${cleanExpr}){%>`;
4421
- }
4422
- blockStack.push({ ctrl: "for", line: lineNo });
4423
- const forExpr = expr.replace(/\)\s*$/, "");
4424
- return `${debugPrefix}<%for(${forExpr}){%>`;
4425
- }
4426
- const tokens = code.split(/\s+/);
4427
- const keyword = tokens.shift() ?? "";
4428
- switch (keyword) {
4429
- case "if": {
4430
- blockStack.push({ ctrl: "if", line: lineNo });
4431
- const rawExpr = tokens.join(" ").trim();
4432
- const expr = trimOuterParens(rawExpr);
4433
- return `${debugPrefix}<%if(${expr}){%>`;
4434
- }
4435
- case "else": {
4436
- if (tokens[0] === "if") {
4437
- tokens.shift();
4438
- const rawExpr = tokens.join(" ").trim();
4439
- const expr = trimOuterParens(rawExpr);
4440
- return `${debugPrefix}<%}else if(${expr}){%>`;
4441
- }
4442
- return `${debugPrefix}<%}else{%>`;
4443
- }
4444
- case "forOf": {
4445
- blockStack.push({ ctrl: "forOf", line: lineNo });
4446
- const object = tokens[0];
4447
- if (tokens.length > 1 && tokens[1] !== "as") {
4448
- throw new Error(
4449
- `[@lark.js/mvc error] bad forOf syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forOf list as item [index]}}`
4450
- );
4451
- }
4452
- const restTokens = tokens.slice(2);
4453
- const asValue = restTokens.join(" ");
4454
- const asExpr = parseAsExpr(asValue);
4455
- const index = asExpr.key || "_i";
4456
- const refObj = /[.[\]]/.test(object) ? `_art_obj_${object.replace(/[^\w]/g, "_")}` : object;
4457
- const refExpr = /[.[\]]/.test(object) ? `,${refObj}=${object}` : "";
4458
- const refObjCount = "_l";
4459
- const valueDecl = asExpr.vars ? `let ${asExpr.vars}=${refObj}[${index}]` : "";
4460
- let firstAndLast = "";
4461
- let lastCount = "";
4462
- if (asExpr.first) {
4463
- firstAndLast += `let ${asExpr.first}=${index}===0;`;
4464
- }
4465
- if (asExpr.last) {
4466
- lastCount = `,_lc=${refObjCount}-1`;
4467
- firstAndLast += `let ${asExpr.last}=${index}===_lc;`;
4468
- }
4469
- return `${debugPrefix}<%for(let ${index}=0${refExpr},${refObjCount}=${refObj}.length${lastCount};${index}<${refObjCount};${index}++){${firstAndLast}${valueDecl}%>`;
4470
- }
4471
- case "forIn": {
4472
- blockStack.push({ ctrl: "forIn", line: lineNo });
4473
- const object = tokens[0];
4474
- if (tokens.length > 1 && tokens[1] !== "as") {
4475
- throw new Error(
4476
- `[@lark.js/mvc error] bad forIn syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{for-in obj as val [key]}}`
4477
- );
4478
- }
4479
- const restTokens2 = tokens.slice(2);
4480
- const asValue2 = restTokens2.join(" ");
4481
- const asExpr2 = parseAsExpr(asValue2);
4482
- const key1 = asExpr2.key || "_k";
4483
- const refObj2 = /[.[\]]/.test(object) ? `_art_obj_${object.replace(/[^\w]/g, "_")}` : object;
4484
- const refExpr2 = /[.[\]]/.test(object) ? `let ${refObj2}=${object};` : "";
4485
- const valueDecl2 = asExpr2.vars ? `let ${asExpr2.vars}=${refObj2}[${key1}]` : "";
4486
- return `${debugPrefix}<%${refExpr2}for(let ${key1} in ${refObj2}){${valueDecl2}%>`;
4487
- }
4488
- case "for": {
4489
- blockStack.push({ ctrl: "for", line: lineNo });
4490
- const expr = tokens.join(" ").trim();
4491
- return `${debugPrefix}<%for(${expr}){%>`;
4492
- }
4493
- case "set":
4494
- return `${debugPrefix}<%let ${tokens.join(" ")};%>`;
4495
- case "/if":
4496
- case "/forOf":
4497
- case "/forIn":
4498
- case "/for": {
4499
- const expectedCtrl = keyword.substring(1);
4500
- const last = blockStack.pop();
4501
- if (!last) {
4502
- throw new Error(
4503
- `[@lark.js/mvc error] unexpected {{${code}}}: no matching open block`
4504
- );
4505
- }
4506
- if (last.ctrl !== expectedCtrl) {
4507
- throw new Error(
4508
- `[@lark.js/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4509
- );
4510
- }
4511
- return `${debugPrefix}<%}%>`;
4512
- }
4513
- default:
4514
- return `${debugPrefix}<%${code}%>`;
4515
- }
4516
- }
4517
- function parseAsExpr(expr) {
4518
- expr = expr.trim();
4519
- if (!expr) {
4520
- return { vars: "", key: "", last: "", first: "", bad: false };
4521
- }
4522
- if (expr.startsWith("{") || expr.startsWith("[")) {
4523
- const stack = [];
4524
- let vars = "";
4525
- let key = "";
4526
- let last = "";
4527
- let first = "";
4528
- let pos = 0;
4529
- let bad = false;
4530
- for (const c of expr) {
4531
- if (pos === 0) vars += c;
4532
- else if (pos === 1) key += c;
4533
- else if (pos === 2) last += c;
4534
- else if (pos === 3) first += c;
4535
- if (c === "{" || c === "[") stack.push(c);
4536
- else if (c === "}") {
4537
- if (stack[stack.length - 1] === "{") stack.pop();
4538
- else {
4539
- bad = true;
4540
- break;
4541
- }
4542
- } else if (c === "]") {
4543
- if (stack[stack.length - 1] === "[") stack.pop();
4544
- else {
4545
- bad = true;
4546
- break;
4547
- }
4548
- } else if (c === " " && !stack.length) {
4549
- pos++;
4550
- }
4551
- }
4552
- return {
4553
- vars: vars.trim(),
4554
- key: key.trim(),
4555
- last: last.trim(),
4556
- first: first.trim(),
4557
- bad: bad || stack.length > 0
4558
- };
4559
- }
4560
- const parts = expr.split(/\s+/);
4561
- return {
4562
- vars: parts[0] || "",
4563
- key: parts[1] || "",
4564
- last: parts[2] || "",
4565
- first: parts[3] || "",
4566
- bad: false
4567
- };
4568
- }
4569
- function compileToFunction(source, debug, file) {
4570
- const matcher = /<%([@=!:])?([\s\S]*?)%>|$/g;
4571
- let index = 0;
4572
- let funcSource = `$out+='`;
4573
- let hasAtRule = false;
4574
- const escapeSlashRegExp = /\\|'/g;
4575
- const escapeBreakReturnRegExp = /\r|\n/g;
4576
- source.replace(matcher, (match, operate, content, offset) => {
4577
- funcSource += source.substring(index, offset).replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
4578
- index = offset + match.length;
4579
- if (debug) {
4580
- let expr = source.substring(
4581
- index - match.length + 2 + (operate ? 1 : 0),
4582
- index - 2
4583
- );
4584
- const x11 = String.fromCharCode(17);
4585
- const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
4586
- const artM = expr.match(artRegExp);
4587
- let art = "";
4588
- let line = -1;
4589
- if (artM) {
4590
- expr = expr.replace(artRegExp, "");
4591
- art = artM[2];
4592
- line = parseInt(artM[1], 10);
4593
- } else {
4594
- expr = expr.replace(escapeSlashRegExp, "\\$&").replace(escapeBreakReturnRegExp, "\\n");
4595
- }
4596
- if (operate === "@") {
4597
- hasAtRule = true;
4598
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$refFn($refAlt,${content}))+'`;
4599
- } else if (operate === "=" || operate === ":") {
4600
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',$encHtml(${content}))+'`;
4601
- } else if (operate === "!") {
4602
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
4603
- content = `$strSafe(${content})`;
4604
- }
4605
- funcSource += `'+($dbgExpr='<%${operate + expr}%>',${content})+'`;
4606
- } else if (content) {
4607
- if (line > -1) {
4608
- funcSource += `';$dbgLine=${line};$dbgArt='${art}';`;
4609
- content = "";
4610
- } else {
4611
- funcSource += `';`;
4612
- }
4613
- if (funcSource.endsWith(`+'';`)) {
4614
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
4615
- }
4616
- if (expr) {
4617
- funcSource += `$dbgExpr='<%${expr}%>';`;
4618
- }
4619
- funcSource += content + `;$out+='`;
4620
- }
4621
- } else {
4622
- if (operate === "@") {
4623
- hasAtRule = true;
4624
- funcSource += `'+$refFn($refAlt,${content})+'`;
4625
- } else if (operate === "=" || operate === ":") {
4626
- funcSource += `'+$encHtml(${content})+'`;
4627
- } else if (operate === "!") {
4628
- if (!content.startsWith("$encUri(") || !content.endsWith(")")) {
4629
- content = `$strSafe(${content})`;
4630
- }
4631
- funcSource += `'+${content}+'`;
4632
- } else if (content) {
4633
- funcSource += `';`;
4634
- if (funcSource.endsWith(`+'';`)) {
4635
- funcSource = funcSource.substring(0, funcSource.length - 4) + ";";
4636
- }
4637
- funcSource += `${content};$out+='`;
4638
- }
4639
- }
4640
- return match;
4641
- });
4642
- funcSource += `';`;
4643
- funcSource = funcSource.replace(/\$out\+='';/g, "");
4644
- funcSource = funcSource.replace(/\$out\+=''\+/g, "$out+=");
4645
- if (debug) {
4646
- const filePart = file ? `\\r\\n\\tat file:${file}` : "";
4647
- 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;}`;
4648
- }
4649
- const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
4650
- funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
4651
- void hasAtRule;
4652
- const refFallback = "if(!$refAlt)$refAlt=$data;";
4653
- const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
4654
- return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
4655
- }
4656
- function compileTemplate(source, options = {}) {
4657
- const { debug = false, globalVars = [], file } = options;
4658
- const { protectedSource, comments } = protectComments(source);
4659
- const converted = convertArtSyntax(protectedSource, debug);
4660
- const viewEventProcessed = processViewEvents(converted);
4661
- const finalSource = restoreComments(viewEventProcessed, comments);
4662
- const funcBody = compileToFunction(finalSource, debug, file);
4663
- const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
4664
- const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
4665
- return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
4666
- export default function(data, viewId, refData) {
4667
- let $data = data || {},
4668
- $viewId = viewId || '';
4669
- return (${funcWithVars})($data, $viewId, refData,
4670
- __larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
4671
- );
4672
- }`;
4673
- }
4674
- function extractGlobalVars(source) {
4675
- const { protectedSource, comments: _comments } = protectComments(source);
4676
- const viewEventProcessed = processViewEvents(protectedSource);
4677
- const converted = convertArtSyntax(viewEventProcessed, false);
4678
- const template = restoreComments(converted, _comments);
4679
- const templateCmdRegExp = /<%([@=!:])?([\s\S]*?)%>|$/g;
4680
- const fnParts = [];
4681
- const htmlStore = {};
4682
- let htmlIndex = 0;
4683
- let lastIndex = 0;
4684
- const htmlKey = String.fromCharCode(5);
4685
- template.replace(
4686
- templateCmdRegExp,
4687
- (match, operate, content, offset) => {
4688
- const start = operate ? 3 : 2;
4689
- const htmlText = template.substring(lastIndex, offset + start);
4690
- const key = htmlKey + htmlIndex++ + htmlKey;
4691
- htmlStore[key] = htmlText;
4692
- lastIndex = offset + match.length - 2;
4693
- if (operate && content.trim()) {
4694
- fnParts.push(';"' + key + '";', "[" + content + "]");
4695
- } else {
4696
- fnParts.push(';"' + key + '";', content || "");
4697
- }
4698
- return match;
4699
- }
4700
- );
4701
- let fn = fnParts.join("");
4702
- fn = `(function(){${fn}})`;
4703
- let ast;
4704
- try {
4705
- ast = babelParse(fn, {
4706
- sourceType: "script",
4707
- allowReturnOutsideFunction: true,
4708
- allowAwaitOutsideFunction: true
4709
- });
4710
- } catch {
4711
- return fallbackExtractVariables(source);
4712
- }
4713
- const globalExists = { ...BUILTIN_GLOBALS };
4714
- const globalVars = /* @__PURE__ */ Object.create(null);
4715
- const fnRange = [];
4716
- walkAst(ast, {
4717
- VariableDeclarator(node) {
4718
- if (node.id.type === "Identifier") {
4719
- const name = node.id.name;
4720
- globalExists[name] = node.init ? 3 : 2;
4721
- }
4722
- },
4723
- FunctionDeclaration(node) {
4724
- if (node.id) {
4725
- globalExists[node.id.name] = 3;
4726
- }
4727
- fnRange.push(node);
4728
- },
4729
- FunctionExpression(node) {
4730
- fnRange.push(node);
4731
- },
4732
- ArrowFunctionExpression(node) {
4733
- fnRange.push(node);
4734
- },
4735
- CallExpression(node) {
4736
- if (node.callee.type === "Identifier") {
4737
- globalExists[node.callee.name] = 1;
4738
- }
4739
- }
4740
- });
4741
- const functionParams = /* @__PURE__ */ Object.create(null);
4742
- for (const fnNode of fnRange) {
4743
- const params = "params" in fnNode ? fnNode.params : [];
4744
- for (const p of params) {
4745
- if (p.type === "Identifier") {
4746
- functionParams[p.name] = 1;
4747
- } else if (p.type === "AssignmentPattern" && p.left.type === "Identifier") {
4748
- functionParams[p.left.name] = 1;
4749
- } else if (p.type === "RestElement" && p.argument.type === "Identifier") {
4750
- functionParams[p.argument.name] = 1;
4751
- }
4752
- }
4753
- }
4754
- walkAst(ast, {
4755
- Identifier(node) {
4756
- const name = node.name;
4757
- if (globalExists[name]) return;
4758
- if (functionParams[name]) return;
4759
- globalVars[name] = 1;
4760
- },
4761
- AssignmentExpression(node) {
4762
- if (node.left.type === "Identifier") {
4763
- const name = node.left.name;
4764
- if (!globalExists[name] || globalExists[name] === 1) {
4765
- globalExists[name] = (globalExists[name] || 0) + 1;
4766
- }
4767
- }
4768
- }
4769
- });
4770
- return Object.keys(globalVars);
4771
- }
4772
- function fallbackExtractVariables(source) {
4773
- const vars = /* @__PURE__ */ new Set();
4774
- const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4775
- let m;
4776
- while ((m = outputRegExp.exec(source)) !== null) {
4777
- vars.add(m[1]);
4778
- }
4779
- const eachRegExp = /\{\{forOf\s+([a-zA-Z_$][\w$]*)\s+as/g;
4780
- while ((m = eachRegExp.exec(source)) !== null) {
4781
- vars.add(m[1]);
4782
- }
4783
- const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4784
- while ((m = ifRegExp.exec(source)) !== null) {
4785
- vars.add(m[1]);
4786
- }
4787
- return Array.from(vars).filter((v) => !BUILTIN_GLOBAL_SET.has(v));
4788
- }
4789
- function walkAst(ast, visitors) {
4790
- function visit(node) {
4791
- const type = node.type;
4792
- if (visitors[type]) {
4793
- visitors[type](node);
4794
- }
4795
- const bag = node;
4796
- for (const key of Object.keys(node)) {
4797
- if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
4798
- continue;
4799
- if (type === "MemberExpression" && key === "property") {
4800
- const me = node;
4801
- if (!me.computed) continue;
4802
- }
4803
- if (type === "ObjectProperty" && key === "key") {
4804
- const op = node;
4805
- if (!op.computed) continue;
4806
- }
4807
- if (type === "ObjectMethod" && key === "key") {
4808
- const om = node;
4809
- if (!om.computed) continue;
4810
- }
4811
- const child = bag[key];
4812
- if (Array.isArray(child)) {
4813
- for (const item of child) {
4814
- if (isAstNode(item)) visit(item);
4815
- }
4816
- } else if (isAstNode(child)) {
4817
- visit(child);
4818
- }
4819
- }
4820
- }
4821
- visit(ast);
4822
- }
4823
- function isAstNode(v) {
4824
- return !!v && typeof v === "object" && typeof v.type === "string";
4825
- }
4826
- var BUILTIN_GLOBALS = {
4827
- // ─── Template runtime helpers (injected by compileToFunction) ───────
4828
- //
4829
- // These variables appear in the generated template function signature
4830
- // or body. They must be excluded from extractGlobalVars() so that
4831
- // they are not mistaken for user data variables and destructured from $data.
4832
- // SPLITTER character constant (same as \x1e), used as namespace separator
4833
- // for refData keys, event attribute encoding, and internal data structures.
4834
- // Declared as: let $splitter='\x1e'
4835
- $splitter: 1,
4836
- // Data — the data object passed from Updater to the template function.
4837
- // User variables are destructured from $data at the top of the function:
4838
- // let {name, age} = $data;
4839
- // This is the first parameter of the generated arrow function.
4840
- $data: 1,
4841
- // Null-safe toString: v => '' + (v == null ? '' : v)
4842
- // Converts null/undefined to empty string, otherwise calls toString().
4843
- // Wraps every {{!raw}} output to prevent "null" / "undefined" rendering.
4844
- $strSafe: 1,
4845
- // HTML entity encoder: v => $strSafe(v).replace(/[&<>"'`]/g, entityMap)
4846
- // Encodes &, <, >, ", ', ` to HTML entities (&amp; &lt; etc.)
4847
- // Applied to all {{=escaped}} and {{:binding}} outputs.
4848
- $encHtml: 1,
4849
- // HTML entity map — internal object used by $encHtml:
4850
- // {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
4851
- // Not a standalone function; referenced inside $encHtml's closure.
4852
- $entMap: 1,
4853
- // HTML entity RegExp — internal regexp used by $encHtml:
4854
- // /[&<>"'`]/g
4855
- $entReg: 1,
4856
- // HTML entity replacer function — internal helper used by $encHtml:
4857
- // m => '&' + $entMap[m] + ';'
4858
- // Maps matched character to its entity string.
4859
- $entFn: 1,
4860
- // Output buffer — the string accumulator for rendered HTML.
4861
- // All template output is appended via $out += '...'.
4862
- // Declared as: let $out = ''
4863
- $out: 1,
4864
- // Reference lookup: (refData, value) => key
4865
- // Finds or allocates a SPLITTER-prefixed key in refData for a given
4866
- // object reference. Used by {{@ref}} operator for passing object
4867
- // references to child views via v-lark attributes.
4868
- $refFn: 1,
4869
- // URI encoder: v => encodeURIComponent($strSafe(v)).replace(/[!')(*]/g, extraMap)
4870
- // Extends encodeURIComponent with encoding of ! ' ( ) *.
4871
- // Applied to values in @event URL parameters and {{!uri}} contexts.
4872
- $encUri: 1,
4873
- // URI encode map — internal object used by $encUri:
4874
- // {'!':'%21','\'':'%27','(':'%28',')':'%29','*':'%2A'}
4875
- $uriMap: 1,
4876
- // URI encode replacer — internal helper used by $encUri:
4877
- // m => $uriMap[m]
4878
- $uriFn: 1,
4879
- // URI encode regexp — internal regexp used by $encUri:
4880
- // /[!')(*]/g
4881
- $uriReg: 1,
4882
- // Quote encoder: v => $strSafe(v).replace(/['"\\]/g, '\\$&')
4883
- // Escapes quotes and backslashes for safe embedding in HTML attribute
4884
- // values (e.g. data-json='...').
4885
- $encQuote: 1,
4886
- // Quote encode regexp — internal regexp used by $encQuote:
4887
- // /['"\\]/g
4888
- $qReg: 1,
4889
- // View ID — the unique identifier of the owning View instance.
4890
- // Injected into @event attribute values at render time so that
4891
- // EventDelegator can dispatch events to the correct View handler.
4892
- // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
4893
- $viewId: 1,
4894
- // Debug: current expression text — stores the template expression being
4895
- // evaluated, for error reporting. Only present in debug mode.
4896
- // e.g. $dbgExpr='<%=user.name%>'
4897
- $dbgExpr: 1,
4898
- // Debug: original art syntax — stores the {{}} template syntax before
4899
- // conversion, for error reporting. Only present in debug mode.
4900
- // e.g. $dbgArt='{{=user.name}}'
4901
- $dbgArt: 1,
4902
- // Debug: source line number — tracks the current line in the template
4903
- // source, for error reporting. Only present in debug mode.
4904
- $dbgLine: 1,
4905
- // RefData alias — fallback reference lookup table.
4906
- // Defaults to $data when no explicit $refAlt is provided.
4907
- // Ensures $refFn() does not crash when @ operator is used without refData.
4908
- $refAlt: 1,
4909
- // Temporary variable — used by the compiler for intermediate
4910
- // expression results in generated code (e.g. loop variables,
4911
- // conditional branches). Declared as: let $tmp
4912
- $tmp: 1,
4913
- // JS literals
4914
- undefined: 1,
4915
- null: 1,
4916
- true: 1,
4917
- false: 1,
4918
- NaN: 1,
4919
- Infinity: 1,
4920
- // JS built-in globals
4921
- window: 1,
4922
- self: 1,
4923
- globalThis: 1,
4924
- document: 1,
4925
- console: 1,
4926
- JSON: 1,
4927
- Math: 1,
4928
- Intl: 1,
4929
- Promise: 1,
4930
- Symbol: 1,
4931
- Number: 1,
4932
- String: 1,
4933
- Boolean: 1,
4934
- Array: 1,
4935
- Object: 1,
4936
- Date: 1,
4937
- RegExp: 1,
4938
- Error: 1,
4939
- TypeError: 1,
4940
- RangeError: 1,
4941
- SyntaxError: 1,
4942
- Map: 1,
4943
- Set: 1,
4944
- WeakMap: 1,
4945
- WeakSet: 1,
4946
- Proxy: 1,
4947
- Reflect: 1,
4948
- ArrayBuffer: 1,
4949
- DataView: 1,
4950
- Float32Array: 1,
4951
- Float64Array: 1,
4952
- Int8Array: 1,
4953
- Int16Array: 1,
4954
- Int32Array: 1,
4955
- Uint8Array: 1,
4956
- Uint16Array: 1,
4957
- Uint32Array: 1,
4958
- Uint8ClampedArray: 1,
4959
- // Functions
4960
- parseInt: 1,
4961
- parseFloat: 1,
4962
- isNaN: 1,
4963
- isFinite: 1,
4964
- encodeURIComponent: 1,
4965
- decodeURIComponent: 1,
4966
- encodeURI: 1,
4967
- decodeURI: 1,
4968
- // Babel helpers
4969
- arguments: 1,
4970
- this: 1,
4971
- require: 1,
4972
- // Lark framework
4973
- Lark: 1
4974
- };
4975
- var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
4976
4218
  export {
4977
4219
  CALL_BREAK_TIME,
4978
4220
  Cache,
@@ -4994,23 +4236,28 @@ export {
4994
4236
  Updater,
4995
4237
  VIEW_EVENT_METHOD_REGEXP,
4996
4238
  View,
4239
+ applyDomOps,
4997
4240
  applyIdUpdates,
4998
4241
  applyStyle,
4999
- applyVdomOps,
5000
4242
  assign,
5001
4243
  bindStore,
5002
- compileTemplate,
5003
4244
  computed,
5004
4245
  create,
5005
- createVdomRef,
4246
+ createDomRef,
5006
4247
  defineStore,
5007
4248
  defineView,
4249
+ domGetCompareKey,
4250
+ domGetNode,
4251
+ domSetAttributes,
4252
+ domSetChildNodes,
4253
+ domSetNode,
4254
+ domSpecialDiff,
4255
+ domUnmountFrames,
5008
4256
  encodeHTML,
5009
4257
  encodeQ,
5010
4258
  encodeSafe,
5011
4259
  encodeURIExtra,
5012
4260
  ensureElementId,
5013
- extractGlobalVars,
5014
4261
  config as frameworkConfig,
5015
4262
  funcWithTry,
5016
4263
  generateId,
@@ -5043,12 +4290,5 @@ export {
5043
4290
  translateData,
5044
4291
  unmark,
5045
4292
  use,
5046
- useUrlState,
5047
- vdomGetCompareKey,
5048
- vdomGetNode,
5049
- vdomSetAttributes,
5050
- vdomSetChildNodes,
5051
- vdomSetNode,
5052
- vdomSpecialDiff,
5053
- vdomUnmountFrames
4293
+ useUrlState
5054
4294
  };