@tarojs/router 3.7.0-alpha.2 → 3.7.0-alpha.20

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.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createBrowserHistory, createHashHistory, Action, parsePath } from 'history';
2
- import { Current, incrementId, eventCenter, createPageConfig, hooks, stringify, requestAnimationFrame } from '@tarojs/runtime';
2
+ import { Current, eventCenter, incrementId, createPageConfig, hooks, stringify, requestAnimationFrame as requestAnimationFrame$1 } from '@tarojs/runtime';
3
3
  import MobileDetect from 'mobile-detect';
4
4
  import queryString from 'query-string';
5
5
  import { defineCustomElementTaroTabbar } from '@tarojs/components/dist/components';
@@ -31,65 +31,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
31
31
  });
32
32
  }
33
33
 
34
- // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
35
- // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
36
- const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
37
- const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
38
- const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
39
- const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
40
- const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
41
- var _a;
42
- const routePath = addLeadingSlash(stripBasename(path, basename));
43
- const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
44
- return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
45
- };
46
- const getCurrentPage = (routerMode = 'hash', basename = '/') => {
47
- const pagePath = routerMode === 'hash'
48
- ? location.hash.slice(1).split('?')[0]
49
- : location.pathname;
50
- return addLeadingSlash(stripBasename(pagePath, basename));
51
- };
52
- class RoutesAlias {
53
- constructor() {
54
- this.conf = [];
55
- this.getConfig = (url = '') => {
56
- const customRoute = this.conf.filter((arr) => {
57
- return arr.includes(url);
58
- });
59
- return customRoute[0];
60
- };
61
- this.getOrigin = (url = '') => {
62
- var _a;
63
- return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
64
- };
65
- this.getAlias = (url = '') => {
66
- var _a;
67
- return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
68
- };
69
- this.getAll = (url = '') => {
70
- return this.conf
71
- .filter((arr) => arr.includes(url))
72
- .reduceRight((p, a) => {
73
- p.unshift(a[1]);
74
- return p;
75
- }, []);
76
- };
77
- }
78
- set(customRoutes = {}) {
79
- for (let key in customRoutes) {
80
- const path = customRoutes[key];
81
- key = addLeadingSlash(key);
82
- if (typeof path === 'string') {
83
- this.conf.push([key, addLeadingSlash(path)]);
84
- }
85
- else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
86
- this.conf.push(...path.map(p => [key, addLeadingSlash(p)]));
87
- }
88
- }
89
- }
90
- }
91
- const routesAlias = new RoutesAlias();
92
-
93
34
  class RouterConfig {
94
35
  static set config(e) {
95
36
  this.__config = e;
@@ -108,7 +49,7 @@ class RouterConfig {
108
49
  }
109
50
  static get customRoutes() { return this.router.customRoutes || {}; }
110
51
  static isPage(url = '') {
111
- return this.pages.findIndex(e => addLeadingSlash(e) === url) !== -1;
52
+ return this.pages.findIndex(e => prependBasename(e) === url) !== -1;
112
53
  }
113
54
  }
114
55
 
@@ -147,7 +88,7 @@ class MpaHistory {
147
88
  return url;
148
89
  }
149
90
  push(to, _state = {}) {
150
- window.location.pathname = this.parseUrl(to);
91
+ window.location.assign(this.parseUrl(to));
151
92
  // this.pushState(_state, '', this.parseUrl(to))
152
93
  }
153
94
  replace(to, _state = {}) {
@@ -292,6 +233,65 @@ class Stacks {
292
233
  }
293
234
  const stacks = new Stacks();
294
235
 
236
+ // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
237
+ // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
238
+ const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
239
+ const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
240
+ const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
241
+ const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
242
+ const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
243
+ var _a;
244
+ const routePath = addLeadingSlash(stripBasename(path, basename));
245
+ const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
246
+ return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
247
+ };
248
+ const getCurrentPage = (routerMode = 'hash', basename = '/') => {
249
+ const pagePath = routerMode === 'hash'
250
+ ? location.hash.slice(1).split('?')[0]
251
+ : location.pathname;
252
+ return addLeadingSlash(stripBasename(pagePath, basename));
253
+ };
254
+ class RoutesAlias {
255
+ constructor() {
256
+ this.conf = [];
257
+ this.getConfig = (url = '') => {
258
+ const customRoute = this.conf.filter((arr) => {
259
+ return arr.includes(url);
260
+ });
261
+ return customRoute[0];
262
+ };
263
+ this.getOrigin = (url = '') => {
264
+ var _a;
265
+ return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
266
+ };
267
+ this.getAlias = (url = '') => {
268
+ var _a;
269
+ return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
270
+ };
271
+ this.getAll = (url = '') => {
272
+ return this.conf
273
+ .filter((arr) => arr.includes(url))
274
+ .reduceRight((p, a) => {
275
+ p.unshift(a[1]);
276
+ return p;
277
+ }, []);
278
+ };
279
+ }
280
+ set(customRoutes = {}) {
281
+ for (let key in customRoutes) {
282
+ const path = customRoutes[key];
283
+ key = addLeadingSlash(key);
284
+ if (typeof path === 'string') {
285
+ this.conf.push([key, addLeadingSlash(path)]);
286
+ }
287
+ else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
288
+ this.conf.push(...path.map(p => [key, addLeadingSlash(p)]));
289
+ }
290
+ }
291
+ }
292
+ }
293
+ const routesAlias = new RoutesAlias();
294
+
295
295
  function processNavigateUrl(option) {
296
296
  var _a;
297
297
  const pathPieces = parsePath(option.url);
@@ -345,7 +345,12 @@ function navigate(option, method) {
345
345
  }
346
346
  else if (method === 'navigateBack') {
347
347
  stacks.delta = option.delta;
348
- history.go(-option.delta);
348
+ if (stacks.length > option.delta) {
349
+ history.go(-option.delta);
350
+ }
351
+ else {
352
+ history.go(1 - stacks.length);
353
+ }
349
354
  }
350
355
  }
