@tarojs/router 3.5.0-alpha.13 → 3.5.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 插入页面动画需要的样式
3
+ */
4
+ export declare function loadAnimateStyle(ms?: number): void;
package/dist/api.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import Taro from '@tarojs/taro';
2
+ export declare function navigateTo(option: Taro.navigateTo.Option): ReturnType<typeof Taro.navigateTo>;
3
+ export declare function redirectTo(option: Taro.redirectTo.Option): ReturnType<typeof Taro.redirectTo>;
4
+ export declare function navigateBack(option?: Taro.navigateBack.Option): ReturnType<typeof Taro.navigateBack>;
5
+ export declare function switchTab(option: Taro.switchTab.Option): ReturnType<typeof Taro.switchTab>;
6
+ export declare function reLaunch(option: Taro.reLaunch.Option): ReturnType<typeof Taro.reLaunch>;
7
+ export declare function getCurrentPages(): Taro.Page[];
package/dist/api.js CHANGED
@@ -8,10 +8,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { parsePath } from 'history';
11
- import stacks from './router/stack';
12
11
  import { history, prependBasename } from './history';
13
- import { routesAlias, addLeadingSlash } from './utils';
14
12
  import { RouterConfig } from './router';
13
+ import stacks from './router/stack';
14
+ import { addLeadingSlash, routesAlias } from './utils';
15
15
  function processNavigateUrl(option) {
16
16
  var _a;
17
17
  const pathPieces = parsePath(option.url);
@@ -0,0 +1,2 @@
1
+ import { PageInstance } from '@tarojs/runtime';
2
+ export declare function bindPageResize(page: PageInstance): void;
@@ -0,0 +1,2 @@
1
+ import { PageInstance } from '@tarojs/runtime';
2
+ export declare function bindPageScroll(page: PageInstance, pageEl: HTMLElement, distance?: number): void;
@@ -5,7 +5,8 @@ export function bindPageScroll(page, pageEl, distance = 50) {
5
5
  pageDOM = pageEl;
6
6
  let isReachBottom = false;
7
7
  pageScrollFn = function () {
8
- page.onPageScroll && page.onPageScroll({
8
+ var _a;
9
+ (_a = page.onPageScroll) === null || _a === void 0 ? void 0 : _a.call(page, {
9
10
  scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
10
11
  });
11
12
  if (isReachBottom && getOffset() > distance) {
@@ -0,0 +1,5 @@
1
+ import { IH5RouterConfig } from '@tarojs/taro/types/compile';
2
+ import { History } from 'history';
3
+ export declare let history: History;
4
+ export declare function setHistoryMode(mode?: IH5RouterConfig['mode'], base?: string): void;
5
+ export declare function prependBasename(url?: string): string;
@@ -0,0 +1,23 @@
1
+ import Taro from "@tarojs/taro";
2
+ import { History } from "history";
3
+ /* eslint-disable dot-notation */
4
+ import { AppInstance } from "@tarojs/runtime";
5
+ import { MpaRouterConfig, SpaRouterConfig } from "../../types/router";
6
+ declare function navigateTo(option: Taro.navigateTo.Option): ReturnType<typeof Taro.navigateTo>;
7
+ declare function redirectTo(option: Taro.redirectTo.Option): ReturnType<typeof Taro.redirectTo>;
8
+ declare function navigateBack(option?: Taro.navigateBack.Option): ReturnType<typeof Taro.navigateBack>;
9
+ declare function switchTab(option: Taro.switchTab.Option): ReturnType<typeof Taro.switchTab>;
10
+ declare function reLaunch(option: Taro.reLaunch.Option): ReturnType<typeof Taro.reLaunch>;
11
+ declare function getCurrentPages(): Taro.Page[];
12
+ declare let history: History;
13
+ // TODO 支持多路由 (APP 生命周期仅触发一次)
14
+ /** Note: 关于多页面应用
15
+ * - 需要配置路由映射(根目录跳转、404 页面……)
16
+ * - app.onPageNotFound 事件不支持
17
+ * - 应用生命周期可能多次触发
18
+ * - TabBar 会多次加载
19
+ * - 不支持路由动画
20
+ */
21
+ declare function createMultiRouter(app: AppInstance, config: MpaRouterConfig, framework?: string): Promise<void>;
22
+ declare function createRouter(app: AppInstance, config: SpaRouterConfig, framework?: string): () => void;
23
+ export { navigateTo, redirectTo, navigateBack, switchTab, reLaunch, getCurrentPages, history, createMultiRouter, createRouter };
package/dist/index.cjs.js CHANGED
@@ -4,18 +4,48 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var history = require('history');
6
6
  var runtime = require('@tarojs/runtime');
7
- var UniversalRouter = require('universal-router');
7
+ var MobileDetect = require('mobile-detect');
8
8
  var queryString = require('query-string');
9
9
  var taro = require('@tarojs/taro');
10
+ var UniversalRouter = require('universal-router');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
13
- var UniversalRouter__default = /*#__PURE__*/_interopDefaultLegacy(UniversalRouter);
14
+ var MobileDetect__default = /*#__PURE__*/_interopDefaultLegacy(MobileDetect);
14
15
  var queryString__default = /*#__PURE__*/_interopDefaultLegacy(queryString);
16
+ var UniversalRouter__default = /*#__PURE__*/_interopDefaultLegacy(UniversalRouter);
15
17
 
18
+ /*! *****************************************************************************
19
+ Copyright (c) Microsoft Corporation.
20
+
21
+ Permission to use, copy, modify, and/or distribute this software for any
22
+ purpose with or without fee is hereby granted.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
25
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
26
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
27
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
28
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30
+ PERFORMANCE OF THIS SOFTWARE.
31
+ ***************************************************************************** */
32
+
33
+ function __awaiter(thisArg, _arguments, P, generator) {
34
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
35
+ return new (P || (P = Promise))(function (resolve, reject) {
36
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
37
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
38
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
39
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
40
+ });
41
+ }
42
+
43
+ // export const removeLeadingSlash = (str = '') => str.replace(/^\.?\//, '')
44
+ // export const removeTrailingSearch = (str = '') => str.replace(/\?[\s\S]*$/, '')
16
45
  const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
17
46
  const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
18
- const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substr(prefix.length) : path;
47
+ const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
48
+ const stripTrailing = (str = '') => str.replace(/[?#][\s\S]*$/, '');
19
49
  class RoutesAlias {
20
50
  constructor() {
21
51
  this.conf = [];
@@ -178,31 +208,6 @@ function prependBasename(url = '') {
178
208
  return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
179
209
  }
180
210
 
181
- /*! *****************************************************************************
182
- Copyright (c) Microsoft Corporation.
183
-
184
- Permission to use, copy, modify, and/or distribute this software for any
185
- purpose with or without fee is hereby granted.
186
-
187
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
188
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
189
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
190
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
191
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
192
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
193
- PERFORMANCE OF THIS SOFTWARE.
194
- ***************************************************************************** */
195
-
196
- function __awaiter(thisArg, _arguments, P, generator) {
197
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
198
- return new (P || (P = Promise))(function (resolve, reject) {
199
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
200
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
201
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
202
- step((generator = generator.apply(thisArg, _arguments || [])).next());
203
- });
204
- }
205
-
206
211
  class Stacks {
207
212
  constructor() {
208
213
  this.stacks = [];
@@ -352,34 +357,35 @@ function getCurrentPages() {
352
357
  return pages.map(e => (Object.assign(Object.assign({}, e), { route: e.path || '' })));
353
358
  }
354
359
 
355
- /**
356
- * 插入页面动画需要的样式
357
- */
358
- function loadAnimateStyle(ms = 300) {
359
- const css = `
360
- .taro_router .taro_page {
361
- position: absolute;
362
- left: 0;
363
- top: 0;
364
- width: 100%;
365
- height: 100%;
366
- background-color: #fff;
367
- transform: translate(100%, 0);
368
- transition: transform ${ms}ms;
369
- z-index: 0;
360
+ let md;
361
+ let preTitle = document.title;
362
+ let isLoadDdEntry = false;
363
+ function getMobileDetect() {
364
+ if (!md) {
365
+ md = new MobileDetect__default["default"](navigator.userAgent);
366
+ }
367
+ return md;
370
368
  }
371
-
372
- .taro_router .taro_page.taro_tabbar_page,
373
- .taro_router .taro_page.taro_page_show.taro_page_stationed {
374
- transform: none;
369
+ function setTitle(title) {
370
+ return __awaiter(this, void 0, void 0, function* () {
371
+ if (preTitle === title)
372
+ return title;
373
+ document.title = title;
374
+ preTitle = title;
375
+ if (process.env.SUPPORT_DINGTALK_NAVIGATE !== 'disabled' && isDingTalk()) {
376
+ if (!isLoadDdEntry) {
377
+ isLoadDdEntry = true;
378
+ require('dingtalk-jsapi/platform');
379
+ }
380
+ const setDingTitle = require('dingtalk-jsapi/api/biz/navigation/setTitle').default;
381
+ setDingTitle({ title });
382
+ }
383
+ return title;
384
+ });
375
385
  }
376
-
377
- .taro_router .taro_page.taro_page_show {
378
- transform: translate(0, 0);
379
- }`;
380
- const style = document.createElement('style');
381
- style.innerHTML = css;
382
- document.getElementsByTagName('head')[0].appendChild(style);
386
+ function isDingTalk() {
387
+ const md = getMobileDetect();
388
+ return md.match(/DingTalk/ig);
383
389
  }
384
390
 
385
391
  let pageResizeFn;
@@ -403,7 +409,8 @@ function bindPageScroll(page, pageEl, distance = 50) {
403
409
  pageDOM = pageEl;
404
410
  let isReachBottom = false;
405
411
  pageScrollFn = function () {
406
- page.onPageScroll && page.onPageScroll({
412
+ var _a;
413
+ (_a = page.onPageScroll) === null || _a === void 0 ? void 0 : _a.call(page, {
407
414
  scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
408
415
  });
409
416
  if (isReachBottom && getOffset() > distance) {
@@ -455,6 +462,192 @@ function initTabbar(config) {
455
462
  taro.initTabBarApis(config);
456
463
  }
457
464
 
465
+ /* eslint-disable dot-notation */
466
+ class MultiPageHandler {
467
+ constructor(config) {
468
+ this.config = config;
469
+ this.mount();
470
+ }
471
+ get appId() { return 'app'; }
472
+ get router() { return this.config.router || {}; }
473
+ get routerMode() { return this.router.mode || 'hash'; }
474
+ get customRoutes() { return this.router.customRoutes || {}; }
475
+ get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
476
+ get PullDownRefresh() { return this.config.PullDownRefresh; }
477
+ set pathname(p) { this.router.pathname = p; }
478
+ get pathname() { return this.router.pathname; }
479
+ get basename() { return this.router.basename || ''; }
480
+ get pageConfig() { return this.config.route; }
481
+ get isTabBar() {
482
+ var _a;
483
+ const routePath = stripBasename(this.pathname, this.basename);
484
+ const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
485
+ if (typeof target === 'string') {
486
+ return target === routePath;
487
+ }
488
+ else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
489
+ return target.includes(routePath);
490
+ }
491
+ return false;
492
+ })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
493
+ return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
494
+ }
495
+ get search() { return location.search.substr(1); }
496
+ getQuery(search = '', options = {}) {
497
+ search = search ? `${search}&${this.search}` : this.search;
498
+ const query = search
499
+ ? queryString__default["default"].parse(search)
500
+ : {};
501
+ return Object.assign(Object.assign({}, query), options);
502
+ }
503
+ mount() {
504
+ var _a;
505
+ setHistoryMode(this.routerMode, this.router.basename);
506
+ (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
507
+ const app = document.createElement('div');
508
+ app.id = this.appId;
509
+ app.classList.add('taro_router');
510
+ if (this.tabBarList.length > 1) {
511
+ const container = document.createElement('div');
512
+ container.classList.add('taro-tabbar__container');
513
+ container.id = 'container';
514
+ const panel = document.createElement('div');
515
+ panel.classList.add('taro-tabbar__panel');
516
+ panel.appendChild(app);
517
+ container.appendChild(panel);
518
+ document.body.appendChild(container);
519
+ initTabbar(this.config);
520
+ }
521
+ else {
522
+ document.body.appendChild(app);
523
+ }
524
+ }
525
+ onReady(page, onLoad = true) {
526
+ var _a;
527
+ const pageEl = this.getPageContainer(page);
528
+ if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
529
+ const el = pageEl.firstElementChild;
530
+ (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el);
531
+ onLoad && (pageEl['__page'] = page);
532
+ }
533
+ }
534
+ load(page, pageConfig = {}) {
535
+ var _a;
536
+ if (!page)
537
+ return;
538
+ (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
539
+ var _a;
540
+ const pageEl = this.getPageContainer(page);
541
+ this.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
542
+ this.onReady(page, true);
543
+ (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
544
+ this.bindPageEvents(page, pageEl, pageConfig);
545
+ });
546
+ }
547
+ getPageContainer(page) {
548
+ var _a;
549
+ const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path;
550
+ const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
551
+ if (page) {
552
+ return document.querySelector(`.taro_page#${id}`);
553
+ }
554
+ const el = (id
555
+ ? document.querySelector(`.taro_page#${id}`)
556
+ : document.querySelector('.taro_page') ||
557
+ document.querySelector('.taro_router'));
558
+ return el || window;
559
+ }
560
+ bindPageEvents(page, pageEl, config = {}) {
561
+ var _a;
562
+ if (!pageEl) {
563
+ pageEl = this.getPageContainer();
564
+ }
565
+ const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
566
+ bindPageScroll(page, pageEl, distance);
567
+ bindPageResize(page);
568
+ }
569
+ }
570
+
571
+ // TODO 支持多路由 (APP 生命周期仅触发一次)
572
+ /** Note: 关于多页面应用
573
+ * - 需要配置路由映射(根目录跳转、404 页面……)
574
+ * - app.onPageNotFound 事件不支持
575
+ * - 应用生命周期可能多次触发
576
+ * - TabBar 会多次加载
577
+ * - 不支持路由动画
578
+ */
579
+ function createMultiRouter(app, config, framework) {
580
+ var _a, _b, _c, _d, _e, _f;
581
+ return __awaiter(this, void 0, void 0, function* () {
582
+ RouterConfig.config = config;
583
+ const handler = new MultiPageHandler(config);
584
+ const launchParam = handler.getQuery();
585
+ (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
586
+ app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
587
+ const pathName = config.pageName;
588
+ const pageConfig = handler.pageConfig;
589
+ let element;
590
+ try {
591
+ element = yield ((_b = pageConfig.load) === null || _b === void 0 ? void 0 : _b.call(pageConfig));
592
+ }
593
+ catch (error) {
594
+ throw new Error(error);
595
+ }
596
+ if (!element)
597
+ return;
598
+ let enablePullDownRefresh = ((_c = config === null || config === void 0 ? void 0 : config.window) === null || _c === void 0 ? void 0 : _c.enablePullDownRefresh) || false;
599
+ runtime.eventCenter.trigger('__taroRouterChange', {
600
+ toLocation: {
601
+ path: pathName
602
+ }
603
+ });
604
+ if (pageConfig) {
605
+ setTitle((_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title);
606
+ if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
607
+ enablePullDownRefresh = pageConfig.enablePullDownRefresh;
608
+ }
609
+ }
610
+ const el = (_e = element.default) !== null && _e !== void 0 ? _e : element;
611
+ const loadConfig = Object.assign({}, pageConfig);
612
+ delete loadConfig['path'];
613
+ delete loadConfig['load'];
614
+ const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, config.PullDownRefresh) : el, pathName + runtime.stringify(launchParam), {}, loadConfig);
615
+ handler.load(page, pageConfig);
616
+ (_f = app.onShow) === null || _f === void 0 ? void 0 : _f.call(app, launchParam);
617
+ });
618
+ }
619
+
620
+ /**
621
+ * 插入页面动画需要的样式
622
+ */
623
+ function loadAnimateStyle(ms = 300) {
624
+ const css = `
625
+ .taro_router .taro_page {
626
+ position: absolute;
627
+ left: 0;
628
+ top: 0;
629
+ width: 100%;
630
+ height: 100%;
631
+ background-color: #fff;
632
+ transform: translate(100%, 0);
633
+ transition: transform ${ms}ms;
634
+ z-index: 0;
635
+ }
636
+
637
+ .taro_router .taro_page.taro_tabbar_page,
638
+ .taro_router .taro_page.taro_page_show.taro_page_stationed {
639
+ transform: none;
640
+ }
641
+
642
+ .taro_router .taro_page.taro_page_show {
643
+ transform: translate(0, 0);
644
+ }`;
645
+ const style = document.createElement('style');
646
+ style.innerHTML = css;
647
+ document.getElementsByTagName('head')[0].appendChild(style);
648
+ }
649
+
650
+ /* eslint-disable dot-notation */
458
651
  function setDisplay(el, type = '') {
459
652
  if (el) {
460
653
  el.style.display = type;
@@ -467,10 +660,10 @@ class PageHandler {
467
660
  this.mount();
468
661
  }
469
662
  get appId() { return 'app'; }
470
- get router() { return this.config.router; }
663
+ get router() { return this.config.router || {}; }
471
664
  get routerMode() { return this.router.mode || 'hash'; }
472
665
  get customRoutes() { return this.router.customRoutes || {}; }
473
- get routes() { return this.config.routes; }
666
+ get routes() { return this.config.routes || []; }
474
667
  get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
475
668
  get PullDownRefresh() { return this.config.PullDownRefresh; }
476
669
  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; }
@@ -517,7 +710,7 @@ class PageHandler {
517
710
  }
518
711
  return false;
519
712
  })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
520
- return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
713
+ return !!pagePath && this.tabBarList.some(t => stripTrailing(t.pagePath) === pagePath);
521
714
  }
522
715
  isSamePage(page) {
523
716
  const routePath = stripBasename(this.pathname, this.basename);
@@ -731,7 +924,6 @@ function createRouter(app, config, framework) {
731
924
  var _a, _b;
732
925
  RouterConfig.config = config;
733
926
  const handler = new PageHandler(config);
734
- const runtimeHooks = runtime.container.get(runtime.SERVICE_IDENTIFIER.Hooks);
735
927
  routesAlias.set(handler.router.customRoutes);
736
928
  const basename = handler.router.basename;
737
929
  const routes = handler.routes.map(route => {
@@ -745,6 +937,7 @@ function createRouter(app, config, framework) {
745
937
  const router = new UniversalRouter__default["default"](routes, { baseUrl: basename || '' });
746
938
  const launchParam = handler.getQuery(stacks.length);
747
939
  (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
940
+ app.onError && window.addEventListener('error', e => { var _a; return (_a = app.onError) === null || _a === void 0 ? void 0 : _a.call(app, e.message); });
748
941
  const render = ({ location, action }) => __awaiter(this, void 0, void 0, function* () {
749
942
  var _c, _d, _e, _f, _g;
750
943
  handler.pathname = decodeURI(location.pathname);
@@ -774,6 +967,7 @@ function createRouter(app, config, framework) {
774
967
  });
775
968
  if (pageConfig) {
776
969
  document.title = (_e = pageConfig.navigationBarTitleText) !== null && _e !== void 0 ? _e : document.title;
970
+ setTitle((_f = pageConfig.navigationBarTitleText) !== null && _f !== void 0 ? _f : document.title);
777
971
  if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
778
972
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
779
973
  }
@@ -785,12 +979,15 @@ function createRouter(app, config, framework) {
785
979
  // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
786
980
  const prevIndex = stacks.getPrevIndex(pathname);
787
981
  const delta = stacks.getDelta(pathname);
788
- handler.unload(currentPage, delta, prevIndex > -1);
789
- if (prevIndex > -1) {
790
- handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
791
- }
792
- else {
793
- shouldLoad = true;
982
+ // NOTE: Safari 内核浏览器在非应用页面返回上一页时,会触发额外的 POP 事件,此处需避免当前页面被错误卸载
983
+ if (currentPage !== stacks.getItem(prevIndex)) {
984
+ handler.unload(currentPage, delta, prevIndex > -1);
985
+ if (prevIndex > -1) {
986
+ handler.show(stacks.getItem(prevIndex), pageConfig, prevIndex);
987
+ }
988
+ else {
989
+ shouldLoad = true;
990
+ }
794
991
  }
795
992
  }
796
993
  else {
@@ -815,12 +1012,12 @@ function createRouter(app, config, framework) {
815
1012
  shouldLoad = true;
816
1013
  }
817
1014
  if (shouldLoad || stacks.length < 1) {
818
- const el = (_f = element.default) !== null && _f !== void 0 ? _f : element;
1015
+ const el = (_g = element.default) !== null && _g !== void 0 ? _g : element;
819
1016
  const loadConfig = Object.assign({}, pageConfig);
820
1017
  const stacksIndex = stacks.length;
821
1018
  delete loadConfig['path'];
822
1019
  delete loadConfig['load'];
823
- const page = runtime.createPageConfig(enablePullDownRefresh ? (_g = runtimeHooks.createPullDownComponent) === null || _g === void 0 ? void 0 : _g.call(runtimeHooks, el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(stacksIndex)), {}, loadConfig);
1020
+ const page = runtime.createPageConfig(enablePullDownRefresh ? runtime.hooks.call('createPullDownComponent', el, location.pathname, framework, handler.PullDownRefresh) : el, pathname + runtime.stringify(handler.getQuery(stacksIndex)), {}, loadConfig);
824
1021
  if (params)
825
1022
  page.options = params;
826
1023
  return handler.load(page, pageConfig, stacksIndex);
@@ -835,160 +1032,6 @@ function createRouter(app, config, framework) {
835
1032
  return exports.history.listen(render);
836
1033
  }
837
1034
 
838
- class MultiPageHandler {
839
- constructor(config) {
840
- this.config = config;
841
- this.mount();
842
- }
843
- get appId() { return 'app'; }
844
- get router() { return this.config.router; }
845
- get routerMode() { return this.router.mode || 'hash'; }
846
- get customRoutes() { return this.router.customRoutes || {}; }
847
- get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
848
- get PullDownRefresh() { return this.config.PullDownRefresh; }
849
- set pathname(p) { this.router.pathname = p; }
850
- get pathname() { return this.router.pathname; }
851
- get basename() { return this.router.basename || ''; }
852
- get pageConfig() { return this.config.route; }
853
- get isTabBar() {
854
- var _a;
855
- const routePath = stripBasename(this.pathname, this.basename);
856
- const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
857
- if (typeof target === 'string') {
858
- return target === routePath;
859
- }
860
- else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
861
- return target.includes(routePath);
862
- }
863
- return false;
864
- })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
865
- return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
866
- }
867
- get search() { return location.search.substr(1); }
868
- getQuery(search = '', options = {}) {
869
- search = search ? `${search}&${this.search}` : this.search;
870
- const query = search
871
- ? queryString__default["default"].parse(search)
872
- : {};
873
- return Object.assign(Object.assign({}, query), options);
874
- }
875
- mount() {
876
- var _a;
877
- setHistoryMode(this.routerMode, this.router.basename);
878
- (_a = document.getElementById('app')) === null || _a === void 0 ? void 0 : _a.remove();
879
- const app = document.createElement('div');
880
- app.id = this.appId;
881
- app.classList.add('taro_router');
882
- if (this.tabBarList.length > 1) {
883
- const container = document.createElement('div');
884
- container.classList.add('taro-tabbar__container');
885
- container.id = 'container';
886
- const panel = document.createElement('div');
887
- panel.classList.add('taro-tabbar__panel');
888
- panel.appendChild(app);
889
- container.appendChild(panel);
890
- document.body.appendChild(container);
891
- initTabbar(this.config);
892
- }
893
- else {
894
- document.body.appendChild(app);
895
- }
896
- }
897
- onReady(page, onLoad = true) {
898
- var _a;
899
- const pageEl = this.getPageContainer(page);
900
- if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
901
- const el = pageEl.firstElementChild;
902
- (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el);
903
- onLoad && (pageEl['__page'] = page);
904
- }
905
- }
906
- load(page, pageConfig = {}) {
907
- var _a;
908
- if (!page)
909
- return;
910
- (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
911
- var _a;
912
- const pageEl = this.getPageContainer(page);
913
- this.isTabBar && (pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page'));
914
- this.onReady(page, true);
915
- (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
916
- this.bindPageEvents(page, pageEl, pageConfig);
917
- });
918
- }
919
- getPageContainer(page) {
920
- var _a;
921
- const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = runtime.Current.page) === null || _a === void 0 ? void 0 : _a.path;
922
- const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
923
- if (page) {
924
- return document.querySelector(`.taro_page#${id}`);
925
- }
926
- const el = (id
927
- ? document.querySelector(`.taro_page#${id}`)
928
- : document.querySelector('.taro_page') ||
929
- document.querySelector('.taro_router'));
930
- return el || window;
931
- }
932
- bindPageEvents(page, pageEl, config = {}) {
933
- var _a;
934
- if (!pageEl) {
935
- pageEl = this.getPageContainer();
936
- }
937
- const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
938
- bindPageScroll(page, pageEl, distance);
939
- bindPageResize(page);
940
- }
941
- }
942
-
943
- // TODO 支持多路由 (APP 生命周期仅触发一次)
944
- /** Note: 关于多页面应用
945
- * - 需要配置路由映射(根目录跳转、404 页面……)
946
- * - app.onPageNotFound 事件不支持
947
- * - 应用生命周期可能多次触发
948
- * - TabBar 会多次加载
949
- * - 不支持路由动画
950
- */
951
- function createMultiRouter(app, config, framework) {
952
- var _a, _b, _c, _d, _e, _f, _g;
953
- return __awaiter(this, void 0, void 0, function* () {
954
- RouterConfig.config = config;
955
- const handler = new MultiPageHandler(config);
956
- const runtimeHooks = runtime.container.get(runtime.SERVICE_IDENTIFIER.Hooks);
957
- const launchParam = handler.getQuery();
958
- (_a = app.onLaunch) === null || _a === void 0 ? void 0 : _a.call(app, launchParam);
959
- const pathName = config.pageName;
960
- const pageConfig = handler.pageConfig;
961
- let element;
962
- try {
963
- element = yield ((_b = pageConfig.load) === null || _b === void 0 ? void 0 : _b.call(pageConfig));
964
- }
965
- catch (error) {
966
- throw new Error(error);
967
- }
968
- if (!element)
969
- return;
970
- let enablePullDownRefresh = ((_c = config === null || config === void 0 ? void 0 : config.window) === null || _c === void 0 ? void 0 : _c.enablePullDownRefresh) || false;
971
- runtime.eventCenter.trigger('__taroRouterChange', {
972
- toLocation: {
973
- path: pathName
974
- }
975
- });
976
- if (pageConfig) {
977
- document.title = (_d = pageConfig.navigationBarTitleText) !== null && _d !== void 0 ? _d : document.title;
978
- if (typeof pageConfig.enablePullDownRefresh === 'boolean') {
979
- enablePullDownRefresh = pageConfig.enablePullDownRefresh;
980
- }
981
- }
982
- const el = (_e = element.default) !== null && _e !== void 0 ? _e : element;
983
- const loadConfig = Object.assign({}, pageConfig);
984
- delete loadConfig['path'];
985
- delete loadConfig['load'];
986
- const page = runtime.createPageConfig(enablePullDownRefresh ? (_f = runtimeHooks.createPullDownComponent) === null || _f === void 0 ? void 0 : _f.call(runtimeHooks, el, location.pathname, framework, config.PullDownRefresh) : el, pathName + runtime.stringify(launchParam), {}, loadConfig);
987
- handler.load(page, pageConfig);
988
- (_g = app.onShow) === null || _g === void 0 ? void 0 : _g.call(app, launchParam);
989
- });
990
- }
991
-
992
1035
  exports.createMultiRouter = createMultiRouter;
993
1036
  exports.createRouter = createRouter;
994
1037
  exports.getCurrentPages = getCurrentPages;