@tarojs/router 4.0.0-canary.8 → 4.0.0

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.
Files changed (45) hide show
  1. package/LICENSE +17 -3
  2. package/README.md +1 -1
  3. package/dist/api.js +31 -22
  4. package/dist/events/resize.d.ts +1 -1
  5. package/dist/events/resize.js +15 -7
  6. package/dist/events/scroll.d.ts +1 -1
  7. package/dist/events/scroll.js +4 -1
  8. package/dist/history.d.ts +22 -1
  9. package/dist/history.js +20 -8
  10. package/dist/index.cjs.js +798 -339
  11. package/dist/index.d.ts +6 -1
  12. package/dist/index.esm.js +758 -311
  13. package/dist/index.js +52 -4
  14. package/dist/navigationBar.d.ts +2 -0
  15. package/dist/navigationBar.js +44 -0
  16. package/dist/router/index.js +7 -3
  17. package/dist/router/mpa.d.ts +2 -1
  18. package/dist/router/mpa.js +29 -19
  19. package/dist/router/multi-page.d.ts +5 -2
  20. package/dist/router/multi-page.js +27 -43
  21. package/dist/router/navigation-bar.d.ts +36 -0
  22. package/dist/router/navigation-bar.js +252 -0
  23. package/dist/router/page.d.ts +11 -4
  24. package/dist/router/page.js +63 -59
  25. package/dist/router/spa.d.ts +2 -1
  26. package/dist/router/spa.js +81 -43
  27. package/dist/router/stack.d.ts +1 -1
  28. package/dist/router/stack.js +2 -1
  29. package/dist/style.d.ts +6 -1
  30. package/dist/style.js +109 -6
  31. package/dist/tabbar.d.ts +2 -1
  32. package/dist/tabbar.js +4 -3
  33. package/dist/utils/index.d.ts +1 -8
  34. package/dist/utils/index.js +5 -20
  35. package/dist/utils/navigate.d.ts +9 -5
  36. package/dist/utils/navigate.js +24 -37
  37. package/package.json +28 -27
  38. package/types/api.d.ts +5 -0
  39. package/types/component.d.ts +5 -0
  40. package/types/router.d.ts +2 -0
  41. package/types/taro.d.ts +8 -0
  42. package/dist/index.cjs.d.ts +0 -22
  43. package/dist/index.cjs.js.map +0 -1
  44. package/dist/index.esm.d.ts +0 -22
  45. package/dist/index.esm.js.map +0 -1
package/dist/index.esm.js CHANGED
@@ -1,40 +1,255 @@
1
- import { createBrowserHistory, createHashHistory, Action, parsePath } from 'history';
2
- import { Current, eventCenter, incrementId, createPageConfig, hooks, stringify, requestAnimationFrame as requestAnimationFrame$1 } from '@tarojs/runtime';
3
- import MobileDetect from 'mobile-detect';
4
- import queryString from 'query-string';
5
1
  import { defineCustomElementTaroTabbar } from '@tarojs/components/dist/components';
6
2
  import { initTabBarApis } from '@tarojs/taro';
3
+ import { __awaiter } from 'tslib';
4
+ import { addLeadingSlash, eventCenter, Current, stripBasename, incrementId, createPageConfig, hooks, stringify, getHomePage, getCurrentPage, stripTrailing, requestAnimationFrame as requestAnimationFrame$1, safeExecute } from '@tarojs/runtime';
5
+ import { EventChannel } from '@tarojs/shared';
6
+ import { createBrowserHistory, createHashHistory, Action, parsePath } from 'history';
7
+ export { createBrowserHistory, createHashHistory } from 'history';
8
+ import queryString from 'query-string';
7
9
  import UniversalRouter from 'universal-router';
8
10
 
