UNPKG

77.2 kBJavaScriptView Raw
1import { defineCustomElementTaroTabbar } from '@tarojs/components/dist/components';
2import { initTabBarApis } from '@tarojs/taro';
3import { __awaiter } from 'tslib';
4import { addLeadingSlash, eventCenter, Current, stripBasename, incrementId, createPageConfig, hooks, stringify, getHomePage, getCurrentPage, stripTrailing, requestAnimationFrame as requestAnimationFrame$1, safeExecute } from '@tarojs/runtime';
5import { EventChannel } from '@tarojs/shared';
6import { createBrowserHistory, createHashHistory, Action, parsePath } from 'history';
7export { createBrowserHistory, createHashHistory } from 'history';
8import queryString from 'query-string';
9import UniversalRouter from 'universal-router';
10
11/**
12 * 插入页面动画需要的样式
13 */
14function loadAnimateStyle(ms = 300) {
15 const css = `
16body {
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 */
47function 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*/
90function 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}
177function 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
185const 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`;
190const 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`;
195const 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`;
198function 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
226function 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}
253
254class RouterConfig {
255 static set config(e) {
256 this.__config = e;
257 }
258 static get config() {
259 return this.__config;
260 }
261 static get pages() {
262 return this.config.pages || [];
263 }
264 static get router() {
265 return this.config.router || {};
266 }
267 static get mode() {
268 return this.router.mode || 'hash';
269 }
270 static get customRoutes() { return this.router.customRoutes || {}; }
271 // 这个方法不考虑 basename 和 customRoutes,只判断原始的 url 是否在 pages 中
272 static isPage(url = '') {
273 return this.pages.findIndex(e => addLeadingSlash(e) === url) !== -1;
274 }
275}
276
277let history;
278let basename = '/';
279class MpaHistory {
280 constructor() {
281 this.back = window.history.back;
282 this.forward = window.history.forward;
283 this.pushState = this.eventState('pushState');
284 this.replaceState = this.eventState('replaceState');
285 }
286 get location() {
287 return {
288 pathname: window.location.pathname,
289 search: window.location.search,
290 hash: window.location.hash,
291 key: `${window.history.length}`,
292 state: window.history.state
293 };
294 }
295 createHref(_to) {
296 throw new Error('Method not implemented.');
297 }
298 parseUrl(to) {
299 let url = to.pathname || '';
300 if (RouterConfig.isPage(addLeadingSlash(url))) {
301 url += '.html';
302 }
303 if (to.search) {
304 url += `?${to.search}`;
305 }
306 if (to.hash) {
307 url += to.hash.startsWith('#') ? to.hash : `#${to.hash}`;
308 }
309 return url;
310 }
311 push(to, _state = {}) {
312 window.location.assign(this.parseUrl(to));
313 // this.pushState(_state, '', this.parseUrl(to))
314 }
315 replace(to, _state = {}) {
316 window.location.replace(this.parseUrl(to));
317 // this.replaceState(_state, '', this.parseUrl(to))
318 }
319 go(delta) {
320 window.history.go(delta);
321 }
322 listen(listener) {
323 function callback(e) {
324 if (e.action === 'pushState') {
325 listener({ action: Action.Push, location: this.location });
326 }
327 else if (e.action === 'replaceState') {
328 listener({ action: Action.Replace, location: this.location });
329 }
330 else {
331 // NOTE: 这里包括 back、forward、go 三种可能,并非是 POP 事件
332 listener({ action: Action.Pop, location: this.location });
333 }
334 }
335 window.addEventListener('popstate', callback);
336 return () => {
337 window.removeEventListener('popstate', callback);
338 };
339 }
340 block(_blocker) {
341 throw new Error('Method not implemented.');
342 }
343 eventState(action) {
344 return (data, unused, url) => {
345 const wrapper = window.history[action](data, unused, url);
346 const evt = new Event(action);
347 evt.action = action;
348 evt.state = data;
349 evt.unused = unused;
350 evt.url = url;
351 window.dispatchEvent(evt);
352 return wrapper;
353 };
354 }
355}
356function setHistory(h, base = '/') {
357 history = h;
358 basename = base;
359}
360function createMpaHistory(_) {
361 return new MpaHistory();
362}
363function setHistoryMode(mode, base = '/') {
364 const options = {
365 window
366 };
367 basename = base;
368 if (mode === 'browser') {
369 history = createBrowserHistory(options);
370 }
371 else if (mode === 'multi') {
372 history = createMpaHistory();
373 }
374 else {
375 // default is hash
376 history = createHashHistory(options);
377 }
378}
379function prependBasename(url = '') {
380 return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
381}
382
383class Stacks {
384 constructor() {
385 this.stacks = [];
386 this.backDelta = 0;
387 this.tabs = {};
388 this.methodName = '';
389 }
390 set delta(delta) {
391 if (delta > 0) {
392 this.backDelta = delta;
393 }
394 else if (this.backDelta > 0) {
395 --this.backDelta;
396 }
397 else {
398 this.backDelta = 0;
399 }
400 }
401 get delta() {
402 return this.backDelta;
403 }
404 set method(methodName) {
405 this.methodName = methodName;
406 }
407 get method() {
408 return this.methodName;
409 }
410 get length() {
411 return this.stacks.length;
412 }
413 get last() {
414 return this.stacks[this.length - 1];
415 }
416 get() {
417 return this.stacks;
418 }
419 getItem(index) {
420 return this.stacks[index];
421 }
422 getLastIndex(pathname, stateWith = 1) {
423 const list = [...this.stacks].reverse();
424 return list.findIndex((page, i) => { var _a; return i >= stateWith && ((_a = page.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname; });
425 }
426 getDelta(pathname) {
427 if (this.backDelta >= 1) {
428 return this.backDelta;
429 }
430 const index = this.getLastIndex(pathname);
431 // NOTE: 此处为了修复浏览器后退多级页面,在大量重复路由状况下可能出现判断错误的情况 (增强判断能力只能考虑在 query 中新增参数来判断,暂时搁置)
432 return index > 0 ? index : 1;
433 }
434 getPrevIndex(pathname, stateWith = 1) {
435 const lastIndex = this.getLastIndex(pathname, stateWith);
436 if (lastIndex < 0) {
437 return -1;
438 }
439 return this.length - 1 - lastIndex;
440 }
441 pop() {
442 return this.stacks.pop();
443 }
444 push(page) {
445 return this.stacks.push(page);
446 }
447 getTabs() {
448 return this.tabs;
449 }
450 pushTab(path) {
451 this.tabs[path] = this.last;
452 this.pop();
453 }
454 popTab(path) {
455 this.push(this.tabs[path]);
456 delete this.tabs[path];
457 }
458 removeTab(path) {
459 delete this.tabs[path];
460 }
461}
462const stacks = new Stacks();
463
464const isWeixin = () => !!navigator.userAgent.match(/\bMicroMessenger\b/ig);
465const isDingTalk = () => !!navigator.userAgent.match(/\bDingTalk\b/ig);
466let preTitle = document.title;
467let isLoadDdEntry = false;
468function 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}
482function setTitle(title) {
483 eventCenter.trigger('__taroH5SetNavigationBarTitle', title);
484}
485function setNavigationBarStyle(option) {
486 eventCenter.trigger('__taroH5setNavigationBarColor', option);
487}
488function setNavigationBarLoading(loading) {
489 eventCenter.trigger('__taroH5setNavigationBarLoading', loading);
490}
491
492class RoutesAlias {
493 constructor() {
494 this.conf = [];
495 this.getConfig = (url = '') => {
496 const customRoute = this.conf.filter((arr) => {
497 return arr.includes(url);
498 });
499 return customRoute[0];
500 };
501 this.getOrigin = (url = '') => {
502 var _a;
503 return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[0]) || url;
504 };
505 this.getAlias = (url = '') => {
506 var _a;
507 return ((_a = this.getConfig(url)) === null || _a === void 0 ? void 0 : _a[1]) || url;
508 };
509 this.getAll = (url = '') => {
510 return this.conf
511 .filter((arr) => arr.includes(url))
512 .reduceRight((p, a) => {
513 p.unshift(a[1]);
514 return p;
515 }, []);
516 };
517 }
518 set(customRoutes = {}) {
519 for (let key in customRoutes) {
520 const path = customRoutes[key];
521 key = addLeadingSlash(key);
522 if (typeof path === 'string') {
523 this.conf.push([key, addLeadingSlash(path)]);
524 }
525 else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
526 this.conf.push(...path.map(p => [key, addLeadingSlash(p)]));
527 }
528 }
529 }
530}
531const routesAlias = new RoutesAlias();
532
533const routeEvtChannel = EventChannel.routeChannel;
534function processNavigateUrl(option) {
535 var _a;
536 const pathPieces = parsePath(option.url);
537 // 处理相对路径
538 if ((_a = pathPieces.pathname) === null || _a === void 0 ? void 0 : _a.includes('./')) {
539 const parts = routesAlias.getOrigin(history.location.pathname).split('/');
540 parts.pop();
541 pathPieces.pathname.split('/').forEach((item) => {
542 if (item === '.')
543 return;
544 item === '..' ? parts.pop() : parts.push(item);
545 });
546 pathPieces.pathname = parts.join('/');
547 }
548 // 确保是 / 开头的路径
549 pathPieces.pathname = addLeadingSlash(pathPieces.pathname);
550 // 处理自定义路由
551 pathPieces.pathname = routesAlias.getAlias(addLeadingSlash(pathPieces.pathname));
552 // 处理 basename
553 pathPieces.pathname = prependBasename(pathPieces.pathname);
554 // hack fix history v5 bug: https://github.com/remix-run/history/issues/814
555 if (!pathPieces.search)
556 pathPieces.search = '';
557 return pathPieces;
558}
559function navigate(option, method) {
560 return __awaiter(this, void 0, void 0, function* () {
561 return new Promise((resolve, reject) => {
562 stacks.method = method;
563 const { success, complete, fail } = option;
564 const unListen = history.listen(() => {
565 const res = { errMsg: `${method}:ok` };
566 if (method === 'navigateTo') {
567 res.eventChannel = routeEvtChannel;
568 routeEvtChannel.addEvents(option.events);
569 }
570 success === null || success === void 0 ? void 0 : success(res);
571 complete === null || complete === void 0 ? void 0 : complete(res);
572 resolve(res);
573 unListen();
574 });
575 try {
576 if ('url' in option) {
577 const pathPieces = processNavigateUrl(option);
578 const state = { timestamp: Date.now() };
579 if (method === 'navigateTo') {
580 // Note: 由于 spa 会针对弱网情况下,短时间内多次跳转同一个页面跳转加了锁,后续如果有用户反馈返回无效,那可能是这个问题
581 history.push(pathPieces, state);
582 }
583 else if (method === 'redirectTo' || method === 'switchTab') {
584 history.replace(pathPieces, state);
585 }
586 else if (method === 'reLaunch') {
587 stacks.delta = stacks.length;
588 history.replace(pathPieces, state);
589 }
590 }
591 else if (method === 'navigateBack') {
592 stacks.delta = option.delta;
593 if (stacks.length > option.delta) {
594 history.go(-option.delta);
595 }
596 else {
597 history.go(1 - stacks.length);
598 }
599 }
600 }
601 catch (error) {
602 const res = { errMsg: `${method}:fail ${error.message || error}` };
603 fail === null || fail === void 0 ? void 0 : fail(res);
604 complete === null || complete === void 0 ? void 0 : complete(res);
605 if (fail || complete) {
606 return resolve(res);
607 }
608 else {
609 return reject(res);
610 }
611 }
612 });
613 });
614}
615function navigateTo(option) {
616 return navigate(option, 'navigateTo');
617}
618function redirectTo(option) {
619 return navigate(option, 'redirectTo');
620}
621function navigateBack(option = { delta: 1 }) {
622 if (!option.delta || option.delta < 1) {
623 option.delta = 1;
624 }
625 return navigate(option, 'navigateBack');
626}
627function switchTab(option) {
628 return navigate(option, 'switchTab');
629}
630function reLaunch(option) {
631 return navigate(option, 'reLaunch');
632}
633function getCurrentPages() {
634 if (process.env.NODE_ENV !== 'production' && RouterConfig.mode === 'multi') {
635 console.warn('多页面路由模式不支持使用 getCurrentPages 方法!');
636 }
637 const pages = stacks.get();
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, '')) || '' })); });
639}
640
641let pageResizeFn;
642function bindPageResize(page) {
643 pageResizeFn && window.removeEventListener('resize', pageResizeFn);
644 pageResizeFn = function () {
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 }
657 };
658 window.addEventListener('resize', pageResizeFn, false);
659}
660
661const pageScrollFn = {};
662let pageDOM = window;
663function bindPageScroll(page, scrollEl, distance = 50) {
664 var _a;
665 const pagePath = (page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.router) === null || _a === void 0 ? void 0 : _a.path);
666 pageScrollFn[pagePath] && scrollEl.removeEventListener('scroll', pageScrollFn[pagePath]);
667 pageDOM = scrollEl;
668 let isReachBottom = false;
669 pageScrollFn[pagePath] = function () {
670 var _a;
671 (_a = page.onPageScroll) === null || _a === void 0 ? void 0 : _a.call(page, {
672 scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
673 });
674 if (isReachBottom && getOffset() > distance) {
675 isReachBottom = false;
676 }
677 if (page.onReachBottom &&
678 !isReachBottom &&
679 getOffset() < distance) {
680 isReachBottom = true;
681 page.onReachBottom();
682 }
683 };
684 pageDOM.addEventListener('scroll', pageScrollFn[pagePath], false);
685}
686function getOffset() {
687 if (pageDOM instanceof Window) {
688 return document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
689 }
690 else {
691 return pageDOM.scrollHeight - pageDOM.scrollTop - pageDOM.clientHeight;
692 }
693}
694
695/* eslint-disable dot-notation */
696class MultiPageHandler {
697 constructor(config, history) {
698 this.history = history;
699 this.config = config;
700 this.mount();
701 }
702 get appId() { return this.config.appId || 'app'; }
703 get router() { return this.config.router || {}; }
704 get routerMode() { return this.router.mode || 'hash'; }
705 get customRoutes() { return this.router.customRoutes || {}; }
706 get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
707 get PullDownRefresh() { return this.config.PullDownRefresh; }
708 set pathname(p) { this.router.pathname = p; }
709 get pathname() { return this.router.pathname; }
710 get basename() { return this.router.basename || ''; }
711 get pageConfig() { return this.config.route; }
712 get isTabBar() {
713 var _a;
714 const routePath = addLeadingSlash(stripBasename(this.pathname, this.basename));
715 const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
716 if (typeof target === 'string') {
717 return target === routePath;
718 }
719 else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
720 return target.includes(routePath);
721 }
722 return false;
723 })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
724 return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
725 }
726 get search() { return location.search.substr(1); }
727 get usingWindowScroll() {
728 var _a;
729 let usingWindowScroll = true;
730 if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
731 usingWindowScroll = this.pageConfig.usingWindowScroll;
732 }
733 const win = window;
734 win.__taroAppConfig || (win.__taroAppConfig = {});
735 win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
736 return usingWindowScroll;
737 }
738 getQuery(search = '', options = {}) {
739 search = search ? `${search}&${this.search}` : this.search;
740 const query = search
741 ? queryString.parse(search)
742 : {};
743 return Object.assign(Object.assign({}, query), options);
744 }
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;
750 }
751 return style !== 'custom';
752 }
753 mount() {
754 setHistory(this.history, this.basename);
755 // Note: 注入页面样式
756 loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll);
757 }
758 onReady(page, onLoad = true) {
759 var _a;
760 const pageEl = this.getPageContainer(page);
761 if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
762 const el = pageEl.firstElementChild;
763 const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
764 if (componentOnReady) {
765 componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
766 requestAnimationFrame(() => {
767 var _a;
768 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
769 pageEl['__isReady'] = true;
770 });
771 });
772 }
773 else {
774 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
775 pageEl['__isReady'] = true;
776 }
777 onLoad && (pageEl['__page'] = page);
778 }
779 }
780 load(page, pageConfig = {}) {
781 var _a;
782 if (!page)
783 return;
784 (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
785 var _a;
786 const pageEl = this.getPageContainer(page);
787 if (this.isTabBar) {
788 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
789 }
790 if (this.isDefaultNavigationStyle()) {
791 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page');
792 }
793 this.onReady(page, true);
794 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
795 this.bindPageEvents(page, pageConfig);
796 this.triggerRouterChange();
797 });
798 }
799 getPageContainer(page) {
800 var _a;
801 const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.page) === null || _a === void 0 ? void 0 : _a.path;
802 const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
803 if (page) {
804 return document.querySelector(`.taro_page#${id}`);
805 }
806 const el = (id
807 ? document.querySelector(`.taro_page#${id}`)
808 : document.querySelector('.taro_page') ||
809 document.querySelector('.taro_router'));
810 return el;
811 }
812 getScrollingElement(page) {
813 if (this.usingWindowScroll)
814 return window;
815 return this.getPageContainer(page) || window;
816 }
817 bindPageEvents(page, config = {}) {
818 var _a;
819 const scrollEl = this.getScrollingElement(page);
820 const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
821 bindPageScroll(page, scrollEl, distance);
822 bindPageResize(page);
823 }
824 triggerRouterChange() {
825 /**
826 * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
827 * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
828 */
829 setTimeout(() => {
830 eventCenter.trigger('__afterTaroRouterChange', {
831 toLocation: {
832 path: this.pathname
833 }
834 });
835 }, 0);
836 }
837}
838
839const createStampId$1 = incrementId();
840const launchStampId$1 = createStampId$1();
841// TODO 支持多路由 (APP 生命周期仅触发一次)
842/** Note: 关于多页面应用
843 * - 需要配置路由映射(根目录跳转、404 页面……)
844 * - app.onPageNotFound 事件不支持
845 * - 应用生命周期可能多次触发
846 * - TabBar 会多次加载
847 * - 不支持路由动画
848 */
849function createMultiRouter(history, app, config, framework) {
850 return __awaiter(this, void 0, void 0, function* () {
851 var _a, _b, _c, _d, _e, _f;
852 if (typeof app.onUnhandledRejection === 'function') {
853 window.addEventListener('unhandledrejection', app.onUnhandledRejection);
854 }
855 eventCenter.on('__taroH5SetNavigationBarTitle', setMpaTitle);
856 RouterConfig.config = config;
857 const handler = new MultiPageHandler(config, history);
858 const launchParam = {
859 path: config.pageName, // 多页面模式没新开一个页面相当于重启,所以直接使用当前页面路径
860 query: handler.getQuery(launchStampId$1),
861 scene: 0,
862 shareTicket: '',
863 referrerInfo: {}
864 };
865 eventCenter.trigger('__taroRouterLaunch', launchParam);
866 (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
867 app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
868 const pathName = config.pageName;
869 const pageConfig = handler.pageConfig;
870 eventCenter.trigger('__taroRouterChange', {
871 toLocation: {
872 path: pathName
873 }
874 });
875 let element;
876 try {
877 element = yield ((_b = pageConfig.load) === null || _b === void 0 ? void 0 : _b.call(pageConfig));
878 if (element instanceof Array) {
879 element = element[0];
880 }
881 }
882 catch (error) {
883 throw new Error(error);
884 }
885 if (!element)
886 return;
887 let enablePullDownRefresh = ((_c = config === null || config === void 0 ? void 0 : config.window) === null || _c === void 0 ? void 0 : _c.enablePullDownRefresh) || false;
888 if (pageConfig) {
889 setMpaTitle((_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title);
890 if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
891 enablePullDownRefresh = pageConfig.enablePullDownRefresh;
892 }
893 }
894 const el = (_e = element.default) !== null && _e !== void 0 ? _e : element;
895 const loadConfig = Object.assign({}, pageConfig);
896 delete loadConfig['path'];
897 delete loadConfig['load'];
898 const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, pathName, framework, handler.PullDownRefresh) : el, pathName + stringify(launchParam), {}, loadConfig);
899 handler.load(page, pageConfig);
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 });
915 });
916}
917
918class 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
1163/* eslint-disable dot-notation */
1164class PageHandler {
1165 constructor(config, history) {
1166 this.history = history;
1167 this.defaultAnimation = { duration: 300, delay: 50 };
1168 this.config = config;
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;
1171 this.mount();
1172 this.navigationBarHandler = new NavigationBarHandler(this);
1173 }
1174 get currentPage() {
1175 const routePath = getCurrentPage(this.routerMode, this.basename);
1176 return routePath === '/' ? this.homePage : routePath;
1177 }
1178 get appId() { return this.config.appId || 'app'; }
1179 get router() { return this.config.router || {}; }
1180 get routerMode() { return this.router.mode || 'hash'; }
1181 get customRoutes() { return this.router.customRoutes || {}; }
1182 get routes() { return this.config.routes || []; }
1183 get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
1184 get PullDownRefresh() { return this.config.PullDownRefresh; }
1185 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; }
1186 get animationDelay() {
1187 var _a;
1188 return (typeof this.animation === 'object'
1189 ? this.animation.delay
1190 : this.animation
1191 ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.delay
1192 : 0) || 0;
1193 }
1194 get animationDuration() {
1195 var _a;
1196 return (typeof this.animation === 'object'
1197 ? this.animation.duration
1198 : this.animation
1199 ? (_a = this.defaultAnimation) === null || _a === void 0 ? void 0 : _a.duration
1200 : 0) || 0;
1201 }
1202 set pathname(p) { this.router.pathname = p; }
1203 get pathname() { return this.router.pathname; }
1204 // Note: 把 pathname 转换为原始路径,主要是处理 customRoutes 和 basename
1205 get originPathname() { return routesAlias.getOrigin(addLeadingSlash(stripBasename(this.pathname, this.basename))); }
1206 get basename() { return this.router.basename || ''; }
1207 get pageConfig() {
1208 const homePage = addLeadingSlash(this.homePage);
1209 return this.routes.find(r => {
1210 const pagePath = addLeadingSlash(r.path);
1211 return [pagePath, homePage].includes(this.originPathname);
1212 });
1213 }
1214 isTabBar(pathname) {
1215 var _a;
1216 const routePath = addLeadingSlash(stripBasename(pathname, this.basename)).split('?')[0];
1217 const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
1218 if (typeof target === 'string') {
1219 return target === routePath;
1220 }
1221 else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
1222 return target.includes(routePath);
1223 }
1224 return false;
1225 })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
1226 return !!pagePath && this.tabBarList.some(t => stripTrailing(t.pagePath) === pagePath);
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 }
1236 isSamePage(page) {
1237 const routePath = stripBasename(this.pathname, this.basename);
1238 const pagePath = stripBasename(page === null || page === void 0 ? void 0 : page.path, this.basename);
1239 return pagePath.startsWith(routePath + '?');
1240 }
1241 get search() {
1242 let search = '?';
1243 if (this.routerMode === 'hash') {
1244 const idx = location.hash.indexOf('?');
1245 if (idx > -1) {
1246 search = location.hash.slice(idx);
1247 }
1248 }
1249 else {
1250 search = location.search;
1251 }
1252 return search.substring(1);
1253 }
1254 get usingWindowScroll() {
1255 var _a;
1256 let usingWindowScroll = false;
1257 if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
1258 usingWindowScroll = this.pageConfig.usingWindowScroll;
1259 }
1260 const win = window;
1261 win.__taroAppConfig || (win.__taroAppConfig = {});
1262 win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
1263 return usingWindowScroll;
1264 }
1265 getQuery(stamp = '', search = '', options = {}) {
1266 search = search ? `${search}&${this.search}` : this.search;
1267 const query = search
1268 ? queryString.parse(search, { decode: false })
1269 : {};
1270 query.stamp = stamp;
1271 return Object.assign(Object.assign({}, query), options);
1272 }
1273 mount() {
1274 setHistory(this.history, this.basename);
1275 this.pathname = history.location.pathname;
1276 // Note: 注入页面样式
1277 this.animation && loadAnimateStyle(this.animationDuration);
1278 loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll, this.router.enhanceAnimation);
1279 }
1280 onReady(page, onLoad = true) {
1281 var _a;
1282 const pageEl = this.getPageContainer(page);
1283 if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
1284 const el = pageEl.firstElementChild;
1285 const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
1286 if (componentOnReady) {
1287 componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
1288 requestAnimationFrame$1(() => {
1289 var _a;
1290 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
1291 pageEl['__isReady'] = true;
1292 });
1293 });
1294 }
1295 else {
1296 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
1297 pageEl['__isReady'] = true;
1298 }
1299 onLoad && (pageEl['__page'] = page);
1300 }
1301 }
1302 load(page, pageConfig = {}, stampId, pageNo = 0) {
1303 var _a, _b;
1304 if (!page)
1305 return;
1306 // NOTE: 页面栈推入太晚可能导致 getCurrentPages 无法获取到当前页面实例
1307 stacks.push(page);
1308 const param = this.getQuery(stampId, '', page.options);
1309 let pageEl = this.getPageContainer(page);
1310 if (pageEl) {
1311 pageEl.classList.remove('taro_page_shade');
1312 this.isTabBar(this.pathname) && pageEl.classList.add('taro_tabbar_page');
1313 this.isDefaultNavigationStyle() && pageEl.classList.add('taro_navigation_page');
1314 this.addAnimation(pageEl, pageNo === 0);
1315 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1316 this.navigationBarHandler.load();
1317 this.bindPageEvents(page, pageConfig);
1318 this.triggerRouterChange();
1319 }
1320 else {
1321 // FIXME 在 iOS 端快速切换页面时,可能不会执行回调注入对应类名导致 TabBar 白屏
1322 (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
1323 var _a;
1324 pageEl = this.getPageContainer(page);
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'));
1327 this.addAnimation(pageEl, pageNo === 0);
1328 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1329 this.navigationBarHandler.load();
1330 this.onReady(page, true);
1331 this.bindPageEvents(page, pageConfig);
1332 this.triggerRouterChange();
1333 });
1334 }
1335 }
1336 unload(page, delta = 1, top = false) {
1337 var _a, _b, _c;
1338 if (!page)
1339 return;
1340 stacks.delta = --delta;
1341 stacks.pop();
1342 if (this.animation && top) {
1343 if (this.unloadTimer) {
1344 clearTimeout(this.unloadTimer);
1345 (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1346 this.unloadTimer = null;
1347 }
1348 this.lastUnloadPage = page;
1349 const pageEl = this.getPageContainer(page);
1350 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
1351 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1352 if (pageEl) {
1353 pageEl.style.zIndex = '1';
1354 }
1355 this.unloadTimer = setTimeout(() => {
1356 var _a, _b;
1357 this.unloadTimer = null;
1358 (_b = (_a = this.lastUnloadPage) === null || _a === void 0 ? void 0 : _a.onUnload) === null || _b === void 0 ? void 0 : _b.call(_a);
1359 eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1360 }, this.animationDuration);
1361 }
1362 else {
1363 const pageEl = this.getPageContainer(page);
1364 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_stationed');
1365 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.remove('taro_page_show');
1366 (_c = page === null || page === void 0 ? void 0 : page.onUnload) === null || _c === void 0 ? void 0 : _c.call(page);
1367 setTimeout(() => {
1368 eventCenter.trigger('__taroPageOnShowAfterDestroyed');
1369 }, 0);
1370 }
1371 if (delta >= 1)
1372 this.unload(stacks.last, delta);
1373 }
1374 show(page, pageConfig = {}, pageNo = 0) {
1375 var _a, _b;
1376 if (!page)
1377 return;
1378 const param = this.getQuery(page['$taroParams']['stamp'], '', page.options);
1379 let pageEl = this.getPageContainer(page);
1380 if (pageEl) {
1381 pageEl.classList.remove('taro_page_shade');
1382 this.addAnimation(pageEl, pageNo === 0);
1383 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1384 this.navigationBarHandler.load();
1385 this.bindPageEvents(page, pageConfig);
1386 this.triggerRouterChange();
1387 }
1388 else {
1389 (_b = page.onLoad) === null || _b === void 0 ? void 0 : _b.call(page, param, () => {
1390 var _a;
1391 pageEl = this.getPageContainer(page);
1392 this.addAnimation(pageEl, pageNo === 0);
1393 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
1394 this.navigationBarHandler.load();
1395 this.onReady(page, false);
1396 this.bindPageEvents(page, pageConfig);
1397 this.triggerRouterChange();
1398 });
1399 }
1400 }
1401 hide(page, animation = false) {
1402 var _a, _b, _c, _d, _e, _f, _g, _h;
1403 if (!page)
1404 return;
1405 // NOTE: 修复多页并发问题,此处可能因为路由跳转过快,执行时页面可能还没有创建成功
1406 const pageEl = this.getPageContainer(page);
1407 if (pageEl) {
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);
1420 }
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);
1428 pageEl.classList.add('taro_page_shade');
1429 this.lastHidePage = pageEl;
1430 }
1431 }
1432 else {
1433 setTimeout(() => this.hide(page), 0);
1434 }
1435 }
1436 addAnimation(pageEl, first = false) {
1437 if (!pageEl)
1438 return;
1439 if (this.animation && !first) {
1440 setTimeout(() => {
1441 pageEl.classList.add('taro_page_show');
1442 setTimeout(() => {
1443 pageEl.classList.add('taro_page_stationed');
1444 }, this.animationDuration);
1445 }, this.animationDelay);
1446 }
1447 else {
1448 pageEl.classList.add('taro_page_show');
1449 pageEl.classList.add('taro_page_stationed');
1450 }
1451 }
1452 getPageContainer(page) {
1453 var _a;
1454 const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.page) === null || _a === void 0 ? void 0 : _a.path;
1455 const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
1456 if (page) {
1457 return document.querySelector(`.taro_page#${id}`);
1458 }
1459 const el = (id
1460 ? document.querySelector(`.taro_page#${id}`)
1461 : document.querySelector('.taro_page') ||
1462 document.querySelector('.taro_router'));
1463 return el;
1464 }
1465 getScrollingElement(page) {
1466 if (this.usingWindowScroll)
1467 return window;
1468 return this.getPageContainer(page) || window;
1469 }
1470 bindPageEvents(page, config = {}) {
1471 var _a;
1472 const scrollEl = this.getScrollingElement(page);
1473 const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
1474 bindPageScroll(page, scrollEl, distance);
1475 bindPageResize(page);
1476 }
1477 triggerRouterChange() {
1478 /**
1479 * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
1480 * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
1481 */
1482 setTimeout(() => {
1483 eventCenter.trigger('__afterTaroRouterChange', {
1484 toLocation: {
1485 path: this.pathname
1486 }
1487 });
1488 }, 0);
1489 }
1490}
1491
1492const createStampId = incrementId();
1493let launchStampId = createStampId();
1494function createRouter(history, app, config, framework) {
1495 var _a, _b;
1496 if (typeof app.onUnhandledRejection === 'function') {
1497 window.addEventListener('unhandledrejection', app.onUnhandledRejection);
1498 }
1499 RouterConfig.config = config;
1500 const handler = new PageHandler(config, history);
1501 // Note: 弱网情况下,快速切换 tab,会造成同个页面实例被多次挂在到页面上,原因是资源请求是异步的,短时间内发起多个请求,
1502 // 会在资源加载完成后,同时走到挂载的逻辑,造成 pageStampId 更新不及时,两个 page 的Id 相同,后面很多操作是通过 getElementById 来进行的
1503 // 所以需要加一个锁来应对这个情况
1504 const pageLock = {};
1505 routesAlias.set(handler.router.customRoutes);
1506 const basename = handler.router.basename;
1507 const routes = handler.routes.map(route => {
1508 const routePath = addLeadingSlash(route.path);
1509 const paths = routesAlias.getAll(routePath);
1510 return {
1511 path: paths.length < 1 ? routePath : paths,
1512 action: route.load
1513 };
1514 });
1515 const router = new UniversalRouter(routes, { baseUrl: basename || '' });
1516 const launchParam = {
1517 path: handler.currentPage,
1518 query: handler.getQuery(launchStampId),
1519 scene: 0,
1520 shareTicket: '',
1521 referrerInfo: {}
1522 };
1523 eventCenter.trigger('__taroRouterLaunch', launchParam);
1524 (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
1525 app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
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)
1531 window.scrollTo(0, 0);
1532 eventCenter.trigger('__taroRouterChange', {
1533 toLocation: {
1534 path: currentPathname
1535 }
1536 });
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;
1542 try {
1543 const result = yield router.resolve(routerPath);
1544 [element, context, params] = yield Promise.all(result);
1545 postLock = pageLock[routerPath];
1546 }
1547 catch (error) {
1548 if (error.status === 404) {
1549 const notFoundEvent = {
1550 isEntryPage: stacks.length === 0,
1551 path: currentPathname,
1552 query: handler.getQuery(createStampId()),
1553 };
1554 (_e = app.onPageNotFound) === null || _e === void 0 ? void 0 : _e.call(app, notFoundEvent);
1555 eventCenter.trigger('__taroRouterNotFound', notFoundEvent);
1556 }
1557 else if (/Loading hot update .* failed./.test(error.message)) {
1558 // NOTE: webpack5 与 prebundle 搭配使用时,开发环境下初次启动时偶发错误,由于 HMR 加载 chunk hash 错误,导致热更新失败
1559 window.location.reload();
1560 }
1561 else {
1562 throw error;
1563 }
1564 }
1565 if (!element || currentLock !== postLock)
1566 return;
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';
1575 if (pageConfig) {
1576 if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
1577 enablePullDownRefresh = pageConfig.enablePullDownRefresh;
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 }
1588 }
1589 eventCenter.trigger('__taroSetNavigationStyle', navigationStyle, navigationBarTextStyle, navigationBarBackgroundColor);
1590 const currentPage = Current.page;
1591 const methodName = (_k = stacks.method) !== null && _k !== void 0 ? _k : '';
1592 const cacheTabs = stacks.getTabs();
1593 let shouldLoad = false;
1594 stacks.method = '';
1595 if (methodName === 'reLaunch') {
1596 handler.unload(currentPage, stacks.length);
1597 // NOTE: 同时卸载缓存在tabs里面的页面实例
1598 for (const key in cacheTabs) {
1599 if (cacheTabs[key]) {
1600 handler.unload(cacheTabs[key]);
1601 stacks.removeTab(key);
1602 }
1603 }
1604 shouldLoad = true;
1605 }
1606 else if (currentPage && handler.isTabBar(pathname)) {
1607 if (handler.isSamePage(currentPage))
1608 return;
1609 if (handler.isTabBar(currentPage.path)) {
1610 // NOTE: 从 tabBar 页面切换到 tabBar 页面
1611 handler.hide(currentPage);
1612 stacks.pushTab(currentPage.path.split('?')[0]);
1613 }
1614 else if (stacks.length > 0) {
1615 const firstIns = stacks.getItem(0);
1616 if (handler.isTabBar(firstIns.path)) {
1617 handler.unload(currentPage, stacks.length - 1, true);
1618 stacks.pushTab(firstIns.path.split('?')[0]);
1619 }
1620 else {
1621 handler.unload(currentPage, stacks.length, true);
1622 }
1623 }
1624 if (cacheTabs[pathname]) {
1625 stacks.popTab(pathname);
1626 return handler.show(stacks.getItem(0), pageConfig, 0);
1627 }
1628 shouldLoad = true;
1629 }
1630 else if (action === 'POP') {
1631 // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
1632 const prevIndex = stacks.getPrevIndex(pathname);
1633 const delta = stacks.getDelta(pathname);
1634 // NOTE: Safari 内核浏览器在非应用页面返回上一页时,会触发额外的 POP 事件,此处需避免当前页面被错误卸载
1635 if (currentPage !== stacks.getItem(prevIndex)) {
1636 handler.unload(currentPage, delta, prevIndex > -1);
1637 if (prevIndex > -1) {
1638 eventCenter.once('__taroPageOnShowAfterDestroyed', () => {
1639 handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
1640 });
1641 }
1642 else {
1643 shouldLoad = true;
1644 }
1645 }
1646 }
1647 else if (action === 'REPLACE') {
1648 const delta = stacks.getDelta(pathname);
1649 // NOTE: 页面路由记录并不会清空,只是移除掉缓存的 stack 以及页面
1650 handler.unload(currentPage, delta);
1651 shouldLoad = true;
1652 }
1653 else if (action === 'PUSH') {
1654 handler.hide(currentPage, true);
1655 shouldLoad = true;
1656 }
1657 if (shouldLoad || stacks.length < 1) {
1658 const el = (_l = element.default) !== null && _l !== void 0 ? _l : element;
1659 const loadConfig = Object.assign({}, pageConfig);
1660 const stacksIndex = stacks.length;
1661 delete loadConfig['path'];
1662 delete loadConfig['load'];
1663 let pageStampId = '';
1664 if (launchStampId) {
1665 pageStampId = launchStampId;
1666 launchStampId = '';
1667 }
1668 else {
1669 pageStampId = createStampId();
1670 }
1671 const page = createPageConfig(enablePullDownRefresh ? hooks.call('createPullDownComponent', el, pathname, framework, handler.PullDownRefresh, pageStampId) : el, pathname + stringify(handler.getQuery(pageStampId)), {}, loadConfig);
1672 if (params)
1673 page.options = params;
1674 handler.load(page, pageConfig, pageStampId, stacksIndex);
1675 }
1676 });
1677 const routePath = addLeadingSlash(stripBasename(history.location.pathname, handler.basename));
1678 if (routePath === '/') {
1679 history.replace(prependBasename(handler.homePage + history.location.search));
1680 }
1681 render({ location: history.location, action: Action.Push });
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 });
1703 return history.listen(render);
1704}
1705
1706function 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}
1720function 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
1747export { createMpaHistory, createMultiRouter, createRouter, getCurrentPages, handleAppMount, handleAppMountWithTabbar, history, isDingTalk, isWeixin, navigateBack, navigateTo, prependBasename, reLaunch, redirectTo, routesAlias, setHistory, setHistoryMode, setMpaTitle, setNavigationBarLoading, setNavigationBarStyle, setTitle, switchTab };