diff --git a/ignite-html-router.js b/ignite-html-router.js index afe7c5f..aa3c982 100644 --- a/ignite-html-router.js +++ b/ignite-html-router.js @@ -3,9 +3,9 @@ import { IgniteTemplate, slot, div, html } from "../ignite-html/ignite-template. import { IgniteCallback} from "../ignite-html/ignite-html.js"; /** - * Creates a route listener that runs when a route is switched. + * Creates a route listener that runs when a route is switched. The listener will run on construct the first time and update the state. * @param {String,String[]} routes A single or multiple set of routes that will invoke the callback if met. - * @param {Function} callback A callback function to invoke if the route is met, it will be passed the pushstate event. + * @param {Function} callback A callback function that is called when the route is met. It will be passed any route data. * @param {Boolean} strict If true all routes must match before running the callback. * @returns {IgniteTemplate} This ignite template. */ @@ -15,28 +15,40 @@ IgniteTemplate.prototype.route = function(routes, callback, strict = false) { routes = [routes]; } - //Create a managed callback - var managed = new IgniteCallback(event => { + //Create an update method that will be used to check and see if the route is met. + var update = (event) => { + console.log("Updating route:", routes); + var routeMatches = false; + //Create an object to hold any data. + var data = {}; + //Based on whether we are strict matching or not check if we have a match. if (!strict) { for (var i = 0; i < routes.length && !routeMatches; i++) { - routeMatches = Router.matches(routes[i]); + routeMatches = Router.matches(routes[i], data); } } else { routeMatches = true; for (var i = 0; i < routes.length && routeMatches; i++) { - routeMatches = Router.matches(routes[i]); + routeMatches = Router.matches(routes[i], data); } } //Invoke the callback if the route matched. if (routeMatches) { - callback(event); + console.log("Route matches"); + if (event && event.data) { + callback(event.data); + } else { + callback(data); + } } + }; - }, () => { + //Create a managed callback + var managed = new IgniteCallback(update, () => { window.removeEventListener("pushstate", managed.callback); }); @@ -46,6 +58,9 @@ IgniteTemplate.prototype.route = function(routes, callback, strict = false) { //Add the managed callback to our template so that upon deconstruction our callback is destroyed correctly. this._callbacks.push(managed); + //Create a constructor callback that will update the state upon first load. + this._constructors.push(update); + return this; }; @@ -271,9 +286,13 @@ class Router { /** * Returns whether or not the current location matches a given route. * @param {String} route The route to check. + * @param {Object} data The object to be populated with data from the route. * @returns {Boolean} Returns whether or not the current browser location matches the route. + * @example matches('/user/**') //Anything after /user/ is considered a match. + * @example matches('/user/{id}/profile') //Anything between /user and /profile is a match. data.id would be set to the value inside {id} + * @example matches('/user/!0/profile') //Anything between /user and /profile that is not '0' is a match. */ - static matches(route) { + static matches(route, data = null) { //Get the path parts from the window var pathParts = []; @@ -322,7 +341,11 @@ class Router { var max = Math.min(pathParts.length, routeParts.length); if (fromRoot) { for (var i = 0; i < max; i++) { - if (routeParts[i].startsWith("!") && pathParts[i] == routeParts[i].substring(1)) { + if (routeParts[i].startsWith("{") && routeParts[i].endsWith("}")) { + if (data) { + data[routeParts[i].substring(1, routeParts[i].length - 1)] = pathParts[i]; + } + } else if (routeParts[i].startsWith("!") && pathParts[i] == routeParts[i].substring(1)) { return false; } else if (routeParts[i] == "**") { return true; @@ -346,8 +369,7 @@ class Router { if (i + offset >= pathParts.length) { return false; } - - if (routeParts[i].startsWith("!") && pathParts[i + offset] == routeParts[i].substring(1)) { + else if (routeParts[i].startsWith("!") && pathParts[i + offset] == routeParts[i].substring(1)) { break; } else if (routeParts[i] == "**") { return true;