From 9bee6456cb05f9e868fa83215c9f6bab3a04a725 Mon Sep 17 00:00:00 2001 From: MattMo Date: Wed, 19 May 2021 10:28:07 -0700 Subject: [PATCH] RouterMatcher is now Router. Added navigate. Added hash mode. --- ignite-html-router.js | 141 ++++++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 55 deletions(-) diff --git a/ignite-html-router.js b/ignite-html-router.js index 9b23f4e..565eee9 100644 --- a/ignite-html-router.js +++ b/ignite-html-router.js @@ -46,11 +46,11 @@ class RouterLink extends IgniteElement { var routeMatches = false; //Check the target first. - routeMatches = RouteMatcher.matches(this.target); + routeMatches = Router.matches(this.target); //Check optional routes next. for (var i = 0; i < this.routes.length && !routeMatches; i++) { - routeMatches = RouteMatcher.matches(this.routes[i]); + routeMatches = Router.matches(this.routes[i]); } if (routeMatches && !this.active) { @@ -62,8 +62,7 @@ class RouterLink extends IgniteElement { onClick(event) { event.preventDefault(); - window.history.pushState(this.target, this.target, this.target); - window.dispatchEvent(new Event("pushstate")); + Router.navigate(this.target, false); } cleanup() { @@ -92,9 +91,9 @@ class RouterView extends IgniteElement { } render() { - return this.template.child( - new slot(this) - ).style("display", this.show, null, (value) => { return value ? null : "none"; }); + return this.template + .child(new slot(this)) + .style("display", this.show, null, value => value ? null : "none"); } ready() { @@ -107,12 +106,12 @@ class RouterView extends IgniteElement { //Based on whether we are strict matching or not check if we have a match. if (!this.strict) { for (var i = 0; i < this.routes.length && !routeMatches; i++) { - routeMatches = RouteMatcher.matches(this.routes[i]); + routeMatches = Router.matches(this.routes[i]); } } else { routeMatches = true; for (var i = 0; i < this.routes.length && routeMatches; i++) { - routeMatches = RouteMatcher.matches(this.routes[i]); + routeMatches = Router.matches(this.routes[i]); } } @@ -130,10 +129,82 @@ class RouterView extends IgniteElement { } } -class RouteMatcher { +class RouterLinkTemplate extends IgniteTemplate { + /** + * Initializes a new router link template. + * @param {String} target The target route when the link is clicked. + * @param {String|String[]} routes Optional routes that can be used to control the active state of the link. + * @param {...any} elements Elements to render within the link. + */ + constructor(target, routes, ...elements) { + super("router-link", elements); + + if (!routes) { + routes = []; + } + + if (!Array.isArray(routes)) { + routes = [routes]; + } + + this.property("target", target); + this.property("routes", routes); + } +} + +class RouterViewTemplate extends IgniteTemplate { + /** + * Initializes a new router view. + * @param {String|String[]} routes Single or multiple routes to trigger this view to render. + * @param {any|any[]} elements Elements to render within the view. + * @param {Boolean} strict If true all routes must match before this view becomes visible. + */ + constructor(routes, elements, strict = false) { + super("router-view", Array.isArray(elements) ? elements : [elements]); + + if (!Array.isArray(routes)) { + routes = [routes]; + } + + this.property("routes", routes); + this.property("strict", strict); + } +} + +class Router { + static navigate(route, refresh = false) { + if (refresh) { + if (Router.hashMode) { + window.location.hash = route; + window.location.reload(); + } else { + window.location.href = route; + } + } else { + if (Router.hashMode) { + window.location.hash = route; + } else { + window.history.pushState(route, route, route); + } + + window.dispatchEvent(new Event("pushstate")); + } + } + static matches(route) { //Get the path parts from the window - var pathParts = window.location.pathname.split("/").splice(1); + var pathParts = []; + + //If hash mode is set and we have a hash location, get it and split it. + if (Router.hashMode && window.location.hash && window.location.hash.length > 0) { + pathParts = window.location.hash.substr(1).split("/"); + if (pathParts.length > 0 && pathParts[0].length == 0) { + pathParts.splice(1); + } + } + else if (!Router.hashMode) { + pathParts = window.location.pathname.split("/").splice(1); + } //Get the route parts var fromRoot = (route.trim().startsWith("/")); @@ -214,55 +285,15 @@ class RouteMatcher { } } -window.RouteMatcher = RouteMatcher; - -class RouterLinkTemplate extends IgniteTemplate { - /** - * Initializes a new router link template. - * @param {String} target The target route when the link is clicked. - * @param {String|String[]} routes Optional routes that can be used to control the active state of the link. - * @param {...any} elements Elements to render within the link. - */ - constructor(target, routes, ...elements) { - super("router-link", elements); - - if (!routes) { - routes = []; - } - - if (!Array.isArray(routes)) { - routes = [routes]; - } - - this.property("target", target); - this.property("routes", routes); - } -} - -class RouterViewTemplate extends IgniteTemplate { - /** - * Initializes a new router view. - * @param {String|String[]} routes Single or multiple routes to trigger this view to render. - * @param {any|any[]} elements Elements to render within the view. - * @param {Boolean} strict If true all routes must match before this view becomes visible. - */ - constructor(routes, elements, strict = false) { - super("router-view", Array.isArray(elements) ? elements : [elements]); - - if (!Array.isArray(routes)) { - routes = [routes]; - } - - this.property("routes", routes); - this.property("strict", strict); - } -} +Router.hashMode = false; customElements.define("router-link", RouterLink); customElements.define("router-view", RouterView); +window.Router = Router; + export { RouterLinkTemplate as RouterLink, RouterViewTemplate as RouterView, - RouteMatcher + Router } \ No newline at end of file