@viewfly/core 1.0.0-alpha.11 → 1.0.0-alpha.13

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.
@@ -211,45 +211,6 @@ declare abstract class NativeRenderer<ElementNode = NativeNode, TextNode = Nativ
211
211
  abstract insertAfter(newNode: ElementNode | TextNode, ref: ElementNode | TextNode, isSvg: boolean): void;
212
212
  }
213
213
 
214
- interface ListenDelegate {
215
- delegate: () => any;
216
- listenFn: ((...args: any[]) => any) | void;
217
- }
218
- interface TextAtom {
219
- type: 'text';
220
- index: number;
221
- jsxNode: string;
222
- nativeNode: NativeNode | null;
223
- child: Atom | null;
224
- sibling: Atom | null;
225
- isSvg: boolean;
226
- }
227
- interface ElementAtom {
228
- type: 'element';
229
- index: number;
230
- jsxNode: JSXNode<string>;
231
- nativeNode: NativeNode | null;
232
- child: Atom | null;
233
- sibling: Atom | null;
234
- isSvg: boolean;
235
- }
236
- interface ComponentAtom {
237
- type: 'component';
238
- index: number;
239
- jsxNode: JSXNode<JSXInternal.ComponentSetup> | Component;
240
- nativeNode: NativeNode | null;
241
- child: Atom | null;
242
- sibling: Atom | null;
243
- isSvg: boolean;
244
- }
245
- type Atom = TextAtom | ElementAtom | ComponentAtom;
246
- interface ComponentView {
247
- atom: Atom;
248
- host: NativeNode;
249
- isParent: boolean;
250
- rootHost: NativeNode;
251
- }
252
-
253
214
  interface Props {
254
215
  children?: JSXInternal.ViewNode | JSXInternal.ViewNode[];
255
216
  }
@@ -261,7 +222,6 @@ interface JSXNode<T = string | JSXInternal.ComponentSetup> {
261
222
  type: T;
262
223
  props: Props & Record<string, any>;
263
224
  key?: Key;
264
- on?: Record<string, ListenDelegate>;
265
225
  }
266
226
  declare const JSXNodeFactory: {
267
227
  createNode<T = string | JSXInternal.ComponentSetup<any>>(type: T, props: Props & Record<string, any>, key?: Key): JSXNode<T>;
@@ -560,6 +520,44 @@ declare global {
560
520
  }
561
521
  }
562
522
 
523
+ declare const TextAtomType: unique symbol;
524
+ declare const ElementAtomType: unique symbol;
525
+ declare const ComponentAtomType: unique symbol;
526
+ interface TextAtom {
527
+ type: typeof TextAtomType;
528
+ index: number;
529
+ jsxNode: string;
530
+ nativeNode: NativeNode | null;
531
+ child: Atom | null;
532
+ sibling: Atom | null;
533
+ isSvg: boolean;
534
+ }
535
+ interface ElementAtom {
536
+ type: typeof ElementAtomType;
537
+ index: number;
538
+ jsxNode: JSXNode<string>;
539
+ nativeNode: NativeNode | null;
540
+ child: Atom | null;
541
+ sibling: Atom | null;
542
+ isSvg: boolean;
543
+ }
544
+ interface ComponentAtom {
545
+ type: typeof ComponentAtomType;
546
+ index: number;
547
+ jsxNode: JSXNode<JSXInternal.ComponentSetup> | Component;
548
+ nativeNode: NativeNode | null;
549
+ child: Atom | null;
550
+ sibling: Atom | null;
551
+ isSvg: boolean;
552
+ }
553
+ type Atom = TextAtom | ElementAtom | ComponentAtom;
554
+ interface ComponentView {
555
+ atom: Atom;
556
+ host: NativeNode;
557
+ isParent: boolean;
558
+ rootHost: NativeNode;
559
+ }
560
+
563
561
  /**
564
562
  * Viewfly 配置项
565
563
  */
@@ -634,6 +634,9 @@ function styleToObject(style) {
634
634
  });
635
635
  return obj;
636
636
  }
637
+ const TextAtomType = Symbol('Text');
638
+ const ElementAtomType = Symbol('Element');
639
+ const ComponentAtomType = Symbol('Component');
637
640
 
638
641
  const componentSetupStack = [];
639
642
  const signalDepsStack = [];
@@ -741,8 +744,9 @@ class Component extends ReflectiveInjector {
741
744
  };
742
745
  }
