client/router: refactor call chains
This commit is contained in:
parent
ee829e42d2
commit
e10ed4bce8
|
@ -11,19 +11,12 @@ router.Context.prototype.pushState = function() {
|
||||||
origPushState.call(this);
|
origPushState.call(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
router.cancel = function(ctx) {
|
|
||||||
prevContext = ctx;
|
|
||||||
ctx.pushState();
|
|
||||||
};
|
|
||||||
|
|
||||||
router.exit(
|
router.exit(
|
||||||
/.*/,
|
/.*/,
|
||||||
(ctx, next) => {
|
(ctx, next) => {
|
||||||
views.unlistenToMessages();
|
views.unlistenToMessages();
|
||||||
if (misc.confirmPageExit()) {
|
if (misc.confirmPageExit()) {
|
||||||
next();
|
next();
|
||||||
} else {
|
|
||||||
router.cancel(ctx);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
// modified page.js by visionmedia
|
// modified page.js by visionmedia
|
||||||
// - removed unused crap
|
// - removed unused crap
|
||||||
// - refactored to classes
|
// - refactored to classes
|
||||||
|
// - simplified method chains
|
||||||
|
// - added ability to call .save() in .exit() without side effects
|
||||||
|
|
||||||
const pathToRegexp = require('path-to-regexp');
|
const pathToRegexp = require('path-to-regexp');
|
||||||
const clickEvent = document.ontouchstart ? 'touchstart' : 'click';
|
const clickEvent = document.ontouchstart ? 'touchstart' : 'click';
|
||||||
let location = window.history.location || window.location;
|
let location = window.history.location || window.location;
|
||||||
|
|
||||||
const base = '';
|
const base = '';
|
||||||
let prevContext = null;
|
|
||||||
|
|
||||||
function _decodeURLEncodedURIComponent(val) {
|
function _decodeURLEncodedURIComponent(val) {
|
||||||
if (typeof val !== 'string') {
|
if (typeof val !== 'string') {
|
||||||
|
@ -93,7 +94,6 @@ class Router {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._callbacks = [];
|
this._callbacks = [];
|
||||||
this._exits = [];
|
this._exits = [];
|
||||||
this._current = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enter(path) {
|
enter(path) {
|
||||||
|
@ -127,76 +127,59 @@ class Router {
|
||||||
if (!this._running) {
|
if (!this._running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._current = '';
|
|
||||||
this._running = false;
|
this._running = false;
|
||||||
document.removeEventListener(clickEvent, this._onClick, false);
|
document.removeEventListener(clickEvent, this._onClick, false);
|
||||||
window.removeEventListener('popstate', this._onPopState, false);
|
window.removeEventListener('popstate', this._onPopState, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
show(path, state, push) {
|
show(path, state, push) {
|
||||||
|
const oldPath = this.ctx ? this.ctx.path : ctx.path;
|
||||||
const ctx = new Context(path, state);
|
const ctx = new Context(path, state);
|
||||||
this._current = ctx.path;
|
this.dispatch(ctx, () => {
|
||||||
this.dispatch(ctx);
|
if (ctx.path !== oldPath && push !== false) {
|
||||||
if (ctx.handled !== false && push !== false) {
|
|
||||||
ctx.pushState();
|
ctx.pushState();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
replace(path, state, dispatch) {
|
replace(path, state, dispatch) {
|
||||||
var ctx = new Context(path, state);
|
var ctx = new Context(path, state);
|
||||||
this._current = ctx.path;
|
|
||||||
ctx.save();
|
|
||||||
if (dispatch) {
|
if (dispatch) {
|
||||||
this.dispatch(ctx);
|
this.dispatch(ctx, () => {
|
||||||
|
ctx.save();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ctx.save();
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(ctx) {
|
dispatch(ctx, middle) {
|
||||||
const prev = prevContext;
|
const swap = (_ctx, next) => {
|
||||||
|
this.ctx = ctx;
|
||||||
|
middle();
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
const callChain = (this.ctx ? this._exits : [])
|
||||||
|
.concat(
|
||||||
|
[swap],
|
||||||
|
this._callbacks,
|
||||||
|
[this._unhandled, (ctx, next) => {}]);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let j = 0;
|
let fn = () => {
|
||||||
|
callChain[i++](this.ctx, fn);
|
||||||
prevContext = ctx;
|
|
||||||
|
|
||||||
const nextExit = () => {
|
|
||||||
const fn = this._exits[j++];
|
|
||||||
if (!fn) {
|
|
||||||
return nextEnter();
|
|
||||||
}
|
|
||||||
fn(prev, nextExit);
|
|
||||||
};
|
};
|
||||||
|
fn();
|
||||||
const nextEnter = () => {
|
|
||||||
const fn = this._callbacks[i++];
|
|
||||||
if (ctx.path !== this._current) {
|
|
||||||
ctx.handled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!fn) {
|
|
||||||
return this._unhandled(ctx);
|
|
||||||
}
|
|
||||||
fn(ctx, nextEnter);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (prev) {
|
|
||||||
nextExit();
|
|
||||||
} else {
|
|
||||||
nextEnter();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_unhandled(ctx) {
|
_unhandled(ctx, next) {
|
||||||
if (ctx.handled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let current = location.pathname + location.search;
|
let current = location.pathname + location.search;
|
||||||
if (current === ctx.canonicalPath) {
|
if (current === ctx.canonicalPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.stop();
|
router.stop();
|
||||||
ctx.handled = false;
|
|
||||||
location.href = ctx.canonicalPath;
|
location.href = ctx.canonicalPath;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue