UNPKG

@sgpinkus/my-vue-router

Version:
237 lines (236 loc) 7.47 kB
import { defineComponent as h, ref as u, watch as b, h as i, createBlock as l, createCommentVNode as _, openBlock as m, unref as p, withCtx as f, renderSlot as d, shallowRef as $ } from "vue"; import { compile as g, match as C } from "path-to-regexp"; const v = h({ name: "RoutePath", props: { path: { type: String, required: !0 } }, setup(e, { slots: t }) { const { route: a } = r.matchPath(e.path); let o = u({}); return b([r == null ? void 0 : r.currentRoute, r == null ? void 0 : r.currentPath], () => { o.value = { route: !0, "route-active": a ? r.isActiveRoute(a) : !1, "route-hyper-active": r.isCurrentPath(e.path) }; }, { immediate: !0 }), () => i( "a", { onClick: (n) => { r.dispatch({ path: e.path }), n.preventDefault(); }, class: o.value, href: e.path }, t.default && t.default() ); } }), y = h({ name: "RouteName", props: { name: { type: String, required: !0 }, params: { type: Object, required: !1 } }, setup(e, { slots: t }) { const { route: a, path: o } = r.matchName(e.name, e.params); let n = u({}); return b([r == null ? void 0 : r.currentRoute, r == null ? void 0 : r.currentPath], () => { n.value = { route: !0, "route-active": a ? r.isActiveRoute(a) : !1, "route-hyper-active": r.isCurrentPath(o) }; }, { immediate: !0 }), () => i( "a", { onClick: (s) => { r.dispatch({ name: e.name, params: e.params }), s.preventDefault(); }, href: o, class: n.value }, t.default && t.default() ); } }), N = h({ name: "RouteView", setup() { return () => { var o; const e = (o = r.currentRoute) == null ? void 0 : o.value; let t = {}; typeof (e == null ? void 0 : e.props) == "function" ? t = e == null ? void 0 : e.props(e) : e != null && e.props && (t = e == null ? void 0 : e.props), P("routeProp", e, r) && (t.route = r == null ? void 0 : r.currentRouteProp()), P("paramsToProps", e, r) && (t = { ...t, ...r.currentRouteParams.value }); const a = e != null && e.component ? i(e.component, t) : []; return k("View render", e.__file), i(a); }; } }); function P(e, t, a) { return t[e] || a.options[e] || !1; } function k(...e) { } const S = /* @__PURE__ */ h({ __name: "route-link", props: { name: {}, params: {}, path: {} }, setup(e) { const t = e; return (a, o) => t.path ? (m(), l(p(v), { key: 0, path: t.path }, { default: f(() => [ d(a.$slots, "default") ]), _: 3 }, 8, ["path"])) : t.name ? (m(), l(p(y), { key: 1, name: t.name, params: t.params }, { default: f(() => [ d(a.$slots, "default") ]), _: 3 }, 8, ["name", "params"])) : _("", !0); } }), A = Symbol(), O = { installGlobalRef: "$router", routeProp: !1, paramsToProps: !1, basePath: void 0 }, j = () => i("div"), q = { name: "null", path: "*", component: j, _match: () => !1, _compile: () => "", _id: -1 }; let r = null; function U(e, t = {}) { return r = new L(e, t), r; } function x() { if (!r) throw new Error("Router not initialized. Call createRouter() first."); return r; } function R(e) { return "component" in e; } function w(e) { return "redirect" in e; } function B(e, t) { return Object.entries(e).length !== Object.entries(t).length ? !1 : Object.entries(e).every(([a, o]) => t[a] === o); } function c(e) { return new URL(e, "http://dummy-base.local"); } function V(e) { const t = c(e).hash.replace(/^#/, ""); if (t) { const a = document.querySelector(`a[name="${t}"`) || document.querySelector(`a[id="${t}"`); a && a.scrollIntoView({}); } } function E(e) { if (e && (e = `/${e}`.replaceAll(/\/+/g, "/"), e !== "/")) return e.replace(/\/$/, ""); } class L { constructor(t, a = {}) { this.currentRoute = $(q), this.currentPath = u(""), this.currentRouteParams = u({}), this.routes = [], this.options = {}, this.options = { ...O, ...a, basePath: E(a.basePath) }, this.routes = t.map((n, s) => ({ ...n, _match: C(n.path), _compile: g(n.path), _id: s })); const o = new URL(window.location.href).pathname; this.setPath(this.unBasePath(o)), window.addEventListener("popstate", (n) => this.historyPopState(n)); } matchPath(t) { const a = c(t); for (const o of this.routes) { const n = o._match(a.pathname); if (n) return { route: o, ...n }; } return { route: void 0, params: {} }; } matchName(t, a = {}) { for (const o of this.routes) if (o.name === t) try { const n = o._compile(a); if (n) return { route: o, path: n }; } catch (n) { console.error(n); continue; } return { route: void 0, path: "" }; } setPath(t, a = !0) { const { route: o, params: n } = this.matchPath(t); return o ? (R(o) ? (this.currentRoute.value = o, this.currentPath.value = t, this.currentRouteParams.value = n, a && window.history.pushState({ path: t }, "", this.rebasePath(t)), V(t)) : w(o) && (window.location.href = this.rebasePath(o.redirect)), !0) : !1; } setName(t, a = {}, o = !0) { const { route: n, path: s } = this.matchName(t, a); return n ? (R(n) ? (this.currentRoute.value = n, this.currentPath.value = s, this.currentRouteParams.value = a, o && window.history.pushState({ name: t, params: a }, "", this.rebasePath(s))) : w(n) && (window.location.href = this.rebasePath(n.redirect)), !0) : !1; } currentRouteProp() { const t = ["name", "path", "meta"]; return { ...Object.fromEntries( Object.entries(this.currentRoute.value).filter(([o]) => t.includes(o)) ), params: this.currentRouteParams.value }; } isActiveRoute(t) { return t._id === this.currentRoute.value._id; } isCurrentPath(t) { return window.location.href.replace(window.location.origin, "") === this.rebasePath(t); } rebasePath(t) { if (!this.options.basePath || c(t).origin !== "http://dummy-base.local") return t; const a = `${this.options.basePath}/${t}`.replaceAll(/\/+/g, "/").trim(); return console.debug(`rebasePath path=${t} to ${a}`), a; } unBasePath(t) { if (!this.options.basePath) return t; const a = t.trim().replace(RegExp(`^${this.options.basePath}`), "/").replaceAll(/\/+/g, "/"); return console.debug(`unbasePath path=${t}, basePath=${this.options.basePath} gives ${a}`), a; } install(t) { t.component("RoutePath", v), t.component("RouteName", y), t.component("RouteView", N), t.component("RouteLink", S), t.provide(A, this), this.options.installGlobalRef && (t.config.globalProperties[this.options.installGlobalRef] = this); } historyPopState(t) { !t || !t.state || ("name" in t.state ? this.setName(t.state.name, t.state.params, !1) : "path" in t.state && this.setPath(t.state.path, !1)); } dispatch(t) { let a = !1; if (!(window.history.state && B(window.history.state, t))) return "name" in t ? a = this.setName(t.name, t.params) : "path" in t && (a = this.setPath(t.path)), a; } } export { S as RouteLink, y as RouteName, v as RoutePath, N as RouteView, L as Router, A as RouterInjectionKey, U as createRouter, x as getRouter, r as router }; //# sourceMappingURL=index.js.map