@tarojs/router 3.7.0-alpha.0 → 3.7.0-alpha.10

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,2 +1,2 @@
1
1
  import { PageInstance } from '@tarojs/runtime';
2
- export declare function bindPageScroll(page: PageInstance, pageEl: HTMLElement, distance?: number): void;
2
+ export declare function bindPageScroll(page: PageInstance, scrollEl: HTMLElement | Window, distance?: number): void;
@@ -1,11 +1,11 @@
1
1
  import { Current } from '@tarojs/runtime';
2
2
  const pageScrollFn = {};
3
3
  let pageDOM = window;
4
- export function bindPageScroll(page, pageEl, distance = 50) {
4
+ export function bindPageScroll(page, scrollEl, distance = 50) {
5
5
  var _a;
6
6
  const pagePath = (page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.router) === null || _a === void 0 ? void 0 : _a.path);
7
- pageScrollFn[pagePath] && pageEl.removeEventListener('scroll', pageScrollFn[pagePath]);
8
- pageDOM = pageEl;
7
+ pageScrollFn[pagePath] && scrollEl.removeEventListener('scroll', pageScrollFn[pagePath]);
8
+ pageDOM = scrollEl;
9
9
  let isReachBottom = false;
10
10
  pageScrollFn[pagePath] = function () {
11
11
  var _a;
package/dist/history.js CHANGED
@@ -35,7 +35,7 @@ class MpaHistory {
35
35
  return url;
36
36
  }
37
37
  push(to, _state = {}) {
38
- window.location.pathname = this.parseUrl(to);
38
+ window.location.assign(this.parseUrl(to));
39
39
  // this.pushState(_state, '', this.parseUrl(to))
40
40
  }
41
41
  replace(to, _state = {}) {
@@ -1,6 +1,5 @@
1
1
  import Taro from "@tarojs/taro";
2
2
  import { History } from "history";
3
- /* eslint-disable dot-notation */
4
3
  import { AppInstance } from "@tarojs/runtime";
5
4
  import { MpaRouterConfig, SpaRouterConfig } from "../../types/router";
6
5
  declare function navigateTo(option: Taro.navigateTo.Option): ReturnType<typeof Taro.navigateTo>;
package/dist/index.cjs.js CHANGED
@@ -41,65 +41,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
41
41
  });
42
42
  }
43
43
 
