From 8c4d348e12b6eb24899dd8f4c110032aaa5574f3 Mon Sep 17 00:00:00 2001 From: Mark Garrigan Date: Fri, 30 Dec 2022 14:58:21 -0600 Subject: [PATCH] first commit --- LICENSE => UNLICENSE | 0 index.js | 92 ++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 28 ++++++++++++++ package.json | 27 +++++++++++++ 4 files changed, 147 insertions(+) rename LICENSE => UNLICENSE (100%) create mode 100644 index.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/LICENSE b/UNLICENSE similarity index 100% rename from LICENSE rename to UNLICENSE diff --git a/index.js b/index.js new file mode 100644 index 0000000..c8c1a3a --- /dev/null +++ b/index.js @@ -0,0 +1,92 @@ +if (typeof window === 'undefined') { + throw new Error('This module only works in the browser.') +} + +const { addEventListener, history, dispatchEvent, location } = window +import { pathToRegexp, match } from 'path-to-regexp' + +const routes = [] + +function handle(path) { + const matched = routes.filter(r => r.regexp.exec(path)) + if (matched.length === 0) { + console.log('No route match.', path) + return false + } + for (let route of matched) { + const { controller, match, name } = route + const data = match(path) + controller.apply({}, [{ name, ...data }]) + return true + } +} + +const Router = { + config({ + base = '/', + controller = () => { + console.log('Default Controller'); + } + }) { + this.controller = controller + if (base[0] !== '/') { + console.error('Base must start with a /'); + return + } + if (base !== '/' && [base.length - 1] === '/') { + console.error('Base can not end with a /'); + return + } + this.base = base + return this + }, + add({ path, controller = this.controller, name } = {}) { + let thePath = path + const pathType = Object.prototype.toString.call(path) + const { base } = this + if (path[0] !== '/' && path !== '*') { + console.error('Path must start with a /'); + return + } + if (path === '*') { + thePath = /.*/ + } + if (base !== '/') { + if (pathType === '[object RegExp]') { + // Add base to the beginning of the path + } + if (pathType === '[object String]') { + thePath = path === '/' ? base : base + path + } + } + routes.push({ name, thePath, controller, regexp: pathToRegexp(thePath), match: match(thePath) }) + return this + }, + start() { + const { pathname, hash } = location + const path = pathname + hash + handle(path) + } +} + +addEventListener('click', function (event) { + const { target } = event + if (target.tagName === 'A') { + const { href } = target + const { origin, pathname, hash, search } = new URL(href) + if (origin !== location.origin) return + if (href.match(/^mailto:/)) return + if (href.match(/^tel:/)) return + if (href.match(/^javascript:/)) return + if (pathname.match(/^#/)) return + event.preventDefault() + history.pushState({}, '', pathname + hash + search) + dispatchEvent(new PopStateEvent('popstate', { state: {} })) + } +}) + +addEventListener('popstate', () => { + Router.start() +}) + +export default Router diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9802daa --- /dev/null +++ b/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "@markgarrigan/router", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@markgarrigan/router", + "version": "0.0.1", + "license": "Unlicense", + "dependencies": { + "path-to-regexp": "^6.2.1" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + } + }, + "dependencies": { + "path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..822da3f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "@markgarrigan/router", + "version": "0.0.1", + "description": "Because I need a router to exactly what I want it to do.", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/markgarrigan/router.git" + }, + "keywords": [ + "javascript", + "router" + ], + "author": "Mark Garrigan", + "license": "Unlicense", + "bugs": { + "url": "https://github.com/markgarrigan/router/issues" + }, + "homepage": "https://github.com/markgarrigan/router#readme", + "dependencies": { + "path-to-regexp": "^6.2.1" + } +}