UNPKG

6.66 kBJavaScriptView Raw
1import { addLeadingSlash, stripBasename, Current, eventCenter } from '@tarojs/runtime';
2import queryString from 'query-string';
3import { bindPageResize } from '../events/resize.js';
4import { bindPageScroll } from '../events/scroll.js';
5import { setHistory } from '../history.js';
6import { loadRouterStyle } from '../style.js';
7
8/* eslint-disable dot-notation */
9class MultiPageHandler {
10 constructor(config, history) {
11 this.history = history;
12 this.config = config;
13 this.mount();
14 }
15 get appId() { return this.config.appId || 'app'; }
16 get router() { return this.config.router || {}; }
17 get routerMode() { return this.router.mode || 'hash'; }
18 get customRoutes() { return this.router.customRoutes || {}; }
19 get tabBarList() { var _a; return ((_a = this.config.tabBar) === null || _a === void 0 ? void 0 : _a.list) || []; }
20 get PullDownRefresh() { return this.config.PullDownRefresh; }
21 set pathname(p) { this.router.pathname = p; }
22 get pathname() { return this.router.pathname; }
23 get basename() { return this.router.basename || ''; }
24 get pageConfig() { return this.config.route; }
25 get isTabBar() {
26 var _a;
27 const routePath = addLeadingSlash(stripBasename(this.pathname, this.basename));
28 const pagePath = ((_a = Object.entries(this.customRoutes).find(([, target]) => {
29 if (typeof target === 'string') {
30 return target === routePath;
31 }
32 else if ((target === null || target === void 0 ? void 0 : target.length) > 0) {
33 return target.includes(routePath);
34 }
35 return false;
36 })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
37 return !!pagePath && this.tabBarList.some(t => t.pagePath === pagePath);
38 }
39 get search() { return location.search.substr(1); }
40 get usingWindowScroll() {
41 var _a;
42 let usingWindowScroll = true;
43 if (typeof ((_a = this.pageConfig) === null || _a === void 0 ? void 0 : _a.usingWindowScroll) === 'boolean') {
44 usingWindowScroll = this.pageConfig.usingWindowScroll;
45 }
46 const win = window;
47 win.__taroAppConfig || (win.__taroAppConfig = {});
48 win.__taroAppConfig.usingWindowScroll = usingWindowScroll;
49 return usingWindowScroll;
50 }
51 getQuery(search = '', options = {}) {
52 search = search ? `${search}&${this.search}` : this.search;
53 const query = search
54 ? queryString.parse(search)
55 : {};
56 return Object.assign(Object.assign({}, query), options);
57 }
58 isDefaultNavigationStyle() {
59 var _a, _b;
60 let style = (_a = this.config.window) === null || _a === void 0 ? void 0 : _a.navigationStyle;
61 if (typeof ((_b = this.pageConfig) === null || _b === void 0 ? void 0 : _b.navigationStyle) === 'string') {
62 style = this.pageConfig.navigationStyle;
63 }
64 return style !== 'custom';
65 }
66 mount() {
67 setHistory(this.history, this.basename);
68 // Note: 注入页面样式
69 loadRouterStyle(this.tabBarList.length > 1, this.usingWindowScroll);
70 }
71 onReady(page, onLoad = true) {
72 var _a;
73 const pageEl = this.getPageContainer(page);
74 if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
75 const el = pageEl.firstElementChild;
76 const componentOnReady = el === null || el === void 0 ? void 0 : el['componentOnReady'];
77 if (componentOnReady) {
78 componentOnReady === null || componentOnReady === void 0 ? void 0 : componentOnReady().then(() => {
79 requestAnimationFrame(() => {
80 var _a;
81 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
82 pageEl['__isReady'] = true;
83 });
84 });
85 }
86 else {
87 (_a = page.onReady) === null || _a === void 0 ? void 0 : _a.call(page);
88 pageEl['__isReady'] = true;
89 }
90 onLoad && (pageEl['__page'] = page);
91 }
92 }
93 load(page, pageConfig = {}) {
94 var _a;
95 if (!page)
96 return;
97 (_a = page.onLoad) === null || _a === void 0 ? void 0 : _a.call(page, this.getQuery('', page.options), () => {
98 var _a;
99 const pageEl = this.getPageContainer(page);
100 if (this.isTabBar) {
101 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_tabbar_page');
102 }
103 if (this.isDefaultNavigationStyle()) {
104 pageEl === null || pageEl === void 0 ? void 0 : pageEl.classList.add('taro_navigation_page');
105 }
106 this.onReady(page, true);
107 (_a = page.onShow) === null || _a === void 0 ? void 0 : _a.call(page);
108 this.bindPageEvents(page, pageConfig);
109 this.triggerRouterChange();
110 });
111 }
112 getPageContainer(page) {
113 var _a;
114 const path = page ? page === null || page === void 0 ? void 0 : page.path : (_a = Current.page) === null || _a === void 0 ? void 0 : _a.path;
115 const id = path === null || path === void 0 ? void 0 : path.replace(/([^a-z0-9\u00a0-\uffff_-])/ig, '\\$1');
116 if (page) {
117 return document.querySelector(`.taro_page#${id}`);
118 }
119 const el = (id
120 ? document.querySelector(`.taro_page#${id}`)
121 : document.querySelector('.taro_page') ||
122 document.querySelector('.taro_router'));
123 return el;
124 }
125 getScrollingElement(page) {
126 if (this.usingWindowScroll)
127 return window;
128 return this.getPageContainer(page) || window;
129 }
130 bindPageEvents(page, config = {}) {
131 var _a;
132 const scrollEl = this.getScrollingElement(page);
133 const distance = config.onReachBottomDistance || ((_a = this.config.window) === null || _a === void 0 ? void 0 : _a.onReachBottomDistance) || 50;
134 bindPageScroll(page, scrollEl, distance);
135 bindPageResize(page);
136 }
137 triggerRouterChange() {
138 /**
139 * @tarojs/runtime 中生命周期跑在 promise 中,所以这里需要 setTimeout 延迟事件调用
140 * TODO 考虑将生命周期返回 Promise,用于处理相关事件调用顺序
141 */
142 setTimeout(() => {
143 eventCenter.trigger('__afterTaroRouterChange', {
144 toLocation: {
145 path: this.pathname
146 }
147 });
148 }, 0);
149 }
150}
151
152export { MultiPageHandler as default };