bobe 0.0.58 → 0.0.60

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.
@@ -253,7 +253,6 @@ class Tokenizer {
253
253
  }
254
254
  isEof() {
255
255
  if (!this.token) return false;
256
- if (this.i >= this.code.length && !this.waitingTokens.len) return true;
257
256
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
258
257
  }
259
258
  setToken(type, value, dt = 1) {
@@ -282,6 +281,7 @@ class Tokenizer {
282
281
  if (this.isEof()) {
283
282
  return this.token;
284
283
  }
284
+ if (this.i >= this.code.length && !this.waitingTokens.len) return this.token;
285
285
  this.token = undefined;
286
286
  if (this.waitingTokens.len) {
287
287
  const item = this.waitingTokens.shift();
@@ -1457,6 +1457,14 @@ class InlineFragment {
1457
1457
  }
1458
1458
  const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
1459
1459
  const isRenderAble = val => aoye.isStore(val) || isUI(val) || val instanceof InlineFragment;
1460
+ const SAFE_HANDLER = {
1461
+ has: () => true,
1462
+ get: (t, k) => {
1463
+ if (typeof k === 'symbol') return t[k];
1464
+ return k in t ? t[k] : undefined;
1465
+ }
1466
+ };
1467
+ const safe = data => new Proxy(data, SAFE_HANDLER);
1460
1468
 
1461
1469
  const KEY_INDEX = '__BOBE_KEY_INDEX';
1462
1470
  let _ctxStack;
@@ -1504,6 +1512,9 @@ class Interpreter {
1504
1512
  if (this.tokenizer.isEof()) {
1505
1513
  if (!ctx.prevSibling) ctx.prevSibling = before;
1506
1514
  this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1515
+ if (ctx.current) {
1516
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1517
+ }
1507
1518
  break;
1508
1519
  }
1509
1520
  const token = this.tokenizer.token;
@@ -1515,6 +1526,7 @@ class Interpreter {
1515
1526
  prev: ctx.prevSibling
1516
1527
  }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType & ContextBit ? NodeSort.Context : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | (ctx.current.__logicType & CtxProviderBit ? NodeSort.CtxProvider : 0));
1517
1528
  if (ctx.current.__logicType) {
1529
+ this.beforeLogicIndent?.(ctx.current);
1518
1530
  if (isLogicNode) {
1519
1531
  aoye.setPulling(ctx.current.effect);
1520
1532
  if (ctx.current.__logicType & FakeType.ForItem) {
@@ -1523,6 +1535,12 @@ class Interpreter {
1523
1535
  }
1524
1536
  } else {
1525
1537
  if (ctx.current) {
1538
+ if (this.beforeIndent?.(ctx.current) === false) {
1539
+ const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 1];
1540
+ this.tokenizer.skip(dentLen);
1541
+ ctx.current = null;
1542
+ continue;
1543
+ }
1526
1544
  ctx.realParent = ctx.current;
1527
1545
  }
1528
1546
  ctx.prevSibling = null;
@@ -1535,6 +1553,7 @@ class Interpreter {
1535
1553
  ctx.prevSibling = before;
1536
1554
  }
1537
1555
  this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1556
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1538
1557
  }
1539
1558
  if (this.tokenizer.token.type & TokenType.Dedent) {
1540
1559
  this.tokenizer.nextToken();
@@ -1569,6 +1588,7 @@ class Interpreter {
1569
1588
  const i = forNode.i,
1570
1589
  arr = forNode.arr,
1571
1590
  snapshot = forNode.snapshot;
1591
+ this.leaveLogicNode?.(parent, false);
1572
1592
  if (i + 1 < arr.length) {
1573
1593
  this.tokenizer.resume(snapshot);
1574
1594
  this.tokenizer.nextToken();
@@ -1591,13 +1611,13 @@ class Interpreter {
1591
1611
  }
1592
1612
  return componentNode;
1593
1613
  }
1594
- insertAfterAnchor(name = 'anchor') {
1614
+ insertAnchor(name = 'anchor', isBefore = false) {
1595
1615
  const _this$ctx = this.ctx,
1596
1616
  realParent = _this$ctx.realParent,
1597
1617
  prevSibling = _this$ctx.prevSibling,
1598
1618
  stack = _this$ctx.stack,
1599
1619
  before = _this$ctx.before;
1600
- const afterAnchor = this.createAnchor(name);
1620
+ const afterAnchor = this.createAnchor(name, isBefore);
1601
1621
  this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1602
1622
  this.handleInsert(realParent, afterAnchor, prevSibling);
1603
1623
  return afterAnchor;
@@ -1651,7 +1671,7 @@ class Interpreter {
1651
1671
  _node = this.componentOrFragmentDeclaration(value, ctx);
1652
1672
  } else {
1653
1673
  _node = this.createNode('text');
1654
- _node.text = String(value);
1674
+ this.setProp(_node, 'text', String(value));
1655
1675
  }
1656
1676
  } else {
1657
1677
  return this.dynamicDeclaration(data, value, ctx);
@@ -1681,11 +1701,11 @@ class Interpreter {
1681
1701
  effect: null,
1682
1702
  textNode: null,
1683
1703
  owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
1684
- snapshot: this.tokenizer.snapshot(['dentStack']),
1704
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1685
1705
  parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1686
1706
  };
1687
1707
  let isUpdate = false;
1688
- node.realAfter = this.insertAfterAnchor(`dynamic-after`);
1708
+ node.realAfter = this.insertAnchor(`dynamic-after`);
1689
1709
  node.effect = this.effect(({
1690
1710
  old,
1691
1711
  val
@@ -1694,7 +1714,7 @@ class Interpreter {
1694
1714
  oldTextNode = node.textNode;
1695
1715
  if (oldLogicType) {
1696
1716
  this.removeLogicNode(node);
1697
- bobeShared.pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
1717
+ bobeShared.pickInPlace(node, ['realParent', 'realBefore', 'realAfter', 'owner', 'snapshot', 'parentDataProvider']);
1698
1718
  }
1699
1719
  if (isRenderAble(val)) {
1700
1720
  if (oldTextNode) {
@@ -1721,11 +1741,13 @@ class Interpreter {
1721
1741
  this.tokenizer = node.tokenizer;
1722
1742
  if (node.fragmentSnapshot) {
1723
1743
  this.tokenizer.resume(node.fragmentSnapshot);
1724
- this.tokenizer.useDedentAsEof = true;
1725
- this.tokenizer.initIndentWhenUseDedentAsEof();
1726
1744
  }
1727
1745
  if (isUpdate) {
1728
- this.program(node.realParent, node.owner, node.realBefore, node);
1746
+ this.tokenizer.useDedentAsEof = false;
1747
+ this.program(node.realParent, node, node.realBefore);
1748
+ } else {
1749
+ this.tokenizer.useDedentAsEof = true;
1750
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1729
1751
  }
1730
1752
  } else {
1731
1753
  node.__logicType = FakeType.DynamicText;
@@ -1734,7 +1756,7 @@ class Interpreter {
1734
1756
  if (isNewTextNode) {
1735
1757
  textNode = node.textNode = this.createNode('text');
1736
1758
  }
1737
- textNode.text = String(val);
1759
+ this.setProp(textNode, 'text', String(val));
1738
1760
  if (isNewTextNode) {
1739
1761
  if (isUpdate) {
1740
1762
  this.handleInsert(node.realParent, textNode, node.realBefore);
@@ -1746,6 +1768,7 @@ class Interpreter {
1746
1768
  prevSibling = _this$ctx2.prevSibling;
1747
1769
  this.handleInsert(realParent, textNode, prevSibling);
1748
1770
  }
1771
+ this.leaveNode?.(textNode, false);
1749
1772
  }
1750
1773
  }
1751
1774
  isUpdate = true;
@@ -1776,7 +1799,7 @@ class Interpreter {
1776
1799
  realBefore: null,
1777
1800
  realAfter: null
1778
1801
  };
1779
- node.realAfter = this.insertAfterAnchor('context-after');
1802
+ node.realAfter = this.insertAnchor('context-after');
1780
1803
  return node;
1781
1804
  }
1782
1805
  formatForCollection(collection) {
@@ -1866,7 +1889,8 @@ class Interpreter {
1866
1889
  i: 0
1867
1890
  };
1868
1891
  if (keyExp) {
1869
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}\n};return v;`);
1892
+ const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
1893
+ forNode.getKey = data => rawGetKey(safe(data));
1870
1894
  }
1871
1895
  window['for1'] = forNode;
1872
1896
  const data = this.getData();
@@ -1874,7 +1898,7 @@ class Interpreter {
1874
1898
  const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
1875
1899
  const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
1876
1900
  forNode.arrSignal = arrSignal;
1877
- forNode.realAfter = this.insertAfterAnchor('for-after');
1901
+ forNode.realAfter = this.insertAnchor('for-after');
1878
1902
  const _forNode$snapshot = forNode.snapshot;
1879
1903
  _forNode$snapshot.dentStack;
1880
1904
  _forNode$snapshot.isFirstToken;
@@ -1897,8 +1921,8 @@ class Interpreter {
1897
1921
  const len = arr.length;
1898
1922
  for (let i = len; i--;) {
1899
1923
  const item = this.createForItem(forNode, i, data);
1900
- item.realAfter = this.insertAfterAnchor('for-item-after');
1901
- item.realBefore = this.insertAfterAnchor('for-item-before');
1924
+ item.realAfter = this.insertAnchor('for-item-after');
1925
+ item.realBefore = this.insertAnchor('for-item-before', true);
1902
1926
  item.realParent = forNode.realParent;
1903
1927
  children[i] = item;
1904
1928
  }
@@ -2065,7 +2089,7 @@ class Interpreter {
2065
2089
  newChildren[i] = item;
2066
2090
  let realAfter = this.createAnchor('for-item-after');
2067
2091
  this.handleInsert(forNode.realParent, realAfter, before);
2068
- let realBefore = this.createAnchor('for-item-before');
2092
+ let realBefore = this.createAnchor('for-item-before', true);
2069
2093
  this.handleInsert(forNode.realParent, realBefore, before);
2070
2094
  item.realBefore = realBefore;
2071
2095
  item.realAfter = realAfter;
@@ -2234,11 +2258,11 @@ class Interpreter {
2234
2258
  resumeSnapshot
2235
2259
  };
2236
2260
  this.onePropParsed = onePropParsed;
2237
- node.realAfter = this.insertAfterAnchor('component-after');
2261
+ node.realAfter = this.insertAnchor('component-after');
2238
2262
  return node;
2239
2263
  }
2240
2264
  getFn(data, expression) {
2241
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
2265
+ return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2242
2266
  }
2243
2267
  getAssignFn(data, expression) {
2244
2268
  const valueId = `value_bobe_${bobeShared.date32()}`;
@@ -2329,7 +2353,7 @@ class Interpreter {
2329
2353
  break;
2330
2354
  }
2331
2355
  ifNode.condition = signal;
2332
- ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
2356
+ ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
2333
2357
  const ef = this.effect(({
2334
2358
  val
2335
2359
  }) => {
@@ -2514,10 +2538,11 @@ class Interpreter {
2514
2538
  firstChild(node) {
2515
2539
  return node.firstChild;
2516
2540
  }
2517
- createAnchor(name) {
2541
+ createAnchor(name, isBefore) {
2518
2542
  return {
2519
2543
  name,
2520
- nextSibling: null
2544
+ nextSibling: null,
2545
+ isBefore
2521
2546
  };
2522
2547
  }
2523
2548
  insertAfter(parent, node, prev) {
@@ -2587,6 +2612,7 @@ function bobe(fragments, ...values) {
2587
2612
  return tokenizer;
2588
2613
  };
2589
2614
  ui.boundStore = aoye.Store.Current;
2615
+ ui[aoye.Keys.ProxyFreeObject] = true;
2590
2616
  ui.__BOBE_IS_UI = true;
2591
2617
  return ui;
2592
2618
  }
@@ -2603,6 +2629,7 @@ function customRender(option) {
2603
2629
  tokenizer
2604
2630
  };
2605
2631
  terp.program(root, componentNode);
2632
+ option.onBeforeFlush?.();
2606
2633
  aoye.flushMicroEffectManual();
2607
2634
  return [componentNode, store];
2608
2635
  };