743
746
  update(newProps, forceUpdate = false) {
747
+ const oldProps = this.props;
744
748
  if (!forceUpdate) {
745
- const { add, remove, replace } = getObjectChanges(newProps, this.props);
749
+ const { add, remove, replace } = getObjectChanges(newProps, oldProps);
746
750
  if (add.length || remove.length || replace.length) {
747
751
  this.invokePropsChangedHooks(newProps);
748
752
  }
@@ -766,7 +770,7 @@ class Component extends ReflectiveInjector {
766
770
  }
767
771
  }
768
772
  if (typeof this.instance.$useMemo === 'function') {
769
- if (this.instance.$useMemo(newProps, this.props)) {
773
+ if (this.instance.$useMemo(newProps, oldProps)) {
770
774
  return this.template;
771
775
  }
772
776
  }
@@ -1284,14 +1288,14 @@ function withMemo(canUseMemo, render) {
1284
1288
  }
1285
1289
 
1286
1290
  const componentViewCache = new WeakMap();
1287
- const listenerReg = /^on(?=[A-Z])/;
1291
+ const listenerReg = /^on[A-Z]/;
1288
1292
  function createRenderer(component, nativeRenderer) {
1289
1293
  let isInit = true;
1290
1294
  return function render(host) {
1291
1295
  if (isInit) {
1292
1296
  isInit = false;
1293
1297
  const atom = {
1294
- type: 'component',
1298
+ type: ComponentAtomType,
1295
1299
  index: 0,
1296
1300
  jsxNode: component,
1297
1301
  sibling: null,
@@ -1312,41 +1316,28 @@ function createRenderer(component, nativeRenderer) {
1312
1316
  }
1313
1317
  function buildView(nativeRenderer, parentComponent, atom, context) {
1314
1318
  const { jsxNode, type } = atom;
1315
- if (type === 'component') {
1319
+ if (type === ComponentAtomType) {
1316
1320
  const component = new Component(parentComponent, jsxNode.type, jsxNode.props, jsxNode.key);
1317
1321
  atom.jsxNode = component;
1318
1322
  componentRender(nativeRenderer, component, atom, context);
1319
1323
  }
1324
+ else if (type === ElementAtomType) {
1325
+ createElement(nativeRenderer, atom, parentComponent, context);
1326
+ }
1320
1327
  else {
1321
- let nativeNode;
1322
- let applyRefs = null;
1323
- if (type === 'element') {
1324
- const { nativeNode: n, applyRefs: a } = createElement(nativeRenderer, jsxNode, atom.isSvg);
1325
- nativeNode = n;
1326
- applyRefs = a;
1327
- }
1328
- else {
1329
- nativeNode = createTextNode(nativeRenderer, jsxNode, atom.isSvg);
1330
- }
1331
- atom.nativeNode = nativeNode;
1332
- insertNode(nativeRenderer, atom, context);
1333
- if (type === 'element') {
1334
- const childContext = {
1335
- isParent: true,
1336
- host: nativeNode,
1337
- rootHost: context.rootHost
1338
- };
1339
- let child = atom.child;
1340
- while (child) {
1341
- buildView(nativeRenderer, parentComponent, child, childContext);
1342
- child = child.sibling;
1343
- }
1344
- }
1345
- context.host = nativeNode;
1346
- context.isParent = false;
1347
- if (applyRefs) {
1348
- applyRefs();
1349
- }
1328
+ createTextNode(nativeRenderer, atom, context);
1329
+ }
1330
+ }
1331
+ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
1332
+ const childContext = {
1333
+ isParent: true,
1334
+ host: atom.nativeNode,
1335
+ rootHost: context.rootHost
1336
+ };
1337
+ let child = atom.child;
1338
+ while (child) {
1339
+ buildView(nativeRenderer, parentComponent, child, childContext);
1340
+ child = child.sibling;
1350
1341
  }
1351
1342
  }
1352
1343
  function updateView(nativeRenderer, component) {
@@ -1416,7 +1407,7 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1416
1407
  const diffIndex = oldAtom.index;
1417
1408
  if (type === oldAtom.type) {
1418
1409
  let commit;
1419
- if (type === 'text') {
1410
+ if (type === TextAtomType) {
1420
1411
  commit = updateText(newAtom, oldAtom, nativeRenderer, context);
1421
1412
  }
1422
1413
  else {
@@ -1426,7 +1417,7 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1426
1417
  oldAtom = oldAtom.sibling;
1427
1418
  continue;
1428
1419
  }
1429
- if (type === 'component') {
1420
+ if (type === ComponentAtomType) {
1430
1421
  commit = updateComponent(newAtom, oldAtom, newAtom.index, diffIndex, nativeRenderer, context);
1431
1422
  }
1432
1423
  else {
@@ -1472,23 +1463,7 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
1472
1463
  }
1473
1464
  context.host = newAtom.nativeNode;
1474
1465
  context.isParent = false;
1475
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1476
- if (newAtom.child) {
1477
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1478
- host: newAtom.nativeNode,
1479
- isParent: true,
1480
- rootHost: context.rootHost
1481
- });
1482
- }
1483
- else if (oldAtom.child) {
1484
- let atom = oldAtom.child;
1485
- nativeRenderer.cleanChildren(oldAtom.nativeNode, oldAtom.isSvg);
1486
- while (atom) {
1487
- cleanView(nativeRenderer, atom, false);
1488
- atom = atom.sibling;
1489
- }
1490
- }
1491
- applyRefs();
1466
+ updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context);
1492
1467
  };
1493
1468
  }
1494
1469
  function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
@@ -1546,13 +1521,21 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1546
1521
  child = child.sibling;
1547
1522
  }
1548
1523
  }
1524
+ function cleanElementChildren(atom, nativeRenderer) {
1525
+ let child = atom.child;
1526
+ nativeRenderer.cleanChildren(atom.nativeNode, atom.isSvg);
1527
+ while (child) {
1528
+ cleanView(nativeRenderer, child, false);
1529
+ child = child.sibling;
1530
+ }
1531
+ }
1549
1532
  function cleanView(nativeRenderer, atom, needClean) {
1550
1533
  if (atom.nativeNode) {
1551
1534
  if (needClean) {
1552
1535
  nativeRenderer.remove(atom.nativeNode, atom.isSvg);
1553
1536
  needClean = false;
1554
1537
  }
1555
- if (atom.type === 'element') {
1538
+ if (atom.type === ElementAtomType) {
1556
1539
  const ref = atom.jsxNode.props[refKey];
1557
1540
  applyRefs(ref, atom.nativeNode, false);
1558
1541
  }
@@ -1581,22 +1564,9 @@ function componentRender(nativeRenderer, component, from, context) {
1581
1564
  }
1582
1565
  component.rendered();
1583
1566
  }
1584
- function createChainByJSXComponent(jsxNode, prevAtom, isSvg) {
1585
- const atom = {
1586
- type: 'component',
1587
- index: prevAtom.index + 1,
1588
- jsxNode,
1589
- sibling: null,
1590
- child: null,
1591
- nativeNode: null,
1592
- isSvg
1593
- };
1594
- prevAtom.sibling = atom;
1595
- return atom;
1596
- }
1597
- function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1567
+ function createChainByJSXNode(type, jsxNode, prevAtom, isSvg) {
1598
1568
  const atom = {
1599
- type: 'text',
1569
+ type,
1600
1570
  index: prevAtom.index + 1,
1601
1571
  jsxNode,
1602
1572
  sibling: null,
@@ -1607,26 +1577,11 @@ function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1607
1577
  prevAtom.sibling = atom;
1608
1578
  return atom;
1609
1579
  }
1610
- function createChainByJSXElement(element, prevAtom, isSvg) {
1611
- isSvg = isSvg || element.type === 'svg';
1612
- const atom = {
1613
- type: 'element',
1614
- index: prevAtom.index + 1,
1615
- jsxNode: element,
1616
- sibling: null,
1617
- child: null,
1618
- nativeNode: null,
1619
- isSvg
1620
- };
1621
- prevAtom.sibling = atom;
1622
- atom.child = createChildChain(element.props.children, isSvg);
1623
- return atom;
1624
- }
1625
1580
  function createChainByNode(jsxNode, prevAtom, isSvg) {
1626
1581
  const type = typeof jsxNode;
1627
1582
  if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1628
1583
  if (typeof jsxNode === 'string') {
1629
- return createChainByJSXText(jsxNode, prevAtom, isSvg);
1584
+ return createChainByJSXNode(TextAtomType, jsxNode, prevAtom, isSvg);
1630
1585
  }
1631
1586
  if (Array.isArray(jsxNode)) {
1632
1587
  return createChainByChildren(jsxNode, prevAtom, isSvg);
@@ -1634,13 +1589,13 @@ function createChainByNode(jsxNode, prevAtom, isSvg) {
1634
1589
  if (type === 'object') {
1635
1590
  const nodeType = typeof jsxNode.type;
1636
1591
  if (nodeType === 'string') {
1637
- return createChainByJSXElement(jsxNode, prevAtom, isSvg);
1592
+ return createChainByJSXNode(ElementAtomType, jsxNode, prevAtom, isSvg || jsxNode.type === 'svg');
1638
1593
  }
1639
1594
  else if (nodeType === 'function') {
1640
- return createChainByJSXComponent(jsxNode, prevAtom, isSvg);
1595
+ return createChainByJSXNode(ComponentAtomType, jsxNode, prevAtom, isSvg);
1641
1596
  }
1642
1597
  }
1643
- return createChainByJSXText(String(jsxNode), prevAtom, isSvg);
1598
+ return createChainByJSXNode(TextAtomType, String(jsxNode), prevAtom, isSvg);
1644
1599
  }
1645
1600
  return prevAtom;
1646
1601
  }
@@ -1668,12 +1623,14 @@ function insertNode(nativeRenderer, atom, context) {
1668
1623
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
1669
1624
  }
1670
1625
  }
1671
- function createElement(nativeRenderer, vNode, isSvg) {
1672
- const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1673
- const props = vNode.props;
1626
+ function createElement(nativeRenderer, atom, parentComponent, context) {
1627
+ const { isSvg, jsxNode } = atom;
1628
+ const nativeNode = nativeRenderer.createElement(jsxNode.type, isSvg);
1629
+ const props = jsxNode.props;
1674
1630
  let bindingRefs;
1675
1631
  for (const key in props) {
1676
1632
  if (key === 'children') {
1633
+ atom.child = createChildChain(jsxNode.props.children, isSvg);
1677
1634
  continue;
1678
1635
  }
1679
1636
  if (key === 'class') {
@@ -1693,7 +1650,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1693
1650
  if (listenerReg.test(key)) {
1694
1651
  const listener = props[key];
1695
1652
  if (typeof listener === 'function') {
1696
- bindEvent(nativeRenderer, vNode, key, nativeNode, listener, isSvg);
1653
+ nativeRenderer.listen(nativeNode, key, listener, isSvg);
1697
1654
  }
1698
1655
  continue;
1699
1656
  }
@@ -1703,28 +1660,39 @@ function createElement(nativeRenderer, vNode, isSvg) {
1703
1660
  }
1704
1661
  nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
1705
1662
  }
1706
- return {
1707
- nativeNode,
1708
- applyRefs: () => {
1709
- applyRefs(bindingRefs, nativeNode, true);
1710
- }
1711
- };
1712
- }
1713
- function createTextNode(nativeRenderer, text, isSvg) {
1714
- return nativeRenderer.createTextNode(text, isSvg);
1715
- }
1716
- function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNode, isSvg) {
1663
+ atom.nativeNode = nativeNode;
1664
+ insertNode(nativeRenderer, atom, context);
1665
+ buildElementChildren(atom, nativeRenderer, parentComponent, context);
1666
+ context.host = nativeNode;
1667
+ context.isParent = false;
1668
+ applyRefs(bindingRefs, nativeNode, true);
1669
+ }
1670
+ function createTextNode(nativeRenderer, atom, context) {
1671
+ const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.isSvg);
1672
+ atom.nativeNode = nativeNode;
1673
+ insertNode(nativeRenderer, atom, context);
1674
+ context.host = nativeNode;
1675
+ context.isParent = false;
1676
+ }
1677
+ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
1678
+ const newVNode = newAtom.jsxNode;
1679
+ const isSvg = newAtom.isSvg;
1680
+ const nativeNode = newAtom.nativeNode;
1681
+ const oldVNode = oldAtom.jsxNode;
1717
1682
  if (newVNode === oldVNode) {
1718
- return () => {
1719
- //
1720
- };
1683
+ parentComponent.changedSubComponents.forEach(child => {
1684
+ updateView(nativeRenderer, child);
1685
+ });
1686
+ return;
1721
1687
  }
1722
1688
  const changes = getObjectChanges(newVNode.props, oldVNode.props);
1723
1689
  let unBindRefs;
1724
1690
  let bindRefs;
1725
- newVNode.on = oldVNode.on;
1691
+ newAtom.child = oldAtom.child;
1726
1692
  for (const [key, value] of changes.remove) {
1727
1693
  if (key === 'children') {
1694
+ cleanElementChildren(oldAtom, nativeRenderer);
1695
+ newAtom.child = null;
1728
1696
  continue;
1729
1697
  }
1730
1698
  if (key === 'class') {
@@ -1739,10 +1707,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1739
1707
  }
1740
1708
  if (listenerReg.test(key)) {
1741
1709
  if (typeof value === 'function') {
1742
- const type = key.replace(listenerReg, '').toLowerCase();
1743
- const oldOn = oldVNode.on;
1744
- nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate, isSvg);
1745
- Reflect.deleteProperty(oldOn, type);
1710
+ nativeRenderer.unListen(nativeNode, key, value, isSvg);
1746
1711
  }
1747
1712
  continue;
1748
1713
  }
@@ -1754,6 +1719,17 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1754
1719
  }
1755
1720
  for (const [key, newValue, oldValue] of changes.replace) {
1756
1721
  if (key === 'children') {
1722
+ newAtom.child = createChildChain(newValue, isSvg);
1723
+ if (!newAtom.child) {
1724
+ cleanElementChildren(oldAtom, nativeRenderer);
1725
+ }
1726
+ else {
1727
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1728
+ host: newAtom.nativeNode,
1729
+ isParent: true,
1730
+ rootHost: context.rootHost
1731
+ });
1732
+ }
1757
1733
  continue;
1758
1734
  }
1759
1735
  if (key === 'class') {
@@ -1775,8 +1751,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1775
1751
  continue;
1776
1752
  }
1777
1753
  if (listenerReg.test(key)) {
1778
- const listenType = key.replace(listenerReg, '').toLowerCase();
1779
- newVNode.on[listenType].listenFn = newValue;
1754
+ nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1755
+ nativeRenderer.listen(nativeNode, key, newValue, isSvg);
1780
1756
  continue;
1781
1757
  }
1782
1758
  if (key === refKey) {
@@ -1788,6 +1764,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1788
1764
  }
1789
1765
  for (const [key, value] of changes.add) {
1790
1766
  if (key === 'children') {
1767
+ newAtom.child = createChildChain(value, isSvg);
1768
+ buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1791
1769
  continue;
1792
1770
  }
1793
1771
  if (key === 'class') {
@@ -1803,7 +1781,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1803
1781
  }
1804
1782
  if (listenerReg.test(key)) {
1805
1783
  if (typeof value === 'function') {
1806
- bindEvent(nativeRenderer, newVNode, key, nativeNode, value, isSvg);
1784
+ nativeRenderer.listen(nativeNode, key, value, isSvg);
1807
1785
  }
1808
1786
  continue;
1809
1787
  }
@@ -1813,10 +1791,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1813
1791
  }
1814
1792
  nativeRenderer.setProperty(nativeNode, key, value, isSvg);
1815
1793
  }
1816
- return () => {
1817
- applyRefs(unBindRefs, nativeNode, false);
1818
- applyRefs(bindRefs, nativeNode, true);
1819
- };
1794
+ applyRefs(unBindRefs, nativeNode, false);
1795
+ applyRefs(bindRefs, nativeNode, true);
1820
1796
  }
1821
1797
  function applyRefs(refs, nativeNode, binding) {
1822
1798
  if (refs) {
@@ -1828,21 +1804,6 @@ function applyRefs(refs, nativeNode, binding) {
1828
1804
  }
1829
1805
  }
1830
1806
  }
1831
- function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1832
- let on = vNode.on;
1833
- if (!on) {
1834
- vNode.on = on = {};
1835
- }
1836
- const type = key.replace(listenerReg, '').toLowerCase();
1837
- const delegateObj = {
1838
- delegate(...args) {
1839
- return delegateObj.listenFn.apply(this, args);
1840
- },
1841
- listenFn
1842
- };
1843
- on[type] = delegateObj;
1844
- nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1845
- }
1846
1807
 
1847
1808
  /**
1848
1809
  * Viewfly 根组件,用于实现组件状态更新事件通知
package/bundles/index.js CHANGED
@@ -636,6 +636,9 @@ function styleToObject(style) {
636
636
  });
637
637
  return obj;
638
638
  }
639
+ const TextAtomType = Symbol('Text');
640
+ const ElementAtomType = Symbol('Element');
641
+ const ComponentAtomType = Symbol('Component');
639
642
 
640
643
  const componentSetupStack = [];
641
644
  const signalDepsStack = [];
@@ -743,8 +746,9 @@ class Component extends ReflectiveInjector {
743
746
  };
744
747
  }
745
748
  update(newProps, forceUpdate = false) {
749
+ const oldProps = this.props;
746
750
  if (!forceUpdate) {
747
- const { add, remove, replace } = getObjectChanges(newProps, this.props);
751
+ const { add, remove, replace } = getObjectChanges(newProps, oldProps);
748
752
  if (add.length || remove.length || replace.length) {
749
753
  this.invokePropsChangedHooks(newProps);
750
754
  }
@@ -768,7 +772,7 @@ class Component extends ReflectiveInjector {
768
772
  }
769
773
  }
770
774
  if (typeof this.instance.$useMemo === 'function') {
771
- if (this.instance.$useMemo(newProps, this.props)) {
775
+ if (this.instance.$useMemo(newProps, oldProps)) {
772
776
  return this.template;
773
777
  }
774
778
  }
@@ -1286,14 +1290,14 @@ function withMemo(canUseMemo, render) {
1286
1290
  }
1287
1291
 
1288
1292
  const componentViewCache = new WeakMap();
1289
- const listenerReg = /^on(?=[A-Z])/;
1293
+ const listenerReg = /^on[A-Z]/;
1290
1294
  function createRenderer(component, nativeRenderer) {
1291
1295
  let isInit = true;
1292
1296
  return function render(host) {
1293
1297
  if (isInit) {
1294
1298
  isInit = false;
1295
1299
  const atom = {
1296
- type: 'component',
1300
+ type: ComponentAtomType,
1297
1301
  index: 0,
1298
1302
  jsxNode: component,
1299
1303
  sibling: null,
@@ -1314,41 +1318,28 @@ function createRenderer(component, nativeRenderer) {
1314
1318
  }
1315
1319
  function buildView(nativeRenderer, parentComponent, atom, context) {
1316
1320
  const { jsxNode, type } = atom;
1317
- if (type === 'component') {
1321
+ if (type === ComponentAtomType) {
1318
1322
  const component = new Component(parentComponent, jsxNode.type, jsxNode.props, jsxNode.key);
1319
1323
  atom.jsxNode = component;
1320
1324
  componentRender(nativeRenderer, component, atom, context);
1321
1325
  }
1326
+ else if (type === ElementAtomType) {
1327
+ createElement(nativeRenderer, atom, parentComponent, context);
1328
+ }
1322
1329
  else {
1323
- let nativeNode;
1324
- let applyRefs = null;
1325
- if (type === 'element') {
1326
- const { nativeNode: n, applyRefs: a } = createElement(nativeRenderer, jsxNode, atom.isSvg);
1327
- nativeNode = n;
1328
- applyRefs = a;
1329
- }
1330
- else {
1331
- nativeNode = createTextNode(nativeRenderer, jsxNode, atom.isSvg);
1332
- }
1333
- atom.nativeNode = nativeNode;
1334
- insertNode(nativeRenderer, atom, context);
1335
- if (type === 'element') {
1336
- const childContext = {
1337
- isParent: true,
1338
- host: nativeNode,
1339
- rootHost: context.rootHost
1340
- };
1341
- let child = atom.child;
1342
- while (child) {
1343
- buildView(nativeRenderer, parentComponent, child, childContext);
1344
- child = child.sibling;
1345
- }
1346
- }
1347
- context.host = nativeNode;
1348
- context.isParent = false;
1349
- if (applyRefs) {
1350
- applyRefs();
1351
- }
1330
+ createTextNode(nativeRenderer, atom, context);
1331
+ }
1332
+ }
1333
+ function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
1334
+ const childContext = {
1335
+ isParent: true,
1336
+ host: atom.nativeNode,
1337
+ rootHost: context.rootHost
1338
+ };
1339
+ let child = atom.child;
1340
+ while (child) {
1341
+ buildView(nativeRenderer, parentComponent, child, childContext);
1342
+ child = child.sibling;
1352
1343
  }
1353
1344
  }
1354
1345
  function updateView(nativeRenderer, component) {
@@ -1418,7 +1409,7 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1418
1409
  const diffIndex = oldAtom.index;
1419
1410
  if (type === oldAtom.type) {
1420
1411
  let commit;
1421
- if (type === 'text') {
1412
+ if (type === TextAtomType) {
1422
1413
  commit = updateText(newAtom, oldAtom, nativeRenderer, context);
1423
1414
  }
1424
1415
  else {
@@ -1428,7 +1419,7 @@ function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, paren
1428
1419
  oldAtom = oldAtom.sibling;
1429
1420
  continue;
1430
1421
  }
1431
- if (type === 'component') {
1422
+ if (type === ComponentAtomType) {
1432
1423
  commit = updateComponent(newAtom, oldAtom, newAtom.index, diffIndex, nativeRenderer, context);
1433
1424
  }
1434
1425
  else {
@@ -1474,23 +1465,7 @@ function updateElement(newAtom, oldAtom, expectIndex, oldIndex, nativeRenderer,
1474
1465
  }
1475
1466
  context.host = newAtom.nativeNode;
1476
1467
  context.isParent = false;
1477
- const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode, newAtom.isSvg);
1478
- if (newAtom.child) {
1479
- diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1480
- host: newAtom.nativeNode,
1481
- isParent: true,
1482
- rootHost: context.rootHost
1483
- });
1484
- }
1485
- else if (oldAtom.child) {
1486
- let atom = oldAtom.child;
1487
- nativeRenderer.cleanChildren(oldAtom.nativeNode, oldAtom.isSvg);
1488
- while (atom) {
1489
- cleanView(nativeRenderer, atom, false);
1490
- atom = atom.sibling;
1491
- }
1492
- }
1493
- applyRefs();
1468
+ updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context);
1494
1469
  };
1495
1470
  }
1496
1471
  function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRenderer, context) {
@@ -1548,13 +1523,21 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
1548
1523
  child = child.sibling;
1549
1524
  }
1550
1525
  }
1526
+ function cleanElementChildren(atom, nativeRenderer) {
1527
+ let child = atom.child;
1528
+ nativeRenderer.cleanChildren(atom.nativeNode, atom.isSvg);
1529
+ while (child) {
1530
+ cleanView(nativeRenderer, child, false);
1531
+ child = child.sibling;
1532
+ }
1533
+ }
1551
1534
  function cleanView(nativeRenderer, atom, needClean) {
1552
1535
  if (atom.nativeNode) {
1553
1536
  if (needClean) {
1554
1537
  nativeRenderer.remove(atom.nativeNode, atom.isSvg);
1555
1538
  needClean = false;
1556
1539
  }
1557
- if (atom.type === 'element') {
1540
+ if (atom.type === ElementAtomType) {
1558
1541
  const ref = atom.jsxNode.props[refKey];
1559
1542
  applyRefs(ref, atom.nativeNode, false);
1560
1543
  }
@@ -1583,22 +1566,9 @@ function componentRender(nativeRenderer, component, from, context) {
1583
1566
  }
1584
1567
  component.rendered();
1585
1568
  }
1586
- function createChainByJSXComponent(jsxNode, prevAtom, isSvg) {
1587
- const atom = {
1588
- type: 'component',
1589
- index: prevAtom.index + 1,
1590
- jsxNode,
1591
- sibling: null,
1592
- child: null,
1593
- nativeNode: null,
1594
- isSvg
1595
- };
1596
- prevAtom.sibling = atom;
1597
- return atom;
1598
- }
1599
- function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1569
+ function createChainByJSXNode(type, jsxNode, prevAtom, isSvg) {
1600
1570
  const atom = {
1601
- type: 'text',
1571
+ type,
1602
1572
  index: prevAtom.index + 1,
1603
1573
  jsxNode,
1604
1574
  sibling: null,
@@ -1609,26 +1579,11 @@ function createChainByJSXText(jsxNode, prevAtom, isSvg) {
1609
1579
  prevAtom.sibling = atom;
1610
1580
  return atom;
1611
1581
  }
1612
- function createChainByJSXElement(element, prevAtom, isSvg) {
1613
- isSvg = isSvg || element.type === 'svg';
1614
- const atom = {
1615
- type: 'element',
1616
- index: prevAtom.index + 1,
1617
- jsxNode: element,
1618
- sibling: null,
1619
- child: null,
1620
- nativeNode: null,
1621
- isSvg
1622
- };
1623
- prevAtom.sibling = atom;
1624
- atom.child = createChildChain(element.props.children, isSvg);
1625
- return atom;
1626
- }
1627
1582
  function createChainByNode(jsxNode, prevAtom, isSvg) {
1628
1583
  const type = typeof jsxNode;
1629
1584
  if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
1630
1585
  if (typeof jsxNode === 'string') {
1631
- return createChainByJSXText(jsxNode, prevAtom, isSvg);
1586
+ return createChainByJSXNode(TextAtomType, jsxNode, prevAtom, isSvg);
1632
1587
  }
1633
1588
  if (Array.isArray(jsxNode)) {
1634
1589
  return createChainByChildren(jsxNode, prevAtom, isSvg);
@@ -1636,13 +1591,13 @@ function createChainByNode(jsxNode, prevAtom, isSvg) {
1636
1591
  if (type === 'object') {
1637
1592
  const nodeType = typeof jsxNode.type;
1638
1593
  if (nodeType === 'string') {
1639
- return createChainByJSXElement(jsxNode, prevAtom, isSvg);
1594
+ return createChainByJSXNode(ElementAtomType, jsxNode, prevAtom, isSvg || jsxNode.type === 'svg');
1640
1595
  }
1641
1596
  else if (nodeType === 'function') {
1642
- return createChainByJSXComponent(jsxNode, prevAtom, isSvg);
1597
+ return createChainByJSXNode(ComponentAtomType, jsxNode, prevAtom, isSvg);
1643
1598
  }
1644
1599
  }
1645
- return createChainByJSXText(String(jsxNode), prevAtom, isSvg);
1600
+ return createChainByJSXNode(TextAtomType, String(jsxNode), prevAtom, isSvg);
1646
1601
  }
1647
1602
  return prevAtom;
1648
1603
  }
@@ -1670,12 +1625,14 @@ function insertNode(nativeRenderer, atom, context) {
1670
1625
  nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
1671
1626
  }
1672
1627
  }
1673
- function createElement(nativeRenderer, vNode, isSvg) {
1674
- const nativeNode = nativeRenderer.createElement(vNode.type, isSvg);
1675
- const props = vNode.props;
1628
+ function createElement(nativeRenderer, atom, parentComponent, context) {
1629
+ const { isSvg, jsxNode } = atom;
1630
+ const nativeNode = nativeRenderer.createElement(jsxNode.type, isSvg);
1631
+ const props = jsxNode.props;
1676
1632
  let bindingRefs;
1677
1633
  for (const key in props) {
1678
1634
  if (key === 'children') {
1635
+ atom.child = createChildChain(jsxNode.props.children, isSvg);
1679
1636
  continue;
1680
1637
  }
1681
1638
  if (key === 'class') {
@@ -1695,7 +1652,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
1695
1652
  if (listenerReg.test(key)) {
1696
1653
  const listener = props[key];
1697
1654
  if (typeof listener === 'function') {
1698
- bindEvent(nativeRenderer, vNode, key, nativeNode, listener, isSvg);
1655
+ nativeRenderer.listen(nativeNode, key, listener, isSvg);
1699
1656
  }
1700
1657
  continue;
1701
1658
  }
@@ -1705,28 +1662,39 @@ function createElement(nativeRenderer, vNode, isSvg) {
1705
1662
  }
1706
1663
  nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
1707
1664
  }
1708
- return {
1709
- nativeNode,
1710
- applyRefs: () => {
1711
- applyRefs(bindingRefs, nativeNode, true);
1712
- }
1713
- };
1714
- }
1715
- function createTextNode(nativeRenderer, text, isSvg) {
1716
- return nativeRenderer.createTextNode(text, isSvg);
1717
- }
1718
- function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNode, isSvg) {
1665
+ atom.nativeNode = nativeNode;
1666
+ insertNode(nativeRenderer, atom, context);
1667
+ buildElementChildren(atom, nativeRenderer, parentComponent, context);
1668
+ context.host = nativeNode;
1669
+ context.isParent = false;
1670
+ applyRefs(bindingRefs, nativeNode, true);
1671
+ }
1672
+ function createTextNode(nativeRenderer, atom, context) {
1673
+ const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.isSvg);
1674
+ atom.nativeNode = nativeNode;
1675
+ insertNode(nativeRenderer, atom, context);
1676
+ context.host = nativeNode;
1677
+ context.isParent = false;
1678
+ }
1679
+ function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
1680
+ const newVNode = newAtom.jsxNode;
1681
+ const isSvg = newAtom.isSvg;
1682
+ const nativeNode = newAtom.nativeNode;
1683
+ const oldVNode = oldAtom.jsxNode;
1719
1684
  if (newVNode === oldVNode) {
1720
- return () => {
1721
- //
1722
- };
1685
+ parentComponent.changedSubComponents.forEach(child => {
1686
+ updateView(nativeRenderer, child);
1687
+ });
1688
+ return;
1723
1689
  }
1724
1690
  const changes = getObjectChanges(newVNode.props, oldVNode.props);
1725
1691
  let unBindRefs;
1726
1692
  let bindRefs;
1727
- newVNode.on = oldVNode.on;
1693
+ newAtom.child = oldAtom.child;
1728
1694
  for (const [key, value] of changes.remove) {
1729
1695
  if (key === 'children') {
1696
+ cleanElementChildren(oldAtom, nativeRenderer);
1697
+ newAtom.child = null;
1730
1698
  continue;
1731
1699
  }
1732
1700
  if (key === 'class') {
@@ -1741,10 +1709,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1741
1709
  }
1742
1710
  if (listenerReg.test(key)) {
1743
1711
  if (typeof value === 'function') {
1744
- const type = key.replace(listenerReg, '').toLowerCase();
1745
- const oldOn = oldVNode.on;
1746
- nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate, isSvg);
1747
- Reflect.deleteProperty(oldOn, type);
1712
+ nativeRenderer.unListen(nativeNode, key, value, isSvg);
1748
1713
  }
1749
1714
  continue;
1750
1715
  }
@@ -1756,6 +1721,17 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1756
1721
  }
1757
1722
  for (const [key, newValue, oldValue] of changes.replace) {
1758
1723
  if (key === 'children') {
1724
+ newAtom.child = createChildChain(newValue, isSvg);
1725
+ if (!newAtom.child) {
1726
+ cleanElementChildren(oldAtom, nativeRenderer);
1727
+ }
1728
+ else {
1729
+ diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
1730
+ host: newAtom.nativeNode,
1731
+ isParent: true,
1732
+ rootHost: context.rootHost
1733
+ });
1734
+ }
1759
1735
  continue;
1760
1736
  }
1761
1737
  if (key === 'class') {
@@ -1777,8 +1753,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1777
1753
  continue;
1778
1754
  }
1779
1755
  if (listenerReg.test(key)) {
1780
- const listenType = key.replace(listenerReg, '').toLowerCase();
1781
- newVNode.on[listenType].listenFn = newValue;
1756
+ nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
1757
+ nativeRenderer.listen(nativeNode, key, newValue, isSvg);
1782
1758
  continue;
1783
1759
  }
1784
1760
  if (key === refKey) {
@@ -1790,6 +1766,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1790
1766
  }
1791
1767
  for (const [key, value] of changes.add) {
1792
1768
  if (key === 'children') {
1769
+ newAtom.child = createChildChain(value, isSvg);
1770
+ buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
1793
1771
  continue;
1794
1772
  }
1795
1773
  if (key === 'class') {
@@ -1805,7 +1783,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1805
1783
  }
1806
1784
  if (listenerReg.test(key)) {
1807
1785
  if (typeof value === 'function') {
1808
- bindEvent(nativeRenderer, newVNode, key, nativeNode, value, isSvg);
1786
+ nativeRenderer.listen(nativeNode, key, value, isSvg);
1809
1787
  }
1810
1788
  continue;
1811
1789
  }
@@ -1815,10 +1793,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
1815
1793
  }
1816
1794
  nativeRenderer.setProperty(nativeNode, key, value, isSvg);
1817
1795
  }
1818
- return () => {
1819
- applyRefs(unBindRefs, nativeNode, false);
1820
- applyRefs(bindRefs, nativeNode, true);
1821
- };
1796
+ applyRefs(unBindRefs, nativeNode, false);
1797
+ applyRefs(bindRefs, nativeNode, true);
1822
1798
  }
1823
1799
  function applyRefs(refs, nativeNode, binding) {
1824
1800
  if (refs) {
@@ -1830,21 +1806,6 @@ function applyRefs(refs, nativeNode, binding) {
1830
1806
  }
1831
1807
  }
1832
1808
  }
1833
- function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
1834
- let on = vNode.on;
1835
- if (!on) {
1836
- vNode.on = on = {};
1837
- }
1838
- const type = key.replace(listenerReg, '').toLowerCase();
1839
- const delegateObj = {
1840
- delegate(...args) {
1841
- return delegateObj.listenFn.apply(this, args);
1842
- },
1843
- listenFn
1844
- };
1845
- on[type] = delegateObj;
1846
- nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
1847
- }
1848
1809
 
1849
1810
  /**
1850
1811
  * Viewfly 根组件,用于实现组件状态更新事件通知
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viewfly/core",
3
- "version": "1.0.0-alpha.11",
3
+ "version": "1.0.0-alpha.13",
4
4
  "description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -50,7 +50,7 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/viewfly/viewfly.git/issues"
52
52
  },
53
- "gitHead": "723da75a9e8e13e8addbe4646358667f476e06f3",
53
+ "gitHead": "ef79169385a2b104fc58cb0b38123443e5baccd7",
54
54
  "dependencies": {
55
55
  "reflect-metadata": "^0.2.2"
56
56
  }