351
356
  catch (error) {
@@ -430,11 +435,11 @@ function bindPageResize(page) {
430
435
 
431
436
  const pageScrollFn = {};
432
437
  let pageDOM = window;
433
- function bindPageScroll(page, pageEl, distance = 50) {
438
+ function bindPageScroll(page, scrollEl, distance = 50) {
434
439
  var _a;
435
440
  const pagePath = (page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.router) === null || _a === void 0 ? void 0 : _a.path);
436
- pageScrollFn[pagePath] && pageEl.removeEventListener('scroll', pageScrollFn[pagePath]);
437
- pageDOM = pageEl;
441
+ pageScrollFn[pagePath] && scrollEl.removeEventListener('scroll', pageScrollFn[pagePath]);
442
+ pageDOM = scrollEl;
438
443
  let isReachBottom = false;
439
444
  pageScrollFn[pagePath] = function () {
440
445
  var _a;
@@ -462,6 +467,75 @@ function getOffset() {
462
467
  }
463
468
  }
464
469
 
470
+ /**
471
+ * 插入页面动画需要的样式
472
+ */
473
+ function loadAnimateStyle(ms = 300) {
474
+ const css = `
475
+ .taro_router > .taro_page {
476
+ position: absolute;
477
+ left: 0;
478
+ top: 0;
479
+ width: 100%;
480
+ height: 100%;
481
+ background-color: #fff;
482
+ transform: translate(100%, 0);
483
+ transition: transform ${ms}ms;
484
+ z-index: 0;
485
+ }
486
+
487
+ .taro_router > .taro_page.taro_tabbar_page,
488
+ .taro_router > .taro_page.taro_page_show.taro_page_stationed {
489
+ transform: none;
490
+ }
491
+
492
+ .taro_router > .taro_page.taro_page_show {
493
+ transform: translate(0, 0);
494
+ }
495
+
496
+ .taro_page_shade,
497
+ .taro_router > .taro_page.taro_page_show.taro_page_stationed:not(.taro_page_shade):not(.taro_tabbar_page):not(:last-child) {
498
+ display: none;
499
+ }`;
500
+ addStyle(css);
501
+ }
502
+ /**
503
+ * 插入路由相关样式
504
+ */
505
+ function loadRouterStyle(usingWindowScroll) {
506
+ const css = `
507
+ .taro_router {
508
+ position: relative;
509
+ width: 100%;
510
+ height: 100%;
511
+ }
512
+
513
+ .taro_page {
514
+ width: 100%;
515
+ height: 100%;
516
+ ${usingWindowScroll ? '' : `
517
+ overflow-x: hidden;
518
+ overflow-y: scroll;
519
+ max-height: 100vh;
520
+ `}
521
+ }
522
+
523
+ .taro-tabbar__container .taro-tabbar__panel {
524
+ overflow: hidden;
525
+ max-height: calc(100vh - var(--taro-tabbar-height) - constant(safe-area-inset-bottom));
526
+ max-height: calc(100vh - var(--taro-tabbar-height) - env(safe-area-inset-bottom));
527
+ }
528
+ `;
529
+ addStyle(css);
530
+ }
531
+ function addStyle(css) {
532
+ if (!css)
533
+ return;
534
+ const style = document.createElement('style');
535
+ style.innerHTML = css;
536
+ document.getElementsByTagName('head')[0].appendChild(style);
537
+ }
538
+
465
539
  // @ts-nocheck
466
540
  function initTabbar(config) {
467
541
  if (config.tabBar == null) {
@@ -522,6 +596,17 @@ class MultiPageHandler {
522
596
  return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
523
597
  }
524
598
  get search() { return location.search.substr(1); }
599
+ get usingWindowScroll() {
600
+ var _a;
601
+ let usingWindowScroll = true;
602
+ if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
603
+ usingWindowScroll = this.pageConfig.usingWindowScroll;
604
+ }
605
+ const win = window;
606
+ win.__taroAppConfig || (win.__taroAppConfig = {});
607
+ win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
608
+ return usingWindowScroll;
609
+ }
525
610
  getQuery(search = '', options = {}) {
526
611
  search = search ? `${search}&${this.search}` : this.search;
527
612
  const query = search
@@ -531,6 +616,7 @@ class MultiPageHandler {
531
616
  }
532
617
  mount() {
533
618
  setHistoryMode(this.routerMode, this.router.basename);
619
+ loadRouterStyle(this.usingWindowScroll);
534
620
  const appId = this.appId;
535
621
  let app = document.getElementById(appId);
536
622
  let isPosition = true;
@@ -567,7 +653,20 @@ class MultiPageHandler {
567
653
  const pageEl = this.getPageContainer(page);
568
654
  if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
569
655
  const el = pageEl.firstElementChild;
570
- (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el);
656
+ const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
657
+ if (componentOnReady) {
658
+ componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
659
+ requestAnimationFrame(() => {
660
+ var _a;
661
+ (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
662
+ pageEl['__isReady'] = true;
663
+ });
664
+ });
665
+ }
666
+ else {
667
+ (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
668
+ pageEl['__isReady'] = true;
669
+ }
571
670
  onLoad && (pageEl['__page'] = page);
572
671
  }
573
672
  }
@@ -577,11 +676,14 @@ class MultiPageHandler {
577
676
  return;
578
677
  (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
579
678
  var _a;
580
- const pageEl = this.getPageContainer(page);
581
- this.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
679
+ if (this.isTabBar) {
680
+ const pageEl = this.getPageContainer(page);
681
+ pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
682
+ }
582
683
  this.onReady(page, true);
583
684
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
584
- this.bindPageEvents(page, pageEl, pageConfig);
685
+ this.bindPageEvents(page, pageConfig);
686
+ this.triggerRouterChange();
585
687
  });
586
688
  }
587
689
  getPageContainer(page) {
@@ -595,17 +697,33 @@ class MultiPageHandler {
595
697
  ? document.querySelector(`.taro_page#${id}`)
596
698
  : document.querySelector('.taro_page') ||
597
699
  document.querySelector('.taro_router'));
598
- return el || window;
700
+ return el;
599
701
  }
600
- bindPageEvents(page, pageEl, config = {}) {
702
+ getScrollingElement(page) {
703
+ if (this.usingWindowScroll)
704
+ return window;
705
+ return this.getPageContainer(page) || window;
706
+ }
707
+ bindPageEvents(page, config = {}) {
601
708
  var _a;
602
- if (!pageEl) {
603
- pageEl = this.getPageContainer();
604
- }
709
+ const scrollEl = this.getScrollingElement(page);
605
710
  const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
606
- bindPageScroll(page, pageEl, distance);
711
+ bindPageScroll(page, scrollEl, distance);
607
712
  bindPageResize(page);
608
713
  }
714
+ triggerRouterChange() {
715
+ /**
716
+ * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
717
+ * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
718
+ */
719
+ setTimeout(() => {
720
+ eventCenter.trigger('__afterTaroRouterChange', {
721
+ toLocation: {
722
+ path: this.pathname
723
+ }
724
+ });
725
+ }, 0);
726
+ }
609
727
  }
610
728
 
611
729
  const createStampId$1 = incrementId();
@@ -621,6 +739,9 @@ const launchStampId$1 = createStampId$1();
621
739
  function createMultiRouter(app, config, framework) {
622
740
  var _a, _b, _c, _d, _e, _f;
623
741
  return __awaiter(this, void 0, void 0, function* () {
742
+ if (typeof app.onUnhandledRejection === 'function') {
743
+ window.addEventListener('unhandledrejection', app.onUnhandledRejection);
744
+ }
624
745
  RouterConfig.config = config;
625
746
  const handler = new MultiPageHandler(config);
626
747
  const launchParam = {
@@ -663,48 +784,13 @@ function createMultiRouter(app, config, framework) {
663
784
  const loadConfig = Object.assign({}, pageConfig);
664
785
  delete loadConfig['path'];
665
786
  delete loadConfig['load'];
666
- const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathName + stringify(launchParam), {}, loadConfig);
787
+ const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, pathName, framework, handler.PullDownRefresh) : el, pathName + stringify(launchParam), {}, loadConfig);
667
788
  handler.load(page, pageConfig);
668
789
  (_f = app.onShow) === null || _f === void 0 ? void 0 : _f.call(app, launchParam);
669
790
  });
670
791
  }
671
792
 
672
- /**
673
- * 插入页面动画需要的样式
674
- */
675
- function loadAnimateStyle(ms = 300) {
676
- const css = `
677
- .taro_router .taro_page {
678
- position: absolute;
679
- left: 0;
680
- top: 0;
681
- width: 100%;
682
- height: 100%;
683
- background-color: #fff;
684
- transform: translate(100%, 0);
685
- transition: transform ${ms}ms;
686
- z-index: 0;
687
- }
688
-
689
- .taro_router .taro_page.taro_tabbar_page,
690
- .taro_router .taro_page.taro_page_show.taro_page_stationed {
691
- transform: none;
692
- }
693
-
694
- .taro_router .taro_page.taro_page_show {
695
- transform: translate(0, 0);
696
- }`;
697
- const style = document.createElement('style');
698
- style.innerHTML = css;
699
- document.getElementsByTagName('head')[0].appendChild(style);
700
- }
701
-
702
793
  /* eslint-disable dot-notation */
703
- function setDisplay(el, type = '') {
704
- if (el) {
705
- el.style.display = type;
706
- }
707
- }
708
794
  class PageHandler {
709
795
  constructor(config) {
710
796
  this.defaultAnimation = { duration: 300, delay: 50 };
@@ -784,6 +870,17 @@ class PageHandler {
784
870
  }
785
871
  return search.substring(1);
786
872
  }
873
+ get usingWindowScroll() {
874
+ var _a;
875
+ let usingWindowScroll = false;
876
+ if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
877
+ usingWindowScroll = this.pageConfig.usingWindowScroll;
878
+ }
879
+ const win = window;
880
+ win.__taroAppConfig || (win.__taroAppConfig = {});
881
+ win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
882
+ return usingWindowScroll;
883
+ }
787
884
  getQuery(stamp = '', search = '', options = {}) {
788
885
  search = search ? `${search}&${this.search}` : this.search;
789
886
  const query = search
@@ -794,7 +891,9 @@ class PageHandler {
794
891
  }
795
892
  mount() {
796
893
  setHistoryMode(this.routerMode, this.router.basename);
894
+ this.pathname = history.location.pathname;
797
895
  this.animation && loadAnimateStyle(this.animationDuration);
896
+ loadRouterStyle(this.usingWindowScroll);
798
897
  const appId = this.appId;
799
898
  let app = document.getElementById(appId);
800
899
  let isPosition = true;
@@ -834,7 +933,7 @@ class PageHandler {
834
933
  const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
835
934
  if (componentOnReady) {
836
935
  componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
837
- requestAnimationFrame(() => {
936
+ requestAnimationFrame$1(() => {
838
937
  var _a;
839
938
  (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
840
939
  pageEl['__isReady'] = true;
@@ -857,11 +956,12 @@ class PageHandler {
857
956
  const param = this.getQuery(stampId, '', page.options);
858
957
  let pageEl = this.getPageContainer(page);
859
958
  if (pageEl) {
860
- setDisplay(pageEl);
959
+ pageEl.classList.remove('taro_page_shade');
861
960
  this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
862
961
  this.addAnimation(pageEl, pageNo === 0);
863
962
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
864
- this.bindPageEvents(page, pageEl, pageConfig);
963
+ this.bindPageEvents(page, pageConfig);
964
+ this.triggerRouterChange();
865
965
  }
866
966
  else {
867
967
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
@@ -871,7 +971,8 @@ class PageHandler {
871
971
  this.addAnimation(pageEl, pageNo === 0);
872
972
  this.onReady(page, true);
873
973
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
874
- this.bindPageEvents(page, pageEl, pageConfig);
974
+ this.bindPageEvents(page, pageConfig);
975
+ this.triggerRouterChange();
875
976
  });
876
977
  }
877
978
  }
@@ -891,10 +992,14 @@ class PageHandler {
891
992
  const pageEl = this.getPageContainer(page);
892
993
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
893
994
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
995
+ if (pageEl) {
996
+ pageEl.style.zIndex = '1';
997
+ }
894
998
  this.unloadTimer = setTimeout(() => {
895
999
  var _a, _b;
896
1000
  this.unloadTimer = null;
897
1001
  (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1002
+ eventCenter.trigger('__taroPageOnShowAfterDestroyed');
898
1003
  }, this.animationDuration);
899
1004
  }
900
1005
  else {
@@ -902,6 +1007,9 @@ class PageHandler {
902
1007
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
903
1008
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
904
1009
  (_c = page === null || page === void 0 ? void 0 : page.onUnload) === null || _c === void 0 ? void 0 : _c.call(page);
1010
+ setTimeout(() => {
1011
+ eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1012
+ }, 0);
905
1013
  }
906
1014
  if (delta >= 1)
907
1015
  this.unload(stacks.last, delta);
@@ -913,10 +1021,11 @@ class PageHandler {
913
1021
  const param = this.getQuery(page['$taroParams']['stamp'], '', page.options);
914
1022
  let pageEl = this.getPageContainer(page);
915
1023
  if (pageEl) {
916
- setDisplay(pageEl);
1024
+ pageEl.classList.remove('taro_page_shade');
917
1025
  this.addAnimation(pageEl, pageNo === 0);
918
1026
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
919
- this.bindPageEvents(page, pageEl, pageConfig);
1027
+ this.bindPageEvents(page, pageConfig);
1028
+ this.triggerRouterChange();
920
1029
  }
921
1030
  else {
922
1031
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
@@ -925,7 +1034,8 @@ class PageHandler {
925
1034
  this.addAnimation(pageEl, pageNo === 0);
926
1035
  this.onReady(page, false);
927
1036
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
928
- this.bindPageEvents(page, pageEl, pageConfig);
1037
+ this.bindPageEvents(page, pageConfig);
1038
+ this.triggerRouterChange();
929
1039
  });
930
1040
  }
931
1041
  }
@@ -939,12 +1049,12 @@ class PageHandler {
939
1049
  if (this.hideTimer) {
940
1050
  clearTimeout(this.hideTimer);
941
1051
  this.hideTimer = null;
942
- setDisplay(this.lastHidePage, 'none');
1052
+ pageEl.classList.add('taro_page_shade');
943
1053
  }
944
1054
  this.lastHidePage = pageEl;
945
1055
  this.hideTimer = setTimeout(() => {
946
1056
  this.hideTimer = null;
947
- setDisplay(this.lastHidePage, 'none');
1057
+ pageEl.classList.add('taro_page_shade');
948
1058
  }, this.animationDuration + this.animationDelay);
949
1059
  (_a = page.onHide) === null || _a === void 0 ? void 0 : _a.call(page);
950
1060
  }
@@ -979,23 +1089,42 @@ class PageHandler {
979
1089
  ? document.querySelector(`.taro_page#${id}`)
980
1090
  : document.querySelector('.taro_page') ||
981
1091
  document.querySelector('.taro_router'));
982
- return el || window;
1092
+ return el;
983
1093
  }
984
- bindPageEvents(page, pageEl, config = {}) {
1094
+ getScrollingElement(page) {
1095
+ if (this.usingWindowScroll)
1096
+ return window;
1097
+ return this.getPageContainer(page) || window;
1098
+ }
1099
+ bindPageEvents(page, config = {}) {
985
1100
  var _a;
986
- if (!pageEl) {
987
- pageEl = this.getPageContainer();
988
- }
1101
+ const scrollEl = this.getScrollingElement(page);
989
1102
  const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
990
- bindPageScroll(page, pageEl, distance);
1103
+ bindPageScroll(page, scrollEl, distance);
991
1104
  bindPageResize(page);
992
1105
  }
1106
+ triggerRouterChange() {
1107
+ /**
1108
+ * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
1109
+ * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
1110
+ */
1111
+ setTimeout(() => {
1112
+ eventCenter.trigger('__afterTaroRouterChange', {
1113
+ toLocation: {
1114
+ path: this.pathname
1115
+ }
1116
+ });
1117
+ }, 0);
1118
+ }
993
1119
  }
994
1120
 
995
1121
  const createStampId = incrementId();
996
1122
  let launchStampId = createStampId();
997
1123
  function createRouter(app, config, framework) {
998
1124
  var _a, _b;
1125
+ if (typeof app.onUnhandledRejection === 'function') {
1126
+ window.addEventListener('unhandledrejection', app.onUnhandledRejection);
1127
+ }
999
1128
  RouterConfig.config = config;
1000
1129
  const handler = new PageHandler(config);
1001
1130
  routesAlias.set(handler.router.customRoutes);
@@ -1020,8 +1149,10 @@ function createRouter(app, config, framework) {
1020
1149
  (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
1021
1150
  app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
1022
1151
  const render = ({ location, action }) => __awaiter(this, void 0, void 0, function* () {
1023
- var _c, _d, _e, _f, _g;
1152
+ var _c, _d, _e, _f, _g, _h;
1024
1153
  handler.pathname = decodeURI(location.pathname);
1154
+ if ((_c = window.__taroAppConfig) === null || _c === void 0 ? void 0 : _c.usingWindowScroll)
1155
+ window.scrollTo(0, 0);
1025
1156
  eventCenter.trigger('__taroRouterChange', {
1026
1157
  toLocation: {
1027
1158
  path: handler.pathname
@@ -1034,9 +1165,13 @@ function createRouter(app, config, framework) {
1034
1165
  }
1035
1166
  catch (error) {
1036
1167
  if (error.status === 404) {
1037
- (_c = app.onPageNotFound) === null || _c === void 0 ? void 0 : _c.call(app, {
1038
- path: handler.pathname
1039
- });
1168
+ const notFoundEvent = {
1169
+ isEntryPage: stacks.length === 0,
1170
+ path: handler.pathname,
1171
+ query: handler.getQuery(createStampId()),
1172
+ };
1173
+ (_d = app.onPageNotFound) === null || _d === void 0 ? void 0 : _d.call(app, notFoundEvent);
1174
+ eventCenter.trigger('__taroRouterNotFound', notFoundEvent);
1040
1175
  }
1041
1176
  else if (/Loading hot update .* failed./.test(error.message)) {
1042
1177
  // NOTE: webpack5 与 prebundle 搭配使用时,开发环境下初次启动时偶发错误,由于 HMR 加载 chunk hash 错误,导致热更新失败
@@ -1049,16 +1184,16 @@ function createRouter(app, config, framework) {
1049
1184
  if (!element)
1050
1185
  return;
1051
1186
  const pageConfig = handler.pageConfig;
1052
- let enablePullDownRefresh = ((_d = config === null || config === void 0 ? void 0 : config.window) === null || _d === void 0 ? void 0 : _d.enablePullDownRefresh) || false;
1187
+ let enablePullDownRefresh = ((_e = config === null || config === void 0 ? void 0 : config.window) === null || _e === void 0 ? void 0 : _e.enablePullDownRefresh) || false;
1053
1188
  if (pageConfig) {
1054
- setTitle((_e = pageConfig.navigationBarTitleText) !== null && _e !== void 0 ? _e : document.title);
1189
+ setTitle((_f = pageConfig.navigationBarTitleText) !== null && _f !== void 0 ? _f : document.title);
1055
1190
  if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
1056
1191
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1057
1192
  }
1058
1193
  }
1059
1194
  const currentPage = Current.page;
1060
1195
  const pathname = handler.pathname;
1061
- const methodName = (_f = stacks.method) !== null && _f !== void 0 ? _f : '';
1196
+ const methodName = (_g = stacks.method) !== null && _g !== void 0 ? _g : '';
1062
1197
  const cacheTabs = stacks.getTabs();
1063
1198
  let shouldLoad = false;
1064
1199
  stacks.method = '';
@@ -1083,11 +1218,11 @@ function createRouter(app, config, framework) {
1083
1218
  else if (stacks.length > 0) {
1084
1219
  const firstIns = stacks.getItem(0);
1085
1220
  if (handler.isTabBar(firstIns.path)) {
1086
- handler.unload(currentPage, stacks.length - 1);
1221
+ handler.unload(currentPage, stacks.length - 1, true);
1087
1222
  stacks.pushTab(firstIns.path.split('?')[0]);
1088
1223
  }
1089
1224
  else {
1090
- handler.unload(currentPage, stacks.length);
1225
+ handler.unload(currentPage, stacks.length, true);
1091
1226
  }
1092
1227
  }
1093
1228
  if (cacheTabs[handler.pathname]) {
@@ -1104,7 +1239,9 @@ function createRouter(app, config, framework) {
1104
1239
  if (currentPage !== stacks.getItem(prevIndex)) {
1105
1240
  handler.unload(currentPage, delta, prevIndex > -1);
1106
1241
  if (prevIndex > -1) {
1107
- handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1242
+ eventCenter.once('__taroPageOnShowAfterDestroyed', () => {
1243
+ handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1244
+ });
1108
1245
  }
1109
1246
  else {
1110
1247
  shouldLoad = true;
@@ -1122,7 +1259,7 @@ function createRouter(app, config, framework) {
1122
1259
  shouldLoad = true;
1123
1260
  }
1124
1261
  if (shouldLoad || stacks.length < 1) {
1125
- const el = (_g = element.default) !== null && _g !== void 0 ? _g : element;
1262
+ const el = (_h = element.default) !== null && _h !== void 0 ? _h : element;
1126
1263
  const loadConfig = Object.assign({}, pageConfig);
1127
1264
  const stacksIndex = stacks.length;
1128
1265
  delete loadConfig['path'];
@@ -1135,16 +1272,11 @@ function createRouter(app, config, framework) {
1135
1272
  else {
1136
1273
  pageStampId = createStampId();
1137
1274
  }
1138
- const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1275
+ const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, pathname, framework, handler.PullDownRefresh, pageStampId) : el, pathname + stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1139
1276
  if (params)
1140
1277
  page.options = params;
1141
1278
  handler.load(page, pageConfig, pageStampId, stacksIndex);
1142
1279
  }
1143
- eventCenter.trigger('__afterTaroRouterChange', {
1144
- toLocation: {
1145
- path: handler.pathname
1146
- }
1147
- });
1148
1280
  });
1149
1281
  const routePath = addLeadingSlash(stripBasename(history.location.pathname, handler.basename));
1150
1282
  if (routePath === '/') {