route-interceptor
Version:
A front-end generic route interceptor
133 lines (129 loc) • 3.56 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
const originWindowOpen = window.open;
let isStarted = false;
function create({ way = [], intercept = () => false, }) {
const start = () => {
if (isStarted) {
return;
}
isStarted = true;
if (way.includes("a")) {
_a(intercept);
}
if (way.includes("window.open")) {
_windowOpen(intercept);
}
if (way.includes("history")) {
_history(intercept);
}
if (way.includes("hash")) {
_hash(intercept);
}
if (way.includes("location")) {
window.$location = getFakeLocation(intercept);
}
};
return {
start,
};
}
/**
* intercept all Anchor tag
*/
function _a(intercept) {
document.addEventListener("click", function (event) {
const path = event.path || (event.composedPath && event.composedPath()) || [];
if (event.defaultPrevented) {
return;
}
for (const item of path) {
if (item instanceof HTMLAnchorElement) {
event.preventDefault();
const to = intercept(item.href);
if (to === false) {
return;
}
return originWindowOpen.call(window, to, item.target || "_self");
}
}
});
}
/**
* intercept window.open
*/
function _windowOpen(intercept) {
window.open = (url, target, features) => {
const path = url ? url.toString() : undefined;
if (path === undefined) {
return null;
}
const to = intercept(path);
if (to === false) {
return null;
}
return originWindowOpen(to, target, features);
};
}
/**
* intercept history pushState & replaceState
*/
function _history(intercept) {
["pushState", "replaceState"].forEach((funcName) => {
const funcNameWithType = funcName;
const originFunc = history[funcNameWithType];
history[funcNameWithType] = (data, unused, url) => {
if (url === undefined || url === null) {
return;
}
const to = intercept(url.toString());
if (to === false) {
return;
}
return originFunc.call(history, data, unused, to);
};
});
}
let _nextHash = "";
/**
* intercept hashchange
*/
function _hash(intercept) {
window.addEventListener("hashchange", function (event) {
const url = new URL(event.newURL);
const { hash } = url;
if (hash === _nextHash) {
_nextHash = "";
return;
}
const to = intercept(hash.slice(1));
if (to === false) {
return;
}
_nextHash = `#${to}`;
this.location.hash = _nextHash;
});
}
/**
* get fake location object
*/
function getFakeLocation(intercept) {
return {
set href(value) {
const to = intercept(value);
if (to === false) {
return;
}
location.href = to;
},
replace: (url) => {
const to = intercept(url.toString());
if (to === false) {
return;
}
location.replace(to);
},
};
}
exports.create = create;
//# sourceMappingURL=index.js.map
;