9
- /******************************************************************************
10
- Copyright (c) Microsoft Corporation.
11
-
12
- Permission to use, copy, modify, and/or distribute this software for any
13
- purpose with or without fee is hereby granted.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
- PERFORMANCE OF THIS SOFTWARE.
22
- ***************************************************************************** */
23
-
24
- function __awaiter(thisArg, _arguments, P, generator) {
25
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26
- return new (P || (P = Promise))(function (resolve, reject) {
27
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30
- step((generator = generator.apply(thisArg, _arguments || [])).next());
31
- });
32
- }
33
-
34
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
35
- var e = new Error(message);
36
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
37
- };
11
+ /**
12
+ * 插入页面动画需要的样式
13
+ */
14
+ function loadAnimateStyle(ms = 300) {
15
+ const css = `
16
+ body {
17
+ /* 防止 iOS 页面滚动 */
18
+ overflow: hidden;
19
+ }
20
+ .taro_router > .taro_page {
21
+ position: absolute;
22
+ left: 0;
23
+ top: 0;
24
+ width: 100%;
25
+ height: 100%;
26
+ background-color: #fff;
27
+ transform: translate(100%, 0);
28
+ transition: transform ${ms}ms;
29
+ z-index: 0;
30
+ }
31
+
32
+ .taro_router > .taro_page.taro_tabbar_page,
33
+ .taro_router > .taro_page.taro_page_show.taro_page_stationed {
34
+ transform: none;
35
+ transition: none;
36
+ }
37
+
38
+ .taro_router > .taro_page.taro_page_show {
39
+ transform: translate(0, 0);
40
+ }
41
+ `;
42
+ addStyle(css);
43
+ }
44
+ /**
45
+ * 插入路由相关样式
46
+ */
47
+ function loadRouterStyle(enableTabBar, enableWindowScroll, enhanceAnimation) {
48
+ const css = `
49
+ .taro_router {
50
+ position: relative;
51
+ width: 100%;
52
+ height: 100%;
53
+ }
54
+
55
+ .taro_page {
56
+ width: 100%;
57
+ height: 100%;
58
+ ${enableWindowScroll ? '' : `
59
+ overflow-x: hidden;
60
+ overflow-y: scroll;
61
+ max-height: 100vh;
62
+ `}
63
+ }
64
+ ${enableTabBar ? `
65
+ .taro-tabbar__container > .taro-tabbar__panel {
66
+ overflow: hidden;
67
+ }
68
+
69
+ .taro-tabbar__container > .taro-tabbar__panel > .taro_page.taro_tabbar_page {
70
+ max-height: calc(100vh - var(--taro-tabbar-height) - constant(safe-area-inset-bottom));
71
+ max-height: calc(100vh - var(--taro-tabbar-height) - env(safe-area-inset-bottom));
72
+ }
73
+
74
+ ` : ''}
75
+ ${enhanceAnimation
76
+ ? `.taro_page_shade:has(+.taro_page_stationed),
77
+ .taro_page_shade.taro_tabbar_page,
78
+ .taro_router > .taro_page.taro_page_show.taro_page_stationed:not(.taro_page_shade):not(.taro_tabbar_page):not(:last-child):has(+.taro_page_stationed) {
79
+ display: none;
80
+ }` : ` .taro_page_shade,
81
+ .taro_router > .taro_page.taro_page_show.taro_page_stationed:not(.taro_page_shade):not(.taro_tabbar_page):not(:last-child) {
82
+ display: none;
83
+ }`}
84
+ `;
85
+ addStyle(css);
86
+ }
87
+ /**
88
+ * 插入导航栏相关的样式
89
+ */
90
+ function loadNavigationBarStyle() {
91
+ const css = `
92
+ .taro-navigation-bar-show {
93
+ display: flex;
94
+ background: white;
95
+ position: sticky;
96
+ z-index: 500;
97
+ top: 0;
98
+ padding-bottom: 8px;
99
+ padding-top: calc(env(safe-area-inset-top) + 8px);
100
+ justify-content: center;
101
+ align-items: center;
102
+ }
103
+
104
+ .taro-navigation-bar-hide {
105
+ display: none;
106
+ }
107
+
108
+ .taro-navigation-bar-title-wrap {
109
+ display: flex;
110
+ height: 24px;
111
+ }
112
+
113
+ .taro-navigation-bar-title-wrap > .taro-navigation-bar-loading {
114
+ display: none;
115
+ animation: loading 2s linear infinite;
116
+ }
117
+
118
+ .taro-navigation-bar-title-wrap .taro-navigation-bar-loading.taro-navigation-bar-loading-show {
119
+ display: flex;
120
+ }
121
+
122
+ .taro-navigation-bar-title-wrap > .taro-navigation-bar-title {
123
+ font-size: 24px;
124
+ height: 24px;
125
+ line-height: 24px;
126
+ max-width: 100px;
127
+ white-space: nowrap;
128
+ overflow: hidden;
129
+ line-height: 24px;
130
+ text-overflow: ellipsis;
131
+ }
132
+
133
+ @keyframes loading {
134
+ from {
135
+ transform: rotate(0deg);
136
+ }
137
+ to {
138
+ transform: rotate(360deg);
139
+ }
140
+ }
141
+
142
+ @keyframes loading {
143
+ from {
144
+ transform: rotate(0deg);
145
+ }
146
+ to {
147
+ transform: rotate(360deg);
148
+ }
149
+ }
150
+
151
+ .taro-navigation-bar-no-icon > .taro-navigation-bar-home {
152
+ display: none;
153
+ }
154
+
155
+ .taro-navigation-bar-no-icon > .taro-navigation-bar-back {
156
+ display: none;
157
+ }
158
+
159
+ .taro-navigation-bar-home-icon > .taro-navigation-bar-home {
160
+ display: flex;
161
+ left: 8px;
162
+ position: absolute;
163
+ width: 24px;
164
+ height: 24px;
165
+ }
166
+
167
+ .taro-navigation-bar-back-icon > .taro-navigation-bar-back {
168
+ display: flex;
169
+ left: 8px;
170
+ position: absolute;
171
+ width: 24px;
172
+ height: 24px;
173
+ }
174
+ `;
175
+ addStyle(css);
176
+ }
177
+ function addStyle(css) {
178
+ if (!css)
179
+ return;
180
+ const style = document.createElement('style');
181
+ style.innerHTML = css;
182
+ document.getElementsByTagName('head')[0].appendChild(style);
183
+ }
184
+
185
+ const home_svg_str = `
186
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
187
+ <path d="M23.8899 12.2737C23.8232 12.3584 23.7237 12.3997 23.6198 12.3974H20.7994V23.5996C20.7994 23.8194 20.6213 24 20.4001 24H14.7994C14.5791 24 14.4002 23.8194 14.4002 23.5996V15.6H9.59963V23.5996C9.59963 23.8194 9.42075 24 9.20033 24H3.59968C3.48981 24 3.38964 23.954 3.31764 23.8811C3.24495 23.8091 3.2004 23.7087 3.2004 23.5996V12.3975H0.398546V12.3967C0.296893 12.396 0.194446 12.3544 0.11579 12.2738C-0.0371146 12.114 -0.0400714 11.864 0.11579 11.7076L11.7201 0.117284C11.8767 -0.0390948 12.1298 -0.0390948 12.2863 0.117284L23.8899 11.7076C24.0465 11.864 24.0265 12.0995 23.8899 12.2737ZM12.0029 0.964625L1.37086 11.5854L3.59968 11.5839V11.5999C3.65537 11.5999 3.70804 11.611 3.75557 11.6307C3.89952 11.692 4.00046 11.8339 4.00046 11.9996V23.1991H8.79955V15.2003C8.79955 14.9789 8.97917 14.8002 9.20033 14.8002H14.7995C15.0207 14.8002 15.2003 14.9789 15.2003 15.2003V23.1991H20.0001V11.9996C20.0001 11.8339 20.1003 11.692 20.2443 11.6307C20.2918 11.611 20.3453 11.5999 20.4001 11.5999V11.5713L22.6193 11.5691L12.0029 0.964625Z" fill="currentColor"/>
188
+ </svg>
189
+ `;
190
+ const back_svg_str = `
191
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
192
+ <path d="M17.8206 22.9016L7.45515 11.8756L17.8206 1.09845C18.0598 0.849741 18.0598 0.435233 17.8206 0.186528C17.5814 -0.0621762 17.1827 -0.0621762 16.9435 0.186528L6.1794 11.4611C5.9402 11.7098 5.9402 12.1244 6.1794 12.3731L16.9435 23.8135C17.1827 24.0622 17.5814 24.0622 17.8206 23.8135C18.0598 23.5648 18.0598 23.1503 17.8206 22.9016Z" fill="currentColor"/>
193
+ </svg>
194
+ `;
195
+ const loading_svg_str = `
196
+ <svg t="1709608074670" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4741" width="24" height="24"><path d="M256 529.066667H85.333333a17.066667 17.066667 0 1 1 0-34.133334h170.666667a17.066667 17.066667 0 0 1 0 34.133334z" opacity=".278" p-id="4742"></path><path d="M99.84 640a17.066667 17.066667 0 0 1-4.437333-33.553067l164.693333-44.373333a17.066667 17.066667 0 1 1 8.891733 32.9728l-164.693333 44.373333a17.544533 17.544533 0 0 1-4.4544 0.580267z" opacity=".322" p-id="4743"></path><path d="M264.533333 462.523733a16.896 16.896 0 0 1-4.369066-0.580266l-164.693334-43.52a17.0496 17.0496 0 1 1 8.721067-32.989867l164.693333 43.52a17.066667 17.066667 0 1 1-4.352 33.570133z" opacity=".239" p-id="4744"></path><path d="M384.017067 307.2a17.032533 17.032533 0 0 1-14.7968-8.533333l-85.333334-147.626667a17.066667 17.066667 0 0 1 29.559467-17.083733l85.333333 147.626666A17.066667 17.066667 0 0 1 384.017067 307.2z" opacity=".122" p-id="4745"></path><path d="M639.982933 307.2a17.0496 17.0496 0 0 1-14.762666-25.6l85.333333-147.626667a17.066667 17.066667 0 1 1 29.559467 17.066667l-85.333334 147.626667a17.032533 17.032533 0 0 1-14.7968 8.533333z" opacity=".922" p-id="4746"></path><path d="M692.906667 347.306667a17.066667 17.066667 0 0 1-12.117334-29.098667l120.337067-121.173333a17.066667 17.066667 0 1 1 24.234667 24.046933l-120.337067 121.173333a17.1008 17.1008 0 0 1-12.117333 5.051734z" opacity=".878" p-id="4747"></path><path d="M733.883733 401.066667a17.066667 17.066667 0 0 1-8.5504-31.8464l147.626667-85.333334a17.0496 17.0496 0 1 1 17.066667 29.5424l-147.626667 85.333334a16.776533 16.776533 0 0 1-8.516267 2.304z" opacity=".839" p-id="4748"></path><path d="M512 273.066667a17.066667 17.066667 0 0 1-17.066667-17.066667V85.333333a17.066667 17.066667 0 0 1 34.133334 0v170.666667a17.066667 17.066667 0 0 1-17.066667 17.066667z" p-id="4749"></path><path d="M578.577067 281.6a17.066667 17.066667 0 0 1-16.520534-21.418667l43.52-164.693333a17.066667 17.066667 0 0 1 33.006934 8.721067l-43.52 164.693333a17.066667 17.066667 0 0 1-16.4864 12.6976z" opacity=".961" p-id="4750"></path><path d="M445.44 282.453333a17.066667 17.066667 0 0 1-16.469333-12.629333l-44.373334-164.693333a17.066667 17.066667 0 0 1 32.955734-8.891734l44.373333 164.693334a17.066667 17.066667 0 0 1-16.4864 21.521066z" opacity=".078" p-id="4751"></path><path d="M924.177067 640c-1.4848 0-2.9696-0.187733-4.4544-0.580267l-164.693334-44.373333a17.066667 17.066667 0 0 1 8.874667-32.9728l164.693333 44.373333a17.066667 17.066667 0 0 1-4.420266 33.553067z" opacity=".722" p-id="4752"></path><path d="M881.476267 742.4a17.015467 17.015467 0 0 1-8.482134-2.269867l-148.48-85.333333a17.0496 17.0496 0 1 1 16.9984-29.5936l148.48 85.333333a17.0496 17.0496 0 0 1-8.516266 31.863467z" opacity=".678" p-id="4753"></path><path d="M813.226667 830.293333a17.015467 17.015467 0 0 1-12.066134-5.000533l-120.337066-120.337067a17.0496 17.0496 0 1 1 24.132266-24.132266l120.337067 120.337066a17.0496 17.0496 0 0 1-12.066133 29.1328z" opacity=".639" p-id="4754"></path><path d="M938.666667 529.066667H768a17.066667 17.066667 0 1 1 0-34.133334h170.666667a17.066667 17.066667 0 1 1 0 34.133334z" opacity=".761" p-id="4755"></path><path d="M401.066667 941.226667a17.066667 17.066667 0 0 1-16.4864-21.504l44.373333-164.693334a17.066667 17.066667 0 1 1 32.955733 8.874667l-44.373333 164.693333a17.066667 17.066667 0 0 1-16.469333 12.629334z" opacity=".478" p-id="4756"></path><path d="M298.6496 898.56a17.066667 17.066667 0 0 1-14.779733-25.565867l85.333333-148.48a17.083733 17.083733 0 0 1 29.5936 16.9984l-85.333333 148.48a17.032533 17.032533 0 0 1-14.813867 8.567467z" opacity=".439" p-id="4757"></path><path d="M512 955.733333a17.066667 17.066667 0 0 1-17.066667-17.066666V768a17.066667 17.066667 0 1 1 34.133334 0v170.666667a17.066667 17.066667 0 0 1-17.066667 17.066666z" opacity=".522" p-id="4758"></path><path d="M725.3504 898.56a17.032533 17.032533 0 0 1-14.7968-8.533333l-85.333333-147.626667a17.066667 17.066667 0 0 1 29.559466-17.066667l85.333334 147.626667a17.066667 17.066667 0 0 1-14.762667 25.6z" opacity=".6" p-id="4759"></path><path d="M622.062933 942.08c-7.509333 0-14.421333-5.0176-16.469333-12.629333l-44.3904-164.693334a17.066667 17.066667 0 1 1 32.9728-8.874666l44.3904 164.693333a17.066667 17.066667 0 0 1-16.503467 21.504z" opacity=".561" p-id="4760"></path><path d="M759.4496 463.36a17.083733 17.083733 0 0 1-4.420267-33.553067l164.693334-44.373333a17.066667 17.066667 0 0 1 8.874666 32.955733l-164.693333 44.373334a16.657067 16.657067 0 0 1-4.4544 0.597333z" opacity=".702" p-id="4761"></path><path d="M330.24 347.306667a17.015467 17.015467 0 0 1-12.066133-5.000534l-120.32-120.32a17.0496 17.0496 0 1 1 24.132266-24.132266l120.32 120.32a17.0496 17.0496 0 0 1-12.066133 29.1328z" opacity=".161" p-id="4762"></path><path d="M290.116267 401.066667a17.032533 17.032533 0 0 1-8.533334-2.286934l-147.626666-85.333333a17.066667 17.066667 0 1 1 17.083733-29.5424l147.626667 85.333333a17.066667 17.066667 0 0 1-8.5504 31.829334z" opacity=".2" p-id="4763"></path><path d="M142.523733 742.4a17.066667 17.066667 0 0 1-8.567466-31.8464l147.626666-85.333333a17.066667 17.066667 0 1 1 17.083734 29.559466l-147.626667 85.333334a16.930133 16.930133 0 0 1-8.516267 2.286933z" opacity=".361" p-id="4764"></path><path d="M209.92 830.293333a17.066667 17.066667 0 0 1-12.117333-29.098666l120.32-121.173334a17.066667 17.066667 0 0 1 24.2176 24.029867l-120.32 121.1904a16.896 16.896 0 0 1-12.100267 5.051733z" opacity=".4" p-id="4765"></path></svg>
197
+ `;
198
+ function initNavigationBar(config, container) {
199
+ if (config.router.mode === 'multi')
200
+ return;
201
+ const navigationBar = document.createElement('div');
202
+ navigationBar.classList.add('taro-navigation-bar-no-icon');
203
+ const navigationBarBackBtn = document.createElement('div');
204
+ navigationBarBackBtn.classList.add('taro-navigation-bar-back');
205
+ const navigationBarHomeBtn = document.createElement('div');
206
+ navigationBarHomeBtn.classList.add('taro-navigation-bar-home');
207
+ navigationBarBackBtn.innerHTML = back_svg_str;
208
+ navigationBarHomeBtn.innerHTML = home_svg_str;
209
+ const navigationBarTitleWrap = document.createElement('div');
210
+ navigationBarTitleWrap.classList.add('taro-navigation-bar-title-wrap');
211
+ const navigationBarLoading = document.createElement('div');
212
+ navigationBarLoading.classList.add('taro-navigation-bar-loading');
213
+ navigationBarLoading.innerHTML = loading_svg_str;
214
+ const navigationBarTitle = document.createElement('div');
215
+ navigationBarTitle.classList.add('taro-navigation-bar-title');
216
+ navigationBarTitleWrap.appendChild(navigationBarLoading);
217
+ navigationBarTitleWrap.appendChild(navigationBarTitle);
218
+ navigationBar.appendChild(navigationBarHomeBtn);
219
+ navigationBar.appendChild(navigationBarBackBtn);
220
+ navigationBar.appendChild(navigationBarTitleWrap);
221
+ navigationBar.id = 'taro-navigation-bar';
222
+ container.prepend(navigationBar);
223
+ loadNavigationBarStyle();
224
+ }
225
+
226
+ function initTabbar(config, history) {
227
+ if (config.tabBar == null || config.tabBar.custom) {
228
+ return;
229
+ }
230
+ // TODO: custom-tab-bar
231
+ defineCustomElementTaroTabbar();
232
+ const tabbar = document.createElement('taro-tabbar');
233
+ const homePage = config.entryPagePath || (config.pages ? config.pages[0] : '');
234
+ tabbar.conf = config.tabBar;
235
+ tabbar.conf.homePage = history.location.pathname === '/' ? homePage : history.location.pathname;
236
+ const routerConfig = config.router;
237
+ tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
238
+ if (routerConfig.customRoutes) {
239
+ tabbar.conf.custom = true;
240
+ tabbar.conf.customRoutes = routerConfig.customRoutes;
241
+ }
242
+ else {
243
+ tabbar.conf.custom = false;
244
+ tabbar.conf.customRoutes = {};
245
+ }
246
+ if (typeof routerConfig.basename !== 'undefined') {
247
+ tabbar.conf.basename = routerConfig.basename;
248
+ }
249
+ const container = document.getElementById('container');
250
+ container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
251
+ initTabBarApis(config);
252
+ }
38
253
 
