curvature
Version:

463 lines (458 loc) • 18.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Router = void 0;
var _View = require("./View");
var _Cache = require("./Cache");
var _Config = require("./Config");
var _Routes = require("./Routes");
var _globalThis$CustomEve;
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var NotFoundError = Symbol('NotFound');
var InternalError = Symbol('Internal');
globalThis.CustomEvent = (_globalThis$CustomEve = globalThis.CustomEvent) !== null && _globalThis$CustomEve !== void 0 ? _globalThis$CustomEve : globalThis.Event;
var Router = /*#__PURE__*/function () {
function Router() {
_classCallCheck(this, Router);
}
_createClass(Router, null, [{
key: "wait",
value: function wait(view) {
var _this = this;
var event = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'DOMContentLoaded';
var node = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document;
node.addEventListener(event, function () {
_this.listen(view);
});
}
}, {
key: "listen",
value: function listen(listener) {
var _this2 = this;
var routes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
this.listener = listener || this.listener;
this.routes = routes || listener.routes;
Object.assign(this.query, this.queryOver({}));
var listen = function listen(event) {
event.preventDefault();
if (event.state && 'routedId' in event.state) {
if (event.state.routedId <= _this2.routeCount) {
_this2.history.splice(event.state.routedId);
_this2.routeCount = event.state.routedId;
} else if (event.state.routedId > _this2.routeCount) {
_this2.history.push(event.state.prev);
_this2.routeCount = event.state.routedId;
}
_this2.state = event.state;
} else {
if (_this2.prevPath !== null && _this2.prevPath !== location.pathname) {
_this2.history.push(_this2.prevPath);
}
}
if (location.origin !== 'null') {
_this2.match(location.pathname, listener);
} else {
_this2.match(_this2.nextPath, listener);
}
};
window.addEventListener('cvUrlChanged', listen);
window.addEventListener('popstate', listen);
var route = location.origin !== 'null' ? location.pathname + location.search : false;
if (location.origin && location.hash) {
route += location.hash;
}
var state = {
routedId: this.routeCount,
url: location.pathname,
prev: this.prevPath
};
if (location.origin !== 'null') {
history.replaceState(state, null, location.pathname);
}
this.go(route !== false ? route : '/');
}
}, {
key: "go",
value: function go(path) {
var silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var configTitle = _Config.Config.get('title');
if (configTitle) {
document.title = configTitle;
}
var state = {
routedId: this.routeCount,
prev: this.prevPath,
url: location.pathname
};
if (silent === -1) {
this.match(path, this.listener, true);
} else if (location.origin === 'null') {
this.nextPath = path;
} else if (silent === 2 && location.pathname !== path) {
history.replaceState(state, null, path);
} else if (location.pathname !== path) {
history.pushState(state, null, path);
}
if (!silent || silent < 0) {
if (silent === false) {
this.path = null;
}
if (!silent) {
if (path.substring(0, 1) === '#') {
window.dispatchEvent(new HashChangeEvent('hashchange'));
} else {
window.dispatchEvent(new CustomEvent('cvUrlChanged'));
}
}
}
this.prevPath = path;
}
}, {
key: "processRoute",
value: function processRoute(routes, selected, args) {
var result = false;
if (typeof routes[selected] === 'function') {
if (routes[selected].prototype instanceof _View.View) {
result = new routes[selected](args);
} else {
result = routes[selected](args);
}
} else {
result = routes[selected];
}
return result;
}
}, {
key: "handleError",
value: function handleError(error, routes, selected, args, listener, path, prev, forceRefresh) {
console.error(error);
if (typeof document !== 'undefined') {
document.dispatchEvent(new CustomEvent('cvRouteError', {
detail: {
error: error,
path: path,
prev: prev,
view: listener,
routes: routes,
selected: selected
}
}));
}
var result = globalThis['devMode'] ? 'Unexpected error: ' + String(error) : 'Unexpected error.';
if (routes[InternalError]) {
args[InternalError] = error;
result = this.processRoute(routes, InternalError, args);
}
this.update(listener, path, result, routes, selected, args, forceRefresh);
}
}, {
key: "match",
value: function match(path, listener) {
var _this3 = this;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var event = null,
request = null,
forceRefresh = false;
if (options === true) {
forceRefresh = options;
}
if (options && _typeof(options) === 'object') {
forceRefresh = options.forceRefresh;
event = options.event;
}
if (typeof document !== 'undefined' && this.path === path && !forceRefresh) {
return;
}
var origin = 'http://example.com';
if (typeof document !== 'undefined') {
origin = location.origin !== "null" ? location.origin : origin;
this.queryString = location.search;
}
var url = new URL(path, origin);
path = this.path = url.pathname;
if (typeof document === 'undefined') {
this.queryString = url.search;
}
var prev = this.prevPath;
var current = listener && listener.args ? listener.args.content : null;
var routes = this.routes || listener && listener.routes || _Routes.Routes.dump();
var query = new URLSearchParams(this.queryString);
if (event && event.request) {
this.request = event.request;
}
for (var key in Object.keys(this.query)) {
delete this.query[key];
}
var _iterator = _createForOfIteratorHelper(query),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _slicedToArray(_step.value, 2),
_key = _step$value[0],
value = _step$value[1];
this.query[_key] = value;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var args = {},
selected = false,
result = '';
if (path.substring(0, 1) === '/') {
path = path.substring(1);
}
path = path.split('/');
for (var i in this.query) {
args[i] = this.query[i];
}
L1: for (var _i in routes) {
var route = _i.split('/');
if (route.length < path.length && route[route.length - 1] !== '*') {
continue;
}
L2: for (var j in route) {
if (route[j].substr(0, 1) == '%') {
var argName = null;
var groups = /^%(\w+)\??/.exec(route[j]);
if (groups && groups[1]) {
argName = groups[1];
}
if (!argName) {
throw new Error("".concat(route[j], " is not a valid argument segment in route \"").concat(_i, "\""));
}
if (!path[j]) {
if (route[j].substr(route[j].length - 1, 1) == '?') {
args[argName] = '';
} else {
continue L1;
}
} else {
args[argName] = path[j];
}
} else if (route[j] !== '*' && path[j] !== route[j]) {
continue L1;
}
}
selected = _i;
result = routes[_i];
if (route[route.length - 1] === '*') {
args.pathparts = path.slice(route.length - 1);
}
break;
}
var eventStart = new CustomEvent('cvRouteStart', {
cancelable: true,
detail: {
path: path,
prev: prev,
root: listener,
selected: selected,
routes: routes
}
});
if (typeof document !== 'undefined') {
if (!document.dispatchEvent(eventStart)) {
return;
}
}
if (!forceRefresh && listener && current && result instanceof Object && current instanceof result && !(result instanceof Promise) && current.update(args)) {
listener.args.content = current;
return true;
}
if (!(selected in routes)) {
routes[selected] = routes[NotFoundError];
}
try {
result = this.processRoute(routes, selected, args);
if (result === false) {
result = this.processRoute(routes, NotFoundError, args);
}
if (!(result instanceof Promise)) {
result = Promise.resolve(result);
// return this.update(
// listener
// , path
// , result
// , routes
// , selected
// , args
// , forceRefresh
// );
}
if (typeof document === 'undefined') {
return result;
}
return result.then(function (realResult) {
_this3.update(listener, path, realResult, routes, selected, args, forceRefresh);
})["catch"](function (error) {
_this3.handleError(error, routes, selected, args, listener, path, prev, forceRefresh);
});
} catch (error) {
this.handleError(error, routes, selected, args, listener, path, prev, forceRefresh);
}
}
}, {
key: "update",
value: function update(listener, path, result, routes, selected, args, forceRefresh) {
if (!listener) {
return;
}
var prev = this.prevPath;
var event = new CustomEvent('cvRoute', {
cancelable: true,
detail: {
result: result,
path: path,
prev: prev,
view: listener,
routes: routes,
selected: selected
}
});
if (result !== false) {
if (listener.args.content instanceof _View.View) {
listener.args.content.pause(true);
listener.args.content.remove();
}
if (document.dispatchEvent(event)) {
listener.args.content = result;
}
if (result instanceof _View.View) {
result.pause(false);
result.update(args, forceRefresh);
}
}
var eventEnd = new CustomEvent('cvRouteEnd', {
cancelable: true,
detail: {
result: result,
path: path,
prev: prev,
view: listener,
routes: routes,
selected: selected
}
});
document.dispatchEvent(eventEnd);
}
}, {
key: "queryOver",
value: function queryOver() {
var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var params = new URLSearchParams(location.search);
var finalArgs = {};
var query = {};
var _iterator2 = _createForOfIteratorHelper(params),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var pair = _step2.value;
query[pair[0]] = pair[1];
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
finalArgs = Object.assign(finalArgs, query, args);
delete finalArgs['api'];
return finalArgs;
// for(let i in query)
// {
// finalArgs[i] = query[i];
// }
// for(let i in args)
// {
// finalArgs[i] = args[i];
// }
}
}, {
key: "queryToString",
value: function queryToString() {
var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var fresh = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var parts = [],
finalArgs = args;
if (!fresh) {
finalArgs = this.queryOver(args);
}
for (var i in finalArgs) {
if (finalArgs[i] === '') {
continue;
}
parts.push(i + '=' + encodeURIComponent(finalArgs[i]));
}
return parts.join('&');
}
}, {
key: "setQuery",
value: function setQuery(name, value, silent) {
var args = this.queryOver();
args[name] = value;
if (value === undefined) {
delete args[name];
}
var queryString = this.queryToString(args, true);
this.go(location.pathname + (queryString ? '?' + queryString : '?'), silent);
}
}]);
return Router;
}();
exports.Router = Router;
Object.defineProperty(Router, 'query', {
configurable: false,
enumerable: false,
writable: false,
value: {}
});
Object.defineProperty(Router, 'history', {
configurable: false,
enumerable: false,
writable: false,
value: []
});
Object.defineProperty(Router, 'routeCount', {
configurable: false,
enumerable: false,
writable: true,
value: 0
});
Object.defineProperty(Router, 'prevPath', {
configurable: false,
enumerable: false,
writable: true,
value: null
});
Object.defineProperty(Router, 'queryString', {
configurable: false,
enumerable: false,
writable: true,
value: null
});
Object.defineProperty(Router, 'InternalError', {
configurable: false,
enumerable: false,
writable: false,
value: InternalError
});
Object.defineProperty(Router, 'NotFoundError', {
configurable: false,
enumerable: false,
writable: false,
value: NotFoundError
});