@tarojs/runtime 3.4.0-beta.0 → 3.4.0-beta.1

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.
@@ -1,4 +1,4 @@
1
- import { isFunction, isUndefined, isObject, warn, isArray, toCamelCase, ensure, toDashed, isString, EMPTY_OBJ, internalComponents, controlledComponent, defaultReconciler, noop } from '@tarojs/shared';
1
+ import { isFunction, isUndefined, isObject, warn, isArray, toCamelCase, noop, ensure, toDashed, isString, EMPTY_OBJ, internalComponents, controlledComponent, defaultReconciler } from '@tarojs/shared';
2
2
  import { injectable, inject, ContainerModule, optional, multiInject, Container } from 'inversify';
3
3
 
4
4
  /*! *****************************************************************************
@@ -1430,10 +1430,13 @@ function hydrate(node) {
1430
1430
  }
1431
1431
  const data = {
1432
1432
  ["nn" /* NodeName */]: nodeName,
1433
- uid: node.uid
1433
+ sid: node.sid
1434
1434
  };
1435
1435
  const { props } = node;
1436
1436
  const SPECIAL_NODES = node.hooks.getSpecialNodes();
1437
+ if (node.uid !== node.sid) {
1438
+ data.uid = node.uid;
1439
+ }
1437
1440
  if (!node.isAnyEventBinded() && SPECIAL_NODES.indexOf(nodeName) > -1) {
1438
1441
  data["nn" /* NodeName */] = `static-${nodeName}`;
1439
1442
  if (nodeName === VIEW && !isHasExtractProp(node)) {
@@ -1472,8 +1475,158 @@ function hydrate(node) {
1472
1475
  return data;
1473
1476
  }
1474
1477
 
1475
- const eventSource = new Map();
1478
+ class EventSource extends Map {
1479
+ removeNode(child) {
1480
+ const { sid, uid } = child;
1481
+ this.delete(sid);
1482
+ if (uid !== sid && uid)
1483
+ this.delete(uid);
1484
+ }
1485
+ removeNodeTree(child) {
1486
+ this.removeNode(child);
1487
+ const { childNodes } = child;
1488
+ childNodes.forEach(node => this.removeNodeTree(node));
1489
+ }
1490
+ }
1491
+ const eventSource = new EventSource();
1476
1492
 
1493
+ const observers = [];
1494
+ /**
1495
+ * The MutationObserver provides the ability
1496
+ * to watch for changes being made to the DOM tree.
1497
+ * It will invoke a specified callback function
1498
+ * when DOM changes occur.
1499
+ * @see https://dom.spec.whatwg.org/#mutationobserver
1500
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
1501
+ */
1502
+ class MutationObserverImpl {
1503
+ constructor(callback) {
1504
+ this.records = [];
1505
+ this.callback = callback;
1506
+ }
1507
+ /**
1508
+ * Configures the MutationObserver
1509
+ * to begin receiving notifications
1510
+ * through its callback function
1511
+ * when DOM changes matching the given options occur.
1512
+ *
1513
+ * Options matching is to be implemented.
1514
+ */
1515
+ observe(target, options) {
1516
+ this.disconnect();
1517
+ this.target = target;
1518
+ this.options = options || {};
1519
+ observers.push(this);
1520
+ }
1521
+ /**
1522
+ * Stop the MutationObserver instance
1523
+ * from receiving further notifications
1524
+ * until and unless observe() is called again.
1525
+ */
1526
+ disconnect() {
1527
+ this.target = null;
1528
+ const index = observers.indexOf(this);
1529
+ if (index >= 0) {
1530
+ observers.splice(index, 1);
1531
+ }
1532
+ }
1533
+ /**
1534
+ * Removes all pending notifications
1535
+ * from the MutationObserver's notification queue
1536
+ * and returns them in a new Array of MutationRecord objects.
1537
+ */
1538
+ takeRecords() {
1539
+ return this.records.splice(0, this.records.length);
1540
+ }
1541
+ }
1542
+ /** Match two TaroNodes by sid. */
1543
+ const sidMatches = (observerTarget, target) => {
1544
+ return !!observerTarget && observerTarget.sid === (target === null || target === void 0 ? void 0 : target.sid);
1545
+ };
1546
+ const isConcerned = (record, options) => {
1547
+ const { characterData, characterDataOldValue, attributes, attributeOldValue, childList } = options;
1548
+ switch (record.type) {
1549
+ case "characterData" /* CHARACTER_DATA */:
1550
+ if (characterData) {
1551
+ if (!characterDataOldValue)
1552
+ record.oldValue = null;
1553
+ return true;
1554
+ }
1555
+ return false;
1556
+ case "attributes" /* ATTRIBUTES */:
1557
+ if (attributes) {
1558
+ if (!attributeOldValue)
1559
+ record.oldValue = null;
1560
+ return true;
1561
+ }
1562
+ return false;
1563
+ case "childList" /* CHILD_LIST */:
1564
+ if (childList) {
1565
+ return true;
1566
+ }
1567
+ return false;
1568
+ }
1569
+ };
1570
+ let pendingMuatations = false;
1571
+ function logMutation(observer, record) {
1572
+ observer.records.push(record);
1573
+ if (!pendingMuatations) {
1574
+ pendingMuatations = true;
1575
+ Promise
1576
+ .resolve()
1577
+ .then(() => {
1578
+ pendingMuatations = false;
1579
+ observers.forEach(observer => {
1580
+ return observer.callback(observer.takeRecords());
1581
+ });
1582
+ });
1583
+ }
1584
+ }
1585
+ function recordMutation(record) {
1586
+ observers.forEach(observer => {
1587
+ const { options } = observer;
1588
+ for (let t = record.target; t; t = t.parentNode) {
1589
+ if (sidMatches(observer.target, t) && isConcerned(record, options)) {
1590
+ logMutation(observer, record);
1591
+ break;
1592
+ }
1593
+ if (!options.subtree)
1594
+ break;
1595
+ }
1596
+ });
1597
+ }
1598
+
1599
+ class MutationObserver {
1600
+ constructor(callback) {
1601
+ if (ENABLE_MUTATION_OBSERVER) {
1602
+ this.core = new MutationObserverImpl(callback);
1603
+ }
1604
+ else {
1605
+ if (process.env.NODE_ENV !== 'production') {
1606
+ console.warn('[Taro Warning] 若要使用 MutationObserver,请在 Taro 编译配置中设置 \'mini.enableMutationObserver: true\'');
1607
+ }
1608
+ this.core = {
1609
+ observe: noop,
1610
+ disconnect: noop,
1611
+ takeRecords: noop
1612
+ };
1613
+ }
1614
+ }
1615
+ observe(...args) {
1616
+ this.core.observe(...args);
1617
+ }
1618
+ disconnect() {
1619
+ this.core.disconnect();
1620
+ }
1621
+ takeRecords() {
1622
+ return this.core.takeRecords();
1623
+ }
1624
+ static record(record) {
1625
+ recordMutation(record);
1626
+ }
1627
+ }
1628
+
1629
+ const CHILDNODES = "cn" /* Childnodes */;
1477
1630
  const nodeId = incrementId();
1478
1631
  let TaroNode = class TaroNode extends TaroEventTarget {
1479
1632
  constructor() {
@@ -1484,20 +1637,34 @@ let TaroNode = class TaroNode extends TaroEventTarget {
1484
1637
  this.hydrate = (node) => () => hydrate(node);
1485
1638
  const impl = getNodeImpl();
1486
1639
  impl.bind(this);
1487
- this.uid = `_n_${nodeId()}`;
1488
- eventSource.set(this.uid, this);
1640
+ this.uid = `_n_${nodeId()}`; // dom 节点 id,开发者可修改
1641
+ this.sid = this.uid; // dom 节点全局唯一 id,不可被修改
1642
+ eventSource.set(this.sid, this);
1489
1643
  }
1490
1644
  /**
1491
1645
  * like jQuery's $.empty()
1492
1646
  */
1493
1647
  _empty() {
1494
- while (this.childNodes.length > 0) {
1495
- const child = this.childNodes[0];
1648
+ while (this.firstChild) {
1649
+ // Data Structure
1650
+ const child = this.firstChild;
1496
1651
  child.parentNode = null;
1497
- eventSource.delete(child.uid);
1498
1652
  this.childNodes.shift();
1653
+ // eventSource
1654
+ eventSource.removeNodeTree(child);
1499
1655
  }
1500
1656
  }
1657
+ updateChildNodes(isClean) {
1658
+ const cleanChildNodes = () => [];
1659
+ const rerenderChildNodes = () => {
1660
+ const childNodes = this.childNodes.filter(node => !isComment(node));
1661
+ return childNodes.map(hydrate);
1662
+ };
1663
+ this.enqueueUpdate({
1664
+ path: `${this._path}.${CHILDNODES}`,
1665
+ value: isClean ? cleanChildNodes : rerenderChildNodes
1666
+ });
1667
+ }
1501
1668
  get _root() {
1502
1669
  var _a;
1503
1670
  return ((_a = this.parentNode) === null || _a === void 0 ? void 0 : _a._root) || null;
@@ -1514,7 +1681,7 @@ let TaroNode = class TaroNode extends TaroEventTarget {
1514
1681
  const list = parentNode.childNodes.filter(node => !isComment(node));
1515
1682
  const indexOfNode = list.indexOf(this);
1516
1683
  const index = this.hooks.getPathIndex(indexOfNode);
1517
- return `${parentNode._path}.${"cn" /* Childnodes */}.${index}`;
1684
+ return `${parentNode._path}.${CHILDNODES}.${index}`;
1518
1685
  }
1519
1686
  return '';
1520
1687
  }
@@ -1545,18 +1712,32 @@ let TaroNode = class TaroNode extends TaroEventTarget {
1545
1712
  * @TODO 等待完整 innerHTML 实现
1546
1713
  */
1547
1714
  set textContent(text) {
1715
+ const document = this._getElement(ElementNames.Document)();
1716
+ const newText = document.createTextNode(text);
1717
+ // @Todo: appendChild 会多触发一次
1718
+ MutationObserver.record({
1719
+ type: "childList" /* CHILD_LIST */,
1720
+ target: this,
1721
+ removedNodes: this.childNodes.slice(),
1722
+ addedNodes: text === '' ? [] : [newText]
1723
+ });
1548
1724
  this._empty();
1549
1725
  if (text === '') {
1550
- this.enqueueUpdate({
1551
- path: `${this._path}.${"cn" /* Childnodes */}`,
1552
- value: () => []
1553
- });
1726
+ this.updateChildNodes(true);
1554
1727
  }
1555
1728
  else {
1556
- const document = this._getElement(ElementNames.Document)();
1557
- this.appendChild(document.createTextNode(text));
1729
+ this.appendChild(newText);
1730
+ this.updateChildNodes();
1558
1731
  }
1559
1732
  }
1733
+ /**
1734
+ * @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/insertBefore
1735
+ * @scenario
1736
+ * [A,B,C]
1737
+ * 1. insert D before C, D has no parent
1738
+ * 2. insert D before C, D has the same parent of C
1739
+ * 3. insert D before C, D has the different parent of C
1740
+ */
1560
1741
  insertBefore(newChild, refChild, isReplace) {
1561
1742
  if (newChild.nodeName === DOCUMENT_FRAGMENT) {
1562
1743
  newChild.childNodes.reduceRight((previousValue, currentValue) => {
@@ -1565,72 +1746,114 @@ let TaroNode = class TaroNode extends TaroEventTarget {
1565
1746
  }, refChild);
1566
1747
  return newChild;
1567
1748
  }
1568
- newChild.remove();
1749
+ // Parent release newChild
1750
+ // - cleanRef: false (No need to clean eventSource, because newChild is about to be inserted)
1751
+ // - update: true (Need to update parent.childNodes, because parent.childNodes is reordered)
1752
+ newChild.remove({ cleanRef: false });
1753
+ // Data structure
1569
1754
  newChild.parentNode = this;
1570
- let payload;
1571
1755
  if (refChild) {
1756
+ // insertBefore & replaceChild
1572
1757
  const index = this.findIndex(refChild);
1573
1758
  this.childNodes.splice(index, 0, newChild);
1574
- if (isReplace) {
1575
- payload = {
1576
- path: newChild._path,
1577
- value: this.hydrate(newChild)
1578
- };
1579
- }
1580
- else {
1581
- payload = {
1582
- path: `${this._path}.${"cn" /* Childnodes */}`,
1583
- value: () => {
1584
- const childNodes = this.childNodes.filter(node => !isComment(node));
1585
- return childNodes.map(hydrate);
1586
- }
1587
- };
1588
- }
1589
1759
  }
1590
1760
  else {
1761
+ // appendChild
1591
1762
  this.childNodes.push(newChild);
1592
- payload = {
1763
+ }
1764
+ // Serialization
1765
+ if (!refChild || isReplace) {
1766
+ // appendChild & replaceChild
1767
+ this.enqueueUpdate({
1593
1768
  path: newChild._path,
1594
1769
  value: this.hydrate(newChild)
1595
- };
1770
+ });
1596
1771
  }
1597
- this.enqueueUpdate(payload);
1598
- if (!eventSource.has(newChild.uid)) {
1599
- eventSource.set(newChild.uid, newChild);
1772
+ else {
1773
+ // insertBefore
1774
+ this.updateChildNodes();
1600
1775
  }
1776
+ MutationObserver.record({
1777
+ type: "childList" /* CHILD_LIST */,
1778
+ target: this,
1779
+ addedNodes: [newChild],
1780
+ removedNodes: isReplace
1781
+ ? [refChild] /** replaceChild */
1782
+ : [],
1783
+ nextSibling: isReplace
1784
+ ? refChild.nextSibling /** replaceChild */
1785
+ : (refChild || null),
1786
+ previousSibling: newChild.previousSibling
1787
+ });
1601
1788
  return newChild;
1602
1789
  }
1603
- appendChild(child) {
1604
- this.insertBefore(child);
1790
+ /**
1791
+ * @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/appendChild
1792
+ * @scenario
1793
+ * [A,B,C]
1794
+ * 1. append C, C has no parent
1795
+ * 2. append C, C has the same parent of B
1796
+ * 3. append C, C has the different parent of B
1797
+ */
1798
+ appendChild(newChild) {
1799
+ return this.insertBefore(newChild);
1605
1800
  }
1801
+ /**
1802
+ * @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/replaceChild
1803
+ * @scenario
1804
+ * [A,B,C]
1805
+ * 1. replace B with C, C has no parent
1806
+ * 2. replace B with C, C has no parent, C has the same parent of B
1807
+ * 3. replace B with C, C has no parent, C has the different parent of B
1808
+ */
1606
1809
  replaceChild(newChild, oldChild) {
1607
- if (oldChild.parentNode === this) {
1608
- this.insertBefore(newChild, oldChild, true);
1609
- oldChild.remove(true);
1610
- return oldChild;
1611
- }
1810
+ if (oldChild.parentNode !== this)
1811
+ return;
1812
+ // Insert the newChild
1813
+ this.insertBefore(newChild, oldChild, true);
1814
+ // Destroy the oldChild
1815
+ // - cleanRef: true (Need to clean eventSource, because the oldChild was detached from the DOM tree)
1816
+ // - update: false (No need to update parent.childNodes, because replace will not cause the parent.childNodes being reordered)
1817
+ oldChild.remove({ doUpdate: false });
1818
+ return oldChild;
1612
1819
  }
1613
- removeChild(child, isReplace) {
1614
- const index = this.findIndex(child);
1615
- this.childNodes.splice(index, 1);
1616
- if (!isReplace) {
1617
- this.enqueueUpdate({
1618
- path: `${this._path}.${"cn" /* Childnodes */}`,
1619
- value: () => {
1620
- const childNodes = this.childNodes.filter(node => !isComment(node));
1621
- return childNodes.map(hydrate);
1622
- }
1820
+ /**
1821
+ * @doc https://developer.mozilla.org/zh-CN/docs/Web/API/Node/removeChild
1822
+ * @scenario
1823
+ * [A,B,C]
1824
+ * 1. remove A or B
1825
+ * 2. remove C
1826
+ */
1827
+ removeChild(child, options = {}) {
1828
+ const { cleanRef, doUpdate } = options;
1829
+ if (cleanRef !== false && doUpdate !== false) {
1830
+ // appendChild/replaceChild/insertBefore 不应该触发
1831
+ // @Todo: 但其实如果 newChild 的父节点是另一颗子树的节点,应该是要触发的
1832
+ MutationObserver.record({
1833
+ type: "childList" /* CHILD_LIST */,
1834
+ target: this,
1835
+ removedNodes: [child],
1836
+ nextSibling: child.nextSibling,
1837
+ previousSibling: child.previousSibling
1623
1838
  });
1624
1839
  }
1840
+ // Data Structure
1841
+ const index = this.findIndex(child);
1842
+ this.childNodes.splice(index, 1);
1625
1843
  child.parentNode = null;
1626
- eventSource.delete(child.uid);
1627
- // @TODO: eventSource memory overflow
1628
- // child._empty()
1844
+ // Set eventSource
1845
+ if (cleanRef !== false) {
1846
+ eventSource.removeNodeTree(child);
1847
+ }
1848
+ // Serialization
1849
+ if (doUpdate !== false) {
1850
+ this.updateChildNodes();
1851
+ }
1629
1852
  return child;
1630
1853
  }
1631
- remove(isReplace) {
1854
+ remove(options) {
1632
1855
  var _a;
1633
- (_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this, isReplace);
1856
+ (_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this, options);
1634
1857
  }
1635
1858
  hasChildNodes() {
1636
1859
  return this.childNodes.length > 0;
@@ -1656,6 +1879,11 @@ let TaroText = class TaroText extends TaroNode {
1656
1879
  this.nodeName = '#text';
1657
1880
  }
1658
1881
  set textContent(text) {
1882
+ MutationObserver.record({
1883
+ target: this,
1884
+ type: "characterData" /* CHARACTER_DATA */,
1885
+ oldValue: this._value
1886
+ });
1659
1887
  this._value = text;
1660
1888
  this.enqueueUpdate({
1661
1889
  path: `${this._path}.${"v" /* Text */}`,
@@ -1869,6 +2097,7 @@ combine('box', ['DecorationBreak', 'Shadow', 'Sizing', 'Snap'], true);
1869
2097
 
1870
2098
  function setStyle(newVal, styleKey) {
1871
2099
  const old = this[styleKey];
2100
+ const oldCssTxt = this.cssText;
1872
2101
  if (newVal) {
1873
2102
  this._usedStyleProp.add(styleKey);
1874
2103
  }
@@ -1879,6 +2108,16 @@ function setStyle(newVal, styleKey) {
1879
2108
  path: `${this._element._path}.${"st" /* Style */}`,
1880
2109
  value: this.cssText
1881
2110
  });
2111
+ // @Todo:
2112
+ // el.style.cssText = 'x: y;m: n'(Bug: 触发两次)
2113
+ // el.style.cssText = 'x: y'(正常)
2114
+ // el.style.x = y(正常)
2115
+ MutationObserver.record({
2116
+ type: "attributes" /* ATTRIBUTES */,
2117
+ target: this._element,
2118
+ attributeName: 'style',
2119
+ oldValue: oldCssTxt
2120
+ });
1882
2121
  }
1883
2122
  }
1884
2123
  function initStyle(ctor) {
@@ -1918,15 +2157,15 @@ class Style {
1918
2157
  });
1919
2158
  }
1920
2159
  get cssText() {
1921
- let text = '';
2160
+ const texts = [];
1922
2161
  this._usedStyleProp.forEach(key => {
1923
2162
  const val = this[key];
1924
2163
  if (!val)
1925
2164
  return;
1926
2165
  const styleName = isCssVariable(key) ? key : toDashed(key);
1927
- text += `${styleName}: ${val};`;
2166
+ texts.push(`${styleName}: ${val};`);
1928
2167
  });
1929
- return text;
2168
+ return texts.join(' ');
1930
2169
  }
1931
2170
  set cssText(str) {
1932
2171
  if (str == null) {
@@ -2033,7 +2272,7 @@ class ClassList extends Set {
2033
2272
  this.el = el;
2034
2273
  }
2035
2274
  get value() {
2036
- return [...this].join(' ');
2275
+ return [...this].filter(v => v !== '').join(' ');
2037
2276
  }
2038
2277
  add(s) {
2039
2278
  super.add(s);
@@ -2160,12 +2399,24 @@ let TaroElement = class TaroElement extends TaroNode {
2160
2399
  var _a, _b;
2161
2400
  process.env.NODE_ENV !== 'production' && warn(isString(value) && value.length > PROPERTY_THRESHOLD, `元素 ${this.nodeName} 的 属性 ${qualifiedName} 的值数据量过大,可能会影响渲染性能。考虑降低图片转为 base64 的阈值或在 CSS 中使用 base64。`);
2162
2401
  const isPureView = this.nodeName === VIEW && !isHasExtractProp(this) && !this.isAnyEventBinded();
2402
+ if (qualifiedName !== STYLE) {
2403
+ MutationObserver.record({
2404
+ target: this,
2405
+ type: "attributes" /* ATTRIBUTES */,
2406
+ attributeName: qualifiedName,
2407
+ oldValue: this.getAttribute(qualifiedName)
2408
+ });
2409
+ }
2163
2410
  switch (qualifiedName) {
2164
2411
  case STYLE:
2165
2412
  this.style.cssText = value;
2166
2413
  break;
2167
2414
  case ID:
2168
- eventSource.delete(this.uid);
2415
+ if (this.uid !== this.sid) {
2416
+ // eventSource[sid] 永远保留,直到组件卸载
2417
+ // eventSource[uid] 可变
2418
+ eventSource.delete(this.uid);
2419
+ }
2169
2420
  value = String(value);
2170
2421
  this.props[qualifiedName] = this.uid = value;
2171
2422
  eventSource.set(value, this);
@@ -2183,7 +2434,7 @@ let TaroElement = class TaroElement extends TaroNode {
2183
2434
  qualifiedName = shortcutAttr(qualifiedName);
2184
2435
  const payload = {
2185
2436
  path: `${this._path}.${toCamelCase(qualifiedName)}`,
2186
- value
2437
+ value: isFunction(value) ? () => value : value
2187
2438
  };
2188
2439
  (_b = (_a = this.hooks).modifySetAttrPayload) === null || _b === void 0 ? void 0 : _b.call(_a, this, qualifiedName, payload);
2189
2440
  this.enqueueUpdate(payload);
@@ -2208,6 +2459,12 @@ let TaroElement = class TaroElement extends TaroNode {
2208
2459
  removeAttribute(qualifiedName) {
2209
2460
  var _a, _b, _c, _d;
2210
2461
  const isStaticView = this.nodeName === VIEW && isHasExtractProp(this) && !this.isAnyEventBinded();
2462
+ MutationObserver.record({
2463
+ target: this,
2464
+ type: "attributes" /* ATTRIBUTES */,
2465
+ attributeName: qualifiedName,
2466
+ oldValue: this.getAttribute(qualifiedName)
2467
+ });
2211
2468
  if (qualifiedName === STYLE) {
2212
2469
  this.style.cssText = '';
2213
2470
  }
@@ -2593,11 +2850,13 @@ function createEvent(event, node) {
2593
2850
  const eventsBatch = {};
2594
2851
  // 小程序的事件代理回调函数
2595
2852
  function eventHandler(event) {
2596
- var _a;
2853
+ var _a, _b;
2597
2854
  const hooks = getHooks();
2598
2855
  (_a = hooks.modifyMpEvent) === null || _a === void 0 ? void 0 : _a.call(hooks, event);
2599
2856
  event.currentTarget || (event.currentTarget = event.target);
2600
- const node = getDocument().getElementById(event.currentTarget.id);
2857
+ const currentTarget = event.currentTarget;
2858
+ const id = ((_b = currentTarget.dataset) === null || _b === void 0 ? void 0 : _b.sid /** sid */) || currentTarget.id /** uid */ || '';
2859
+ const node = getDocument().getElementById(id);
2601
2860
  if (node) {
2602
2861
  const dispatch = () => {
2603
2862
  var _a;
@@ -3015,8 +3274,12 @@ class StyleTagParser {
3015
3274
  // console.log('res this.styles: ', this.styles)
3016
3275
  }
3017
3276
  parseSelector(src) {
3018
- // todo: 属性选择器里可以带空格:[a = "b"],这里的 split(' ') 需要作兼容
3019
- const list = src.trim().replace(/ *([>~+]) */g, ' $1').replace(/ +/g, ' ').split(' ');
3277
+ const list = src
3278
+ .trim()
3279
+ .replace(/ *([>~+]) */g, ' $1')
3280
+ .replace(/ +/g, ' ')
3281
+ .replace(/\[\s*([^[\]=\s]+)\s*=\s*([^[\]=\s]+)\s*\]/g, '[$1=$2]')
3282
+ .split(' ');
3020
3283
  const selectors = list.map(item => {
3021
3284
  const firstChar = item.charAt(0);
3022
3285
  const selector = {
@@ -3522,7 +3785,7 @@ function bindInnerHTML(ctx, getDoc) {
3522
3785
  configurable: true,
3523
3786
  enumerable: true,
3524
3787
  set(html) {
3525
- setInnerHTML.call(ctx, ctx, html, getDoc);
3788
+ setInnerHTML.call(this, this, html, getDoc);
3526
3789
  },
3527
3790
  get() {
3528
3791
  return '';
@@ -4207,7 +4470,7 @@ function createPageConfig(component, pageName, data, pageConfig) {
4207
4470
  let loadResolver;
4208
4471
  let hasLoaded;
4209
4472
  const config = {
4210
- [ONLOAD](options, cb) {
4473
+ [ONLOAD](options = {}, cb) {
4211
4474
  hasLoaded = new Promise(resolve => { loadResolver = resolve; });
4212
4475
  perf.start(PAGE_INIT);
4213
4476
  Current.page = this;
@@ -4251,6 +4514,7 @@ function createPageConfig(component, pageName, data, pageConfig) {
4251
4514
  instances.delete($taroPath);
4252
4515
  if (pageElement) {
4253
4516
  pageElement.ctx = null;
4517
+ pageElement = null;
4254
4518
  }
4255
4519
  if (prepareMountList.length) {
4256
4520
  prepareMountList.forEach(fn => fn());
@@ -4428,5 +4692,5 @@ const nextTick = (cb, ctx) => {
4428
4692
  }
4429
4693
  };
4430
4694
 
4431
- export { Current, ElementNames, Events, FormElement, SERVICE_IDENTIFIER, SVGElement, Style, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, addLeadingSlash, caf as cancelAnimationFrame, container, createComponentConfig, createDocument, createEvent, createPageConfig, createRecursiveComponentConfig, document$1 as document, eventCenter, eventHandler, getComputedStyle, getCurrentInstance, getPageInstance, hydrate, incrementId, injectPageInstance, navigator, nextTick, now, options, processPluginHooks, raf as requestAnimationFrame, safeExecute, stringify, window$1 as window };
4695
+ export { Current, ElementNames, Events, FormElement, MutationObserver, SERVICE_IDENTIFIER, SVGElement, Style, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, addLeadingSlash, caf as cancelAnimationFrame, container, createComponentConfig, createDocument, createEvent, createPageConfig, createRecursiveComponentConfig, document$1 as document, eventCenter, eventHandler, eventSource, getComputedStyle, getCurrentInstance, getPageInstance, hydrate, incrementId, injectPageInstance, navigator, nextTick, now, options, processPluginHooks, raf as requestAnimationFrame, safeExecute, stringify, window$1 as window };
4432
4696
  //# sourceMappingURL=runtime.esm.js.map