39
254
  class RouterConfig {
40
255
  static set config(e) {
@@ -53,8 +268,9 @@ class RouterConfig {
53
268
  return this.router.mode || 'hash';
54
269
  }
55
270
  static get customRoutes() { return this.router.customRoutes || {}; }
271
+ // 这个方法不考虑 basename 和 customRoutes,只判断原始的 url 是否在 pages 中
56
272
  static isPage(url = '') {
57
- return this.pages.findIndex(e => prependBasename(e) === url) !== -1;
273
+ return this.pages.findIndex(e => addLeadingSlash(e) === url) !== -1;
58
274
  }
59
275
  }
60
276
 
@@ -81,14 +297,14 @@ class MpaHistory {
81
297
  }
82
298
  parseUrl(to) {
83
299
  let url = to.pathname || '';
84
- if (RouterConfig.isPage(url)) {
300
+ if (RouterConfig.isPage(addLeadingSlash(url))) {
85
301
  url += '.html';
86
302
  }
87
303
  if (to.search) {
88
304
  url += `?${to.search}`;
89
305
  }
90
306
  if (to.hash) {
91
- url += `#${to.hash}`;
307
+ url += to.hash.startsWith('#') ? to.hash : `#${to.hash}`;
92
308
  }
93
309
  return url;
94
310
  }
@@ -137,6 +353,13 @@ class MpaHistory {
137
353
  };
138
354
  }
139
355
  }
