@tarojs/router 3.3.11 → 3.3.15

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.
package/dist/index.js CHANGED
@@ -27,14 +27,14 @@ function _extends() {
27
27
  var r,B=r||(r={});B.Pop="POP";B.Push="PUSH";B.Replace="REPLACE";var C="production"!==process.env.NODE_ENV?function(b){return Object.freeze(b)}:function(b){return b};function D(b,h){if(!b){"undefined"!==typeof console&&console.warn(h);try{throw Error(h);}catch(k){}}}function E(b){b.preventDefault();b.returnValue="";}
28
28
  function F(){var b=[];return {get length(){return b.length},push:function(h){b.push(h);return function(){b=b.filter(function(k){return k!==h});}},call:function(h){b.forEach(function(k){return k&&k(h)});}}}function H(){return Math.random().toString(36).substr(2,8)}function I(b){var h=b.pathname,k=b.search;b=b.hash;return (void 0===h?"/":h)+(void 0===k?"":k)+(void 0===b?"":b)}
29
29
  function J(b){var h={};if(b){var k=b.indexOf("#");0<=k&&(h.hash=b.substr(k),b=b.substr(0,k));k=b.indexOf("?");0<=k&&(h.search=b.substr(k),b=b.substr(0,k));b&&(h.pathname=b);}return h}
30
- function createBrowserHistory(b){function h(){var c=p.location,a=m.state||{};return [a.idx,C({pathname:c.pathname,search:c.search,hash:c.hash,state:a.usr||null,key:a.key||"default"})]}function k(c){return "string"===typeof c?c:I(c)}function x(c,a){void 0===a&&(a=null);return C(_extends({},q,"string"===typeof c?J(c):c,{state:a,key:H()}))}function z(c){t=c;c=h();v=c[0];q=c[1];d.call({action:t,location:q});}function A(c,a){function e(){A(c,a);}var l=r.Push,g=x(c,a);if(!f.length||(f.call({action:l,
31
- location:g,retry:e}),!1)){var n=[{usr:g.state,key:g.key,idx:v+1},k(g)];g=n[0];n=n[1];try{m.pushState(g,"",n);}catch(G){p.location.assign(n);}z(l);}}function y(c,a){function e(){y(c,a);}var l=r.Replace,g=x(c,a);f.length&&(f.call({action:l,location:g,retry:e}),1)||(g=[{usr:g.state,key:g.key,idx:v},k(g)],m.replaceState(g[0],"",g[1]),z(l));}function w(c){m.go(c);}void 0===b&&(b={});b=b.window;var p=void 0===b?document.defaultView:b,m=p.history,u=null;p.addEventListener("popstate",function(){if(u){ f.call(u),
32
- u=null; }else {var c=r.Pop,a=h(),e=a[0];a=a[1];if(f.length){ if(null!=e){var l=v-e;l&&(u={action:c,location:a,retry:function(){w(-1*l);}},w(l));}else { "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):void 0; } }else { z(c); }}});var t=
33
- r.Pop;b=h();var v=b[0],q=b[1],d=F(),f=F();null==v&&(v=0,m.replaceState(_extends({},m.state,{idx:v}),""));return {get action(){return t},get location(){return q},createHref:k,push:A,replace:y,go:w,back:function(){w(-1);},forward:function(){w(1);},listen:function(c){return d.push(c)},block:function(c){var a=f.push(c);1===f.length&&p.addEventListener("beforeunload",E);return function(){a();f.length||p.removeEventListener("beforeunload",E);}}}}function createHashHistory(b){function h(){var a=J(m.location.hash.substr(1)),e=a.pathname,l=a.search;a=a.hash;var g=u.state||{};return [g.idx,C({pathname:void 0===e?"/":e,search:void 0===l?"":l,hash:void 0===a?"":a,state:g.usr||null,key:g.key||"default"})]}function k(){if(t){ c.call(t),t=null; }else {var a=r.Pop,e=h(),l=e[0];e=e[1];if(c.length){ if(null!=l){var g=q-l;g&&(t={action:a,location:e,retry:function(){p(-1*g);}},p(g));}else { "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):
34
- void 0; } }else { A(a); }}}function x(a){var e=document.querySelector("base"),l="";e&&e.getAttribute("href")&&(e=m.location.href,l=e.indexOf("#"),l=-1===l?e:e.slice(0,l));return l+"#"+("string"===typeof a?a:I(a))}function z(a,e){void 0===e&&(e=null);return C(_extends({},d,"string"===typeof a?J(a):a,{state:e,key:H()}))}function A(a){v=a;a=h();q=a[0];d=a[1];f.call({action:v,location:d});}function y(a,e){function l(){y(a,e);}var g=r.Push,n=z(a,e);"production"!==process.env.NODE_ENV?D("/"===n.pathname.charAt(0),
35
- "Relative pathnames are not supported in hash history.push("+JSON.stringify(a)+")"):void 0;if(!c.length||(c.call({action:g,location:n,retry:l}),!1)){var G=[{usr:n.state,key:n.key,idx:q+1},x(n)];n=G[0];G=G[1];try{u.pushState(n,"",G);}catch(K){m.location.assign(G);}A(g);}}function w(a,e){function l(){w(a,e);}var g=r.Replace,n=z(a,e);"production"!==process.env.NODE_ENV?D("/"===n.pathname.charAt(0),"Relative pathnames are not supported in hash history.replace("+JSON.stringify(a)+")"):void 0;c.length&&(c.call({action:g,
36
- location:n,retry:l}),1)||(n=[{usr:n.state,key:n.key,idx:q},x(n)],u.replaceState(n[0],"",n[1]),A(g));}function p(a){u.go(a);}void 0===b&&(b={});b=b.window;var m=void 0===b?document.defaultView:b,u=m.history,t=null;m.addEventListener("popstate",k);m.addEventListener("hashchange",function(){var a=h()[1];I(a)!==I(d)&&k();});var v=r.Pop;b=h();var q=b[0],d=b[1],f=F(),c=F();null==q&&(q=0,u.replaceState(_extends({},u.state,{idx:q}),""));return {get action(){return v},get location(){return d},createHref:x,push:y,
37
- replace:w,go:p,back:function(){p(-1);},forward:function(){p(1);},listen:function(a){return f.push(a)},block:function(a){var e=c.push(a);1===c.length&&m.addEventListener("beforeunload",E);return function(){e();c.length||m.removeEventListener("beforeunload",E);}}}}
30
+ function createBrowserHistory(b){function h(){var c=p.location,a=m.state||{};return [a.idx,C({pathname:c.pathname,search:c.search,hash:c.hash,state:a.usr||null,key:a.key||"default"})]}function k(c){return "string"===typeof c?c:I(c)}function x(c,a){void 0===a&&(a=null);return C(_extends({pathname:q.pathname,hash:"",search:""},"string"===typeof c?J(c):c,{state:a,key:H()}))}function z(c){t=c;c=h();v=c[0];q=c[1];d.call({action:t,location:q});}function A(c,a){function e(){A(c,a);}var l=r.Push,g=x(c,
31
+ a);if(!f.length||(f.call({action:l,location:g,retry:e}),!1)){var n=[{usr:g.state,key:g.key,idx:v+1},k(g)];g=n[0];n=n[1];try{m.pushState(g,"",n);}catch(G){p.location.assign(n);}z(l);}}function y(c,a){function e(){y(c,a);}var l=r.Replace,g=x(c,a);f.length&&(f.call({action:l,location:g,retry:e}),1)||(g=[{usr:g.state,key:g.key,idx:v},k(g)],m.replaceState(g[0],"",g[1]),z(l));}function w(c){m.go(c);}void 0===b&&(b={});b=b.window;var p=void 0===b?document.defaultView:b,m=p.history,u=null;p.addEventListener("popstate",
32
+ function(){if(u){ f.call(u),u=null; }else {var c=r.Pop,a=h(),e=a[0];a=a[1];if(f.length){ if(null!=e){var l=v-e;l&&(u={action:c,location:a,retry:function(){w(-1*l);}},w(l));}else { "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):
33
+ void 0; } }else { z(c); }}});var t=r.Pop;b=h();var v=b[0],q=b[1],d=F(),f=F();null==v&&(v=0,m.replaceState(_extends({},m.state,{idx:v}),""));return {get action(){return t},get location(){return q},createHref:k,push:A,replace:y,go:w,back:function(){w(-1);},forward:function(){w(1);},listen:function(c){return d.push(c)},block:function(c){var a=f.push(c);1===f.length&&p.addEventListener("beforeunload",E);return function(){a();f.length||p.removeEventListener("beforeunload",E);}}}}function createHashHistory(b){function h(){var a=J(m.location.hash.substr(1)),e=a.pathname,l=a.search;a=a.hash;var g=u.state||{};return [g.idx,C({pathname:void 0===e?"/":e,search:void 0===l?"":l,hash:void 0===a?"":a,state:g.usr||null,key:g.key||"default"})]}function k(){if(t){ c.call(t),t=null; }else {var a=r.Pop,e=h(),l=e[0];e=e[1];if(c.length){ if(null!=l){var g=q-l;g&&(t={action:a,location:e,retry:function(){p(-1*g);}},p(g));}else { "production"!==process.env.NODE_ENV?D(!1,"You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation."):
34
+ void 0; } }else { A(a); }}}function x(a){var e=document.querySelector("base"),l="";e&&e.getAttribute("href")&&(e=m.location.href,l=e.indexOf("#"),l=-1===l?e:e.slice(0,l));return l+"#"+("string"===typeof a?a:I(a))}function z(a,e){void 0===e&&(e=null);return C(_extends({pathname:d.pathname,hash:"",search:""},"string"===typeof a?J(a):a,{state:e,key:H()}))}function A(a){v=a;a=h();q=a[0];d=a[1];f.call({action:v,location:d});}function y(a,e){function l(){y(a,e);}var g=r.Push,n=z(a,e);"production"!==process.env.NODE_ENV?
35
+ D("/"===n.pathname.charAt(0),"Relative pathnames are not supported in hash history.push("+JSON.stringify(a)+")"):void 0;if(!c.length||(c.call({action:g,location:n,retry:l}),!1)){var G=[{usr:n.state,key:n.key,idx:q+1},x(n)];n=G[0];G=G[1];try{u.pushState(n,"",G);}catch(K){m.location.assign(G);}A(g);}}function w(a,e){function l(){w(a,e);}var g=r.Replace,n=z(a,e);"production"!==process.env.NODE_ENV?D("/"===n.pathname.charAt(0),"Relative pathnames are not supported in hash history.replace("+JSON.stringify(a)+
36
+ ")"):void 0;c.length&&(c.call({action:g,location:n,retry:l}),1)||(n=[{usr:n.state,key:n.key,idx:q},x(n)],u.replaceState(n[0],"",n[1]),A(g));}function p(a){u.go(a);}void 0===b&&(b={});b=b.window;var m=void 0===b?document.defaultView:b,u=m.history,t=null;m.addEventListener("popstate",k);m.addEventListener("hashchange",function(){var a=h()[1];I(a)!==I(d)&&k();});var v=r.Pop;b=h();var q=b[0],d=b[1],f=F(),c=F();null==q&&(q=0,u.replaceState(_extends({},u.state,{idx:q}),""));return {get action(){return v},get location(){return d},
37
+ createHref:x,push:y,replace:w,go:p,back:function(){p(-1);},forward:function(){p(1);},listen:function(a){return f.push(a)},block:function(a){var e=c.push(a);1===c.length&&m.addEventListener("beforeunload",E);return function(){e();c.length||m.removeEventListener("beforeunload",E);}}}}
38
38
 
39
39
  var basename = '/';
40
40
  function setHistoryMode(mode, base) {
@@ -52,13 +52,60 @@ function setHistoryMode(mode, base) {
52
52
  exports.history = createHashHistory(options);
53
53
  }
54
54
  }
55
- function parsePath(url) {
55
+ function prependBasename(url) {
56
56
  if ( url === void 0 ) url = '';
57
57
 
58
58
  return basename.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
59
- }
59
+ }
60
+ var hasBasename = function (path, prefix) { return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); };
61
+ var stripBasename = function (path, prefix) { return hasBasename(path, prefix) ? path.substr(prefix.length) : path; };
62
+
63
+ var Stacks = function Stacks() {
64
+ this.stacks = [];
65
+ this.backDelta = 0;
66
+ };
67
+
68
+ var prototypeAccessors = { delta: { configurable: true },length: { configurable: true },last: { configurable: true } };
69
+ prototypeAccessors.delta.set = function (delta) {
70
+ if (delta > 0) {
71
+ this.backDelta = delta;
72
+ }
73
+ else {
74
+ --this.backDelta;
75
+ }
76
+ };
77
+ prototypeAccessors.length.get = function () {
78
+ return this.stacks.length;
79
+ };
80
+ prototypeAccessors.last.get = function () {
81
+ return this.stacks[this.length - 1];
82
+ };
83
+ Stacks.prototype.get = function get () {
84
+ return this.stacks;
85
+ };
86
+ Stacks.prototype.getItem = function getItem (index) {
87
+ return this.stacks[index];
88
+ };
89
+ Stacks.prototype.getDelta = function getDelta (pathname) {
90
+ if (this.backDelta >= 1) {
91
+ return this.backDelta;
92
+ }
93
+ // NOTE: 此处为了修复浏览器后退多级页面,在大量重复路由状况下可能出现判断错误的情况 (增强判断能力只能考虑在 query 中新增参数来判断,暂时搁置)
94
+ var prevIndex = this.stacks.findIndex(function (r) { var _a; return ((_a = r.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname; });
95
+ return this.length - 1 - prevIndex;
96
+ };
97
+ Stacks.prototype.getPrevIndex = function getPrevIndex (pathname) {
98
+ return this.length - 1 - this.getDelta(pathname);
99
+ };
100
+ Stacks.prototype.pop = function pop () {
101
+ return this.stacks.pop();
102
+ };
103
+ Stacks.prototype.push = function push (page) {
104
+ return this.stacks.push(page);
105
+ };
60
106
 
61
- var stacks = [];
107
+ Object.defineProperties( Stacks.prototype, prototypeAccessors );
108
+ var stacks = new Stacks();
62
109
 
63
110
  var routesAlias = {};
64
111
  function setRoutesAlias(alias) {
@@ -70,75 +117,81 @@ function addLeadingSlash(path) {
70
117
  }
71
118
  return path.charAt(0) === '/' ? path : '/' + path;
72
119
  }
73
- // 解决navigateBack调用delta>1时,路由栈异常问题
74
- // 比如:A->B->C,navigateBack({delta: 2}),此时路由栈中还存在B页面
75
- // 原因:主要是由于一次性退出多层级页面时,此action只会执行一次,此处进行手动处理
76
- var historyBackDelta = 1;
77
- function setHistoryBackDelta(delta) {
78
- historyBackDelta = delta;
79
- }
80
- // eslint-disable-next-line @typescript-eslint/ban-types
81
- var throttle = function (fn, threshold) {
82
- var lastTime = 0;
83
- return function () {
84
- var now = Date.now();
85
- if (now - lastTime > threshold) {
86
- fn.apply(this, arguments);
87
- lastTime = now;
88
- }
89
- };
120
+ var isTabBar = function (config) {
121
+ var _a, _b;
122
+ var ref = config.router;
123
+ var customRoutes = ref.customRoutes; if ( customRoutes === void 0 ) customRoutes = {};
124
+ var basename = ref.basename; if ( basename === void 0 ) basename = '';
125
+ var pathname = ref.pathname;
126
+ var routePath = stripBasename(pathname, basename);
127
+ var pagePath = ((_a = Object.entries(customRoutes).find(function (ref) {
128
+ var target = ref[1];
129
+
130
+ return target === routePath;
131
+ })) === null || _a === void 0 ? void 0 : _a[0]) || routePath;
132
+ return !!pagePath && (((_b = config.tabBar) === null || _b === void 0 ? void 0 : _b.list) || []).some(function (t) { return t.pagePath === pagePath; });
90
133
  };
91
134
 
92
135
  function processNavigateUrl(option) {
93
- var url = option.url;
94
- var matches = option.url.match(/[?&?].*/);
95
- var parameters = '';
96
- if (matches && matches.length) {
97
- parameters = matches[0];
98
- url = url.replace(parameters, '');
99
- }
136
+ var _a;
137
+ var pathPieces = J(option.url);
138
+ // 处理自定义路由
100
139
  Object.keys(routesAlias).forEach(function (key) {
101
- if (addLeadingSlash(key) === addLeadingSlash(url)) {
102
- option.url = routesAlias[key] + parameters;
140
+ if (addLeadingSlash(key) === addLeadingSlash(pathPieces.pathname)) {
141
+ pathPieces.pathname = routesAlias[key];
103
142
  }
104
143
  });
105
- }
106
- function navigate(option, method) {
107
- var success = option.success;
108
- var complete = option.complete;
109
- var fail = option.fail;
110
- var failReason;
111
- if (option.url) {
112
- processNavigateUrl(option);
113
- }
114
- try {
115
- if (method === 'navigateTo') {
116
- exports.history.push(parsePath(option.url), { timestamp: Date.now() });
117
- }
118
- else if (method === 'redirectTo') {
119
- exports.history.replace(parsePath(option.url), { timestamp: Date.now() });
120
- }
121
- else if (method === 'navigateBack') {
122
- setHistoryBackDelta(option.delta);
123
- exports.history.go(-option.delta);
124
- }
125
- }
126
- catch (error) {
127
- failReason = error;
144
+ // 处理相对路径
145
+ if ((_a = pathPieces === null || pathPieces === void 0 ? void 0 : pathPieces.pathname) === null || _a === void 0 ? void 0 : _a.includes('./')) {
146
+ var parts = exports.history.location.pathname.split('/');
147
+ parts.pop();
148
+ pathPieces.pathname.split('/').forEach(function (item) {
149
+ if (item === '.') {
150
+ return;
151
+ }
152
+ item === '..' ? parts.pop() : parts.push(item);
153
+ });
154
+ pathPieces.pathname = parts.join('/');
128
155
  }
156
+ // 处理 basename
157
+ pathPieces.pathname = prependBasename(pathPieces.pathname);
158
+ // hack fix history v5 bug: https://github.com/remix-run/history/issues/814
159
+ if (!pathPieces.search)
160
+ { pathPieces.search = ''; }
161
+ return pathPieces;
162
+ }
163
+ async function navigate(option, method) {
129
164
  return new Promise(function (resolve, reject) {
130
- if (failReason) {
131
- fail && fail(failReason);
132
- complete && complete();
133
- reject(failReason);
134
- return;
135
- }
136
- var unlisten = exports.history.listen(function () {
137
- success && success();
138
- complete && complete();
165
+ var success = option.success;
166
+ var complete = option.complete;
167
+ var fail = option.fail;
168
+ var unListen = exports.history.listen(function () {
169
+ success === null || success === void 0 ? void 0 : success();
170
+ complete === null || complete === void 0 ? void 0 : complete();
139
171
  resolve();
140
- unlisten();
172
+ unListen();
141
173
  });
174
+ try {
175
+ if ('url' in option) {
176
+ var pathPieces = processNavigateUrl(option);
177
+ var state = { timestamp: Date.now() };
178
+ if (method === 'navigateTo') {
179
+ exports.history.push(pathPieces, state);
180
+ }
181
+ else if (method === 'redirectTo') {
182
+ exports.history.replace(pathPieces, state);
183
+ }
184
+ }
185
+ else if (method === 'navigateBack') {
186
+ stacks.delta = option.delta;
187
+ exports.history.go(-option.delta);
188
+ }
189
+ }
190
+ catch (error) {
191
+ fail === null || fail === void 0 ? void 0 : fail(error);
192
+ complete === null || complete === void 0 ? void 0 : complete();
193
+ reject(error);
194
+ }
142
195
  });
143
196
  }
144
197
  function navigateTo(option) {
@@ -156,13 +209,15 @@ function navigateBack(options) {
156
209
  return navigate(options, 'navigateBack');
157
210
  }
158
211
  function switchTab(option) {
159
- return navigateTo(option);
212
+ // TODO: 清除掉所有的栈去目标页面
213
+ return redirectTo(option);
160
214
  }
161
215
  function reLaunch(option) {
216
+ // TODO: 清除掉所有的栈去目标页面
162
217
  return redirectTo(option);
163
218
  }
164
219
  function getCurrentPages() {
165
- return stacks;
220
+ return stacks.get();
166
221
  }
167
222
 
168
223
  /**
@@ -808,6 +863,7 @@ var UniversalRouter = function () {
808
863
 
809
864
  UniversalRouter.pathToRegexp = pathToRegexp_1;
810
865
 
866
+ var Taro = require('@tarojs/taro-h5');
811
867
  function initTabbar(config) {
812
868
  if (config.tabBar == null) {
813
869
  return;
@@ -819,7 +875,6 @@ function initTabbar(config) {
819
875
  tabbar.conf.homePage = exports.history.location.pathname === '/' ? homePage : exports.history.location.pathname;
820
876
  var routerConfig = config.router;
821
877
  tabbar.conf.mode = routerConfig && routerConfig.mode ? routerConfig.mode : 'hash';
822
- tabbar.conf.custom = !!routerConfig.customRoutes;
823
878
  if (routerConfig.customRoutes) {
824
879
  tabbar.conf.custom = true;
825
880
  tabbar.conf.customRoutes = routerConfig.customRoutes;
@@ -828,9 +883,13 @@ function initTabbar(config) {
828
883
  tabbar.conf.custom = false;
829
884
  tabbar.conf.customRoutes = {};
830
885
  }
886
+ if (typeof routerConfig.basename !== 'undefined') {
887
+ tabbar.conf.basename = routerConfig.basename;
888
+ }
831
889
  var container = document.getElementById('container');
832
890
  // eslint-disable-next-line no-unused-expressions
833
891
  container === null || container === void 0 ? void 0 : container.appendChild(tabbar);
892
+ Taro.initTabBarApis(config);
834
893
  }
835
894
 
836
895
  var routerConfig = Object.create(null);
@@ -854,6 +913,58 @@ function init(config) {
854
913
  initTabbar(config);
855
914
  }
856
915
 
916
+ var pageScrollFn;
917
+ var pageDOM = window;
918
+ function bindPageScroll(page, config) {
919
+ pageDOM.removeEventListener('scroll', pageScrollFn);
920
+ pageDOM = getScrollContainer();
921
+ var distance = config.onReachBottomDistance || 50;
922
+ var isReachBottom = false;
923
+ pageScrollFn = function () {
924
+ page.onPageScroll && page.onPageScroll({
925
+ scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
926
+ });
927
+ if (isReachBottom && getOffset() > distance) {
928
+ isReachBottom = false;
929
+ }
930
+ if (page.onReachBottom &&
931
+ !isReachBottom &&
932
+ getOffset() < distance) {
933
+ isReachBottom = true;
934
+ page.onReachBottom();
935
+ }
936
+ };
937
+ pageDOM.addEventListener('scroll', pageScrollFn, false);
938
+ }
939
+ window.addEventListener('DOMSubtreeModified', function (e) {
940
+ var _a;
941
+ // @ts-ignore
942
+ var className = (_a = e.target) === null || _a === void 0 ? void 0 : _a.className;
943
+ if (className && /taro-tabbar__/.test(className)) {
944
+ pageDOM.removeEventListener('scroll', pageScrollFn);
945
+ pageDOM = getScrollContainer();
946
+ pageDOM.addEventListener('scroll', pageScrollFn, false);
947
+ }
948
+ }, false);
949
+ function getScrollContainer() {
950
+ if (document.querySelector('.taro-tabbar__tabbar') === null) {
951
+ // 没设置tabbar
952
+ return window;
953
+ }
954
+ else {
955
+ // 有设置tabbar
956
+ return document.querySelector('.taro-tabbar__panel') || window;
957
+ }
958
+ }
959
+ function getOffset() {
960
+ if (pageDOM instanceof Window) {
961
+ return document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
962
+ }
963
+ else {
964
+ return pageDOM.scrollHeight - pageDOM.scrollTop - pageDOM.clientHeight;
965
+ }
966
+ }
967
+
857
968
  function createCommonjsModule(fn, module) {
858
969
  return module = { exports: {} }, fn(module, module.exports), module.exports;
859
970
  }
@@ -1410,14 +1521,25 @@ var queryString_5 = queryString.stringifyUrl;
1410
1521
  var queryString_6 = queryString.pick;
1411
1522
  var queryString_7 = queryString.exclude;
1412
1523
 
1524
+ function getSearch() {
1525
+ var search = '?';
1526
+ if (routerConfig.router.mode === 'hash') {
1527
+ var idx = location.hash.indexOf('?');
1528
+ if (idx > -1) {
1529
+ search = location.hash.slice(idx);
1530
+ }
1531
+ }
1532
+ else {
1533
+ search = location.search;
1534
+ }
1535
+ return search.substr(1);
1536
+ }
1413
1537
  var qs = function (stamp) {
1414
1538
  if ( stamp === void 0 ) stamp = 0;
1415
1539
 
1416
- var search = routerConfig.router.mode === 'hash'
1417
- ? location.hash.slice(routerConfig.router.pathname.length + 1)
1418
- : location.search;
1540
+ var search = getSearch();
1419
1541
  var query = search
1420
- ? queryString.parse(search.substr(1))
1542
+ ? queryString.parse(search)
1421
1543
  : {};
1422
1544
  if (stamp) {
1423
1545
  query.stamp = stamp.toString();
@@ -1425,98 +1547,14 @@ var qs = function (stamp) {
1425
1547
  return query;
1426
1548
  };
1427
1549
 
1428
- var pageScrollFn;
1429
- var pageDOM = window;
1430
- function bindPageScroll(page, config) {
1431
- pageDOM.removeEventListener('scroll', pageScrollFn);
1432
- pageDOM = getScrollContainer();
1433
- var distance = config.onReachBottomDistance || 50;
1434
- var isReachBottom = false;
1435
- pageScrollFn = function () {
1436
- page.onPageScroll && page.onPageScroll({
1437
- scrollTop: pageDOM instanceof Window ? window.scrollY : pageDOM.scrollTop
1438
- });
1439
- if (isReachBottom && getOffset() > distance) {
1440
- isReachBottom = false;
1441
- }
1442
- if (page.onReachBottom &&
1443
- !isReachBottom &&
1444
- getOffset() < distance) {
1445
- isReachBottom = true;
1446
- page.onReachBottom();
1447
- }
1448
- };
1449
- pageDOM.addEventListener('scroll', pageScrollFn, false);
1450
- }
1451
- window.addEventListener('DOMSubtreeModified', function (e) {
1452
- var _a;
1453
- // @ts-ignore
1454
- var className = (_a = e.target) === null || _a === void 0 ? void 0 : _a.className;
1455
- if (className && /taro-tabbar__/.test(className)) {
1456
- pageDOM.removeEventListener('scroll', pageScrollFn);
1457
- pageDOM = getScrollContainer();
1458
- pageDOM.addEventListener('scroll', pageScrollFn, false);
1459
- }
1460
- }, false);
1461
- function getScrollContainer() {
1462
- if (document.querySelector('.taro-tabbar__tabbar') === null) {
1463
- // 没设置tabbar
1464
- return window;
1465
- }
1466
- else {
1467
- // 有设置tabbar
1468
- return document.querySelector('.taro-tabbar__panel') || window;
1469
- }
1470
- }
1471
- function getOffset() {
1472
- if (pageDOM instanceof Window) {
1473
- return document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
1474
- }
1475
- else {
1476
- return pageDOM.scrollHeight - pageDOM.scrollTop - pageDOM.clientHeight;
1477
- }
1478
- }
1479
-
1480
1550
  /* eslint-disable dot-notation */
1481
- function hidePage(page) {
1482
- if (page != null) {
1483
- page.onHide();
1484
- var pageEl = document.getElementById(page.path);
1485
- if (pageEl) {
1486
- pageEl.style.display = 'none';
1487
- }
1488
- }
1489
- }
1490
- function showPage(page, pageConfig, stacksIndex) {
1491
- if ( stacksIndex === void 0 ) stacksIndex = 0;
1492
-
1493
- if (page != null) {
1494
- page.onShow();
1495
- var pageEl = document.getElementById(page.path);
1496
- if (pageEl) {
1497
- pageEl.style.display = 'block';
1498
- }
1499
- else {
1500
- page.onLoad(qs(stacksIndex));
1501
- pageEl = document.getElementById(page.path);
1502
- pageOnReady(pageEl, page, false);
1503
- }
1504
- bindPageScroll(page, pageConfig || {});
1505
- }
1506
- }
1507
- function unloadPage(page) {
1508
- if (page != null) {
1509
- stacks.pop();
1510
- page.onUnload();
1511
- }
1512
- }
1513
- function pageOnReady(pageEl, page, onLoad) {
1551
+ function pageOnReady(page, onLoad) {
1514
1552
  if ( onLoad === void 0 ) onLoad = true;
1515
1553
 
1516
1554
  var _a;
1555
+ var pageEl = document.getElementById(page.path);
1517
1556
  if (pageEl && !(pageEl === null || pageEl === void 0 ? void 0 : pageEl['__isReady'])) {
1518
1557
  var el = pageEl.firstElementChild;
1519
- // eslint-disable-next-line no-unused-expressions
1520
1558
  (_a = el === null || el === void 0 ? void 0 : el['componentOnReady']) === null || _a === void 0 ? void 0 : _a.call(el).then(function () {
1521
1559
  runtime.requestAnimationFrame(function () {
1522
1560
  page.onReady();
@@ -1527,24 +1565,64 @@ function pageOnReady(pageEl, page, onLoad) {
1527
1565
  }
1528
1566
  }
1529
1567
  function loadPage(page, pageConfig, stacksIndex) {
1568
+ if ( pageConfig === void 0 ) pageConfig = {};
1530
1569
  if ( stacksIndex === void 0 ) stacksIndex = 0;
1531
1570
 
1532
- if (page !== null) {
1533
- var pageEl = document.getElementById(page.path);
1534
- if (pageEl) {
1535
- pageEl.style.display = 'block';
1536
- }
1537
- else {
1538
- page.onLoad(qs(stacksIndex), function () {
1539
- pageEl = document.getElementById(page.path);
1540
- pageOnReady(pageEl, page);
1541
- });
1542
- }
1543
- stacks.push(page);
1544
- page.onShow();
1545
- bindPageScroll(page, pageConfig || {});
1571
+ if (!page)
1572
+ { return; }
1573
+ var pageEl = document.getElementById(page.path);
1574
+ if (pageEl) {
1575
+ pageEl.style.display = 'block';
1576
+ }
1577
+ else {
1578
+ page.onLoad(qs(stacksIndex), function () { return pageOnReady(page, true); });
1579
+ }
1580
+ stacks.push(page);
1581
+ page.onShow();
1582
+ bindPageScroll(page, pageConfig);
1583
+ }
1584
+ function unloadPage(page, delta) {
1585
+ if ( delta === void 0 ) delta = 1;
1586
+
1587
+ if (!page)
1588
+ { return; }
1589
+ stacks.delta = --delta;
1590
+ stacks.pop();
1591
+ page.onUnload();
1592
+ if (delta >= 1)
1593
+ { unloadPage(stacks.last, delta); }
1594
+ }
1595
+ function showPage(page, pageConfig, stacksIndex) {
1596
+ if ( pageConfig === void 0 ) pageConfig = {};
1597
+ if ( stacksIndex === void 0 ) stacksIndex = 0;
1598
+
1599
+ if (!page)
1600
+ { return; }
1601
+ page.onShow();
1602
+ var pageEl = document.getElementById(page.path);
1603
+ if (pageEl) {
1604
+ pageEl.style.display = 'block';
1605
+ }
1606
+ else {
1607
+ page.onLoad(qs(stacksIndex), function () { return pageOnReady(page, false); });
1546
1608
  }
1609
+ bindPageScroll(page, pageConfig);
1547
1610
  }
1611
+ function hidePage(page) {
1612
+ if (!page)
1613
+ { return; }
1614
+ // NOTE: 修复多页并发问题,此处可能因为路由跳转过快,执行时页面可能还没有创建成功
1615
+ var pageEl = document.getElementById(page.path);
1616
+ if (pageEl) {
1617
+ pageEl.style.display = 'none';
1618
+ page.onHide();
1619
+ }
1620
+ else {
1621
+ setTimeout(function () { return hidePage(page); }, 0);
1622
+ }
1623
+ }
1624
+
1625
+ /* eslint-disable dot-notation */
1548
1626
  function createRouter(app, config, framework) {
1549
1627
  var _a;
1550
1628
  init(config);
@@ -1563,11 +1641,11 @@ function createRouter(app, config, framework) {
1563
1641
  var basename = config.router.basename;
1564
1642
  var router = new UniversalRouter(routes, { baseUrl: basename || '' });
1565
1643
  app.onLaunch();
1566
- var render = throttle(async function (ref) {
1644
+ var render = async function (ref) {
1567
1645
  var location = ref.location;
1568
1646
  var action = ref.action;
1569
1647
 
1570
- var _a, _b, _c, _d, _e;
1648
+ var _a, _b, _c, _d;
1571
1649
  routerConfig.router.pathname = location.pathname;
1572
1650
  var element;
1573
1651
  try {
@@ -1599,63 +1677,51 @@ function createRouter(app, config, framework) {
1599
1677
  document.title = (_b = pageConfig.navigationBarTitleText) !== null && _b !== void 0 ? _b : document.title;
1600
1678
  enablePullDownRefresh = pageConfig.enablePullDownRefresh;
1601
1679
  }
1680
+ var currentPage = runtime.Current.page;
1681
+ var pathname = location.pathname;
1602
1682
  var shouldLoad = false;
1603
1683
  if (action === 'POP') {
1604
- unloadPage(runtime.Current.page);
1605
- var delta = historyBackDelta;
1606
- while (delta-- > 1) {
1607
- unloadPage(stacks.slice(-1)[0]);
1608
- }
1609
- // 最终必须重置为 1
1610
- setHistoryBackDelta(1);
1611
- var prevIndex = stacks.reduceRight(function (p, s, i) {
1612
- if (p !== 0)
1613
- { return p; }
1614
- else if (s.path === location.pathname + runtime.stringify(qs(i)))
1615
- { return i; }
1616
- else
1617
- { return 0; }
1618
- }, 0);
1619
- var prev = stacks[prevIndex];
1620
- if (prev) {
1621
- showPage(prev, pageConfig, prevIndex);
1684
+ // NOTE: 浏览器事件退后多次时,该事件只会被触发一次
1685
+ var prevIndex = stacks.getPrevIndex(pathname);
1686
+ var delta = stacks.getDelta(pathname);
1687
+ unloadPage(currentPage, delta);
1688
+ if (prevIndex > -1) {
1689
+ showPage(stacks.getItem(prevIndex), pageConfig, prevIndex);
1622
1690
  }
1623
1691
  else {
1624
1692
  shouldLoad = true;
1625
1693
  }
1626
1694
  }
1627
1695
  else if (action === 'PUSH') {
1628
- hidePage(runtime.Current.page);
1696
+ hidePage(currentPage);
1629
1697
  shouldLoad = true;
1630
1698
  }
1631
1699
  else if (action === 'REPLACE') {
1632
- unloadPage(runtime.Current.page);
1700
+ if (isTabBar(config)) {
1701
+ hidePage(currentPage);
1702
+ var prevIndex$1 = stacks.getPrevIndex(pathname);
1703
+ if (prevIndex$1 > -1) {
1704
+ // NOTE: tabbar 页且之前出现过,直接复用
1705
+ return showPage(stacks.getItem(prevIndex$1), pageConfig, prevIndex$1);
1706
+ }
1707
+ }
1708
+ else {
1709
+ unloadPage(currentPage);
1710
+ }
1633
1711
  shouldLoad = true;
1634
1712
  }
1635
1713
  if (shouldLoad) {
1636
1714
  var el = (_c = element.default) !== null && _c !== void 0 ? _c : element;
1637
- var config$1 = Object.assign({}, pageConfig);
1638
- delete config$1['path'];
1639
- delete config$1['load'];
1640
- var pathname = basename ? location.pathname.replace(basename, '') : location.pathname;
1641
- var routerIndex;
1642
- var isTabBar = (_d = routerConfig.tabBar) === null || _d === void 0 ? void 0 : _d.list.some(function (TabBarItem) {
1643
- var _a;
1644
- return ((_a = TabBarItem.pagePath) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname;
1645
- });
1646
- if ((stacks === null || stacks === void 0 ? void 0 : stacks.length) > 0 && isTabBar) {
1647
- routerIndex = stacks.findIndex(function (r) {
1648
- var _a;
1649
- return ((_a = r.path) === null || _a === void 0 ? void 0 : _a.replace(/\?.*/g, '')) === pathname;
1650
- });
1651
- }
1652
- routerIndex = ((routerIndex || routerIndex === 0) && routerIndex !== -1) ? routerIndex : stacks.length;
1653
- var page = runtime.createPageConfig(enablePullDownRefresh ? (_e = runtimeHooks.createPullDownComponent) === null || _e === void 0 ? void 0 : _e.call(runtimeHooks, el, location.pathname, framework, routerConfig.PullDownRefresh) : el, pathname + runtime.stringify(qs(routerIndex)), {}, config$1);
1654
- loadPage(page, pageConfig, routerIndex);
1715
+ var loadConfig = Object.assign({}, pageConfig);
1716
+ var stacksIndex = stacks.length;
1717
+ delete loadConfig['path'];
1718
+ delete loadConfig['load'];
1719
+ var page = runtime.createPageConfig(enablePullDownRefresh ? (_d = runtimeHooks.createPullDownComponent) === null || _d === void 0 ? void 0 : _d.call(runtimeHooks, el, location.pathname, framework, routerConfig.PullDownRefresh) : el, pathname + runtime.stringify(qs(stacksIndex)), {}, loadConfig);
1720
+ return loadPage(page, pageConfig, stacksIndex);
1655
1721
  }
1656
- }, 500);
1722
+ };
1657
1723
  if (exports.history.location.pathname === '/') {
1658
- exports.history.replace(parsePath(routes[0].path + exports.history.location.search));
1724
+ exports.history.replace(prependBasename(routes[0].path + exports.history.location.search));
1659
1725
  }
1660
1726
  render({ location: exports.history.location, action: r.Push });
1661
1727
  app.onShow(qs(stacks.length));