UNPKG

omi-router

Version:

Router for Omi

323 lines (322 loc) 9.8 kB
import { mixin as O, tag as D, Component as N, render as S, h as I } from "omi"; function $(e) { for (var t = [], r = 0; r < e.length; ) { var a = e[r]; if (a === "*" || a === "+" || a === "?") { t.push({ type: "MODIFIER", index: r, value: e[r++] }); continue; } if (a === "\\") { t.push({ type: "ESCAPED_CHAR", index: r++, value: e[r++] }); continue; } if (a === "{") { t.push({ type: "OPEN", index: r, value: e[r++] }); continue; } if (a === "}") { t.push({ type: "CLOSE", index: r, value: e[r++] }); continue; } if (a === ":") { for (var c = "", n = r + 1; n < e.length; ) { var i = e.charCodeAt(n); if ( // `0-9` i >= 48 && i <= 57 || // `A-Z` i >= 65 && i <= 90 || // `a-z` i >= 97 && i <= 122 || // `_` i === 95 ) { c += e[n++]; continue; } break; } if (!c) throw new TypeError("Missing parameter name at ".concat(r)); t.push({ type: "NAME", index: r, value: c }), r = n; continue; } if (a === "(") { var h = 1, l = "", n = r + 1; if (e[n] === "?") throw new TypeError('Pattern cannot start with "?" at '.concat(n)); for (; n < e.length; ) { if (e[n] === "\\") { l += e[n++] + e[n++]; continue; } if (e[n] === ")") { if (h--, h === 0) { n++; break; } } else if (e[n] === "(" && (h++, e[n + 1] !== "?")) throw new TypeError("Capturing groups are not allowed at ".concat(n)); l += e[n++]; } if (h) throw new TypeError("Unbalanced pattern at ".concat(r)); if (!l) throw new TypeError("Missing pattern at ".concat(r)); t.push({ type: "PATTERN", index: r, value: l }), r = n; continue; } t.push({ type: "CHAR", index: r, value: e[r++] }); } return t.push({ type: "END", index: r, value: "" }), t; } function q(e, t) { t === void 0 && (t = {}); for (var r = $(e), a = t.prefixes, c = a === void 0 ? "./" : a, n = "[^".concat(E(t.delimiter || "/#?"), "]+?"), i = [], h = 0, l = 0, d = "", o = function(f) { if (l < r.length && r[l].type === f) return r[l++].value; }, R = function(f) { var w = o(f); if (w !== void 0) return w; var g = r[l], C = g.type, T = g.index; throw new TypeError("Unexpected ".concat(C, " at ").concat(T, ", expected ").concat(f)); }, A = function() { for (var f = "", w; w = o("CHAR") || o("ESCAPED_CHAR"); ) f += w; return f; }; l < r.length; ) { var x = o("CHAR"), P = o("NAME"), m = o("PATTERN"); if (P || m) { var v = x || ""; c.indexOf(v) === -1 && (d += v, v = ""), d && (i.push(d), d = ""), i.push({ name: P || h++, prefix: v, suffix: "", pattern: m || n, modifier: o("MODIFIER") || "" }); continue; } var u = x || o("ESCAPED_CHAR"); if (u) { d += u; continue; } d && (i.push(d), d = ""); var y = o("OPEN"); if (y) { var v = A(), b = o("NAME") || "", s = o("PATTERN") || "", p = A(); R("CLOSE"), i.push({ name: b || (s ? h++ : ""), pattern: b && !s ? n : s, prefix: v, suffix: p, modifier: o("MODIFIER") || "" }); continue; } R("END"); } return i; } function E(e) { return e.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); } function H(e) { return e && e.sensitive ? "" : "i"; } function W(e, t) { if (!t) return e; for (var r = /\((?:\?<(.*?)>)?(?!\?)/g, a = 0, c = r.exec(e.source); c; ) t.push({ // Use parenthesized substring match if available, index otherwise name: c[1] || a++, prefix: "", suffix: "", modifier: "", pattern: "" }), c = r.exec(e.source); return e; } function F(e, t, r) { var a = e.map(function(c) { return _(c, t, r).source; }); return new RegExp("(?:".concat(a.join("|"), ")"), H(r)); } function L(e, t, r) { return U(q(e, r), t, r); } function U(e, t, r) { r === void 0 && (r = {}); for (var a = r.strict, c = a === void 0 ? !1 : a, n = r.start, i = n === void 0 ? !0 : n, h = r.end, l = h === void 0 ? !0 : h, d = r.encode, o = d === void 0 ? function(T) { return T; } : d, R = r.delimiter, A = R === void 0 ? "/#?" : R, x = r.endsWith, P = x === void 0 ? "" : x, m = "[".concat(E(P), "]|$"), v = "[".concat(E(A), "]"), u = i ? "^" : "", y = 0, b = e; y < b.length; y++) { var s = b[y]; if (typeof s == "string") u += E(o(s)); else { var p = E(o(s.prefix)), f = E(o(s.suffix)); if (s.pattern) if (t && t.push(s), p || f) if (s.modifier === "+" || s.modifier === "*") { var w = s.modifier === "*" ? "?" : ""; u += "(?:".concat(p, "((?:").concat(s.pattern, ")(?:").concat(f).concat(p, "(?:").concat(s.pattern, "))*)").concat(f, ")").concat(w); } else u += "(?:".concat(p, "(").concat(s.pattern, ")").concat(f, ")").concat(s.modifier); else s.modifier === "+" || s.modifier === "*" ? u += "((?:".concat(s.pattern, ")").concat(s.modifier, ")") : u += "(".concat(s.pattern, ")").concat(s.modifier); else u += "(?:".concat(p).concat(f, ")").concat(s.modifier); } } if (l) c || (u += "".concat(v, "?")), u += r.endsWith ? "(?=".concat(m, ")") : "$"; else { var g = e[e.length - 1], C = typeof g == "string" ? v.indexOf(g[g.length - 1]) > -1 : g === void 0; c || (u += "(?:".concat(v, "(?=").concat(m, "))?")), C || (u += "(?=".concat(v, "|").concat(m, ")")); } return new RegExp(u, H(r)); } function _(e, t, r) { return e instanceof RegExp ? W(e, t) : Array.isArray(e) ? F(e, t, r) : L(e, t, r); } var j = Object.defineProperty, Q = Object.getOwnPropertyDescriptor, V = (e, t, r, a) => { for (var c = a > 1 ? void 0 : a ? Q(t, r) : t, n = e.length - 1, i; n >= 0; n--) (i = e[n]) && (c = (a ? i(t, r, c) : i(c)) || c); return a && c && j(t, r, c), c; }; O({ router: null }); let M = class extends N { constructor() { super(...arguments), this.currentRoute = null, this.routes = [], this.isHashMode = !0, this.params = {}, this.query = {}, this.hash = "", this.base = ""; } install() { O({ router: this }), this.base = this.props.base || "", this.isHashMode = this.props.hash !== !1, this.routes = this.props.routes.map((e) => { const t = []; if (e.render && (e.render = e.render.bind(this)), e.path === "*") return { ...e, regex: /(.*)/ }; const r = _(e.path, t); return { ...e, keys: t, regex: r }; }), window.onpopstate = (e) => { this.matchAndRender(this.getRoutePath()); }, this.matchAndRender(this.getRoutePath()); } getRoutePath() { return this.isHashMode ? window.location.hash.split("?")[0].replace("#", "") || "/" : window.location.pathname; } getQueryPath() { return this.isHashMode ? window.location.hash.split("?")[1] : window.location.search; } beforeEach(e) { this.beforeEachCallback = e; } afterEach(e) { this.afterEachCallback = e; } push(e) { history.pushState({}, "", this.isHashMode ? `#${e}` : e), this.matchAndRender(e); } replace(e) { history.replaceState({}, "", e), this.matchAndRender(e); } go(e) { history.go(e); } back() { history.back(); } forward() { history.forward(); } matchAndRender(e) { var t, r; for (const a of this.routes) { const c = (t = a.regex) == null ? void 0 : t.exec(e); if (c) { if (a.redirect) { if (this.isHashMode) window.location.hash = a.redirect; else { const i = this.base + a.redirect; window.location.href = window.location.origin + i; } return; } if (this.beforeEachCallback) { const i = this.beforeEachCallback({ path: e }, { path: window.location.pathname }); if (i === !1) return; if (typeof i == "string") { this.push(i); return; } else if (typeof i == "object") { this.push(i.path); return; } } if (a.beforeEnter && a.beforeEnter({ path: e }, { path: window.location.pathname }) === !1) return; this.currentRoute = a, this.params = {}, (r = a.keys) == null || r.forEach((i, h) => { this.params[i.name] = c[h + 1]; }); const n = new URLSearchParams(this.getQueryPath()); this.query = {}, Array.from(n.entries()).forEach(([i, h]) => { this.query[i] = h; }), this.hash = window.location.hash, this.afterEachCallback && this.afterEachCallback({ path: e }, { path: window.location.pathname }), this.update(); break; } } } render() { return this.currentRoute && this.currentRoute.render ? this.currentRoute.render(this) : null; } }; M = V([ D("router-view") ], M); class B { constructor(t) { this.params = {}, this.query = {}, this.hash = "", this.currentRoute = null, this.el = S( /* @__PURE__ */ I( "router-view", { onInstall: (r) => { r.detail.constructor.css = t.css; }, routes: t.routes, base: t.base, hash: t.hash } ), t.renderTo ); } beforeEach(t) { this.el.beforeEach(t); } afterEach(t) { this.el.afterEach(t); } push(t) { this.el.push(t); } replace(t) { this.el.replace(t); } go(t) { this.el.go(t); } back() { this.el.back(); } forward() { this.el.forward(); } } export { B as Router };