356
+ function setHistory(h, base = '/') {
357
+ history = h;
358
+ basename = base;
359
+ }
360
+ function createMpaHistory(_) {
361
+ return new MpaHistory();
362
+ }
140
363
  function setHistoryMode(mode, base = '/') {
141
364
  const options = {
142
365
  window
@@ -146,7 +369,7 @@ function setHistoryMode(mode, base = '/') {
146
369
  history = createBrowserHistory(options);
147
370
  }
148
371
  else if (mode === 'multi') {
149
- history = new MpaHistory();
372
+ history = createMpaHistory();
150
373
  }
151
374
  else {
152
375
  // default is hash
@@ -238,24 +461,34 @@ class Stacks {
238
461
  }
239
462
  const stacks = new Stacks();
240
463
 
241
- // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
242
- // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
243
- const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
244
- const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
245
- const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
246
- const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
247
- const getHomePage = (path = '', basename = '', customRoutes = {}, entryPagePath = '') => {
248
- var _a;
249
- const routePath = addLeadingSlash(stripBasename(path, basename));
250
- const alias = ((_a = Object.entries(customRoutes).find(([key]) => key === routePath)) === null || _a === void 0 ? void 0 : _a[1]) || routePath;
251
- return entryPagePath || (typeof alias === 'string' ? alias : alias[0]) || basename;
252
- };
253
- const getCurrentPage = (routerMode = 'hash', basename = '/') => {
254
- const pagePath = routerMode === 'hash'
255
- ? location.hash.slice(1).split('?')[0]
256
- : location.pathname;
257
- return addLeadingSlash(stripBasename(pagePath, basename));
258
- };
464
+ const isWeixin = () => !!navigator.userAgent.match(/\bMicroMessenger\b/ig);
465
+ const isDingTalk = () => !!navigator.userAgent.match(/\bDingTalk\b/ig);
466
+ let preTitle = document.title;
467
+ let isLoadDdEntry = false;
468
+ function setMpaTitle(title) {
469
+ if (preTitle === title)
470
+ return;
471
+ document.title = title;
472
+ preTitle = title;
473
+ if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
474
+ if (!isLoadDdEntry) {
475
+ isLoadDdEntry = true;
476
+ require('dingtalk-jsapi/platform');
477
+ }
478
+ const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
479
+ setDingTitle({ title });
480
+ }
481
+ }
482
+ function setTitle(title) {
483
+ eventCenter.trigger('__taroH5SetNavigationBarTitle', title);
484
+ }
485
+ function setNavigationBarStyle(option) {
486
+ eventCenter.trigger('__taroH5setNavigationBarColor', option);
487
+ }
488
+ function setNavigationBarLoading(loading) {
489
+ eventCenter.trigger('__taroH5setNavigationBarLoading', loading);
490
+ }
491
+
259
492
  class RoutesAlias {
260
493
  constructor() {
261
494
  this.conf = [];
@@ -297,6 +530,7 @@ class RoutesAlias {
297
530
  }
298
531
  const routesAlias = new RoutesAlias();
299
532
 
533
+ const routeEvtChannel = EventChannel.routeChannel;
300
534
  function processNavigateUrl(option) {
301
535
  var _a;
302
536
  const pathPieces = parsePath(option.url);
@@ -305,13 +539,14 @@ function processNavigateUrl(option) {
305
539
  const parts = routesAlias.getOrigin(history.location.pathname).split('/');
306
540
  parts.pop();
307
541
  pathPieces.pathname.split('/').forEach((item) => {
308
- if (item === '.') {
542
+ if (item === '.')
309
543
  return;
310
- }
311
544
  item === '..' ? parts.pop() : parts.push(item);
312
545
  });
313
546
  pathPieces.pathname = parts.join('/');
314
547
  }
548
+ // 确保是 / 开头的路径
549
+ pathPieces.pathname = addLeadingSlash(pathPieces.pathname);
315
550
  // 处理自定义路由
316
551
  pathPieces.pathname = routesAlias.getAlias(addLeadingSlash(pathPieces.pathname));
317
552
  // 处理 basename
@@ -328,6 +563,10 @@ function navigate(option, method) {
328
563
  const { success, complete, fail } = option;
329
564
  const unListen = history.listen(() => {
330
565
  const res = { errMsg: `${method}:ok` };
566
+ if (method === 'navigateTo') {
567
+ res.eventChannel = routeEvtChannel;
568
+ routeEvtChannel.addEvents(option.events);
569
+ }
331
570
  success === null || success === void 0 ? void 0 : success(res);
332
571
  complete === null || complete === void 0 ? void 0 : complete(res);
333
572
  resolve(res);
@@ -338,6 +577,7 @@ function navigate(option, method) {
338
577
  const pathPieces = processNavigateUrl(option);
339
578
  const state = { timestamp: Date.now() };
340
579
  if (method === 'navigateTo') {
580
+ // Note: 由于 spa 会针对弱网情况下,短时间内多次跳转同一个页面跳转加了锁,后续如果有用户反馈返回无效,那可能是这个问题
341
581
  history.push(pathPieces, state);
342
582
  }
343
583
  else if (method === 'redirectTo' || method === 'switchTab') {
@@ -362,7 +602,12 @@ function navigate(option, method) {
362
602
  const res = { errMsg: `${method}:fail ${error.message || error}` };
363
603
  fail === null || fail === void 0 ? void 0 : fail(res);
364
604
  complete === null || complete === void 0 ? void 0 : complete(res);
365
- reject(res);
605
+ if (fail || complete) {
606
+ return resolve(res);
607
+ }
608
+ else {
609
+ return reject(res);
610
+ }
366
611
  }
367
612
  });
368
613
  });
@@ -393,47 +638,22 @@ function getCurrentPages() {
393
638
  return pages.map(e => { var _a; return (Object.assign(Object.assign({}, e), { route: ((_a = e.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) || '' })); });
394
639
  }
395
640
 
396
- let md;
397
- let preTitle = document.title;
398
- let isLoadDdEntry = false;
399
- function getMobileDetect() {
400
- if (!md) {
401
- md = new MobileDetect(navigator.userAgent);
402
- }
403
- return md;
404
- }
405
- function setTitle(title) {
406
- return __awaiter(this, void 0, void 0, function* () {
407
- if (preTitle === title)
408
- return title;
409
- document.title = title;
410
- preTitle = title;
411
- if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
412
- if (!isLoadDdEntry) {
413
- isLoadDdEntry = true;
414
- require('dingtalk-jsapi/platform');
415
- }
416
- const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
417
- setDingTitle({ title });
418
- }
419
- return title;
420
- });
421
- }
422
- function isDingTalk() {
423
- const md = getMobileDetect();
424
- return md.match(/DingTalk/ig);
425
- }
426
-
427
641
  let pageResizeFn;
428
642
  function bindPageResize(page) {
429
643
  pageResizeFn && window.removeEventListener('resize', pageResizeFn);
430
644
  pageResizeFn = function () {
431
- page.onResize && page.onResize({
432
- size: {
433
- windowHeight: window.innerHeight,
434
- windowWidth: window.innerWidth
435
- }
436
- });
645
+ if (page.onResize) {
646
+ const mediaQuery = window.matchMedia('(orientation: portrait)');
647
+ page.onResize({
648
+ deviceOrientation: mediaQuery.matches ? 'portrait' : 'landscape',
649
+ size: {
650
+ windowHeight: window.innerHeight,
651
+ windowWidth: window.innerWidth,
652
+ screenHeight: window.screen.height,
653
+ screenWidth: window.screen.width,
654
+ }
655
+ });
656
+ }
437
657
  };
438
658
  window.addEventListener('resize', pageResizeFn, false);
439
659
  }
@@ -472,111 +692,10 @@ function getOffset() {
472
692
  }
473
693
  }
474
694
 
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
- `;
501
- addStyle(css);
502
- }
503
- /**
504
- * 插入路由相关样式
505
- */
506
- function loadRouterStyle(usingWindowScroll) {
507
- const css = `
508
- .taro_router {
509
- position: relative;
510
- width: 100%;
511
- height: 100%;
512
- }
513
-
514
- .taro_page {
515
- width: 100%;
516
- height: 100%;
517
- ${usingWindowScroll ? '' : `
518
- overflow-x: hidden;
519
- overflow-y: scroll;
520
- max-height: 100vh;
521
- `}
522
- }
523
-
524
- .taro-tabbar__container > .taro-tabbar__panel {
525
- overflow: hidden;
526
- }
527
-
528
- .taro-tabbar__container > .taro-tabbar__panel > .taro_page.taro_tabbar_page {
529
- max-height: calc(100vh - var(--taro-tabbar-height) - constant(safe-area-inset-bottom));
530
- max-height: calc(100vh - var(--taro-tabbar-height) - env(safe-area-inset-bottom));
531
- }
532
-
533
- .taro_page_shade,
534
- .taro_router > .taro_page.taro_page_show.taro_page_stationed:not(.taro_page_shade):not(.taro_tabbar_page):not(:last-child) {
535
- display: none;
536
- }
537
- `;
538
- addStyle(css);
539
- }
540
- function addStyle(css) {
541
- if (!css)
542
- return;
543
- const style = document.createElement('style');
544
- style.innerHTML = css;
545
- document.getElementsByTagName('head')[0].appendChild(style);
546
- }
547
-
548
- // @ts-nocheck
549
- function initTabbar(config) {
550
- if (config.tabBar == null || config.tabBar.custom) {
551
- return;
552
- }
553
- // TODO: custom-tab-bar
554
- defineCustomElementTaroTabbar();
555
- const tabbar = document.createElement('taro-tabbar');
556
- const homePage = config.entryPagePath || (config.pages ? config.pages[0] : '');
557
- tabbar.conf = config.tabBar;
558
- tabbar.conf.homePage = history.location.pathname === '/' ? homePage : history.location.pathname;
559
- const routerConfig = config.router;
560
- tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
561
- if (routerConfig.customRoutes) {
562
- tabbar.conf.custom = true;
563
- tabbar.conf.customRoutes = routerConfig.customRoutes;
564
- }
565
- else {
566
- tabbar.conf.custom = false;
567
- tabbar.conf.customRoutes = {};
568
- }
569
- if (typeof routerConfig.basename !== 'undefined') {
570
- tabbar.conf.basename = routerConfig.basename;
571
- }
572
- const container = document.getElementById('container');
573
- container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
574
- initTabBarApis(config);
575
- }
576
-
577
695
  /* eslint-disable dot-notation */
578
696
  class MultiPageHandler {
579
- constructor(config) {
697
+ constructor(config, history) {
698
+ this.history = history;
580
699
  this.config = config;
581
700
  this.mount();
582
701
  }
@@ -623,39 +742,18 @@ class MultiPageHandler {
623
742
  : {};
624
743
  return Object.assign(Object.assign({}, query), options);
625
744
  }
626
- mount() {
627
- setHistoryMode(this.routerMode, this.router.basename);
628
- loadRouterStyle(this.usingWindowScroll);
629
- const appId = this.appId;
630
- let app = document.getElementById(appId);
631
- let isPosition = true;
632
- if (!app) {
633
- app = document.createElement('div');
634
- app.id = appId;
635
- isPosition = false;
636
- }
637
- const appWrapper = (app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body;
638
- app.classList.add('taro_router');
639
- if (this.tabBarList.length > 1) {
640
- const container = document.createElement('div');
641
- container.classList.add('taro-tabbar__container');
642
- container.id = 'container';
643
- const panel = document.createElement('div');
644
- panel.classList.add('taro-tabbar__panel');
645
- panel.appendChild(app.cloneNode(true));
646
- container.appendChild(panel);
647
- if (!isPosition) {
648
- appWrapper.appendChild(container);
649
- }
650
- else {
651
- appWrapper.replaceChild(container, app);
652
- }
653
- initTabbar(this.config);
654
- }
655
- else {
656
- if (!isPosition)
657
- appWrapper.appendChild(app);
745
+ isDefaultNavigationStyle() {
746
+ var _a, _b;
747
+ let style = (_a = this.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
748
+ if (typeof ((_b = this.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
749
+ style = this.pageConfig.navigationStyle;
658
750
  }
751
+ return style !== 'custom';
752
+ }
753
+ mount() {
754
+ setHistory(this.history, this.basename);
755
+ // Note: 注入页面样式
756
+ loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll);
659
757
  }
660
758
  onReady(page, onLoad = true) {
661
759
  var _a;
@@ -685,10 +783,13 @@ class MultiPageHandler {
685
783
  return;
686
784
  (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
687
785
  var _a;
786
+ const pageEl = this.getPageContainer(page);
688
787
  if (this.isTabBar) {
689
- const pageEl = this.getPageContainer(page);
690
788
  pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
691
789
  }
790
+ if (this.isDefaultNavigationStyle()) {
791
+ pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page');
792
+ }
692
793
  this.onReady(page, true);
693
794
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
694
795
  this.bindPageEvents(page, pageConfig);
@@ -745,16 +846,17 @@ const launchStampId$1 = createStampId$1();
745
846
  * - TabBar 会多次加载
746
847
  * - 不支持路由动画
747
848
  */
748
- function createMultiRouter(app, config, framework) {
749
- var _a, _b, _c, _d, _e, _f;
849
+ function createMultiRouter(history, app, config, framework) {
750
850
  return __awaiter(this, void 0, void 0, function* () {
851
+ var _a, _b, _c, _d, _e, _f;
751
852
  if (typeof app.onUnhandledRejection === 'function') {
752
853
  window.addEventListener('unhandledrejection', app.onUnhandledRejection);
753
854
  }
855
+ eventCenter.on('__taroH5SetNavigationBarTitle', setMpaTitle);
754
856
  RouterConfig.config = config;
755
- const handler = new MultiPageHandler(config);
857
+ const handler = new MultiPageHandler(config, history);
756
858
  const launchParam = {
757
- path: config.pageName,
859
+ path: config.pageName, // 多页面模式没新开一个页面相当于重启,所以直接使用当前页面路径
758
860
  query: handler.getQuery(launchStampId$1),
759
861
  scene: 0,
760
862
  shareTicket: '',
@@ -784,7 +886,7 @@ function createMultiRouter(app, config, framework) {
784
886
  return;
785
887
  let enablePullDownRefresh = ((_c = config === null || config === void 0 ? void 0 : config.window) === null || _c === void 0 ? void 0 : _c.enablePullDownRefresh) || false;
786
888
  if (pageConfig) {
787
- setTitle((_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title);
889
+ setMpaTitle((_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title);
788
890
  if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
789
891
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
790
892
  }
@@ -796,16 +898,278 @@ function createMultiRouter(app, config, framework) {
796
898
  const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, pathName, framework, handler.PullDownRefresh) : el, pathName + stringify(launchParam), {}, loadConfig);
797
899
  handler.load(page, pageConfig);
798
900
  (_f = app.onShow) === null || _f === void 0 ? void 0 : _f.call(app, launchParam);
901
+ window.addEventListener('visibilitychange', () => {
902
+ var _a, _b, _c;
903
+ const currentPath = ((_a = Current.page) === null || _a === void 0 ? void 0 : _a.path) || '';
904
+ const path = currentPath.substring(0, currentPath.indexOf('?'));
905
+ const param = {};
906
+ // app的 onShow/onHide 生命周期的路径信息为当前页面的路径
907
+ Object.assign(param, launchParam, { path });
908
+ if (document.visibilityState === 'visible') {
909
+ (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, param);
910
+ }
911
+ else {
912
+ (_c = app.onHide) === null || _c === void 0 ? void 0 : _c.call(app, param);
913
+ }
914
+ });
799
915
  });
800
916
  }
801
917
 
918
+ class NavigationBarHandler {
919
+ constructor(pageContext) {
920
+ this.isLoadDdEntry = false;
921
+ this.cache = {};
922
+ this.pageContext = pageContext;
923
+ this.init();
924
+ eventCenter.on('__taroH5SetNavigationBarTitle', (title) => {
925
+ this.setTitle(title);
926
+ });
927
+ eventCenter.on('__taroH5setNavigationBarLoading', (loading) => {
928
+ this.setNavigationLoading(loading);
929
+ });
930
+ eventCenter.on('__taroH5setNavigationBarColor', ({ backgroundColor, frontColor }) => {
931
+ if (typeof backgroundColor === 'string')
932
+ this.setNavigationBarBackground(backgroundColor);
933
+ if (typeof frontColor === 'string')
934
+ this.setNavigationBarTextStyle(frontColor);
935
+ });
936
+ }
937
+ toHomeFn() {
938
+ reLaunch({ url: this.pageContext.originHomePage });
939
+ }
940
+ backFn() {
941
+ navigateBack();
942
+ }
943
+ get homeBtnElement() {
944
+ var _a;
945
+ if (!this.navigationBarElement)
946
+ return null;
947
+ return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-home')) === null || _a === void 0 ? void 0 : _a[0];
948
+ }
949
+ get backBtnElement() {
950
+ var _a;
951
+ if (!this.navigationBarElement)
952
+ return null;
953
+ return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-back')) === null || _a === void 0 ? void 0 : _a[0];
954
+ }
955
+ get titleElement() {
956
+ var _a;
957
+ if (!this.navigationBarElement)
958
+ return null;
959
+ return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-title')) === null || _a === void 0 ? void 0 : _a[0];
960
+ }
961
+ get loadingElement() {
962
+ if (!this.navigationBarElement)
963
+ return null;
964
+ return this.navigationBarElement.getElementsByClassName('taro-navigation-bar-loading')[0];
965
+ }
966
+ init() {
967
+ var _a, _b;
968
+ this.setNavigationBarElement();
969
+ if (!this.navigationBarElement)
970
+ return;
971
+ (_a = this.homeBtnElement) === null || _a === void 0 ? void 0 : _a.addEventListener('click', this.toHomeFn.bind(this));
972
+ (_b = this.backBtnElement) === null || _b === void 0 ? void 0 : _b.addEventListener('click', this.backFn.bind(this));
973
+ }
974
+ setNavigationBarElement() {
975
+ this.navigationBarElement = document.getElementById('taro-navigation-bar');
976
+ }
977
+ load() {
978
+ this.setCacheValue();
979
+ this.setTitle();
980
+ this.setNavigationBarVisible();
981
+ this.setFnBtnState();
982
+ this.setNavigationBarBackground();
983
+ this.setNavigationBarTextStyle();
984
+ this.setNavigationLoading();
985
+ }
986
+ setCacheValue() {
987
+ const currentPage = this.pageContext.originPathname;
988
+ if (typeof this.cache[currentPage] !== 'object') {
989
+ this.cache[currentPage] = {};
990
+ }
991
+ }
992
+ setFnBtnState() {
993
+ const currentRouter = this.pageContext.currentPage;
994
+ if (this.pageContext.isTabBar(currentRouter) || this.pageContext.homePage === currentRouter) {
995
+ this.fnBtnToggleToNone();
996
+ }
997
+ else if (stacks.length > 1) {
998
+ this.fnBtnToggleToBack();
999
+ }
1000
+ else {
1001
+ this.fnBtnToggleToHome();
1002
+ }
1003
+ }
1004
+ shiftLoadingState(show) {
1005
+ if (!this.loadingElement)
1006
+ return;
1007
+ if (show) {
1008
+ this.loadingElement.classList.add('taro-navigation-bar-loading-show');
1009
+ }
1010
+ else {
1011
+ this.loadingElement.classList.remove('taro-navigation-bar-loading-show');
1012
+ }
1013
+ }
1014
+ setNavigationLoading(show) {
1015
+ var _a;
1016
+ if (!this.navigationBarElement)
1017
+ return;
1018
+ const currentPage = this.pageContext.originPathname;
1019
+ let isShow;
1020
+ if (typeof show === 'boolean') {
1021
+ isShow = show;
1022
+ this.cache[currentPage] &&
1023
+ (this.cache[currentPage].loading = isShow);
1024
+ }
1025
+ else {
1026
+ const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.loading;
1027
+ if (typeof cacheValue === 'boolean') {
1028
+ isShow = cacheValue;
1029
+ }
1030
+ else {
1031
+ // 默认值为 false
1032
+ isShow = false;
1033
+ this.cache[currentPage] &&
1034
+ (this.cache[currentPage].loading = isShow);
1035
+ }
1036
+ }
1037
+ this.shiftLoadingState(isShow);
1038
+ }
1039
+ setNavigationBarBackground(backgroundColor) {
1040
+ var _a, _b, _c;
1041
+ if (!this.navigationBarElement)
1042
+ return;
1043
+ const currentPage = this.pageContext.originPathname;
1044
+ let color;
1045
+ if (typeof backgroundColor === 'string') {
1046
+ color = backgroundColor;
1047
+ this.cache[currentPage] &&
1048
+ (this.cache[currentPage].backgroundColor = color);
1049
+ }
1050
+ else {
1051
+ const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.backgroundColor;
1052
+ if (typeof cacheValue === 'string') {
1053
+ color = cacheValue;
1054
+ }
1055
+ else {
1056
+ color = ((_c = (_b = this.pageContext.config) === null || _b === void 0 ? void 0 : _b.window) === null || _c === void 0 ? void 0 : _c.navigationBarBackgroundColor) || '#000000';
1057
+ this.cache[currentPage] &&
1058
+ (this.cache[currentPage].backgroundColor = color);
1059
+ }
1060
+ }
1061
+ this.navigationBarElement.style.background = color;
1062
+ }
1063
+ setNavigationBarTextStyle(fontColor) {
1064
+ var _a, _b, _c;
1065
+ if (!this.navigationBarElement)
1066
+ return;
1067
+ const currentPage = this.pageContext.originPathname;
1068
+ let color;
1069
+ if (typeof fontColor === 'string') {
1070
+ color = fontColor;
1071
+ this.cache[currentPage] &&
1072
+ (this.cache[currentPage].fontColor = color);
1073
+ }
1074
+ else {
1075
+ const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.fontColor;
1076
+ if (typeof cacheValue === 'string') {
1077
+ color = cacheValue;
1078
+ }
1079
+ else {
1080
+ color = ((_c = (_b = this.pageContext.config) === null || _b === void 0 ? void 0 : _b.window) === null || _c === void 0 ? void 0 : _c.navigationBarTextStyle) || 'white';
1081
+ this.cache[currentPage] &&
1082
+ (this.cache[currentPage].fontColor = color);
1083
+ }
1084
+ }
1085
+ this.navigationBarElement.style.color = color;
1086
+ }
1087
+ setTitle(title) {
1088
+ var _a, _b, _c;
1089
+ const currentPage = this.pageContext.originPathname;
1090
+ let proceedTitle;
1091
+ if (typeof title === 'string') {
1092
+ proceedTitle = title;
1093
+ this.cache[currentPage] &&
1094
+ (this.cache[currentPage].title = proceedTitle);
1095
+ }
1096
+ else {
1097
+ const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.title;
1098
+ if (typeof cacheValue === 'string') {
1099
+ proceedTitle = cacheValue;
1100
+ }
1101
+ else {
1102
+ proceedTitle = (_c = (_b = this.pageContext.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationBarTitleText) !== null && _c !== void 0 ? _c : document.title;
1103
+ this.cache[currentPage] &&
1104
+ (this.cache[currentPage].title = proceedTitle);
1105
+ }
1106
+ }
1107
+ if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
1108
+ if (!this.isLoadDdEntry) {
1109
+ this.isLoadDdEntry = true;
1110
+ require('dingtalk-jsapi/platform');
1111
+ }
1112
+ const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
1113
+ setDingTitle({ proceedTitle });
1114
+ }
1115
+ document.title = proceedTitle;
1116
+ if (!this.titleElement)
1117
+ return;
1118
+ this.titleElement.innerHTML = proceedTitle;
1119
+ }
1120
+ fnBtnToggleToHome() {
1121
+ if (!this.navigationBarElement)
1122
+ return;
1123
+ this.navigationBarElement.classList.add('taro-navigation-bar-home-icon');
1124
+ this.navigationBarElement.classList.remove('taro-navigation-bar-back-icon');
1125
+ }
1126
+ fnBtnToggleToBack() {
1127
+ if (!this.navigationBarElement)
1128
+ return;
1129
+ this.navigationBarElement.classList.remove('taro-navigation-bar-home-icon');
1130
+ this.navigationBarElement.classList.add('taro-navigation-bar-back-icon');
1131
+ }
1132
+ fnBtnToggleToNone() {
1133
+ if (!this.navigationBarElement)
1134
+ return;
1135
+ this.navigationBarElement.classList.remove('taro-navigation-bar-home-icon');
1136
+ this.navigationBarElement.classList.remove('taro-navigation-bar-back-icon');
1137
+ }
1138
+ setNavigationBarVisible(show) {
1139
+ var _a, _b;
1140
+ if (!this.navigationBarElement)
1141
+ return;
1142
+ let shouldShow;
1143
+ if (typeof show === 'boolean') {
1144
+ shouldShow = show;
1145
+ }
1146
+ else {
1147
+ shouldShow = (_a = this.pageContext.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
1148
+ if (typeof ((_b = this.pageContext.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
1149
+ shouldShow = this.pageContext.pageConfig.navigationStyle;
1150
+ }
1151
+ }
1152
+ if (shouldShow === 'default') {
1153
+ this.navigationBarElement.classList.add('taro-navigation-bar-show');
1154
+ this.navigationBarElement.classList.remove('taro-navigation-bar-hide');
1155
+ }
1156
+ else {
1157
+ this.navigationBarElement.classList.add('taro-navigation-bar-hide');
1158
+ this.navigationBarElement.classList.remove('taro-navigation-bar-show');
1159
+ }
1160
+ }
1161
+ }
1162
+
802
1163
  /* eslint-disable dot-notation */
803
1164
  class PageHandler {
804
- constructor(config) {
1165
+ constructor(config, history) {
1166
+ this.history = history;
805
1167
  this.defaultAnimation = { duration: 300, delay: 50 };
806
1168
  this.config = config;
807
1169
  this.homePage = getHomePage(this.routes[0].path, this.basename, this.customRoutes, this.config.entryPagePath);
1170
+ this.originHomePage = this.config.entryPagePath || this.routes[0].path || this.basename;
808
1171
  this.mount();
1172
+ this.navigationBarHandler = new NavigationBarHandler(this);
809
1173
  }
810
1174
  get currentPage() {
811
1175
  const routePath = getCurrentPage(this.routerMode, this.basename);
@@ -837,14 +1201,14 @@ class PageHandler {
837
1201
  }
838
1202
  set pathname(p) { this.router.pathname = p; }
839
1203
  get pathname() { return this.router.pathname; }
1204
+ // Note: 把 pathname 转换为原始路径,主要是处理 customRoutes 和 basename
1205
+ get originPathname() { return routesAlias.getOrigin(addLeadingSlash(stripBasename(this.pathname, this.basename))); }
840
1206
  get basename() { return this.router.basename || ''; }
841
1207
  get pageConfig() {
842
- const routePath = addLeadingSlash(stripBasename(this.pathname, this.basename));
843
1208
  const homePage = addLeadingSlash(this.homePage);
844
1209
  return this.routes.find(r => {
845
- var _a;
846
1210
  const pagePath = addLeadingSlash(r.path);
847
- return [pagePath, homePage].includes(routePath) || ((_a = routesAlias.getConfig(pagePath)) === null || _a === void 0 ? void 0 : _a.includes(routePath));
1211
+ return [pagePath, homePage].includes(this.originPathname);
848
1212
  });
849
1213
  }
850
1214
  isTabBar(pathname) {
@@ -861,6 +1225,14 @@ class PageHandler {
861
1225
  })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
862
1226
  return !!pagePath && this.tabBarList.some(t => stripTrailing(t.pagePath) === pagePath);
863
1227
  }
1228
+ isDefaultNavigationStyle() {
1229
+ var _a, _b;
1230
+ let style = (_a = this.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
1231
+ if (typeof ((_b = this.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
1232
+ style = this.pageConfig.navigationStyle;
1233
+ }
1234
+ return style !== 'custom';
1235
+ }
864
1236
  isSamePage(page) {
865
1237
  const routePath = stripBasename(this.pathname, this.basename);
866
1238
  const pagePath = stripBasename(page === null || page === void 0 ? void 0 : page.path, this.basename);
@@ -899,40 +1271,11 @@ class PageHandler {
899
1271
  return Object.assign(Object.assign({}, query), options);
900
1272
  }
901
1273
  mount() {
902
- setHistoryMode(this.routerMode, this.router.basename);
1274
+ setHistory(this.history, this.basename);
903
1275
  this.pathname = history.location.pathname;
1276
+ // Note: 注入页面样式
904
1277
  this.animation && loadAnimateStyle(this.animationDuration);
905
- loadRouterStyle(this.usingWindowScroll);
906
- const appId = this.appId;
907
- let app = document.getElementById(appId);
908
- let isPosition = true;
909
- if (!app) {
910
- app = document.createElement('div');
911
- app.id = appId;
912
- isPosition = false;
913
- }
914
- const appWrapper = (app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body;
915
- app.classList.add('taro_router');
916
- if (this.tabBarList.length > 1) {
917
- const container = document.createElement('div');
918
- container.classList.add('taro-tabbar__container');
919
- container.id = 'container';
920
- const panel = document.createElement('div');
921
- panel.classList.add('taro-tabbar__panel');
922
- panel.appendChild(app.cloneNode(true));
923
- container.appendChild(panel);
924
- if (!isPosition) {
925
- appWrapper.appendChild(container);
926
- }
927
- else {
928
- appWrapper.replaceChild(container, app);
929
- }
930
- initTabbar(this.config);
931
- }
932
- else {
933
- if (!isPosition)
934
- appWrapper.appendChild(app);
935
- }
1278
+ loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll, this.router.enhanceAnimation);
936
1279
  }
937
1280
  onReady(page, onLoad = true) {
938
1281
  var _a;
@@ -967,19 +1310,24 @@ class PageHandler {
967
1310
  if (pageEl) {
968
1311
  pageEl.classList.remove('taro_page_shade');
969
1312
  this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
1313
+ this.isDefaultNavigationStyle() && pageEl.classList.add('taro_navigation_page');
970
1314
  this.addAnimation(pageEl, pageNo === 0);
971
1315
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1316
+ this.navigationBarHandler.load();
972
1317
  this.bindPageEvents(page, pageConfig);
973
1318
  this.triggerRouterChange();
974
1319
  }
975
1320
  else {
1321
+ // FIXME 在 iOS 端快速切换页面时,可能不会执行回调注入对应类名导致 TabBar 白屏
976
1322
  (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
977
1323
  var _a;
978
1324
  pageEl = this.getPageContainer(page);
979
1325
  this.isTabBar(this.pathname) && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
1326
+ this.isDefaultNavigationStyle() && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page'));
980
1327
  this.addAnimation(pageEl, pageNo === 0);
981
- this.onReady(page, true);
982
1328
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1329
+ this.navigationBarHandler.load();
1330
+ this.onReady(page, true);
983
1331
  this.bindPageEvents(page, pageConfig);
984
1332
  this.triggerRouterChange();
985
1333
  });
@@ -1033,6 +1381,7 @@ class PageHandler {
1033
1381
  pageEl.classList.remove('taro_page_shade');
1034
1382
  this.addAnimation(pageEl, pageNo === 0);
1035
1383
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1384
+ this.navigationBarHandler.load();
1036
1385
  this.bindPageEvents(page, pageConfig);
1037
1386
  this.triggerRouterChange();
1038
1387
  }
@@ -1041,31 +1390,44 @@ class PageHandler {
1041
1390
  var _a;
1042
1391
  pageEl = this.getPageContainer(page);
1043
1392
  this.addAnimation(pageEl, pageNo === 0);
1044
- this.onReady(page, false);
1045
1393
  (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1394
+ this.navigationBarHandler.load();
1395
+ this.onReady(page, false);
1046
1396
  this.bindPageEvents(page, pageConfig);
1047
1397
  this.triggerRouterChange();
1048
1398
  });
1049
1399
  }
1050
1400
  }
1051
- hide(page) {
1052
- var _a;
1401
+ hide(page, animation = false) {
1402
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1053
1403
  if (!page)
1054
1404
  return;
1055
1405
  // NOTE: 修复多页并发问题,此处可能因为路由跳转过快,执行时页面可能还没有创建成功
1056
1406
  const pageEl = this.getPageContainer(page);
1057
1407
  if (pageEl) {
1058
- if (this.hideTimer) {
1059
- clearTimeout(this.hideTimer);
1060
- this.hideTimer = null;
1061
- pageEl.classList.add('taro_page_shade');
1408
+ if (animation) {
1409
+ if (this.hideTimer) {
1410
+ clearTimeout(this.hideTimer);
1411
+ this.hideTimer = null;
1412
+ (_c = (_b = (_a = this.lastHidePage) === null || _a === void 0 ? void 0 : _a.classList) === null || _b === void 0 ? void 0 : _b.add) === null || _c === void 0 ? void 0 : _c.call(_b, 'taro_page_shade');
1413
+ }
1414
+ this.lastHidePage = pageEl;
1415
+ this.hideTimer = setTimeout(() => {
1416
+ this.hideTimer = null;
1417
+ pageEl.classList.add('taro_page_shade');
1418
+ }, this.animationDuration + this.animationDelay);
1419
+ (_d = page.onHide) === null || _d === void 0 ? void 0 : _d.call(page);
1062
1420
  }
1063
- this.lastHidePage = pageEl;
1064
- this.hideTimer = setTimeout(() => {
1065
- this.hideTimer = null;
1421
+ else {
1422
+ if (this.hideTimer) {
1423
+ clearTimeout(this.hideTimer);
1424
+ this.hideTimer = null;
1425
+ (_g = (_f = (_e = this.lastHidePage) === null || _e === void 0 ? void 0 : _e.classList) === null || _f === void 0 ? void 0 : _f.add) === null || _g === void 0 ? void 0 : _g.call(_f, 'taro_page_shade');
1426
+ }
1427
+ (_h = page.onHide) === null || _h === void 0 ? void 0 : _h.call(page);
1066
1428
  pageEl.classList.add('taro_page_shade');
1067
- }, this.animationDuration + this.animationDelay);
1068
- (_a = page.onHide) === null || _a === void 0 ? void 0 : _a.call(page);
1429
+ this.lastHidePage = pageEl;
1430
+ }
1069
1431
  }
1070
1432
  else {
1071
1433
  setTimeout(() => this.hide(page), 0);
@@ -1129,13 +1491,17 @@ class PageHandler {
1129
1491
 
1130
1492
  const createStampId = incrementId();
1131
1493
  let launchStampId = createStampId();
1132
- function createRouter(app, config, framework) {
1494
+ function createRouter(history, app, config, framework) {
1133
1495
  var _a, _b;
1134
1496
  if (typeof app.onUnhandledRejection === 'function') {
1135
1497
  window.addEventListener('unhandledrejection', app.onUnhandledRejection);
1136
1498
  }
1137
1499
  RouterConfig.config = config;
1138
- const handler = new PageHandler(config);
1500
+ const handler = new PageHandler(config, history);
1501
+ // Note: 弱网情况下,快速切换 tab,会造成同个页面实例被多次挂在到页面上,原因是资源请求是异步的,短时间内发起多个请求,
1502
+ // 会在资源加载完成后,同时走到挂载的逻辑,造成 pageStampId 更新不及时,两个 page 的Id 相同,后面很多操作是通过 getElementById 来进行的
1503
+ // 所以需要加一个锁来应对这个情况
1504
+ const pageLock = {};
1139
1505
  routesAlias.set(handler.router.customRoutes);
1140
1506
  const basename = handler.router.basename;
1141
1507
  const routes = handler.routes.map(route => {
@@ -1157,29 +1523,35 @@ function createRouter(app, config, framework) {
1157
1523
  eventCenter.trigger('__taroRouterLaunch', launchParam);
1158
1524
  (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
1159
1525
  app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
1160
- const render = ({ location, action }) => __awaiter(this, void 0, void 0, function* () {
1161
- var _c, _d, _e, _f, _g, _h;
1162
- handler.pathname = decodeURI(location.pathname);
1163
- if ((_c = window.__taroAppConfig) === null || _c === void 0 ? void 0 : _c.usingWindowScroll)
1526
+ const render = (_c) => __awaiter(this, [_c], void 0, function* ({ location, action }) {
1527
+ var _d, _e, _f, _g, _h, _j, _k, _l;
1528
+ // Note: 由于下面有异步加载操作 先不要在这里去设置 handler.pathname
1529
+ const currentPathname = decodeURI(location.pathname);
1530
+ if ((_d = window.__taroAppConfig) === null || _d === void 0 ? void 0 : _d.usingWindowScroll)
1164
1531
  window.scrollTo(0, 0);
1165
1532
  eventCenter.trigger('__taroRouterChange', {
1166
1533
  toLocation: {
1167
- path: handler.pathname
1534
+ path: currentPathname
1168
1535
  }
1169
1536
  });
1170
- let element, params;
1537
+ let element, context, params;
1538
+ const routerPath = handler.router.forcePath || currentPathname;
1539
+ pageLock[routerPath] = typeof pageLock[routerPath] === 'number' ? pageLock[routerPath] + 1 : 1;
1540
+ const currentLock = pageLock[routerPath];
1541
+ let postLock;
1171
1542
  try {
1172
- const result = yield router.resolve(handler.router.forcePath || handler.pathname);
1173
- [element, , params] = yield Promise.all(result);
1543
+ const result = yield router.resolve(routerPath);
1544
+ [element, context, params] = yield Promise.all(result);
1545
+ postLock = pageLock[routerPath];
1174
1546
  }
1175
1547
  catch (error) {
1176
1548
  if (error.status === 404) {
1177
1549
  const notFoundEvent = {
1178
1550
  isEntryPage: stacks.length === 0,
1179
- path: handler.pathname,
1551
+ path: currentPathname,
1180
1552
  query: handler.getQuery(createStampId()),
1181
1553
  };
1182
- (_d = app.onPageNotFound) === null || _d === void 0 ? void 0 : _d.call(app, notFoundEvent);
1554
+ (_e = app.onPageNotFound) === null || _e === void 0 ? void 0 : _e.call(app, notFoundEvent);
1183
1555
  eventCenter.trigger('__taroRouterNotFound', notFoundEvent);
1184
1556
  }
1185
1557
  else if (/Loading hot update .* failed./.test(error.message)) {
@@ -1187,22 +1559,36 @@ function createRouter(app, config, framework) {
1187
1559
  window.location.reload();
1188
1560
  }
1189
1561
  else {
1190
- throw new Error(error);
1562
+ throw error;
1191
1563
  }
1192
1564
  }
1193
- if (!element)
1565
+ if (!element || currentLock !== postLock)
1194
1566
  return;
1195
- const pageConfig = handler.pageConfig;
1196
- let enablePullDownRefresh = ((_e = config === null || config === void 0 ? void 0 : config.window) === null || _e === void 0 ? void 0 : _e.enablePullDownRefresh) || false;
1567
+ // Note: 异步结束后,在设置 handler.pathname
1568
+ // context.pathname universal-router 被处理过了,是发起资源请求的时候传入的 pathname,即 await router.resolve(routerPath) 这个 routerPath
1569
+ handler.pathname = context.pathname;
1570
+ const { pathname, pageConfig } = handler;
1571
+ let enablePullDownRefresh = ((_f = config === null || config === void 0 ? void 0 : config.window) === null || _f === void 0 ? void 0 : _f.enablePullDownRefresh) || false;
1572
+ let navigationStyle = ((_g = config === null || config === void 0 ? void 0 : config.window) === null || _g === void 0 ? void 0 : _g.navigationStyle) || 'default';
1573
+ let navigationBarTextStyle = ((_h = config === null || config === void 0 ? void 0 : config.window) === null || _h === void 0 ? void 0 : _h.navigationBarTextStyle) || 'white';
1574
+ let navigationBarBackgroundColor = ((_j = config === null || config === void 0 ? void 0 : config.window) === null || _j === void 0 ? void 0 : _j.navigationBarBackgroundColor) || '#000000';
1197
1575
  if (pageConfig) {
1198
- setTitle((_f = pageConfig.navigationBarTitleText) !== null && _f !== void 0 ? _f : document.title);
1199
1576
  if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
1200
1577
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1201
1578
  }
1579
+ if (typeof pageConfig.navigationStyle === 'string') {
1580
+ navigationStyle = pageConfig.navigationStyle;
1581
+ }
1582
+ if (typeof pageConfig.navigationBarTextStyle === 'string') {
1583
+ navigationBarTextStyle = pageConfig.navigationBarTextStyle;
1584
+ }
1585
+ if (typeof pageConfig.navigationBarBackgroundColor === 'string') {
1586
+ navigationBarBackgroundColor = pageConfig.navigationBarBackgroundColor;
1587
+ }
1202
1588
  }
1589
+ eventCenter.trigger('__taroSetNavigationStyle', navigationStyle, navigationBarTextStyle, navigationBarBackgroundColor);
1203
1590
  const currentPage = Current.page;
1204
- const pathname = handler.pathname;
1205
- const methodName = (_g = stacks.method) !== null && _g !== void 0 ? _g : '';
1591
+ const methodName = (_k = stacks.method) !== null && _k !== void 0 ? _k : '';
1206
1592
  const cacheTabs = stacks.getTabs();
1207
1593
  let shouldLoad = false;
1208
1594
  stacks.method = '';
@@ -1217,10 +1603,11 @@ function createRouter(app, config, framework) {
1217
1603
  }
1218
1604
  shouldLoad = true;
1219
1605
  }
1220
- else if (currentPage && handler.isTabBar(handler.pathname)) {
1606
+ else if (currentPage && handler.isTabBar(pathname)) {
1221
1607
  if (handler.isSamePage(currentPage))
1222
1608
  return;
1223
1609
  if (handler.isTabBar(currentPage.path)) {
1610
+ // NOTE: 从 tabBar 页面切换到 tabBar 页面
1224
1611
  handler.hide(currentPage);
1225
1612
  stacks.pushTab(currentPage.path.split('?')[0]);
1226
1613
  }
@@ -1234,8 +1621,8 @@ function createRouter(app, config, framework) {
1234
1621
  handler.unload(currentPage, stacks.length, true);
1235
1622
  }
1236
1623
  }
1237
- if (cacheTabs[handler.pathname]) {
1238
- stacks.popTab(handler.pathname);
1624
+ if (cacheTabs[pathname]) {
1625
+ stacks.popTab(pathname);
1239
1626
  return handler.show(stacks.getItem(0), pageConfig, 0);
1240
1627
  }
1241
1628
  shouldLoad = true;
@@ -1264,11 +1651,11 @@ function createRouter(app, config, framework) {
1264
1651
  shouldLoad = true;
1265
1652
  }
1266
1653
  else if (action === 'PUSH') {
1267
- handler.hide(currentPage);
1654
+ handler.hide(currentPage, true);
1268
1655
  shouldLoad = true;
1269
1656
  }
1270
1657
  if (shouldLoad || stacks.length < 1) {
1271
- const el = (_h = element.default) !== null && _h !== void 0 ? _h : element;
1658
+ const el = (_l = element.default) !== null && _l !== void 0 ? _l : element;
1272
1659
  const loadConfig = Object.assign({}, pageConfig);
1273
1660
  const stacksIndex = stacks.length;
1274
1661
  delete loadConfig['path'];
@@ -1293,8 +1680,68 @@ function createRouter(app, config, framework) {
1293
1680
  }
1294
1681
  render({ location: history.location, action: Action.Push });
1295
1682
  (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, launchParam);
1683
+ window.addEventListener('visibilitychange', () => {
1684
+ var _a, _b, _c, _d, _e, _f, _g;
1685
+ const currentPath = ((_a = Current.page) === null || _a === void 0 ? void 0 : _a.path) || '';
1686
+ const path = currentPath.substring(0, currentPath.indexOf('?'));
1687
+ const param = {};
1688
+ // app的 onShow/onHide 生命周期的路径信息为当前页面的路径
1689
+ Object.assign(param, launchParam, { path });
1690
+ if (document.visibilityState === 'visible') {
1691
+ (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, param);
1692
+ // 单页面app显示后一刻会触发当前 page.onShow 生命周期函数
1693
+ (_d = (_c = Current.page) === null || _c === void 0 ? void 0 : _c.onShow) === null || _d === void 0 ? void 0 : _d.call(_c);
1694
+ }
1695
+ else {
1696
+ // 单页面app隐藏前一刻会触发当前 page.onHide 生命周期函数
1697
+ if ((_e = Current.page) === null || _e === void 0 ? void 0 : _e.path) {
1698
+ safeExecute((_f = Current.page) === null || _f === void 0 ? void 0 : _f.path, 'onHide');
1699
+ }
1700
+ (_g = app.onHide) === null || _g === void 0 ? void 0 : _g.call(app, param);
1701
+ }
1702
+ });
1296
1703
  return history.listen(render);
1297
1704
  }
1298
1705
 
1299
- export { createMultiRouter, createRouter, getCurrentPages, history, navigateBack, navigateTo, reLaunch, redirectTo, switchTab };
1300
- //# sourceMappingURL=index.esm.js.map
1706
+ function handleAppMount(config, _, appId = config.appId || 'app') {
1707
+ let app = document.getElementById(appId);
1708
+ let isPosition = true;
1709
+ if (!app) {
1710
+ app = document.createElement('div');
1711
+ app.id = appId;
1712
+ isPosition = false;
1713
+ }
1714
+ const appWrapper = ((app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body);
1715
+ app.classList.add('taro_router');
1716
+ if (!isPosition)
1717
+ appWrapper.appendChild(app);
1718
+ initNavigationBar(config, appWrapper);
1719
+ }
1720
+ function handleAppMountWithTabbar(config, history, appId = config.appId || 'app') {
1721
+ let app = document.getElementById(appId);
1722
+ let isPosition = true;
1723
+ if (!app) {
1724
+ app = document.createElement('div');
1725
+ app.id = appId;
1726
+ isPosition = false;
1727
+ }
1728
+ const appWrapper = ((app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body);
1729
+ app.classList.add('taro_router');
1730
+ const container = document.createElement('div');
1731
+ container.classList.add('taro-tabbar__container');
1732
+ container.id = 'container';
1733
+ const panel = document.createElement('div');
1734
+ panel.classList.add('taro-tabbar__panel');
1735
+ panel.appendChild(app.cloneNode(true));
1736
+ container.appendChild(panel);
1737
+ if (!isPosition) {
1738
+ appWrapper.appendChild(container);
1739
+ }
1740
+ else {
1741
+ appWrapper.replaceChild(container, app);
1742
+ }
1743
+ initTabbar(config, history);
1744
+ initNavigationBar(config, container);
1745
+ }
1746
+
1747
+ export { createMpaHistory, createMultiRouter, createRouter, getCurrentPages, handleAppMount, handleAppMountWithTabbar, history, isDingTalk, isWeixin, navigateBack, navigateTo, prependBasename, reLaunch, redirectTo, routesAlias, setHistory, setHistoryMode, setMpaTitle, setNavigationBarLoading, setNavigationBarStyle, setTitle, switchTab };