@tarojs/router 3.3.14 → 3.3.18

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
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var runtime = require('@tarojs/runtime');
6
+ var taro = require('@tarojs/taro');
6
7
 
7
8
  function _extends() {
8
9
  _extends = Object.assign || function (target) {
@@ -56,62 +57,156 @@ function prependBasename(url) {
56
57
  if ( url === void 0 ) url = '';
57
58
 
58
59
  return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
59
- }
60
+ }
61
+ var hasBasename = function (path, prefix) {
62
+ if ( path === void 0 ) path = '';
63
+ if ( prefix === void 0 ) prefix = '';
60
64
 
61
- var stacks = [];
65
+ return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path);
66
+ };
67
+ var stripBasename = function (path, prefix) {
68
+ if ( path === void 0 ) path = '';
69
+ if ( prefix === void 0 ) prefix = '';
70
+
71
+ return hasBasename(path, prefix) ? path.substr(prefix.length) : path;
72
+ };
73
+
74
+ var Stacks = function Stacks() {
75
+ this.stacks = [];
76
+ this.backDelta = 0;
77
+ };
78
+
79
+ var prototypeAccessors = { delta: { configurable: true },length: { configurable: true },last: { configurable: true } };
80
+ prototypeAccessors.delta.set = function (delta) {
81
+ if (delta > 0) {
82
+ this.backDelta = delta;
83
+ }
84
+ else {
85
+ --this.backDelta;
86
+ }
87
+ };
88
+ prototypeAccessors.length.get = function () {
89
+ return this.stacks.length;
90
+ };
91
+ prototypeAccessors.last.get = function () {
92
+ return this.stacks[this.length - 1];
93
+ };
94
+ Stacks.prototype.get = function get () {
95
+ return this.stacks;
96
+ };
97
+ Stacks.prototype.getItem = function getItem (index) {
98
+ return this.stacks[index];
99
+ };
100
+ Stacks.prototype.getLastIndex = function getLastIndex (pathname, stateWith) {
101
+ if ( stateWith === void 0 ) stateWith = 1;
102
+
103
+ var list = [].concat( this.stacks ).reverse();
104
+ return list.findIndex(function (page, i) { var _a; return i >= stateWith && ((_a = page.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname; });
105
+ };
106
+ Stacks.prototype.getDelta = function getDelta (pathname) {
107
+ if (this.backDelta >= 1) {
108
+ return this.backDelta;
109
+ }
110
+ // NOTE: 此处为了修复浏览器后退多级页面,在大量重复路由状况下可能出现判断错误的情况 (增强判断能力只能考虑在 query 中新增参数来判断,暂时搁置)
111
+ return this.getLastIndex(pathname) || 1;
112
+ };
113
+ Stacks.prototype.getPrevIndex = function getPrevIndex (pathname, stateWith) {
114
+ if ( stateWith === void 0 ) stateWith = 1;
115
+
116
+ var lastIndex = this.getLastIndex(pathname, stateWith);
117
+ if (lastIndex < 0) {
118
+ return -1;
119
+ }
120
+ return this.length - 1 - lastIndex;
121
+ };
122
+ Stacks.prototype.pop = function pop () {
123
+ return this.stacks.pop();
124
+ };
125
+ Stacks.prototype.push = function push (page) {
126
+ return this.stacks.push(page);
127
+ };
128
+
129
+ Object.defineProperties( Stacks.prototype, prototypeAccessors );
130
+ var stacks = new Stacks();
62
131
 
63
- var routesAlias = {};
64
- function setRoutesAlias(alias) {
65
- routesAlias = alias;
66
- }
67
132
  function addLeadingSlash(path) {
68
133
  if (path == null) {
69
134
  return '';
70
135
  }
71
136
  return path.charAt(0) === '/' ? path : '/' + path;
72
137
  }
73
- // 解决navigateBack调用delta>1时,路由栈异常问题
74
- // 比如:A->B->C,navigateBack({delta: 2}),此时路由栈中还存在B页面
75
- // 原因:主要是由于一次性退出多层级页面时,此action只会执行一次,此处进行手动处理
76
- var historyBackDelta = 1;
77
- function setHistoryBackDelta(delta) {
78
- historyBackDelta = delta;
79
- }
80
- // eslint-disable-next-line @typescript-eslint/ban-types
81
- var throttle = function (fn, threshold) {
82
- var lastTime = 0;
83
- return function () {
84
- var now = Date.now();
85
- if (now - lastTime > threshold) {
86
- fn.apply(this, arguments);
87
- lastTime = now;
88
- }
138
+ var RoutesAlias = function RoutesAlias() {
139
+ var this$1 = this;
140
+
141
+ this.conf = [];
142
+ this.getConfig = function (url) {
143
+ if ( url === void 0 ) url = '';
144
+
145
+ var customRoute = this$1.conf.filter(function (arr) {
146
+ return arr.includes(url);
147
+ });
148
+ return customRoute[0];
149
+ };
150
+ this.getOrigin = function (url) {
151
+ if ( url === void 0 ) url = '';
152
+
153
+ var _a;
154
+ return ((_a = this$1.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
155
+ };
156
+ this.getAlias = function (url) {
157
+ if ( url === void 0 ) url = '';
158
+
159
+ var _a;
160
+ return ((_a = this$1.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
161
+ };
162
+ this.getAll = function (url) {
163
+ if ( url === void 0 ) url = '';
164
+
165
+ return this$1.conf.filter(function (arr) {
166
+ return arr.includes(url);
167
+ }).reduce(function (p, a) {
168
+ p.push(a[1]);
169
+ return p;
170
+ }, [url]);
89
171
  };
90
172
  };
91
- var stripBasename = function (path, basename) { return path.startsWith(basename) ? path.replace(basename, '') : path; };
92
- var isTabBar = function (config) {
93
- var _a, _b;
94
- var ref = config.router;
95
- var customRoutes = ref.customRoutes; if ( customRoutes === void 0 ) customRoutes = {};
96
- var basename = ref.basename; if ( basename === void 0 ) basename = '';
97
- var pathname = ref.pathname;
98
- var routePath = stripBasename(pathname, basename);
99
- var pagePath = ((_a = Object.entries(customRoutes).find(function (ref) {
100
- var target = ref[1];
101
-
102
- return target === routePath;
103
- })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
104
- return !!pagePath && (((_b = config.tabBar) === null || _b === void 0 ? void 0 : _b.list) || []).some(function (t) { return t.pagePath === pagePath; });
105
- };
173
+ RoutesAlias.prototype.set = function set (customRoutes) {
174
+ var this$1 = this;
175
+ var ref;
176
+
177
+ if ( customRoutes === void 0 ) customRoutes = {};
178
+ var loop = function ( key ) {
179
+ var path = customRoutes[key];
180
+ key = addLeadingSlash(key);
181
+ if (typeof path === 'string') {
182
+ this$1.conf.push([key, addLeadingSlash(path)]);
183
+ }
184
+ else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
185
+ (ref = this$1.conf).push.apply(ref, path.map(function (p) { return [key, addLeadingSlash(p)]; }));
186
+ }
187
+ };
188
+
189
+ for (var key in customRoutes) loop( key );
190
+ };
191
+ var routesAlias = new RoutesAlias();
106
192
 
107
193
  function processNavigateUrl(option) {
194
+ var _a;
108
195
  var pathPieces = J(option.url);
109
196
  // 处理自定义路由
110
- Object.keys(routesAlias).forEach(function (key) {
111
- if (addLeadingSlash(key) === addLeadingSlash(pathPieces.pathname)) {
112
- pathPieces.pathname = routesAlias[key];
113
- }
114
- });
197
+ pathPieces.pathname = routesAlias.getAlias(addLeadingSlash(pathPieces.pathname));
198
+ // 处理相对路径
199
+ if ((_a = pathPieces === null || pathPieces === void 0 ? void 0 : pathPieces.pathname) === null || _a === void 0 ? void 0 : _a.includes('./')) {
200
+ var parts = exports.history.location.pathname.split('/');
201
+ parts.pop();
202
+ pathPieces.pathname.split('/').forEach(function (item) {
203
+ if (item === '.') {
204
+ return;
205
+ }
206
+ item === '..' ? parts.pop() : parts.push(item);
207
+ });
208
+ pathPieces.pathname = parts.join('/');
209
+ }
115
210
  // 处理 basename
116
211
  pathPieces.pathname = prependBasename(pathPieces.pathname);
117
212
  // hack fix history v5 bug: https://github.com/remix-run/history/issues/814
@@ -125,9 +220,10 @@ async function navigate(option, method) {
125
220
  var complete = option.complete;
126
221
  var fail = option.fail;
127
222
  var unListen = exports.history.listen(function () {
128
- success === null || success === void 0 ? void 0 : success();
129
- complete === null || complete === void 0 ? void 0 : complete();
130
- resolve();
223
+ var res = { errMsg: (method + ": ok") };
224
+ success === null || success === void 0 ? void 0 : success(res);
225
+ complete === null || complete === void 0 ? void 0 : complete(res);
226
+ resolve(res);
131
227
  unListen();
132
228
  });
133
229
  try {
@@ -137,19 +233,24 @@ async function navigate(option, method) {
137
233
  if (method === 'navigateTo') {
138
234
  exports.history.push(pathPieces, state);
139
235
  }
140
- else if (method === 'redirectTo') {
236
+ else if (method === 'redirectTo' || method === 'switchTab') {
237
+ exports.history.replace(pathPieces, state);
238
+ }
239
+ else if (method === 'reLaunch') {
240
+ stacks.delta = stacks.length;
141
241
  exports.history.replace(pathPieces, state);
142
242
  }
143
243
  }
144
244
  else if (method === 'navigateBack') {
145
- setHistoryBackDelta(option.delta);
245
+ stacks.delta = option.delta;
146
246
  exports.history.go(-option.delta);
147
247
  }
148
248
  }
149
249
  catch (error) {
150
- fail === null || fail === void 0 ? void 0 : fail(error);
151
- complete === null || complete === void 0 ? void 0 : complete();
152
- reject(error);
250
+ var res = { errMsg: (method + ": fail " + (error.message || error)) };
251
+ fail === null || fail === void 0 ? void 0 : fail(res);
252
+ complete === null || complete === void 0 ? void 0 : complete(res);
253
+ reject(res);
153
254
  }
154
255
  });
155
256
  }
@@ -168,15 +269,14 @@ function navigateBack(options) {
168
269
  return navigate(options, 'navigateBack');
169
270
  }
170
271
  function switchTab(option) {
171
- // TODO: 清除掉所有的栈去目标页面
172
- return redirectTo(option);
272
+ return navigate(option, 'switchTab');
173
273
  }
174
274
  function reLaunch(option) {
175
- // TODO: 清除掉所有的栈去目标页面
176
- return redirectTo(option);
275
+ return navigate(option, 'reLaunch');
177
276
  }
178
277
  function getCurrentPages() {
179
- return stacks;
278
+ var pages = stacks.get();
279
+ return pages.map(function (e) { return (Object.assign(Object.assign({}, e), { route: e.path || '' })); });
180
280
  }
181
281
 
182
282
  /**
@@ -822,55 +922,6 @@ var UniversalRouter = function () {
822
922
 
823
923
  UniversalRouter.pathToRegexp = pathToRegexp_1;
824
924
 
825
- function initTabbar(config) {
826
- if (config.tabBar == null) {
827
- return;
828
- }
829
- // TODO: 找到 tabbar 的类型
830
- var tabbar = document.createElement('taro-tabbar');
831
- var homePage = config.pages ? config.pages[0] : '';
832
- tabbar.conf = config.tabBar;
833
- tabbar.conf.homePage = exports.history.location.pathname === '/' ? homePage : exports.history.location.pathname;
834
- var routerConfig = config.router;
835
- tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
836
- tabbar.conf.custom = !!routerConfig.customRoutes;
837
- if (routerConfig.customRoutes) {
838
- tabbar.conf.custom = true;
839
- tabbar.conf.customRoutes = routerConfig.customRoutes;
840
- }
841
- else {
842
- tabbar.conf.custom = false;
843
- tabbar.conf.customRoutes = {};
844
- }
845
- if (typeof routerConfig.basename !== 'undefined') {
846
- tabbar.conf.basename = routerConfig.basename;
847
- }
848
- var container = document.getElementById('container');
849
- // eslint-disable-next-line no-unused-expressions
850
- container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
851
- }
852
-
853
- var routerConfig = Object.create(null);
854
- function init(config) {
855
- var _a;
856
- config.router.mode = config.router.mode || 'hash';
857
- setHistoryMode(config.router.mode, config.router.basename);
858
- Object.assign(routerConfig, config);
859
- (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
860
- var container = document.createElement('div');
861
- container.classList.add('taro-tabbar__container');
862
- container.id = 'container';
863
- var panel = document.createElement('div');
864
- panel.classList.add('taro-tabbar__panel');
865
- var app = document.createElement('div');
866
- app.id = 'app';
867
- app.classList.add('taro_router');
868
- panel.appendChild(app);
869
- container.appendChild(panel);
870
- document.body.appendChild(container);
871
- initTabbar(config);
872
- }
873
-
874
925
  function createCommonjsModule(fn, module) {
875
926
  return module = { exports: {} }, fn(module, module.exports), module.exports;
876
927
  }
@@ -1427,21 +1478,6 @@ var queryString_5 = queryString.stringifyUrl;
1427
1478
  var queryString_6 = queryString.pick;
1428
1479
  var queryString_7 = queryString.exclude;
1429
1480
 
1430
- var qs = function (stamp) {
1431
- if ( stamp === void 0 ) stamp = 0;
1432
-
1433
- var search = routerConfig.router.mode === 'hash'
1434
- ? location.hash.slice(routerConfig.router.pathname.length + 1)
1435
- : location.search;
1436
- var query = search
1437
- ? queryString.parse(search.substr(1))
1438
- : {};
1439
- if (stamp) {
1440
- query.stamp = stamp.toString();
1441
- }
1442
- return query;
1443
- };
1444
-
1445
1481
  var pageScrollFn;
1446
1482
  var pageDOM = window;
1447
1483
  function bindPageScroll(page, config) {
@@ -1466,24 +1502,22 @@ function bindPageScroll(page, config) {
1466
1502
  pageDOM.addEventListener('scroll', pageScrollFn, false);
1467
1503
  }
1468
1504
  window.addEventListener('DOMSubtreeModified', function (e) {
1469
- var _a;
1470
- // @ts-ignore
1471
- var className = (_a = e.target) === null || _a === void 0 ? void 0 : _a.className;
1472
- if (className && /taro-tabbar__/.test(className)) {
1505
+ var target = e.target;
1506
+ var className = target === null || target === void 0 ? void 0 : target.className;
1507
+ if (className && /taro_page/.test(className)) {
1473
1508
  pageDOM.removeEventListener('scroll', pageScrollFn);
1474
1509
  pageDOM = getScrollContainer();
1475
1510
  pageDOM.addEventListener('scroll', pageScrollFn, false);
1476
1511
  }
1477
1512
  }, false);
1478
1513
  function getScrollContainer() {
1479
- if (document.querySelector('.taro-tabbar__tabbar') === null) {
1480
- // 没设置tabbar
1481
- return window;
1482
- }
1483
- else {
1484
- // 有设置tabbar
1485
- return document.querySelector('.taro-tabbar__panel') || window;
1486
- }
1514
+ var _a;
1515
+ var id = (_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path;
1516
+ var el = (id
1517
+ ? document.getElementById(id)
1518
+ : document.querySelector('.taro_page') ||
1519
+ document.querySelector('.taro_router'));
1520
+ return el || window;
1487
1521
  }
1488
1522
  function getOffset() {
1489
1523
  if (pageDOM instanceof Window) {
@@ -1494,47 +1528,174 @@ function getOffset() {
1494
1528
  }
1495
1529
  }
1496
1530
 
1497
- /* eslint-disable dot-notation */
1498
- function hidePage(page) {
1499
- if (page != null) {
1500
- page.onHide();
1501
- var pageEl = document.getElementById(page.path);
1502
- if (pageEl) {
1503
- pageEl.style.display = 'none';
1504
- }
1531
+ /**
1532
+ * 插入页面动画需要的样式
1533
+ */
1534
+ function loadAnimateStyle(ms) {
1535
+ if ( ms === void 0 ) ms = 300;
1536
+
1537
+ var css = "\n.taro_router .taro_page {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n transform: translate3d(100%, 0, 0);\n transition: transform " + ms + "ms;\n}\n\n.taro_router .taro_page.taro_tabbar_page {\n transform: none;\n}\n\n.taro_router .taro_page.taro_page_show {\n transform: translate3d(0, 0, 0);\n}";
1538
+ var style = document.createElement('style');
1539
+ style.innerHTML = css;
1540
+ document.getElementsByTagName('head')[0].appendChild(style);
1541
+ }
1542
+
1543
+ // @ts-nocheck
1544
+ function initTabbar(config) {
1545
+ if (config.tabBar == null) {
1546
+ return;
1547
+ }
1548
+ // TODO: custom-tab-bar
1549
+ var tabbar = document.createElement('taro-tabbar');
1550
+ var homePage = config.entryPagePath || (config.pages ? config.pages[0] : '');
1551
+ tabbar.conf = config.tabBar;
1552
+ tabbar.conf.homePage = exports.history.location.pathname === '/' ? homePage : exports.history.location.pathname;
1553
+ var routerConfig = config.router;
1554
+ tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
1555
+ if (routerConfig.customRoutes) {
1556
+ tabbar.conf.custom = true;
1557
+ tabbar.conf.customRoutes = routerConfig.customRoutes;
1558
+ }
1559
+ else {
1560
+ tabbar.conf.custom = false;
1561
+ tabbar.conf.customRoutes = {};
1562
+ }
1563
+ if (typeof routerConfig.basename !== 'undefined') {
1564
+ tabbar.conf.basename = routerConfig.basename;
1565
+ }
1566
+ var container = document.getElementById('container');
1567
+ container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
1568
+ taro.initTabBarApis(config);
1569
+ }
1570
+
1571
+ function setDisplay(el, type) {
1572
+ if ( type === void 0 ) type = '';
1573
+
1574
+ if (el) {
1575
+ el.style.display = type;
1505
1576
  }
1506
1577
  }
1507
- function showPage(page, pageConfig, stacksIndex) {
1508
- if ( stacksIndex === void 0 ) stacksIndex = 0;
1578
+ var PageHandler = function PageHandler(config) {
1579
+ this.defaultAnimation = { duration: 300, delay: 50 };
1580
+ this.config = config;
1581
+ this.mount();
1582
+ };
1583
+
1584
+ var prototypeAccessors$1 = { appId: { configurable: true },router: { configurable: true },routerMode: { configurable: true },customRoutes: { configurable: true },routes: { configurable: true },tabBarList: { configurable: true },PullDownRefresh: { configurable: true },animation: { configurable: true },animationDelay: { configurable: true },animationDuration: { configurable: true },pathname: { configurable: true },basename: { configurable: true },pageConfig: { configurable: true },isTabBar: { configurable: true },search: { configurable: true } };
1585
+ prototypeAccessors$1.appId.get = function () { return 'app'; };
1586
+ prototypeAccessors$1.router.get = function () { return this.config.router; };
1587
+ prototypeAccessors$1.routerMode.get = function () { return this.router.mode || 'hash'; };
1588
+ prototypeAccessors$1.customRoutes.get = function () { return this.router.customRoutes || {}; };
1589
+ prototypeAccessors$1.routes.get = function () { return this.config.routes; };
1590
+ prototypeAccessors$1.tabBarList.get = function () { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; };
1591
+ prototypeAccessors$1.PullDownRefresh.get = function () { return this.config.PullDownRefresh; };
1592
+ prototypeAccessors$1.animation.get = function () { var _a, _b; return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.animation) !== null && _b !== void 0 ? _b : this.defaultAnimation; };
1593
+ prototypeAccessors$1.animationDelay.get = function () {
1594
+ var _a;
1595
+ return typeof this.animation === 'object'
1596
+ ? this.animation.delay
1597
+ : this.animation
1598
+ ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.delay
1599
+ : 0;
1600
+ };
1601
+ prototypeAccessors$1.animationDuration.get = function () {
1602
+ var _a;
1603
+ return typeof this.animation === 'object'
1604
+ ? this.animation.duration
1605
+ : this.animation
1606
+ ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.duration
1607
+ : 0;
1608
+ };
1609
+ prototypeAccessors$1.pathname.set = function (p) { this.router.pathname = p; };
1610
+ prototypeAccessors$1.pathname.get = function () { return this.router.pathname; };
1611
+ prototypeAccessors$1.basename.get = function () { return this.router.basename || ''; };
1612
+ prototypeAccessors$1.pageConfig.get = function () {
1613
+ var this$1 = this;
1509
1614
 
1510
- if (page != null) {
1511
- page.onShow();
1512
- var pageEl = document.getElementById(page.path);
1513
- if (pageEl) {
1514
- pageEl.style.display = 'block';
1615
+ return this.routes.find(function (r) {
1616
+ var _a;
1617
+ var routePath = stripBasename(this$1.pathname, this$1.basename);
1618
+ var pagePath = addLeadingSlash(r.path);
1619
+ return pagePath === routePath || ((_a = routesAlias.getConfig(pagePath)) === null || _a === void 0 ? void 0 : _a.includes(routePath));
1620
+ });
1621
+ };
1622
+ prototypeAccessors$1.isTabBar.get = function () {
1623
+ var _a;
1624
+ var routePath = stripBasename(this.pathname, this.basename);
1625
+ var pagePath = ((_a = Object.entries(this.customRoutes).find(function (ref) {
1626
+ var target = ref[1];
1627
+
1628
+ if (typeof target === 'string') {
1629
+ return target === routePath;
1515
1630
  }
1516
- else {
1517
- page.onLoad(qs(stacksIndex));
1518
- pageEl = document.getElementById(page.path);
1519
- pageOnReady(pageEl, page, false);
1631
+ else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
1632
+ return target.includes(routePath);
1633
+ }
1634
+ return false;
1635
+ })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
1636
+ return !!pagePath && this.tabBarList.some(function (t) { return t.pagePath === pagePath; });
1637
+ };
1638
+ PageHandler.prototype.isSamePage = function isSamePage (page) {
1639
+ var routePath = stripBasename(this.pathname, this.basename);
1640
+ var pagePath = stripBasename(page === null || page === void 0 ? void 0 : page.path, this.basename);
1641
+ return pagePath.startsWith(routePath + '?');
1642
+ };
1643
+ prototypeAccessors$1.search.get = function () {
1644
+ var search = '?';
1645
+ if (this.routerMode) {
1646
+ var idx = location.hash.indexOf('?');
1647
+ if (idx > -1) {
1648
+ search = location.hash.slice(idx);
1520
1649
  }
1521
- bindPageScroll(page, pageConfig || {});
1522
1650
  }
1523
- }
1524
- function unloadPage(page) {
1525
- if (page != null) {
1526
- stacks.pop();
1527
- page.onUnload();
1651
+ else {
1652
+ search = location.search;
1528
1653
  }
1529
- }
1530
- function pageOnReady(pageEl, page, onLoad) {
1531
- if ( onLoad === void 0 ) onLoad = true;
1654
+ return search.substr(1);
1655
+ };
1656
+ PageHandler.prototype.getQuery = function getQuery (stamp) {
1657
+ if ( stamp === void 0 ) stamp = 0;
1532
1658
 
1659
+ var search = this.search;
1660
+ var query = search
1661
+ ? queryString.parse(search)
1662
+ : {};
1663
+ if (stamp) {
1664
+ query.stamp = stamp.toString();
1665
+ }
1666
+ return query;
1667
+ };
1668
+ PageHandler.prototype.mount = function mount () {
1533
1669
  var _a;
1670
+ setHistoryMode(this.routerMode, this.router.basename);
1671
+ (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
1672
+ this.animation && loadAnimateStyle(this.animationDuration);
1673
+ var app = document.createElement('div');
1674
+ app.id = this.appId;
1675
+ app.classList.add('taro_router');
1676
+ if (this.tabBarList.length > 1) {
1677
+ var container = document.createElement('div');
1678
+ container.classList.add('taro-tabbar__container');
1679
+ container.id = 'container';
1680
+ var panel = document.createElement('div');
1681
+ panel.classList.add('taro-tabbar__panel');
1682
+ panel.appendChild(app);
1683
+ container.appendChild(panel);
1684
+ document.body.appendChild(container);
1685
+ initTabbar(this.config);
1686
+ }
1687
+ else {
1688
+ document.body.appendChild(app);
1689
+ }
1690
+ };
1691
+ PageHandler.prototype.onReady = function onReady (page, onLoad) {
1692
+ if ( onLoad === void 0 ) onLoad = true;
1693
+
1694
+ var _a, _b;
1695
+ var pageEl = document.getElementById(page.path);
1534
1696
  if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
1535
1697
  var el = pageEl.firstElementChild;
1536
- // eslint-disable-next-line no-unused-expressions
1537
- (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el).then(function () {
1698
+ (_b = (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el)) === null || _b === void 0 ? void 0 : _b.then(function () {
1538
1699
  runtime.requestAnimationFrame(function () {
1539
1700
  page.onReady();
1540
1701
  pageEl['__isReady'] = true;
@@ -1542,58 +1703,151 @@ function pageOnReady(pageEl, page, onLoad) {
1542
1703
  });
1543
1704
  onLoad && (pageEl['__page'] = page);
1544
1705
  }
1545
- }
1546
- function loadPage(page, pageConfig, stacksIndex) {
1547
- if ( stacksIndex === void 0 ) stacksIndex = 0;
1706
+ };
1707
+ PageHandler.prototype.load = function load (page, pageConfig, stacksIndex) {
1708
+ var this$1 = this;
1709
+ if ( pageConfig === void 0 ) pageConfig = {};
1710
+ if ( stacksIndex === void 0 ) stacksIndex = 0;
1548
1711
 
1549
- if (page !== null) {
1550
- var pageEl = document.getElementById(page.path);
1551
- if (pageEl) {
1552
- pageEl.style.display = 'block';
1712
+ if (!page)
1713
+ { return; }
1714
+ var pageEl = document.getElementById(page.path);
1715
+ if (pageEl) {
1716
+ setDisplay(pageEl);
1717
+ this.isTabBar && pageEl.classList.add('taro_tabbar_page');
1718
+ this.addAnimation(pageEl, stacksIndex === 0);
1719
+ }
1720
+ else {
1721
+ page.onLoad(this.getQuery(stacksIndex), function () {
1722
+ pageEl = document.getElementById(page.path);
1723
+ this$1.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
1724
+ this$1.addAnimation(pageEl, stacksIndex === 0);
1725
+ this$1.onReady(page, true);
1726
+ });
1727
+ }
1728
+ stacks.push(page);
1729
+ page.onShow();
1730
+ bindPageScroll(page, pageConfig);
1731
+ };
1732
+ PageHandler.prototype.unload = function unload (page, delta, top) {
1733
+ var this$1 = this;
1734
+ if ( delta === void 0 ) delta = 1;
1735
+ if ( top === void 0 ) top = false;
1736
+
1737
+ var _a;
1738
+ if (!page)
1739
+ { return; }
1740
+ stacks.delta = --delta;
1741
+ stacks.pop();
1742
+ if (this.animation && top) {
1743
+ if (this.unloadTimer) {
1744
+ clearTimeout(this.unloadTimer);
1745
+ (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload();
1746
+ this.unloadTimer = null;
1553
1747
  }
1554
- else {
1555
- page.onLoad(qs(stacksIndex), function () {
1556
- pageEl = document.getElementById(page.path);
1557
- pageOnReady(pageEl, page);
1558
- });
1748
+ this.lastUnloadPage = page;
1749
+ var pageEl = document.getElementById(page.path);
1750
+ pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1751
+ this.unloadTimer = setTimeout(function () {
1752
+ var _a;
1753
+ this$1.unloadTimer = null;
1754
+ (_a = this$1.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload();
1755
+ }, this.animationDuration);
1756
+ }
1757
+ if (delta >= 1)
1758
+ { this.unload(stacks.last, delta); }
1759
+ };
1760
+ PageHandler.prototype.show = function show (page, pageConfig, stacksIndex) {
1761
+ var this$1 = this;
1762
+ if ( pageConfig === void 0 ) pageConfig = {};
1763
+ if ( stacksIndex === void 0 ) stacksIndex = 0;
1764
+
1765
+ if (!page)
1766
+ { return; }
1767
+ page.onShow();
1768
+ var pageEl = document.getElementById(page.path);
1769
+ if (pageEl) {
1770
+ setDisplay(pageEl);
1771
+ this.addAnimation(pageEl, stacksIndex === 0);
1772
+ }
1773
+ else {
1774
+ page.onLoad(this.getQuery(stacksIndex), function () {
1775
+ pageEl = document.getElementById(page.path);
1776
+ this$1.addAnimation(pageEl, stacksIndex === 0);
1777
+ this$1.onReady(page, false);
1778
+ });
1779
+ }
1780
+ bindPageScroll(page, pageConfig);
1781
+ };
1782
+ PageHandler.prototype.hide = function hide (page) {
1783
+ var this$1 = this;
1784
+
1785
+ if (!page)
1786
+ { return; }
1787
+ // NOTE: 修复多页并发问题,此处可能因为路由跳转过快,执行时页面可能还没有创建成功
1788
+ var pageEl = document.getElementById(page.path);
1789
+ if (pageEl) {
1790
+ if (this.hideTimer) {
1791
+ clearTimeout(this.hideTimer);
1792
+ this.hideTimer = null;
1793
+ setDisplay(this.lastHidePage, 'none');
1559
1794
  }
1560
- stacks.push(page);
1561
- page.onShow();
1562
- bindPageScroll(page, pageConfig || {});
1795
+ this.lastHidePage = pageEl;
1796
+ this.hideTimer = setTimeout(function () {
1797
+ this$1.hideTimer = null;
1798
+ setDisplay(this$1.lastHidePage, 'none');
1799
+ }, this.animationDelay);
1800
+ page.onHide();
1563
1801
  }
1564
- }
1802
+ else {
1803
+ setTimeout(function () { return this$1.hide(page); }, 0);
1804
+ }
1805
+ };
1806
+ PageHandler.prototype.addAnimation = function addAnimation (pageEl, first) {
1807
+ if ( first === void 0 ) first = false;
1808
+
1809
+ if (!pageEl)
1810
+ { return; }
1811
+ if (this.animation && !first) {
1812
+ setTimeout(function () {
1813
+ pageEl.classList.add('taro_page_show');
1814
+ }, this.animationDelay);
1815
+ }
1816
+ else {
1817
+ pageEl.classList.add('taro_page_show');
1818
+ }
1819
+ };
1820
+
1821
+ Object.defineProperties( PageHandler.prototype, prototypeAccessors$1 );
1822
+
1823
+ /* eslint-disable dot-notation */
1565
1824
  function createRouter(app, config, framework) {
1566
1825
  var _a;
1567
- init(config);
1568
- var routes = [];
1569
- var alias = (_a = config.router.customRoutes) !== null && _a !== void 0 ? _a : {};
1826
+ var handler = new PageHandler(config);
1570
1827
  var runtimeHooks = runtime.container.get(runtime.SERVICE_IDENTIFIER.Hooks);
1571
- setRoutesAlias(alias);
1572
- for (var i = 0; i < config.routes.length; i++) {
1573
- var route = config.routes[i];
1574
- var path = addLeadingSlash(route.path);
1575
- routes.push({
1576
- path: alias[path] || path,
1577
- action: route.load
1578
- });
1579
- }
1580
- var basename = config.router.basename;
1828
+ routesAlias.set(handler.router.customRoutes);
1829
+ var basename = handler.router.basename;
1830
+ var routes = handler.routes.map(function (route) { return ({
1831
+ path: routesAlias.getAll(addLeadingSlash(route.path)),
1832
+ action: route.load
1833
+ }); });
1834
+ var entryPagePath = config.entryPagePath || ((_a = routes[0].path) === null || _a === void 0 ? void 0 : _a[0]);
1581
1835
  var router = new UniversalRouter(routes, { baseUrl: basename || '' });
1582
1836
  app.onLaunch();
1583
- var render = throttle(async function (ref) {
1837
+ var render = async function (ref) {
1584
1838
  var location = ref.location;
1585
1839
  var action = ref.action;
1586
1840
 
1587
1841
  var _a, _b, _c, _d;
1588
- routerConfig.router.pathname = location.pathname;
1842
+ handler.pathname = location.pathname;
1589
1843
  var element;
1590
1844
  try {
1591
- element = await router.resolve(config.router.forcePath || location.pathname);
1845
+ element = await router.resolve(handler.router.forcePath || handler.pathname);
1592
1846
  }
1593
1847
  catch (error) {
1594
1848
  if (error.status === 404) {
1595
1849
  (_a = app.onPageNotFound) === null || _a === void 0 ? void 0 : _a.call(app, {
1596
- path: location.pathname
1850
+ path: handler.pathname
1597
1851
  });
1598
1852
  }
1599
1853
  else {
@@ -1602,84 +1856,68 @@ function createRouter(app, config, framework) {
1602
1856
  }
1603
1857
  if (!element)
1604
1858
  { return; }
1605
- var pageConfig = config.routes.find(function (r) {
1606
- var path = addLeadingSlash(r.path);
1607
- return path === location.pathname || alias[path] === location.pathname;
1608
- });
1859
+ var pageConfig = handler.pageConfig;
1609
1860
  var enablePullDownRefresh = false;
1610
1861
  runtime.eventCenter.trigger('__taroRouterChange', {
1611
1862
  toLocation: {
1612
- path: location.pathname
1863
+ path: handler.pathname
1613
1864
  }
1614
1865
  });
1615
1866
  if (pageConfig) {
1616
1867
  document.title = (_b = pageConfig.navigationBarTitleText) !== null && _b !== void 0 ? _b : document.title;
1617
1868
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1618
1869
  }
1870
+ var currentPage = runtime.Current.page;
1871
+ var pathname = handler.pathname;
1619
1872
  var shouldLoad = false;
1620
1873
  if (action === 'POP') {
1621
- unloadPage(runtime.Current.page);
1622
- var delta = historyBackDelta;
1623
- while (delta-- > 1) {
1624
- unloadPage(stacks.slice(-1)[0]);
1625
- }
1626
- // 最终必须重置为 1
1627
- setHistoryBackDelta(1);
1628
- var prevIndex = stacks.reduceRight(function (p, s, i) {
1629
- if (p !== 0)
1630
- { return p; }
1631
- else if (s.path === location.pathname + runtime.stringify(qs(i)))
1632
- { return i; }
1633
- else
1634
- { return 0; }
1635
- }, 0);
1636
- var prev = stacks[prevIndex];
1637
- if (prev) {
1638
- showPage(prev, pageConfig, prevIndex);
1874
+ // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
1875
+ var prevIndex = stacks.getPrevIndex(pathname);
1876
+ var delta = stacks.getDelta(pathname);
1877
+ handler.unload(currentPage, delta, prevIndex > -1);
1878
+ if (prevIndex > -1) {
1879
+ handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1639
1880
  }
1640
1881
  else {
1641
1882
  shouldLoad = true;
1642
1883
  }
1643
1884
  }
1644
- else if (action === 'PUSH') {
1645
- hidePage(runtime.Current.page);
1646
- shouldLoad = true;
1647
- }
1648
- else if (action === 'REPLACE') {
1649
- if (isTabBar(config)) {
1650
- hidePage(runtime.Current.page);
1651
- var pathname = stripBasename(config.router.pathname, basename);
1652
- var prevIndex$1 = stacks.findIndex(function (r) {
1653
- var _a;
1654
- return ((_a = r.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname;
1655
- });
1885
+ else {
1886
+ if (handler.isTabBar) {
1887
+ if (handler.isSamePage(currentPage))
1888
+ { return; }
1889
+ var prevIndex$1 = stacks.getPrevIndex(pathname, 0);
1890
+ handler.hide(currentPage);
1656
1891
  if (prevIndex$1 > -1) {
1657
- // tabbar 页且之前出现过,直接复用
1658
- var prev$1 = stacks[prevIndex$1];
1659
- return showPage(prev$1, pageConfig, prevIndex$1);
1892
+ // NOTE: tabbar 页且之前出现过,直接复用
1893
+ return handler.show(stacks.getItem(prevIndex$1), pageConfig, prevIndex$1);
1660
1894
  }
1661
1895
  }
1662
- else {
1663
- unloadPage(runtime.Current.page);
1896
+ else if (action === 'REPLACE') {
1897
+ var delta$1 = stacks.getDelta(pathname);
1898
+ // NOTE: 页面路由记录并不会清空,只是移除掉缓存的 stack 以及页面
1899
+ handler.unload(currentPage, delta$1);
1900
+ }
1901
+ else if (action === 'PUSH') {
1902
+ handler.hide(currentPage);
1664
1903
  }
1665
1904
  shouldLoad = true;
1666
1905
  }
1667
- if (shouldLoad) {
1906
+ if (shouldLoad || stacks.length < 1) {
1668
1907
  var el = (_c = element.default) !== null && _c !== void 0 ? _c : element;
1669
1908
  var loadConfig = Object.assign({}, pageConfig);
1909
+ var stacksIndex = stacks.length;
1670
1910
  delete loadConfig['path'];
1671
1911
  delete loadConfig['load'];
1672
- var pathname$1 = stripBasename(config.router.pathname, basename);
1673
- var routerIndex = stacks.length;
1674
- var page = runtime.createPageConfig(enablePullDownRefresh ? (_d = runtimeHooks.createPullDownComponent) === null || _d === void 0 ? void 0 : _d.call(runtimeHooks, el, location.pathname, framework, routerConfig.PullDownRefresh) : el, pathname$1 + runtime.stringify(qs(routerIndex)), {}, loadConfig);
1675
- loadPage(page, pageConfig, routerIndex);
1912
+ var page = runtime.createPageConfig(enablePullDownRefresh ? (_d = runtimeHooks.createPullDownComponent) === null || _d === void 0 ? void 0 : _d.call(runtimeHooks, el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(stacksIndex)), {}, loadConfig);
1913
+ return handler.load(page, pageConfig, stacksIndex);
1676
1914
  }
1677
- }, 500);
1915
+ };
1678
1916
  if (exports.history.location.pathname === '/') {
1679
- exports.history.replace(prependBasename(routes[0].path + exports.history.location.search));
1917
+ exports.history.replace(prependBasename(entryPagePath + exports.history.location.search));
1680
1918
  }
1681
1919
  render({ location: exports.history.location, action: r.Push });
1682
- app.onShow(qs(stacks.length));
1920
+ app.onShow(handler.getQuery(stacks.length));
1683
1921
  return exports.history.listen(render);
1684
1922
  }
1685
1923