44
- // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
45
- // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
46
- const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
47
- const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
48
- const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
49
- const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
50
- const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
51
- var _a;
52
- const routePath = addLeadingSlash(stripBasename(path, basename));
53
- const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
54
- return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
55
- };
56
- const getCurrentPage = (routerMode = 'hash', basename = '/') => {
57
- const pagePath = routerMode === 'hash'
58
- ? location.hash.slice(1).split('?')[0]
59
- : location.pathname;
60
- return addLeadingSlash(stripBasename(pagePath, basename));
61
- };
62
- class RoutesAlias {
63
- constructor() {
64
- this.conf = [];
65
- this.getConfig = (url = '') => {
66
- const customRoute = this.conf.filter((arr) => {
67
- return arr.includes(url);
68
- });
69
- return customRoute[0];
70
- };
71
- this.getOrigin = (url = '') => {
72
- var _a;
73
- return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
74
- };
75
- this.getAlias = (url = '') => {
76
- var _a;
77
- return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
78
- };
79
- this.getAll = (url = '') => {
80
- return this.conf
81
- .filter((arr) => arr.includes(url))
82
- .reduceRight((p, a) => {
83
- p.unshift(a[1]);
84
- return p;
85
- }, []);
86
- };
87
- }
88
- set(customRoutes = {}) {
89
- for (let key in customRoutes) {
90
- const path = customRoutes[key];
91
- key = addLeadingSlash(key);
92
- if (typeof path === 'string') {
93
- this.conf.push([key, addLeadingSlash(path)]);
94
- }
95
- else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
96
- this.conf.push(...path.map(p => [key, addLeadingSlash(p)]));
97
- }
98
- }
99
- }
100
- }
101
- const routesAlias = new RoutesAlias();
102
-
103
44
  class RouterConfig {
104
45
  static set config(e) {
105
46
  this.__config = e;
@@ -118,7 +59,7 @@ class RouterConfig {
118
59
  }
119
60
  static get customRoutes() { return this.router.customRoutes || {}; }
120
61
  static isPage(url = '') {
121
- return this.pages.findIndex(e => addLeadingSlash(e) === url) !== -1;
62
+ return this.pages.findIndex(e => prependBasename(e) === url) !== -1;
122
63
  }
123
64
  }
124
65
 
@@ -157,7 +98,7 @@ class MpaHistory {
157
98
  return url;
158
99
  }
159
100
  push(to, _state = {}) {
160
- window.location.pathname = this.parseUrl(to);
101
+ window.location.assign(this.parseUrl(to));
161
102
  // this.pushState(_state, '', this.parseUrl(to))
162
103
  }
163
104
  replace(to, _state = {}) {
@@ -302,6 +243,65 @@ class Stacks {
302
243
  }
303
244
  const stacks = new Stacks();
304
245
 
246
+ // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
247
+ // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
248
+ const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
249
+ const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
250
+ const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
251
+ const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
252
+ const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
253
+ var _a;
254
+ const routePath = addLeadingSlash(stripBasename(path, basename));
255
+ const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
256
+ return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
257
+ };
258
+ const getCurrentPage = (routerMode = 'hash', basename = '/') => {
259
+ const pagePath = routerMode === 'hash'
260
+ ? location.hash.slice(1).split('?')[0]
261
+ : location.pathname;
262
+ return addLeadingSlash(stripBasename(pagePath, basename));
263
+ };
264
+ class RoutesAlias {
265
+ constructor() {
266
+ this.conf = [];
267
+ this.getConfig = (url = '') => {
268
+ const customRoute = this.conf.filter((arr) => {
269
+ return arr.includes(url);
270
+ });
271
+ return customRoute[0];
272
+ };
273
+ this.getOrigin = (url = '') => {
274
+ var _a;
275
+ return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
276
+ };
277
+ this.getAlias = (url = '') => {
278
+ var _a;
279
+ return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
280
+ };
281
+ this.getAll = (url = '') => {
282
+ return this.conf
283
+ .filter((arr) => arr.includes(url))
284
+ .reduceRight((p, a) => {
285
+ p.unshift(a[1]);
286
+ return p;
287
+ }, []);
288
+ };
289
+ }
290
+ set(customRoutes = {}) {
291
+ for (let key in customRoutes) {
292
+ const path = customRoutes[key];
293
+ key = addLeadingSlash(key);
294
+ if (typeof path === 'string') {
295
+ this.conf.push([key, addLeadingSlash(path)]);
296
+ }
297
+ else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
298
+ this.conf.push(...path.map(p => [key, addLeadingSlash(p)]));
299
+ }
300
+ }
301
+ }
302
+ }
303
+ const routesAlias = new RoutesAlias();
304
+
305
305
  function processNavigateUrl(option) {
306
306
  var _a;
307
307
  const pathPieces = history.parsePath(option.url);
@@ -440,11 +440,11 @@ function bindPageResize(page) {
440
440
 
441
441
  const pageScrollFn = {};
442
442
  let pageDOM = window;
443
- function bindPageScroll(page, pageEl, distance = 50) {
443
+ function bindPageScroll(page, scrollEl, distance = 50) {
444
444
  var _a;
445
445
  const pagePath = (page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.router) === null || _a === void 0 ? void 0 : _a.path);
446
- pageScrollFn[pagePath] && pageEl.removeEventListener('scroll', pageScrollFn[pagePath]);
447
- pageDOM = pageEl;
446
+ pageScrollFn[pagePath] && scrollEl.removeEventListener('scroll', pageScrollFn[pagePath]);
447
+ pageDOM = scrollEl;
448
448
  let isReachBottom = false;
449
449
  pageScrollFn[pagePath] = function () {
450
450
  var _a;
@@ -472,6 +472,77 @@ function getOffset() {
472
472
  }
473
473
  }
474
474
 
475
+ /**
476
+ * 插入页面动画需要的样式
477
+ */
478
+ function loadAnimateStyle(ms = 300) {
479
+ const css = `
480
+ .taro_router .taro_page {
481
+ position: absolute;
482
+ left: 0;
483
+ top: 0;
484
+ width: 100%;
485
+ height: 100%;
486
+ background-color: #fff;
487
+ transform: translate(100%, 0);
488
+ transition: transform ${ms}ms;
489
+ z-index: 0;
490
+ }
491
+
492
+ .taro_router .taro_page.taro_tabbar_page,
493
+ .taro_router .taro_page.taro_page_show.taro_page_stationed {
494
+ transform: none;
495
+ }
496
+
497
+ .taro_router .taro_page.taro_page_show {
498
+ transform: translate(0, 0);
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
+ min-height: 100vh;
512
+ }
513
+
514
+ .taro-tabbar__container .taro_router {
515
+ min-height: calc(100vh - 50px);
516
+ }
517
+
518
+ .taro_page {
519
+ width: 100%;
520
+ height: 100%;
521
+ ${usingWindowScroll ? '' : `
522
+ overflow-x: hidden;
523
+ overflow-y: scroll;
524
+ max-height: 100vh;
525
+ `}
526
+ }
527
+
528
+ .taro-tabbar__container .taro-tabbar__panel {
529
+ overflow: hidden;
530
+ }
531
+
532
+ .taro-tabbar__container .taro_page.taro_tabbar_page {
533
+ max-height: calc(100vh - 50px);
534
+ }
535
+ `;
536
+ addStyle(css);
537
+ }
538
+ function addStyle(css) {
539
+ if (!css)
540
+ return;
541
+ const style = document.createElement('style');
542
+ style.innerHTML = css;
543
+ document.getElementsByTagName('head')[0].appendChild(style);
544
+ }
545
+
475
546
  // @ts-nocheck
476
547
  function initTabbar(config) {
477
548
  if (config.tabBar == null) {
@@ -532,6 +603,17 @@ class MultiPageHandler {
532
603
  return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
533
604
  }
534
605
  get search() { return location.search.substr(1); }
606
+ get usingWindowScroll() {
607
+ var _a;
608
+ let usingWindowScroll = true;
609
+ if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
610
+ usingWindowScroll = this.pageConfig.usingWindowScroll;
611
+ }
612
+ const win = window;
613
+ win.__taroAppConfig || (win.__taroAppConfig = {});
614
+ win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
615
+ return usingWindowScroll;
616
+ }
535
617
  getQuery(search = '', options = {}) {
536
618
  search = search ? `${search}&${this.search}` : this.search;
537
619
  const query = search
@@ -541,6 +623,7 @@ class MultiPageHandler {
541
623
  }
542
624
  mount() {
543
625
  setHistoryMode(this.routerMode, this.router.basename);
626
+ loadRouterStyle(this.usingWindowScroll);
544
627
  const appId = this.appId;
545
628
  let app = document.getElementById(appId);
546
629
  let isPosition = true;
@@ -577,7 +660,20 @@ class MultiPageHandler {
577
660
  const pageEl = this.getPageContainer(page);
578
661
  if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
579
662
  const el = pageEl.firstElementChild;
580
- (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el);
663
+ const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
664
+ if (componentOnReady) {
665
+ componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
666
+ requestAnimationFrame(() => {
667
+ var _a;
668
+ (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
669
+ pageEl['__isReady'] = true;
670
+ });
671
+ });
672
+ }
673
+ else {
674
+ (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
675
+ pageEl['__isReady'] = true;
676
+ }
581
677
  onLoad && (pageEl['__page'] = page);
582
678
  }
583
679
  }
@@ -587,11 +683,14 @@ class MultiPageHandler {
587
683
  return;
588
684
  (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
589
685
  var _a;
590
- const pageEl = this.getPageContainer(page);
591
- this.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
686
+ if (this.isTabBar) {
687
+ const pageEl = this.getPageContainer(page);
688
+ pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
689
+ }
592
690
  this.onReady(page, true);
593
691
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
594
- this.bindPageEvents(page, pageEl, pageConfig);
692
+ this.bindPageEvents(page, pageConfig);
693
+ this.triggerRouterChange();
595
694
  });
596
695
  }
597
696
  getPageContainer(page) {
@@ -605,17 +704,33 @@ class MultiPageHandler {
605
704
  ? document.querySelector(`.taro_page#${id}`)
606
705
  : document.querySelector('.taro_page') ||
607
706
  document.querySelector('.taro_router'));
608
- return el || window;
707
+ return el;
609
708
  }
610
- bindPageEvents(page, pageEl, config = {}) {
709
+ getScrollingElement(page) {
710
+ if (this.usingWindowScroll)
711
+ return window;
712
+ return this.getPageContainer(page) || window;
713
+ }
714
+ bindPageEvents(page, config = {}) {
611
715
  var _a;
612
- if (!pageEl) {
613
- pageEl = this.getPageContainer();
614
- }
716
+ const scrollEl = this.getScrollingElement(page);
615
717
  const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
616
- bindPageScroll(page, pageEl, distance);
718
+ bindPageScroll(page, scrollEl, distance);
617
719
  bindPageResize(page);
618
720
  }
721
+ triggerRouterChange() {
722
+ /**
723
+ * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
724
+ * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
725
+ */
726
+ setTimeout(() => {
727
+ runtime.eventCenter.trigger('__afterTaroRouterChange', {
728
+ toLocation: {
729
+ path: this.pathname
730
+ }
731
+ });
732
+ }, 0);
733
+ }
619
734
  }
620
735
 
621
736
  const createStampId$1 = runtime.incrementId();
@@ -631,6 +746,9 @@ const launchStampId$1 = createStampId$1();
631
746
  function createMultiRouter(app, config, framework) {
632
747
  var _a, _b, _c, _d, _e, _f;
633
748
  return __awaiter(this, void 0, void 0, function* () {
749
+ if (typeof app.onUnhandledRejection === 'function') {
750
+ window.addEventListener('unhandledrejection', app.onUnhandledRejection);
751
+ }
634
752
  RouterConfig.config = config;
635
753
  const handler = new MultiPageHandler(config);
636
754
  const launchParam = {
@@ -673,42 +791,12 @@ function createMultiRouter(app, config, framework) {
673
791
  const loadConfig = Object.assign({}, pageConfig);
674
792
  delete loadConfig['path'];
675
793
  delete loadConfig['load'];
676
- const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathName + runtime.stringify(launchParam), {}, loadConfig);
794
+ const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, pathName, framework, handler.PullDownRefresh) : el, pathName + runtime.stringify(launchParam), {}, loadConfig);
677
795
  handler.load(page, pageConfig);
678
796
  (_f = app.onShow) === null || _f === void 0 ? void 0 : _f.call(app, launchParam);
679
797
  });
680
798
  }
681
799
 
682
- /**
683
- * 插入页面动画需要的样式
684
- */
685
- function loadAnimateStyle(ms = 300) {
686
- const css = `
687
- .taro_router .taro_page {
688
- position: absolute;
689
- left: 0;
690
- top: 0;
691
- width: 100%;
692
- height: 100%;
693
- background-color: #fff;
694
- transform: translate(100%, 0);
695
- transition: transform ${ms}ms;
696
- z-index: 0;
697
- }
698
-
699
- .taro_router .taro_page.taro_tabbar_page,
700
- .taro_router .taro_page.taro_page_show.taro_page_stationed {
701
- transform: none;
702
- }
703
-
704
- .taro_router .taro_page.taro_page_show {
705
- transform: translate(0, 0);
706
- }`;
707
- const style = document.createElement('style');
708
- style.innerHTML = css;
709
- document.getElementsByTagName('head')[0].appendChild(style);
710
- }
711
-
712
800
  /* eslint-disable dot-notation */
713
801
  function setDisplay(el, type = '') {
714
802
  if (el) {
@@ -794,6 +882,17 @@ class PageHandler {
794
882
  }
795
883
  return search.substring(1);
796
884
  }
885
+ get usingWindowScroll() {
886
+ var _a;
887
+ let usingWindowScroll = false;
888
+ if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
889
+ usingWindowScroll = this.pageConfig.usingWindowScroll;
890
+ }
891
+ const win = window;
892
+ win.__taroAppConfig || (win.__taroAppConfig = {});
893
+ win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
894
+ return usingWindowScroll;
895
+ }
797
896
  getQuery(stamp = '', search = '', options = {}) {
798
897
  search = search ? `${search}&${this.search}` : this.search;
799
898
  const query = search
@@ -804,7 +903,9 @@ class PageHandler {
804
903
  }
805
904
  mount() {
806
905
  setHistoryMode(this.routerMode, this.router.basename);
906
+ this.pathname = exports.history.location.pathname;
807
907
  this.animation && loadAnimateStyle(this.animationDuration);
908
+ loadRouterStyle(this.usingWindowScroll);
808
909
  const appId = this.appId;
809
910
  let app = document.getElementById(appId);
810
911
  let isPosition = true;
@@ -871,7 +972,8 @@ class PageHandler {
871
972
  this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
872
973
  this.addAnimation(pageEl, pageNo === 0);
873
974
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
874
- this.bindPageEvents(page, pageEl, pageConfig);
975
+ this.bindPageEvents(page, pageConfig);
976
+ this.triggerRouterChange();
875
977
  }
876
978
  else {
877
979
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
@@ -881,7 +983,8 @@ class PageHandler {
881
983
  this.addAnimation(pageEl, pageNo === 0);
882
984
  this.onReady(page, true);
883
985
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
884
- this.bindPageEvents(page, pageEl, pageConfig);
986
+ this.bindPageEvents(page, pageConfig);
987
+ this.triggerRouterChange();
885
988
  });
886
989
  }
887
990
  }
@@ -901,10 +1004,14 @@ class PageHandler {
901
1004
  const pageEl = this.getPageContainer(page);
902
1005
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
903
1006
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1007
+ if (pageEl) {
1008
+ pageEl.style.zIndex = '1';
1009
+ }
904
1010
  this.unloadTimer = setTimeout(() => {
905
1011
  var _a, _b;
906
1012
  this.unloadTimer = null;
907
1013
  (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1014
+ runtime.eventCenter.trigger('__taroPageOnShowAfterDestroyed');
908
1015
  }, this.animationDuration);
909
1016
  }
910
1017
  else {
@@ -912,6 +1019,9 @@ class PageHandler {
912
1019
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
913
1020
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
914
1021
  (_c = page === null || page === void 0 ? void 0 : page.onUnload) === null || _c === void 0 ? void 0 : _c.call(page);
1022
+ setTimeout(() => {
1023
+ runtime.eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1024
+ }, 0);
915
1025
  }
916
1026
  if (delta >= 1)
917
1027
  this.unload(stacks.last, delta);
@@ -926,7 +1036,8 @@ class PageHandler {
926
1036
  setDisplay(pageEl);
927
1037
  this.addAnimation(pageEl, pageNo === 0);
928
1038
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
929
- this.bindPageEvents(page, pageEl, pageConfig);
1039
+ this.bindPageEvents(page, pageConfig);
1040
+ this.triggerRouterChange();
930
1041
  }
931
1042
  else {
932
1043
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
@@ -935,7 +1046,8 @@ class PageHandler {
935
1046
  this.addAnimation(pageEl, pageNo === 0);
936
1047
  this.onReady(page, false);
937
1048
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
938
- this.bindPageEvents(page, pageEl, pageConfig);
1049
+ this.bindPageEvents(page, pageConfig);
1050
+ this.triggerRouterChange();
939
1051
  });
940
1052
  }
941
1053
  }
@@ -989,23 +1101,42 @@ class PageHandler {
989
1101
  ? document.querySelector(`.taro_page#${id}`)
990
1102
  : document.querySelector('.taro_page') ||
991
1103
  document.querySelector('.taro_router'));
992
- return el || window;
1104
+ return el;
993
1105
  }
994
- bindPageEvents(page, pageEl, config = {}) {
1106
+ getScrollingElement(page) {
1107
+ if (this.usingWindowScroll)
1108
+ return window;
1109
+ return this.getPageContainer(page) || window;
1110
+ }
1111
+ bindPageEvents(page, config = {}) {
995
1112
  var _a;
996
- if (!pageEl) {
997
- pageEl = this.getPageContainer();
998
- }
1113
+ const scrollEl = this.getScrollingElement(page);
999
1114
  const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
1000
- bindPageScroll(page, pageEl, distance);
1115
+ bindPageScroll(page, scrollEl, distance);
1001
1116
  bindPageResize(page);
1002
1117
  }
1118
+ triggerRouterChange() {
1119
+ /**
1120
+ * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
1121
+ * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
1122
+ */
1123
+ setTimeout(() => {
1124
+ runtime.eventCenter.trigger('__afterTaroRouterChange', {
1125
+ toLocation: {
1126
+ path: this.pathname
1127
+ }
1128
+ });
1129
+ }, 0);
1130
+ }
1003
1131
  }
1004
1132
 
1005
1133
  const createStampId = runtime.incrementId();
1006
1134
  let launchStampId = createStampId();
1007
1135
  function createRouter(app, config, framework) {
1008
1136
  var _a, _b;
1137
+ if (typeof app.onUnhandledRejection === 'function') {
1138
+ window.addEventListener('unhandledrejection', app.onUnhandledRejection);
1139
+ }
1009
1140
  RouterConfig.config = config;
1010
1141
  const handler = new PageHandler(config);
1011
1142
  routesAlias.set(handler.router.customRoutes);
@@ -1030,8 +1161,10 @@ function createRouter(app, config, framework) {
1030
1161
  (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
1031
1162
  app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
1032
1163
  const render = ({ location, action }) => __awaiter(this, void 0, void 0, function* () {
1033
- var _c, _d, _e, _f, _g;
1164
+ var _c, _d, _e, _f, _g, _h;
1034
1165
  handler.pathname = decodeURI(location.pathname);
1166
+ if ((_c = window.__taroAppConfig) === null || _c === void 0 ? void 0 : _c.usingWindowScroll)
1167
+ window.scrollTo(0, 0);
1035
1168
  runtime.eventCenter.trigger('__taroRouterChange', {
1036
1169
  toLocation: {
1037
1170
  path: handler.pathname
@@ -1044,9 +1177,13 @@ function createRouter(app, config, framework) {
1044
1177
  }
1045
1178
  catch (error) {
1046
1179
  if (error.status === 404) {
1047
- (_c = app.onPageNotFound) === null || _c === void 0 ? void 0 : _c.call(app, {
1048
- path: handler.pathname
1049
- });
1180
+ const notFoundEvent = {
1181
+ isEntryPage: stacks.length === 0,
1182
+ path: handler.pathname,
1183
+ query: handler.getQuery(createStampId()),
1184
+ };
1185
+ (_d = app.onPageNotFound) === null || _d === void 0 ? void 0 : _d.call(app, notFoundEvent);
1186
+ runtime.eventCenter.trigger('__taroRouterNotFound', notFoundEvent);
1050
1187
  }
1051
1188
  else if (/Loading hot update .* failed./.test(error.message)) {
1052
1189
  // NOTE: webpack5 与 prebundle 搭配使用时,开发环境下初次启动时偶发错误,由于 HMR 加载 chunk hash 错误,导致热更新失败
@@ -1059,16 +1196,16 @@ function createRouter(app, config, framework) {
1059
1196
  if (!element)
1060
1197
  return;
1061
1198
  const pageConfig = handler.pageConfig;
1062
- let enablePullDownRefresh = ((_d = config === null || config === void 0 ? void 0 : config.window) === null || _d === void 0 ? void 0 : _d.enablePullDownRefresh) || false;
1199
+ let enablePullDownRefresh = ((_e = config === null || config === void 0 ? void 0 : config.window) === null || _e === void 0 ? void 0 : _e.enablePullDownRefresh) || false;
1063
1200
  if (pageConfig) {
1064
- setTitle((_e = pageConfig.navigationBarTitleText) !== null && _e !== void 0 ? _e : document.title);
1201
+ setTitle((_f = pageConfig.navigationBarTitleText) !== null && _f !== void 0 ? _f : document.title);
1065
1202
  if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
1066
1203
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1067
1204
  }
1068
1205
  }
1069
1206
  const currentPage = runtime.Current.page;
1070
1207
  const pathname = handler.pathname;
1071
- const methodName = (_f = stacks.method) !== null && _f !== void 0 ? _f : '';
1208
+ const methodName = (_g = stacks.method) !== null && _g !== void 0 ? _g : '';
1072
1209
  const cacheTabs = stacks.getTabs();
1073
1210
  let shouldLoad = false;
1074
1211
  stacks.method = '';
@@ -1093,11 +1230,11 @@ function createRouter(app, config, framework) {
1093
1230
  else if (stacks.length > 0) {
1094
1231
  const firstIns = stacks.getItem(0);
1095
1232
  if (handler.isTabBar(firstIns.path)) {
1096
- handler.unload(currentPage, stacks.length - 1);
1233
+ handler.unload(currentPage, stacks.length - 1, true);
1097
1234
  stacks.pushTab(firstIns.path.split('?')[0]);
1098
1235
  }
1099
1236
  else {
1100
- handler.unload(currentPage, stacks.length);
1237
+ handler.unload(currentPage, stacks.length, true);
1101
1238
  }
1102
1239
  }
1103
1240
  if (cacheTabs[handler.pathname]) {
@@ -1114,7 +1251,9 @@ function createRouter(app, config, framework) {
1114
1251
  if (currentPage !== stacks.getItem(prevIndex)) {
1115
1252
  handler.unload(currentPage, delta, prevIndex > -1);
1116
1253
  if (prevIndex > -1) {
1117
- handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1254
+ runtime.eventCenter.once('__taroPageOnShowAfterDestroyed', () => {
1255
+ handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1256
+ });
1118
1257
  }
1119
1258
  else {
1120
1259
  shouldLoad = true;
@@ -1132,7 +1271,7 @@ function createRouter(app, config, framework) {
1132
1271
  shouldLoad = true;
1133
1272
  }
1134
1273
  if (shouldLoad || stacks.length < 1) {
1135
- const el = (_g = element.default) !== null && _g !== void 0 ? _g : element;
1274
+ const el = (_h = element.default) !== null && _h !== void 0 ? _h : element;
1136
1275
  const loadConfig = Object.assign({}, pageConfig);
1137
1276
  const stacksIndex = stacks.length;
1138
1277
  delete loadConfig['path'];
@@ -1145,16 +1284,11 @@ function createRouter(app, config, framework) {
1145
1284
  else {
1146
1285
  pageStampId = createStampId();
1147
1286
  }
1148
- const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1287
+ const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, pathname, framework, handler.PullDownRefresh, pageStampId) : el, pathname + runtime.stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1149
1288
  if (params)
1150
1289
  page.options = params;
1151
1290
  handler.load(page, pageConfig, pageStampId, stacksIndex);
1152
1291
  }
1153
- runtime.eventCenter.trigger('__afterTaroRouterChange', {
1154
- toLocation: {
1155
- path: handler.pathname
1156
- }
1157
- });
1158
1292
  });
1159
1293
  const routePath = addLeadingSlash(stripBasename(exports.history.location.pathname, handler.basename));
1160
1294
  if (routePath === '/') {