UNPKG

78.3 kBJavaScriptView Raw
1'use strict';
2
3var components = require('@tarojs/components/dist/components');
4var taro = require('@tarojs/taro');
5var tslib = require('tslib');
6var runtime = require('@tarojs/runtime');
7var shared = require('@tarojs/shared');
8var history = require('history');
9var queryString = require('query-string');
10var UniversalRouter = require('universal-router');
11
12/**
13 * 插入页面动画需要的样式
14 */
15function loadAnimateStyle(ms = 300) {
16 const css = `
17body {
18 /* 防止 iOS 页面滚动 */
19 overflow: hidden;
20}
21.taro_router > .taro_page {
22 position: absolute;
23 left: 0;
24 top: 0;
25 width: 100%;
26 height: 100%;
27 background-color: #fff;
28 transform: translate(100%, 0);
29 transition: transform ${ms}ms;
30 z-index: 0;
31}
32
33.taro_router > .taro_page.taro_tabbar_page,
34.taro_router > .taro_page.taro_page_show.taro_page_stationed {
35 transform: none;
36 transition: none;
37}
38
39.taro_router > .taro_page.taro_page_show {
40 transform: translate(0, 0);
41}
42`;
43 addStyle(css);
44}
45/**
46 * 插入路由相关样式
47 */
48function loadRouterStyle(enableTabBar, enableWindowScroll, enhanceAnimation) {
49 const css = `
50 .taro_router {
51 position: relative;
52 width: 100%;
53 height: 100%;
54 }
55
56 .taro_page {
57 width: 100%;
58 height: 100%;
59${enableWindowScroll ? '' : `
60 overflow-x: hidden;
61 overflow-y: scroll;
62 max-height: 100vh;
63`}
64 }
65${enableTabBar ? `
66 .taro-tabbar__container > .taro-tabbar__panel {
67 overflow: hidden;
68 }
69
70 .taro-tabbar__container > .taro-tabbar__panel > .taro_page.taro_tabbar_page {
71 max-height: calc(100vh - var(--taro-tabbar-height) - constant(safe-area-inset-bottom));
72 max-height: calc(100vh - var(--taro-tabbar-height) - env(safe-area-inset-bottom));
73 }
74
75` : ''}
76${enhanceAnimation
77 ? `.taro_page_shade:has(+.taro_page_stationed),
78 .taro_page_shade.taro_tabbar_page,
79 .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) {
80 display: none;
81 }` : ` .taro_page_shade,
82 .taro_router > .taro_page.taro_page_show.taro_page_stationed:not(.taro_page_shade):not(.taro_tabbar_page):not(:last-child) {
83 display: none;
84 }`}
85`;
86 addStyle(css);
87}
88/**
89 * 插入导航栏相关的样式
90*/
91function loadNavigationBarStyle() {
92 const css = `
93 .taro-navigation-bar-show {
94 display: flex;
95 background: white;
96 position: sticky;
97 z-index: 500;
98 top: 0;
99 padding-bottom: 8px;
100 padding-top: calc(env(safe-area-inset-top) + 8px);
101 justify-content: center;
102 align-items: center;
103 }
104
105 .taro-navigation-bar-hide {
106 display: none;
107 }
108
109 .taro-navigation-bar-title-wrap {
110 display: flex;
111 height: 24px;
112 }
113
114 .taro-navigation-bar-title-wrap > .taro-navigation-bar-loading {
115 display: none;
116 animation: loading 2s linear infinite;
117 }
118
119 .taro-navigation-bar-title-wrap .taro-navigation-bar-loading.taro-navigation-bar-loading-show {
120 display: flex;
121 }
122
123 .taro-navigation-bar-title-wrap > .taro-navigation-bar-title {
124 font-size: 24px;
125 height: 24px;
126 line-height: 24px;
127 max-width: 100px;
128 white-space: nowrap;
129 overflow: hidden;
130 line-height: 24px;
131 text-overflow: ellipsis;
132 }
133
134 @keyframes loading {
135 from {
136 transform: rotate(0deg);
137 }
138 to {
139 transform: rotate(360deg);
140 }
141 }
142
143 @keyframes loading {
144 from {
145 transform: rotate(0deg);
146 }
147 to {
148 transform: rotate(360deg);
149 }
150 }
151
152 .taro-navigation-bar-no-icon > .taro-navigation-bar-home {
153 display: none;
154 }
155
156 .taro-navigation-bar-no-icon > .taro-navigation-bar-back {
157 display: none;
158 }
159
160 .taro-navigation-bar-home-icon > .taro-navigation-bar-home {
161 display: flex;
162 left: 8px;
163 position: absolute;
164 width: 24px;
165 height: 24px;
166 }
167
168 .taro-navigation-bar-back-icon > .taro-navigation-bar-back {
169 display: flex;
170 left: 8px;
171 position: absolute;
172 width: 24px;
173 height: 24px;
174 }
175`;
176 addStyle(css);
177}
178function addStyle(css) {
179 if (!css)
180 return;
181 const style = document.createElement('style');
182 style.innerHTML = css;
183 document.getElementsByTagName('head')[0].appendChild(style);
184}
185
186const home_svg_str = `
187<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
188 <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"/>
189</svg>
190`;
191const back_svg_str = `
192<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
193 <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"/>
194</svg>
195`;
196const loading_svg_str = `
197<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>
198`;
199function initNavigationBar(config, container) {
200 if (config.router.mode === 'multi')
201 return;
202 const navigationBar = document.createElement('div');
203 navigationBar.classList.add('taro-navigation-bar-no-icon');
204 const navigationBarBackBtn = document.createElement('div');
205 navigationBarBackBtn.classList.add('taro-navigation-bar-back');
206 const navigationBarHomeBtn = document.createElement('div');
207 navigationBarHomeBtn.classList.add('taro-navigation-bar-home');
208 navigationBarBackBtn.innerHTML = back_svg_str;
209 navigationBarHomeBtn.innerHTML = home_svg_str;
210 const navigationBarTitleWrap = document.createElement('div');
211 navigationBarTitleWrap.classList.add('taro-navigation-bar-title-wrap');
212 const navigationBarLoading = document.createElement('div');
213 navigationBarLoading.classList.add('taro-navigation-bar-loading');
214 navigationBarLoading.innerHTML = loading_svg_str;
215 const navigationBarTitle = document.createElement('div');
216 navigationBarTitle.classList.add('taro-navigation-bar-title');
217 navigationBarTitleWrap.appendChild(navigationBarLoading);
218 navigationBarTitleWrap.appendChild(navigationBarTitle);
219 navigationBar.appendChild(navigationBarHomeBtn);
220 navigationBar.appendChild(navigationBarBackBtn);
221 navigationBar.appendChild(navigationBarTitleWrap);
222 navigationBar.id = 'taro-navigation-bar';
223 container.prepend(navigationBar);
224 loadNavigationBarStyle();
225}
226
227function initTabbar(config, history) {
228 if (config.tabBar == null || config.tabBar.custom) {
229 return;
230 }
231 // TODO: custom-tab-bar
232 components.defineCustomElementTaroTabbar();
233 const tabbar = document.createElement('taro-tabbar');
234 const homePage = config.entryPagePath || (config.pages ? config.pages[0] : '');
235 tabbar.conf = config.tabBar;
236 tabbar.conf.homePage = history.location.pathname === '/' ? homePage : history.location.pathname;
237 const routerConfig = config.router;
238 tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
239 if (routerConfig.customRoutes) {
240 tabbar.conf.custom = true;
241 tabbar.conf.customRoutes = routerConfig.customRoutes;
242 }
243 else {
244 tabbar.conf.custom = false;
245 tabbar.conf.customRoutes = {};
246 }
247 if (typeof routerConfig.basename !== 'undefined') {
248 tabbar.conf.basename = routerConfig.basename;
249 }
250 const container = document.getElementById('container');
251 container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
252 taro.initTabBarApis(config);
253}
254
255class RouterConfig {
256 static set config(e) {
257 this.__config = e;
258 }
259 static get config() {
260 return this.__config;
261 }
262 static get pages() {
263 return this.config.pages || [];
264 }
265 static get router() {
266 return this.config.router || {};
267 }
268 static get mode() {
269 return this.router.mode || 'hash';
270 }
271 static get customRoutes() { return this.router.customRoutes || {}; }
272 // 这个方法不考虑 basename 和 customRoutes,只判断原始的 url 是否在 pages 中
273 static isPage(url = '') {
274 return this.pages.findIndex(e => runtime.addLeadingSlash(e) === url) !== -1;
275 }
276}
277
278exports.history = void 0;
279let basename = '/';
280class MpaHistory {
281 constructor() {
282 this.back = window.history.back;
283 this.forward = window.history.forward;
284 this.pushState = this.eventState('pushState');
285 this.replaceState = this.eventState('replaceState');
286 }
287 get location() {
288 return {
289 pathname: window.location.pathname,
290 search: window.location.search,
291 hash: window.location.hash,
292 key: `${window.history.length}`,
293 state: window.history.state
294 };
295 }
296 createHref(_to) {
297 throw new Error('Method not implemented.');
298 }
299 parseUrl(to) {
300 let url = to.pathname || '';
301 if (RouterConfig.isPage(runtime.addLeadingSlash(url))) {
302 url += '.html';
303 }
304 if (to.search) {
305 url += `?${to.search}`;
306 }
307 if (to.hash) {
308 url += to.hash.startsWith('#') ? to.hash : `#${to.hash}`;
309 }
310 return url;
311 }
312 push(to, _state = {}) {
313 window.location.assign(this.parseUrl(to));
314 // this.pushState(_state, '', this.parseUrl(to))
315 }
316 replace(to, _state = {}) {
317 window.location.replace(this.parseUrl(to));
318 // this.replaceState(_state, '', this.parseUrl(to))
319 }
320 go(delta) {
321 window.history.go(delta);
322 }
323 listen(listener) {
324 function callback(e) {
325 if (e.action === 'pushState') {
326 listener({ action: history.Action.Push, location: this.location });
327 }
328 else if (e.action === 'replaceState') {
329 listener({ action: history.Action.Replace, location: this.location });
330 }
331 else {
332 // NOTE: 这里包括 back、forward、go 三种可能,并非是 POP 事件
333 listener({ action: history.Action.Pop, location: this.location });
334 }
335 }
336 window.addEventListener('popstate', callback);
337 return () => {
338 window.removeEventListener('popstate', callback);
339 };
340 }
341 block(_blocker) {
342 throw new Error('Method not implemented.');
343 }
344 eventState(action) {
345 return (data, unused, url) => {
346 const wrapper = window.history[action](data, unused, url);
347 const evt = new Event(action);
348 evt.action = action;
349 evt.state = data;
350 evt.unused = unused;
351 evt.url = url;
352 window.dispatchEvent(evt);
353 return wrapper;
354 };
355 }
356}
357function setHistory(h, base = '/') {
358 exports.history = h;
359 basename = base;
360}
361function createMpaHistory(_) {
362 return new MpaHistory();
363}
364function setHistoryMode(mode, base = '/') {
365 const options = {
366 window
367 };
368 basename = base;
369 if (mode === 'browser') {
370 exports.history = history.createBrowserHistory(options);
371 }
372 else if (mode === 'multi') {
373 exports.history = createMpaHistory();
374 }
375 else {
376 // default is hash
377 exports.history = history.createHashHistory(options);
378 }
379}
380function prependBasename(url = '') {
381 return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
382}
383
384class Stacks {
385 constructor() {
386 this.stacks = [];
387 this.backDelta = 0;
388 this.tabs = {};
389 this.methodName = '';
390 }
391 set delta(delta) {
392 if (delta > 0) {
393 this.backDelta = delta;
394 }
395 else if (this.backDelta > 0) {
396 --this.backDelta;
397 }
398 else {
399 this.backDelta = 0;
400 }
401 }
402 get delta() {
403 return this.backDelta;
404 }
405 set method(methodName) {
406 this.methodName = methodName;
407 }
408 get method() {
409 return this.methodName;
410 }
411 get length() {
412 return this.stacks.length;
413 }
414 get last() {
415 return this.stacks[this.length - 1];
416 }
417 get() {
418 return this.stacks;
419 }
420 getItem(index) {
421 return this.stacks[index];
422 }
423 getLastIndex(pathname, stateWith = 1) {
424 const list = [...this.stacks].reverse();
425 return list.findIndex((page, i) => { var _a; return i >= stateWith && ((_a = page.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname; });
426 }
427 getDelta(pathname) {
428 if (this.backDelta >= 1) {
429 return this.backDelta;
430 }
431 const index = this.getLastIndex(pathname);
432 // NOTE: 此处为了修复浏览器后退多级页面,在大量重复路由状况下可能出现判断错误的情况 (增强判断能力只能考虑在 query 中新增参数来判断,暂时搁置)
433 return index > 0 ? index : 1;
434 }
435 getPrevIndex(pathname, stateWith = 1) {
436 const lastIndex = this.getLastIndex(pathname, stateWith);
437 if (lastIndex < 0) {
438 return -1;
439 }
440 return this.length - 1 - lastIndex;
441 }
442 pop() {
443 return this.stacks.pop();
444 }
445 push(page) {
446 return this.stacks.push(page);
447 }
448 getTabs() {
449 return this.tabs;
450 }
451 pushTab(path) {
452 this.tabs[path] = this.last;
453 this.pop();
454 }
455 popTab(path) {
456 this.push(this.tabs[path]);
457 delete this.tabs[path];
458 }
459 removeTab(path) {
460 delete this.tabs[path];
461 }
462}
463const stacks = new Stacks();
464
465const isWeixin = () => !!navigator.userAgent.match(/\bMicroMessenger\b/ig);
466const isDingTalk = () => !!navigator.userAgent.match(/\bDingTalk\b/ig);
467let preTitle = document.title;
468let isLoadDdEntry = false;
469function setMpaTitle(title) {
470 if (preTitle === title)
471 return;
472 document.title = title;
473 preTitle = title;
474 if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
475 if (!isLoadDdEntry) {
476 isLoadDdEntry = true;
477 require('dingtalk-jsapi/platform');
478 }
479 const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
480 setDingTitle({ title });
481 }
482}
483function setTitle(title) {
484 runtime.eventCenter.trigger('__taroH5SetNavigationBarTitle', title);
485}
486function setNavigationBarStyle(option) {
487 runtime.eventCenter.trigger('__taroH5setNavigationBarColor', option);
488}
489function setNavigationBarLoading(loading) {
490 runtime.eventCenter.trigger('__taroH5setNavigationBarLoading', loading);
491}
492
493class RoutesAlias {
494 constructor() {
495 this.conf = [];
496 this.getConfig = (url = '') => {
497 const customRoute = this.conf.filter((arr) => {
498 return arr.includes(url);
499 });
500 return customRoute[0];
501 };
502 this.getOrigin = (url = '') => {
503 var _a;
504 return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
505 };
506 this.getAlias = (url = '') => {
507 var _a;
508 return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
509 };
510 this.getAll = (url = '') => {
511 return this.conf
512 .filter((arr) => arr.includes(url))
513 .reduceRight((p, a) => {
514 p.unshift(a[1]);
515 return p;
516 }, []);
517 };
518 }
519 set(customRoutes = {}) {
520 for (let key in customRoutes) {
521 const path = customRoutes[key];
522 key = runtime.addLeadingSlash(key);
523 if (typeof path === 'string') {
524 this.conf.push([key, runtime.addLeadingSlash(path)]);
525 }
526 else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
527 this.conf.push(...path.map(p => [key, runtime.addLeadingSlash(p)]));
528 }
529 }
530 }
531}
532const routesAlias = new RoutesAlias();
533
534const routeEvtChannel = shared.EventChannel.routeChannel;
535function processNavigateUrl(option) {
536 var _a;
537 const pathPieces = history.parsePath(option.url);
538 // 处理相对路径
539 if ((_a = pathPieces.pathname) === null || _a === void 0 ? void 0 : _a.includes('./')) {
540 const parts = routesAlias.getOrigin(exports.history.location.pathname).split('/');
541 parts.pop();
542 pathPieces.pathname.split('/').forEach((item) => {
543 if (item === '.')
544 return;
545 item === '..' ? parts.pop() : parts.push(item);
546 });
547 pathPieces.pathname = parts.join('/');
548 }
549 // 确保是 / 开头的路径
550 pathPieces.pathname = runtime.addLeadingSlash(pathPieces.pathname);
551 // 处理自定义路由
552 pathPieces.pathname = routesAlias.getAlias(runtime.addLeadingSlash(pathPieces.pathname));
553 // 处理 basename
554 pathPieces.pathname = prependBasename(pathPieces.pathname);
555 // hack fix history v5 bug: https://github.com/remix-run/history/issues/814
556 if (!pathPieces.search)
557 pathPieces.search = '';
558 return pathPieces;
559}
560function navigate(option, method) {
561 return tslib.__awaiter(this, void 0, void 0, function* () {
562 return new Promise((resolve, reject) => {
563 stacks.method = method;
564 const { success, complete, fail } = option;
565 const unListen = exports.history.listen(() => {
566 const res = { errMsg: `${method}:ok` };
567 if (method === 'navigateTo') {
568 res.eventChannel = routeEvtChannel;
569 routeEvtChannel.addEvents(option.events);
570 }
571 success === null || success === void 0 ? void 0 : success(res);
572 complete === null || complete === void 0 ? void 0 : complete(res);
573 resolve(res);
574 unListen();
575 });
576 try {
577 if ('url' in option) {
578 const pathPieces = processNavigateUrl(option);
579 const state = { timestamp: Date.now() };
580 if (method === 'navigateTo') {
581 // Note: 由于 spa 会针对弱网情况下,短时间内多次跳转同一个页面跳转加了锁,后续如果有用户反馈返回无效,那可能是这个问题
582 exports.history.push(pathPieces, state);
583 }
584 else if (method === 'redirectTo' || method === 'switchTab') {
585 exports.history.replace(pathPieces, state);
586 }
587 else if (method === 'reLaunch') {
588 stacks.delta = stacks.length;
589 exports.history.replace(pathPieces, state);
590 }
591 }
592 else if (method === 'navigateBack') {
593 stacks.delta = option.delta;
594 if (stacks.length > option.delta) {
595 exports.history.go(-option.delta);
596 }
597 else {
598 exports.history.go(1 - stacks.length);
599 }
600 }
601 }
602 catch (error) {
603 const res = { errMsg: `${method}:fail ${error.message || error}` };
604 fail === null || fail === void 0 ? void 0 : fail(res);
605 complete === null || complete === void 0 ? void 0 : complete(res);
606 if (fail || complete) {
607 return resolve(res);
608 }
609 else {
610 return reject(res);
611 }
612 }
613 });
614 });
615}
616function navigateTo(option) {
617 return navigate(option, 'navigateTo');
618}
619function redirectTo(option) {
620 return navigate(option, 'redirectTo');
621}
622function navigateBack(option = { delta: 1 }) {
623 if (!option.delta || option.delta < 1) {
624 option.delta = 1;
625 }
626 return navigate(option, 'navigateBack');
627}
628function switchTab(option) {
629 return navigate(option, 'switchTab');
630}
631function reLaunch(option) {
632 return navigate(option, 'reLaunch');
633}
634function getCurrentPages() {
635 if (process.env.NODE_ENV !== 'production' && RouterConfig.mode === 'multi') {
636 console.warn('多页面路由模式不支持使用 getCurrentPages 方法!');
637 }
638 const pages = stacks.get();
639 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, '')) || '' })); });
640}
641
642let pageResizeFn;
643function bindPageResize(page) {
644 pageResizeFn && window.removeEventListener('resize', pageResizeFn);
645 pageResizeFn = function () {
646 if (page.onResize) {
647 const mediaQuery = window.matchMedia('(orientation: portrait)');
648 page.onResize({
649 deviceOrientation: mediaQuery.matches ? 'portrait' : 'landscape',
650 size: {
651 windowHeight: window.innerHeight,
652 windowWidth: window.innerWidth,
653 screenHeight: window.screen.height,
654 screenWidth: window.screen.width,
655 }
656 });
657 }
658 };
659 window.addEventListener('resize', pageResizeFn, false);
660}
661
662const pageScrollFn = {};
663let pageDOM = window;
664function bindPageScroll(page, scrollEl, distance = 50) {
665 var _a;
666 const pagePath = (page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.router) === null || _a === void 0 ? void 0 : _a.path);
667 pageScrollFn[pagePath] && scrollEl.removeEventListener('scroll', pageScrollFn[pagePath]);
668 pageDOM = scrollEl;
669 let isReachBottom = false;
670 pageScrollFn[pagePath] = function () {
671 var _a;
672 (_a = page.onPageScroll) === null || _a === void 0 ? void 0 : _a.call(page, {
673 scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
674 });
675 if (isReachBottom && getOffset() > distance) {
676 isReachBottom = false;
677 }
678 if (page.onReachBottom &&
679 !isReachBottom &&
680 getOffset() < distance) {
681 isReachBottom = true;
682 page.onReachBottom();
683 }
684 };
685 pageDOM.addEventListener('scroll', pageScrollFn[pagePath], false);
686}
687function getOffset() {
688 if (pageDOM instanceof Window) {
689 return document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
690 }
691 else {
692 return pageDOM.scrollHeight - pageDOM.scrollTop - pageDOM.clientHeight;
693 }
694}
695
696/* eslint-disable dot-notation */
697class MultiPageHandler {
698 constructor(config, history) {
699 this.history = history;
700 this.config = config;
701 this.mount();
702 }
703 get appId() { return this.config.appId || 'app'; }
704 get router() { return this.config.router || {}; }
705 get routerMode() { return this.router.mode || 'hash'; }
706 get customRoutes() { return this.router.customRoutes || {}; }
707 get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
708 get PullDownRefresh() { return this.config.PullDownRefresh; }
709 set pathname(p) { this.router.pathname = p; }
710 get pathname() { return this.router.pathname; }
711 get basename() { return this.router.basename || ''; }
712 get pageConfig() { return this.config.route; }
713 get isTabBar() {
714 var _a;
715 const routePath = runtime.addLeadingSlash(runtime.stripBasename(this.pathname, this.basename));
716 const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
717 if (typeof target === 'string') {
718 return target === routePath;
719 }
720 else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
721 return target.includes(routePath);
722 }
723 return false;
724 })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
725 return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
726 }
727 get search() { return location.search.substr(1); }
728 get usingWindowScroll() {
729 var _a;
730 let usingWindowScroll = true;
731 if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
732 usingWindowScroll = this.pageConfig.usingWindowScroll;
733 }
734 const win = window;
735 win.__taroAppConfig || (win.__taroAppConfig = {});
736 win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
737 return usingWindowScroll;
738 }
739 getQuery(search = '', options = {}) {
740 search = search ? `${search}&${this.search}` : this.search;
741 const query = search
742 ? queryString.parse(search)
743 : {};
744 return Object.assign(Object.assign({}, query), options);
745 }
746 isDefaultNavigationStyle() {
747 var _a, _b;
748 let style = (_a = this.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
749 if (typeof ((_b = this.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
750 style = this.pageConfig.navigationStyle;
751 }
752 return style !== 'custom';
753 }
754 mount() {
755 setHistory(this.history, this.basename);
756 // Note: 注入页面样式
757 loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll);
758 }
759 onReady(page, onLoad = true) {
760 var _a;
761 const pageEl = this.getPageContainer(page);
762 if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
763 const el = pageEl.firstElementChild;
764 const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
765 if (componentOnReady) {
766 componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
767 requestAnimationFrame(() => {
768 var _a;
769 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
770 pageEl['__isReady'] = true;
771 });
772 });
773 }
774 else {
775 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
776 pageEl['__isReady'] = true;
777 }
778 onLoad && (pageEl['__page'] = page);
779 }
780 }
781 load(page, pageConfig = {}) {
782 var _a;
783 if (!page)
784 return;
785 (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
786 var _a;
787 const pageEl = this.getPageContainer(page);
788 if (this.isTabBar) {
789 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
790 }
791 if (this.isDefaultNavigationStyle()) {
792 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page');
793 }
794 this.onReady(page, true);
795 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
796 this.bindPageEvents(page, pageConfig);
797 this.triggerRouterChange();
798 });
799 }
800 getPageContainer(page) {
801 var _a;
802 const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path;
803 const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
804 if (page) {
805 return document.querySelector(`.taro_page#${id}`);
806 }
807 const el = (id
808 ? document.querySelector(`.taro_page#${id}`)
809 : document.querySelector('.taro_page') ||
810 document.querySelector('.taro_router'));
811 return el;
812 }
813 getScrollingElement(page) {
814 if (this.usingWindowScroll)
815 return window;
816 return this.getPageContainer(page) || window;
817 }
818 bindPageEvents(page, config = {}) {
819 var _a;
820 const scrollEl = this.getScrollingElement(page);
821 const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
822 bindPageScroll(page, scrollEl, distance);
823 bindPageResize(page);
824 }
825 triggerRouterChange() {
826 /**
827 * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
828 * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
829 */
830 setTimeout(() => {
831 runtime.eventCenter.trigger('__afterTaroRouterChange', {
832 toLocation: {
833 path: this.pathname
834 }
835 });
836 }, 0);
837 }
838}
839
840const createStampId$1 = runtime.incrementId();
841const launchStampId$1 = createStampId$1();
842// TODO 支持多路由 (APP 生命周期仅触发一次)
843/** Note: 关于多页面应用
844 * - 需要配置路由映射(根目录跳转、404 页面……)
845 * - app.onPageNotFound 事件不支持
846 * - 应用生命周期可能多次触发
847 * - TabBar 会多次加载
848 * - 不支持路由动画
849 */
850function createMultiRouter(history, app, config, framework) {
851 return tslib.__awaiter(this, void 0, void 0, function* () {
852 var _a, _b, _c, _d, _e, _f;
853 if (typeof app.onUnhandledRejection === 'function') {
854 window.addEventListener('unhandledrejection', app.onUnhandledRejection);
855 }
856 runtime.eventCenter.on('__taroH5SetNavigationBarTitle', setMpaTitle);
857 RouterConfig.config = config;
858 const handler = new MultiPageHandler(config, history);
859 const launchParam = {
860 path: config.pageName, // 多页面模式没新开一个页面相当于重启,所以直接使用当前页面路径
861 query: handler.getQuery(launchStampId$1),
862 scene: 0,
863 shareTicket: '',
864 referrerInfo: {}
865 };
866 runtime.eventCenter.trigger('__taroRouterLaunch', launchParam);
867 (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
868 app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
869 const pathName = config.pageName;
870 const pageConfig = handler.pageConfig;
871 runtime.eventCenter.trigger('__taroRouterChange', {
872 toLocation: {
873 path: pathName
874 }
875 });
876 let element;
877 try {
878 element = yield ((_b = pageConfig.load) === null || _b === void 0 ? void 0 : _b.call(pageConfig));
879 if (element instanceof Array) {
880 element = element[0];
881 }
882 }
883 catch (error) {
884 throw new Error(error);
885 }
886 if (!element)
887 return;
888 let enablePullDownRefresh = ((_c = config === null || config === void 0 ? void 0 : config.window) === null || _c === void 0 ? void 0 : _c.enablePullDownRefresh) || false;
889 if (pageConfig) {
890 setMpaTitle((_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title);
891 if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
892 enablePullDownRefresh = pageConfig.enablePullDownRefresh;
893 }
894 }
895 const el = (_e = element.default) !== null && _e !== void 0 ? _e : element;
896 const loadConfig = Object.assign({}, pageConfig);
897 delete loadConfig['path'];
898 delete loadConfig['load'];
899 const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, pathName, framework, handler.PullDownRefresh) : el, pathName + runtime.stringify(launchParam), {}, loadConfig);
900 handler.load(page, pageConfig);
901 (_f = app.onShow) === null || _f === void 0 ? void 0 : _f.call(app, launchParam);
902 window.addEventListener('visibilitychange', () => {
903 var _a, _b, _c;
904 const currentPath = ((_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path) || '';
905 const path = currentPath.substring(0, currentPath.indexOf('?'));
906 const param = {};
907 // app的 onShow/onHide 生命周期的路径信息为当前页面的路径
908 Object.assign(param, launchParam, { path });
909 if (document.visibilityState === 'visible') {
910 (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, param);
911 }
912 else {
913 (_c = app.onHide) === null || _c === void 0 ? void 0 : _c.call(app, param);
914 }
915 });
916 });
917}
918
919class NavigationBarHandler {
920 constructor(pageContext) {
921 this.isLoadDdEntry = false;
922 this.cache = {};
923 this.pageContext = pageContext;
924 this.init();
925 runtime.eventCenter.on('__taroH5SetNavigationBarTitle', (title) => {
926 this.setTitle(title);
927 });
928 runtime.eventCenter.on('__taroH5setNavigationBarLoading', (loading) => {
929 this.setNavigationLoading(loading);
930 });
931 runtime.eventCenter.on('__taroH5setNavigationBarColor', ({ backgroundColor, frontColor }) => {
932 if (typeof backgroundColor === 'string')
933 this.setNavigationBarBackground(backgroundColor);
934 if (typeof frontColor === 'string')
935 this.setNavigationBarTextStyle(frontColor);
936 });
937 }
938 toHomeFn() {
939 reLaunch({ url: this.pageContext.originHomePage });
940 }
941 backFn() {
942 navigateBack();
943 }
944 get homeBtnElement() {
945 var _a;
946 if (!this.navigationBarElement)
947 return null;
948 return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-home')) === null || _a === void 0 ? void 0 : _a[0];
949 }
950 get backBtnElement() {
951 var _a;
952 if (!this.navigationBarElement)
953 return null;
954 return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-back')) === null || _a === void 0 ? void 0 : _a[0];
955 }
956 get titleElement() {
957 var _a;
958 if (!this.navigationBarElement)
959 return null;
960 return (_a = this.navigationBarElement.getElementsByClassName('taro-navigation-bar-title')) === null || _a === void 0 ? void 0 : _a[0];
961 }
962 get loadingElement() {
963 if (!this.navigationBarElement)
964 return null;
965 return this.navigationBarElement.getElementsByClassName('taro-navigation-bar-loading')[0];
966 }
967 init() {
968 var _a, _b;
969 this.setNavigationBarElement();
970 if (!this.navigationBarElement)
971 return;
972 (_a = this.homeBtnElement) === null || _a === void 0 ? void 0 : _a.addEventListener('click', this.toHomeFn.bind(this));
973 (_b = this.backBtnElement) === null || _b === void 0 ? void 0 : _b.addEventListener('click', this.backFn.bind(this));
974 }
975 setNavigationBarElement() {
976 this.navigationBarElement = document.getElementById('taro-navigation-bar');
977 }
978 load() {
979 this.setCacheValue();
980 this.setTitle();
981 this.setNavigationBarVisible();
982 this.setFnBtnState();
983 this.setNavigationBarBackground();
984 this.setNavigationBarTextStyle();
985 this.setNavigationLoading();
986 }
987 setCacheValue() {
988 const currentPage = this.pageContext.originPathname;
989 if (typeof this.cache[currentPage] !== 'object') {
990 this.cache[currentPage] = {};
991 }
992 }
993 setFnBtnState() {
994 const currentRouter = this.pageContext.currentPage;
995 if (this.pageContext.isTabBar(currentRouter) || this.pageContext.homePage === currentRouter) {
996 this.fnBtnToggleToNone();
997 }
998 else if (stacks.length > 1) {
999 this.fnBtnToggleToBack();
1000 }
1001 else {
1002 this.fnBtnToggleToHome();
1003 }
1004 }
1005 shiftLoadingState(show) {
1006 if (!this.loadingElement)
1007 return;
1008 if (show) {
1009 this.loadingElement.classList.add('taro-navigation-bar-loading-show');
1010 }
1011 else {
1012 this.loadingElement.classList.remove('taro-navigation-bar-loading-show');
1013 }
1014 }
1015 setNavigationLoading(show) {
1016 var _a;
1017 if (!this.navigationBarElement)
1018 return;
1019 const currentPage = this.pageContext.originPathname;
1020 let isShow;
1021 if (typeof show === 'boolean') {
1022 isShow = show;
1023 this.cache[currentPage] &&
1024 (this.cache[currentPage].loading = isShow);
1025 }
1026 else {
1027 const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.loading;
1028 if (typeof cacheValue === 'boolean') {
1029 isShow = cacheValue;
1030 }
1031 else {
1032 // 默认值为 false
1033 isShow = false;
1034 this.cache[currentPage] &&
1035 (this.cache[currentPage].loading = isShow);
1036 }
1037 }
1038 this.shiftLoadingState(isShow);
1039 }
1040 setNavigationBarBackground(backgroundColor) {
1041 var _a, _b, _c;
1042 if (!this.navigationBarElement)
1043 return;
1044 const currentPage = this.pageContext.originPathname;
1045 let color;
1046 if (typeof backgroundColor === 'string') {
1047 color = backgroundColor;
1048 this.cache[currentPage] &&
1049 (this.cache[currentPage].backgroundColor = color);
1050 }
1051 else {
1052 const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.backgroundColor;
1053 if (typeof cacheValue === 'string') {
1054 color = cacheValue;
1055 }
1056 else {
1057 color = ((_c = (_b = this.pageContext.config) === null || _b === void 0 ? void 0 : _b.window) === null || _c === void 0 ? void 0 : _c.navigationBarBackgroundColor) || '#000000';
1058 this.cache[currentPage] &&
1059 (this.cache[currentPage].backgroundColor = color);
1060 }
1061 }
1062 this.navigationBarElement.style.background = color;
1063 }
1064 setNavigationBarTextStyle(fontColor) {
1065 var _a, _b, _c;
1066 if (!this.navigationBarElement)
1067 return;
1068 const currentPage = this.pageContext.originPathname;
1069 let color;
1070 if (typeof fontColor === 'string') {
1071 color = fontColor;
1072 this.cache[currentPage] &&
1073 (this.cache[currentPage].fontColor = color);
1074 }
1075 else {
1076 const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.fontColor;
1077 if (typeof cacheValue === 'string') {
1078 color = cacheValue;
1079 }
1080 else {
1081 color = ((_c = (_b = this.pageContext.config) === null || _b === void 0 ? void 0 : _b.window) === null || _c === void 0 ? void 0 : _c.navigationBarTextStyle) || 'white';
1082 this.cache[currentPage] &&
1083 (this.cache[currentPage].fontColor = color);
1084 }
1085 }
1086 this.navigationBarElement.style.color = color;
1087 }
1088 setTitle(title) {
1089 var _a, _b, _c;
1090 const currentPage = this.pageContext.originPathname;
1091 let proceedTitle;
1092 if (typeof title === 'string') {
1093 proceedTitle = title;
1094 this.cache[currentPage] &&
1095 (this.cache[currentPage].title = proceedTitle);
1096 }
1097 else {
1098 const cacheValue = (_a = this.cache[currentPage]) === null || _a === void 0 ? void 0 : _a.title;
1099 if (typeof cacheValue === 'string') {
1100 proceedTitle = cacheValue;
1101 }
1102 else {
1103 proceedTitle = (_c = (_b = this.pageContext.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationBarTitleText) !== null && _c !== void 0 ? _c : document.title;
1104 this.cache[currentPage] &&
1105 (this.cache[currentPage].title = proceedTitle);
1106 }
1107 }
1108 if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
1109 if (!this.isLoadDdEntry) {
1110 this.isLoadDdEntry = true;
1111 require('dingtalk-jsapi/platform');
1112 }
1113 const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
1114 setDingTitle({ proceedTitle });
1115 }
1116 document.title = proceedTitle;
1117 if (!this.titleElement)
1118 return;
1119 this.titleElement.innerHTML = proceedTitle;
1120 }
1121 fnBtnToggleToHome() {
1122 if (!this.navigationBarElement)
1123 return;
1124 this.navigationBarElement.classList.add('taro-navigation-bar-home-icon');
1125 this.navigationBarElement.classList.remove('taro-navigation-bar-back-icon');
1126 }
1127 fnBtnToggleToBack() {
1128 if (!this.navigationBarElement)
1129 return;
1130 this.navigationBarElement.classList.remove('taro-navigation-bar-home-icon');
1131 this.navigationBarElement.classList.add('taro-navigation-bar-back-icon');
1132 }
1133 fnBtnToggleToNone() {
1134 if (!this.navigationBarElement)
1135 return;
1136 this.navigationBarElement.classList.remove('taro-navigation-bar-home-icon');
1137 this.navigationBarElement.classList.remove('taro-navigation-bar-back-icon');
1138 }
1139 setNavigationBarVisible(show) {
1140 var _a, _b;
1141 if (!this.navigationBarElement)
1142 return;
1143 let shouldShow;
1144 if (typeof show === 'boolean') {
1145 shouldShow = show;
1146 }
1147 else {
1148 shouldShow = (_a = this.pageContext.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
1149 if (typeof ((_b = this.pageContext.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
1150 shouldShow = this.pageContext.pageConfig.navigationStyle;
1151 }
1152 }
1153 if (shouldShow === 'default') {
1154 this.navigationBarElement.classList.add('taro-navigation-bar-show');
1155 this.navigationBarElement.classList.remove('taro-navigation-bar-hide');
1156 }
1157 else {
1158 this.navigationBarElement.classList.add('taro-navigation-bar-hide');
1159 this.navigationBarElement.classList.remove('taro-navigation-bar-show');
1160 }
1161 }
1162}
1163
1164/* eslint-disable dot-notation */
1165class PageHandler {
1166 constructor(config, history) {
1167 this.history = history;
1168 this.defaultAnimation = { duration: 300, delay: 50 };
1169 this.config = config;
1170 this.homePage = runtime.getHomePage(this.routes[0].path, this.basename, this.customRoutes, this.config.entryPagePath);
1171 this.originHomePage = this.config.entryPagePath || this.routes[0].path || this.basename;
1172 this.mount();
1173 this.navigationBarHandler = new NavigationBarHandler(this);
1174 }
1175 get currentPage() {
1176 const routePath = runtime.getCurrentPage(this.routerMode, this.basename);
1177 return routePath === '/' ? this.homePage : routePath;
1178 }
1179 get appId() { return this.config.appId || 'app'; }
1180 get router() { return this.config.router || {}; }
1181 get routerMode() { return this.router.mode || 'hash'; }
1182 get customRoutes() { return this.router.customRoutes || {}; }
1183 get routes() { return this.config.routes || []; }
1184 get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
1185 get PullDownRefresh() { return this.config.PullDownRefresh; }
1186 get animation() { var _a, _b; return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.animation) !== null && _b !== void 0 ? _b : this.defaultAnimation; }
1187 get animationDelay() {
1188 var _a;
1189 return (typeof this.animation === 'object'
1190 ? this.animation.delay
1191 : this.animation
1192 ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.delay
1193 : 0) || 0;
1194 }
1195 get animationDuration() {
1196 var _a;
1197 return (typeof this.animation === 'object'
1198 ? this.animation.duration
1199 : this.animation
1200 ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.duration
1201 : 0) || 0;
1202 }
1203 set pathname(p) { this.router.pathname = p; }
1204 get pathname() { return this.router.pathname; }
1205 // Note: 把 pathname 转换为原始路径,主要是处理 customRoutes 和 basename
1206 get originPathname() { return routesAlias.getOrigin(runtime.addLeadingSlash(runtime.stripBasename(this.pathname, this.basename))); }
1207 get basename() { return this.router.basename || ''; }
1208 get pageConfig() {
1209 const homePage = runtime.addLeadingSlash(this.homePage);
1210 return this.routes.find(r => {
1211 const pagePath = runtime.addLeadingSlash(r.path);
1212 return [pagePath, homePage].includes(this.originPathname);
1213 });
1214 }
1215 isTabBar(pathname) {
1216 var _a;
1217 const routePath = runtime.addLeadingSlash(runtime.stripBasename(pathname, this.basename)).split('?')[0];
1218 const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
1219 if (typeof target === 'string') {
1220 return target === routePath;
1221 }
1222 else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
1223 return target.includes(routePath);
1224 }
1225 return false;
1226 })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
1227 return !!pagePath && this.tabBarList.some(t => runtime.stripTrailing(t.pagePath) === pagePath);
1228 }
1229 isDefaultNavigationStyle() {
1230 var _a, _b;
1231 let style = (_a = this.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
1232 if (typeof ((_b = this.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
1233 style = this.pageConfig.navigationStyle;
1234 }
1235 return style !== 'custom';
1236 }
1237 isSamePage(page) {
1238 const routePath = runtime.stripBasename(this.pathname, this.basename);
1239 const pagePath = runtime.stripBasename(page === null || page === void 0 ? void 0 : page.path, this.basename);
1240 return pagePath.startsWith(routePath + '?');
1241 }
1242 get search() {
1243 let search = '?';
1244 if (this.routerMode === 'hash') {
1245 const idx = location.hash.indexOf('?');
1246 if (idx > -1) {
1247 search = location.hash.slice(idx);
1248 }
1249 }
1250 else {
1251 search = location.search;
1252 }
1253 return search.substring(1);
1254 }
1255 get usingWindowScroll() {
1256 var _a;
1257 let usingWindowScroll = false;
1258 if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
1259 usingWindowScroll = this.pageConfig.usingWindowScroll;
1260 }
1261 const win = window;
1262 win.__taroAppConfig || (win.__taroAppConfig = {});
1263 win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
1264 return usingWindowScroll;
1265 }
1266 getQuery(stamp = '', search = '', options = {}) {
1267 search = search ? `${search}&${this.search}` : this.search;
1268 const query = search
1269 ? queryString.parse(search, { decode: false })
1270 : {};
1271 query.stamp = stamp;
1272 return Object.assign(Object.assign({}, query), options);
1273 }
1274 mount() {
1275 setHistory(this.history, this.basename);
1276 this.pathname = exports.history.location.pathname;
1277 // Note: 注入页面样式
1278 this.animation && loadAnimateStyle(this.animationDuration);
1279 loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll, this.router.enhanceAnimation);
1280 }
1281 onReady(page, onLoad = true) {
1282 var _a;
1283 const pageEl = this.getPageContainer(page);
1284 if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
1285 const el = pageEl.firstElementChild;
1286 const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
1287 if (componentOnReady) {
1288 componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
1289 runtime.requestAnimationFrame(() => {
1290 var _a;
1291 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
1292 pageEl['__isReady'] = true;
1293 });
1294 });
1295 }
1296 else {
1297 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
1298 pageEl['__isReady'] = true;
1299 }
1300 onLoad && (pageEl['__page'] = page);
1301 }
1302 }
1303 load(page, pageConfig = {}, stampId, pageNo = 0) {
1304 var _a, _b;
1305 if (!page)
1306 return;
1307 // NOTE: 页面栈推入太晚可能导致 getCurrentPages 无法获取到当前页面实例
1308 stacks.push(page);
1309 const param = this.getQuery(stampId, '', page.options);
1310 let pageEl = this.getPageContainer(page);
1311 if (pageEl) {
1312 pageEl.classList.remove('taro_page_shade');
1313 this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
1314 this.isDefaultNavigationStyle() && pageEl.classList.add('taro_navigation_page');
1315 this.addAnimation(pageEl, pageNo === 0);
1316 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1317 this.navigationBarHandler.load();
1318 this.bindPageEvents(page, pageConfig);
1319 this.triggerRouterChange();
1320 }
1321 else {
1322 // FIXME 在 iOS 端快速切换页面时,可能不会执行回调注入对应类名导致 TabBar 白屏
1323 (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
1324 var _a;
1325 pageEl = this.getPageContainer(page);
1326 this.isTabBar(this.pathname) && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
1327 this.isDefaultNavigationStyle() && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page'));
1328 this.addAnimation(pageEl, pageNo === 0);
1329 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1330 this.navigationBarHandler.load();
1331 this.onReady(page, true);
1332 this.bindPageEvents(page, pageConfig);
1333 this.triggerRouterChange();
1334 });
1335 }
1336 }
1337 unload(page, delta = 1, top = false) {
1338 var _a, _b, _c;
1339 if (!page)
1340 return;
1341 stacks.delta = --delta;
1342 stacks.pop();
1343 if (this.animation && top) {
1344 if (this.unloadTimer) {
1345 clearTimeout(this.unloadTimer);
1346 (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1347 this.unloadTimer = null;
1348 }
1349 this.lastUnloadPage = page;
1350 const pageEl = this.getPageContainer(page);
1351 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
1352 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1353 if (pageEl) {
1354 pageEl.style.zIndex = '1';
1355 }
1356 this.unloadTimer = setTimeout(() => {
1357 var _a, _b;
1358 this.unloadTimer = null;
1359 (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1360 runtime.eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1361 }, this.animationDuration);
1362 }
1363 else {
1364 const pageEl = this.getPageContainer(page);
1365 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
1366 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1367 (_c = page === null || page === void 0 ? void 0 : page.onUnload) === null || _c === void 0 ? void 0 : _c.call(page);
1368 setTimeout(() => {
1369 runtime.eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1370 }, 0);
1371 }
1372 if (delta >= 1)
1373 this.unload(stacks.last, delta);
1374 }
1375 show(page, pageConfig = {}, pageNo = 0) {
1376 var _a, _b;
1377 if (!page)
1378 return;
1379 const param = this.getQuery(page['$taroParams']['stamp'], '', page.options);
1380 let pageEl = this.getPageContainer(page);
1381 if (pageEl) {
1382 pageEl.classList.remove('taro_page_shade');
1383 this.addAnimation(pageEl, pageNo === 0);
1384 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1385 this.navigationBarHandler.load();
1386 this.bindPageEvents(page, pageConfig);
1387 this.triggerRouterChange();
1388 }
1389 else {
1390 (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
1391 var _a;
1392 pageEl = this.getPageContainer(page);
1393 this.addAnimation(pageEl, pageNo === 0);
1394 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1395 this.navigationBarHandler.load();
1396 this.onReady(page, false);
1397 this.bindPageEvents(page, pageConfig);
1398 this.triggerRouterChange();
1399 });
1400 }
1401 }
1402 hide(page, animation = false) {
1403 var _a, _b, _c, _d, _e, _f, _g, _h;
1404 if (!page)
1405 return;
1406 // NOTE: 修复多页并发问题,此处可能因为路由跳转过快,执行时页面可能还没有创建成功
1407 const pageEl = this.getPageContainer(page);
1408 if (pageEl) {
1409 if (animation) {
1410 if (this.hideTimer) {
1411 clearTimeout(this.hideTimer);
1412 this.hideTimer = null;
1413 (_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');
1414 }
1415 this.lastHidePage = pageEl;
1416 this.hideTimer = setTimeout(() => {
1417 this.hideTimer = null;
1418 pageEl.classList.add('taro_page_shade');
1419 }, this.animationDuration + this.animationDelay);
1420 (_d = page.onHide) === null || _d === void 0 ? void 0 : _d.call(page);
1421 }
1422 else {
1423 if (this.hideTimer) {
1424 clearTimeout(this.hideTimer);
1425 this.hideTimer = null;
1426 (_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');
1427 }
1428 (_h = page.onHide) === null || _h === void 0 ? void 0 : _h.call(page);
1429 pageEl.classList.add('taro_page_shade');
1430 this.lastHidePage = pageEl;
1431 }
1432 }
1433 else {
1434 setTimeout(() => this.hide(page), 0);
1435 }
1436 }
1437 addAnimation(pageEl, first = false) {
1438 if (!pageEl)
1439 return;
1440 if (this.animation && !first) {
1441 setTimeout(() => {
1442 pageEl.classList.add('taro_page_show');
1443 setTimeout(() => {
1444 pageEl.classList.add('taro_page_stationed');
1445 }, this.animationDuration);
1446 }, this.animationDelay);
1447 }
1448 else {
1449 pageEl.classList.add('taro_page_show');
1450 pageEl.classList.add('taro_page_stationed');
1451 }
1452 }
1453 getPageContainer(page) {
1454 var _a;
1455 const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path;
1456 const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
1457 if (page) {
1458 return document.querySelector(`.taro_page#${id}`);
1459 }
1460 const el = (id
1461 ? document.querySelector(`.taro_page#${id}`)
1462 : document.querySelector('.taro_page') ||
1463 document.querySelector('.taro_router'));
1464 return el;
1465 }
1466 getScrollingElement(page) {
1467 if (this.usingWindowScroll)
1468 return window;
1469 return this.getPageContainer(page) || window;
1470 }
1471 bindPageEvents(page, config = {}) {
1472 var _a;
1473 const scrollEl = this.getScrollingElement(page);
1474 const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
1475 bindPageScroll(page, scrollEl, distance);
1476 bindPageResize(page);
1477 }
1478 triggerRouterChange() {
1479 /**
1480 * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
1481 * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
1482 */
1483 setTimeout(() => {
1484 runtime.eventCenter.trigger('__afterTaroRouterChange', {
1485 toLocation: {
1486 path: this.pathname
1487 }
1488 });
1489 }, 0);
1490 }
1491}
1492
1493const createStampId = runtime.incrementId();
1494let launchStampId = createStampId();
1495function createRouter(history$1, app, config, framework) {
1496 var _a, _b;
1497 if (typeof app.onUnhandledRejection === 'function') {
1498 window.addEventListener('unhandledrejection', app.onUnhandledRejection);
1499 }
1500 RouterConfig.config = config;
1501 const handler = new PageHandler(config, history$1);
1502 // Note: 弱网情况下,快速切换 tab,会造成同个页面实例被多次挂在到页面上,原因是资源请求是异步的,短时间内发起多个请求,
1503 // 会在资源加载完成后,同时走到挂载的逻辑,造成 pageStampId 更新不及时,两个 page 的Id 相同,后面很多操作是通过 getElementById 来进行的
1504 // 所以需要加一个锁来应对这个情况
1505 const pageLock = {};
1506 routesAlias.set(handler.router.customRoutes);
1507 const basename = handler.router.basename;
1508 const routes = handler.routes.map(route => {
1509 const routePath = runtime.addLeadingSlash(route.path);
1510 const paths = routesAlias.getAll(routePath);
1511 return {
1512 path: paths.length < 1 ? routePath : paths,
1513 action: route.load
1514 };
1515 });
1516 const router = new UniversalRouter(routes, { baseUrl: basename || '' });
1517 const launchParam = {
1518 path: handler.currentPage,
1519 query: handler.getQuery(launchStampId),
1520 scene: 0,
1521 shareTicket: '',
1522 referrerInfo: {}
1523 };
1524 runtime.eventCenter.trigger('__taroRouterLaunch', launchParam);
1525 (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
1526 app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
1527 const render = (_c) => tslib.__awaiter(this, [_c], void 0, function* ({ location, action }) {
1528 var _d, _e, _f, _g, _h, _j, _k, _l;
1529 // Note: 由于下面有异步加载操作 先不要在这里去设置 handler.pathname
1530 const currentPathname = decodeURI(location.pathname);
1531 if ((_d = window.__taroAppConfig) === null || _d === void 0 ? void 0 : _d.usingWindowScroll)
1532 window.scrollTo(0, 0);
1533 runtime.eventCenter.trigger('__taroRouterChange', {
1534 toLocation: {
1535 path: currentPathname
1536 }
1537 });
1538 let element, context, params;
1539 const routerPath = handler.router.forcePath || currentPathname;
1540 pageLock[routerPath] = typeof pageLock[routerPath] === 'number' ? pageLock[routerPath] + 1 : 1;
1541 const currentLock = pageLock[routerPath];
1542 let postLock;
1543 try {
1544 const result = yield router.resolve(routerPath);
1545 [element, context, params] = yield Promise.all(result);
1546 postLock = pageLock[routerPath];
1547 }
1548 catch (error) {
1549 if (error.status === 404) {
1550 const notFoundEvent = {
1551 isEntryPage: stacks.length === 0,
1552 path: currentPathname,
1553 query: handler.getQuery(createStampId()),
1554 };
1555 (_e = app.onPageNotFound) === null || _e === void 0 ? void 0 : _e.call(app, notFoundEvent);
1556 runtime.eventCenter.trigger('__taroRouterNotFound', notFoundEvent);
1557 }
1558 else if (/Loading hot update .* failed./.test(error.message)) {
1559 // NOTE: webpack5 与 prebundle 搭配使用时,开发环境下初次启动时偶发错误,由于 HMR 加载 chunk hash 错误,导致热更新失败
1560 window.location.reload();
1561 }
1562 else {
1563 throw error;
1564 }
1565 }
1566 if (!element || currentLock !== postLock)
1567 return;
1568 // Note: 异步结束后,在设置 handler.pathname
1569 // context.pathname 在 universal-router 被处理过了,是发起资源请求的时候传入的 pathname,即 await router.resolve(routerPath) 这个 routerPath
1570 handler.pathname = context.pathname;
1571 const { pathname, pageConfig } = handler;
1572 let enablePullDownRefresh = ((_f = config === null || config === void 0 ? void 0 : config.window) === null || _f === void 0 ? void 0 : _f.enablePullDownRefresh) || false;
1573 let navigationStyle = ((_g = config === null || config === void 0 ? void 0 : config.window) === null || _g === void 0 ? void 0 : _g.navigationStyle) || 'default';
1574 let navigationBarTextStyle = ((_h = config === null || config === void 0 ? void 0 : config.window) === null || _h === void 0 ? void 0 : _h.navigationBarTextStyle) || 'white';
1575 let navigationBarBackgroundColor = ((_j = config === null || config === void 0 ? void 0 : config.window) === null || _j === void 0 ? void 0 : _j.navigationBarBackgroundColor) || '#000000';
1576 if (pageConfig) {
1577 if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
1578 enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1579 }
1580 if (typeof pageConfig.navigationStyle === 'string') {
1581 navigationStyle = pageConfig.navigationStyle;
1582 }
1583 if (typeof pageConfig.navigationBarTextStyle === 'string') {
1584 navigationBarTextStyle = pageConfig.navigationBarTextStyle;
1585 }
1586 if (typeof pageConfig.navigationBarBackgroundColor === 'string') {
1587 navigationBarBackgroundColor = pageConfig.navigationBarBackgroundColor;
1588 }
1589 }
1590 runtime.eventCenter.trigger('__taroSetNavigationStyle', navigationStyle, navigationBarTextStyle, navigationBarBackgroundColor);
1591 const currentPage = runtime.Current.page;
1592 const methodName = (_k = stacks.method) !== null && _k !== void 0 ? _k : '';
1593 const cacheTabs = stacks.getTabs();
1594 let shouldLoad = false;
1595 stacks.method = '';
1596 if (methodName === 'reLaunch') {
1597 handler.unload(currentPage, stacks.length);
1598 // NOTE: 同时卸载缓存在tabs里面的页面实例
1599 for (const key in cacheTabs) {
1600 if (cacheTabs[key]) {
1601 handler.unload(cacheTabs[key]);
1602 stacks.removeTab(key);
1603 }
1604 }
1605 shouldLoad = true;
1606 }
1607 else if (currentPage && handler.isTabBar(pathname)) {
1608 if (handler.isSamePage(currentPage))
1609 return;
1610 if (handler.isTabBar(currentPage.path)) {
1611 // NOTE: 从 tabBar 页面切换到 tabBar 页面
1612 handler.hide(currentPage);
1613 stacks.pushTab(currentPage.path.split('?')[0]);
1614 }
1615 else if (stacks.length > 0) {
1616 const firstIns = stacks.getItem(0);
1617 if (handler.isTabBar(firstIns.path)) {
1618 handler.unload(currentPage, stacks.length - 1, true);
1619 stacks.pushTab(firstIns.path.split('?')[0]);
1620 }
1621 else {
1622 handler.unload(currentPage, stacks.length, true);
1623 }
1624 }
1625 if (cacheTabs[pathname]) {
1626 stacks.popTab(pathname);
1627 return handler.show(stacks.getItem(0), pageConfig, 0);
1628 }
1629 shouldLoad = true;
1630 }
1631 else if (action === 'POP') {
1632 // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
1633 const prevIndex = stacks.getPrevIndex(pathname);
1634 const delta = stacks.getDelta(pathname);
1635 // NOTE: Safari 内核浏览器在非应用页面返回上一页时,会触发额外的 POP 事件,此处需避免当前页面被错误卸载
1636 if (currentPage !== stacks.getItem(prevIndex)) {
1637 handler.unload(currentPage, delta, prevIndex > -1);
1638 if (prevIndex > -1) {
1639 runtime.eventCenter.once('__taroPageOnShowAfterDestroyed', () => {
1640 handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1641 });
1642 }
1643 else {
1644 shouldLoad = true;
1645 }
1646 }
1647 }
1648 else if (action === 'REPLACE') {
1649 const delta = stacks.getDelta(pathname);
1650 // NOTE: 页面路由记录并不会清空,只是移除掉缓存的 stack 以及页面
1651 handler.unload(currentPage, delta);
1652 shouldLoad = true;
1653 }
1654 else if (action === 'PUSH') {
1655 handler.hide(currentPage, true);
1656 shouldLoad = true;
1657 }
1658 if (shouldLoad || stacks.length < 1) {
1659 const el = (_l = element.default) !== null && _l !== void 0 ? _l : element;
1660 const loadConfig = Object.assign({}, pageConfig);
1661 const stacksIndex = stacks.length;
1662 delete loadConfig['path'];
1663 delete loadConfig['load'];
1664 let pageStampId = '';
1665 if (launchStampId) {
1666 pageStampId = launchStampId;
1667 launchStampId = '';
1668 }
1669 else {
1670 pageStampId = createStampId();
1671 }
1672 const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, pathname, framework, handler.PullDownRefresh, pageStampId) : el, pathname + runtime.stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1673 if (params)
1674 page.options = params;
1675 handler.load(page, pageConfig, pageStampId, stacksIndex);
1676 }
1677 });
1678 const routePath = runtime.addLeadingSlash(runtime.stripBasename(history$1.location.pathname, handler.basename));
1679 if (routePath === '/') {
1680 history$1.replace(prependBasename(handler.homePage + history$1.location.search));
1681 }
1682 render({ location: history$1.location, action: history.Action.Push });
1683 (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, launchParam);
1684 window.addEventListener('visibilitychange', () => {
1685 var _a, _b, _c, _d, _e, _f, _g;
1686 const currentPath = ((_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path) || '';
1687 const path = currentPath.substring(0, currentPath.indexOf('?'));
1688 const param = {};
1689 // app的 onShow/onHide 生命周期的路径信息为当前页面的路径
1690 Object.assign(param, launchParam, { path });
1691 if (document.visibilityState === 'visible') {
1692 (_b = app.onShow) === null || _b === void 0 ? void 0 : _b.call(app, param);
1693 // 单页面app显示后一刻会触发当前 page.onShow 生命周期函数
1694 (_d = (_c = runtime.Current.page) === null || _c === void 0 ? void 0 : _c.onShow) === null || _d === void 0 ? void 0 : _d.call(_c);
1695 }
1696 else {
1697 // 单页面app隐藏前一刻会触发当前 page.onHide 生命周期函数
1698 if ((_e = runtime.Current.page) === null || _e === void 0 ? void 0 : _e.path) {
1699 runtime.safeExecute((_f = runtime.Current.page) === null || _f === void 0 ? void 0 : _f.path, 'onHide');
1700 }
1701 (_g = app.onHide) === null || _g === void 0 ? void 0 : _g.call(app, param);
1702 }
1703 });
1704 return history$1.listen(render);
1705}
1706
1707function handleAppMount(config, _, appId = config.appId || 'app') {
1708 let app = document.getElementById(appId);
1709 let isPosition = true;
1710 if (!app) {
1711 app = document.createElement('div');
1712 app.id = appId;
1713 isPosition = false;
1714 }
1715 const appWrapper = ((app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body);
1716 app.classList.add('taro_router');
1717 if (!isPosition)
1718 appWrapper.appendChild(app);
1719 initNavigationBar(config, appWrapper);
1720}
1721function handleAppMountWithTabbar(config, history, appId = config.appId || 'app') {
1722 let app = document.getElementById(appId);
1723 let isPosition = true;
1724 if (!app) {
1725 app = document.createElement('div');
1726 app.id = appId;
1727 isPosition = false;
1728 }
1729 const appWrapper = ((app === null || app === void 0 ? void 0 : app.parentNode) || (app === null || app === void 0 ? void 0 : app.parentElement) || document.body);
1730 app.classList.add('taro_router');
1731 const container = document.createElement('div');
1732 container.classList.add('taro-tabbar__container');
1733 container.id = 'container';
1734 const panel = document.createElement('div');
1735 panel.classList.add('taro-tabbar__panel');
1736 panel.appendChild(app.cloneNode(true));
1737 container.appendChild(panel);
1738 if (!isPosition) {
1739 appWrapper.appendChild(container);
1740 }
1741 else {
1742 appWrapper.replaceChild(container, app);
1743 }
1744 initTabbar(config, history);
1745 initNavigationBar(config, container);
1746}
1747
1748Object.defineProperty(exports, "createBrowserHistory", {
1749 enumerable: true,
1750 get: function () { return history.createBrowserHistory; }
1751});
1752Object.defineProperty(exports, "createHashHistory", {
1753 enumerable: true,
1754 get: function () { return history.createHashHistory; }
1755});
1756exports.createMpaHistory = createMpaHistory;
1757exports.createMultiRouter = createMultiRouter;
1758exports.createRouter = createRouter;
1759exports.getCurrentPages = getCurrentPages;
1760exports.handleAppMount = handleAppMount;
1761exports.handleAppMountWithTabbar = handleAppMountWithTabbar;
1762exports.isDingTalk = isDingTalk;
1763exports.isWeixin = isWeixin;
1764exports.navigateBack = navigateBack;
1765exports.navigateTo = navigateTo;
1766exports.prependBasename = prependBasename;
1767exports.reLaunch = reLaunch;
1768exports.redirectTo = redirectTo;
1769exports.routesAlias = routesAlias;
1770exports.setHistory = setHistory;
1771exports.setHistoryMode = setHistoryMode;
1772exports.setMpaTitle = setMpaTitle;
1773exports.setNavigationBarLoading = setNavigationBarLoading;
1774exports.setNavigationBarStyle = setNavigationBarStyle;
1775exports.setTitle = setTitle;
1776exports.switchTab = switchTab;