From 162694d2e270b2ed7f4591eb4fde7927574095a2 Mon Sep 17 00:00:00 2001 From: Matthew Robb Date: Sun, 1 Dec 2019 19:33:16 -0500 Subject: [PATCH] Moved route matching logic into utils --- src/navigator.js | 37 +++-------------------------------- src/utils.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/navigator.js b/src/navigator.js index 66c055b0..951dce7f 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -1,9 +1,7 @@ +import { matchRoute } from './utils' import * as store from './store' export default function (routes, cb) { - const fallbacks = routes.filter(route => route.isFallback) - routes = routes.filter(route => !route.isFallback) - addEventListener('popstate', updatePage); addEventListener('replacestate', updatePage); addEventListener('pushstate', updatePage); @@ -22,39 +20,10 @@ export default function (routes, cb) { }) function updatePage() { - const url = window.location.pathname - const urlWithIndex = url.match(/\/index\/?$/) ? - url : - (url + "/index").replace(/\/+/g, "/"); //remove duplicate slashes - const urlWithSlash = (url + '/').replace(/\/+/g, "/") - - let route = - routes.filter(route => urlWithIndex.match(route.regex))[0] - || routes.filter(route => url.match(route.regex))[0] - || fallbacks.filter(route => urlWithSlash.match(route.regex))[0] - || fallbacks.filter(route => url.match(route.regex))[0] - - if (!route) throw new Error(`Route could not be found. Make sure ${url}.svelte or ${url}/index.svelte exists. A restart may be required.`) - - + const match = matchRoute(location.pathname, routes); + const route = { ...match.route, params: match.params }; const components = [...route.layouts, route.component]; - const regexUrl = route.regex.match(/\/index$/) ? urlWithIndex : url - - const params = {}; - if (route.paramKeys) { - regexUrl.match(route.regex).forEach((match, i) => { - if (i === 0) return; - const key = route.paramKeys[i - 1]; - params[key] = match; - }); - } - - route.params = params - - //set the route in the store - store.route.set(route) - //run callback in Router.svelte cb({ components, route }) } diff --git a/src/utils.js b/src/utils.js index 385ee925..4d7378ad 100644 --- a/src/utils.js +++ b/src/utils.js @@ -34,4 +34,54 @@ export const url = (path, params) => { path = path.replace(`:${key}`, value) } return path +} + +export const matchRoute = (url, routes)=> { + const urlWithIndex = url.match(/\/index\/?$/) ? url : ( + (url + "/index").replace(/\/+/g, "/") //remove duplicate slashes + ) + + let route, match, fallback, fallbackMatch + + for (let i = 0, len = routes.length; i < len; i++) { + const { [i]: r } = routes + + if (r.isFallback) { + if (fallback) { + continue + } else if (fallbackMatch = urlWithIndex.match(r.regex)) { + fallback = r + url = urlWithIndex + } else if (fallbackMatch = url.match(r.regex)) { + fallback = r + } + } else if (match = urlWithIndex.match(r.regex)) { + route = r + url = urlWithIndex + } else if (match = url.match(r.regex)) { + route = r + } + + if (route) break + } + + if (!route) { + if (!fallback) throw new Error( + `Route could not be found. Make sure ${url}.svelte, ${url}/index.svelte or a fallback exists. A restart may be required.` + ) + + route = fallback + match = fallbackMatch + } + + const params = {} + + if (route.paramKeys) { + for (let i = 0, len = route.paramKeys.length; i < len; i++) { + const { [i]: key } = route.paramKeys + params[key] = match[i + 1] + } + } + + return { url, match, params, route } } \ No newline at end of file