From ac5534a22f1e40f230ca505ce4e4c8bc27e4cdfb Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Tue, 24 Jun 2025 22:58:24 -0500 Subject: [PATCH 1/2] refactor: Update names & types for nav handler to make it more clear --- src/router.js | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/router.js b/src/router.js index 545d22c..7b72c52 100644 --- a/src/router.js +++ b/src/router.js @@ -7,38 +7,55 @@ import { useContext, useMemo, useReducer, useLayoutEffect, useRef } from 'preact * @typedef {import('./internal.d.ts').VNode} VNode */ -let push, scope; -const UPDATE = (state, url) => { +/** @type {boolean} */ +let push; +/** @type {string | RegExp | undefined} */ +let scope; + +/** + * @param {string} href + * @returns {boolean} + */ +function isInScope(href) { + return !scope || (typeof scope == 'string' + ? href.startsWith(scope) + : scope.test(href) + ); +} + +/** + * @param {string} state + * @param {MouseEvent | PopStateEvent | string | { url: string, replace?: boolean }} e + */ +function handleNav(state, e) { + let url = ''; push = undefined; - if (url && url.type === 'click') { + if (e && e.type === 'click') { // ignore events the browser takes care of already: - if (url.ctrlKey || url.metaKey || url.altKey || url.shiftKey || url.button !== 0) { + if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button !== 0) { return state; } - const link = url.composedPath().find(el => el.nodeName == 'A' && el.href), + const link = e.composedPath().find(el => el.nodeName == 'A' && el.href), href = link && link.getAttribute('href'); if ( !link || link.origin != location.origin || /^#/.test(href) || !/^(_?self)?$/i.test(link.target) || - scope && (typeof scope == 'string' - ? !href.startsWith(scope) - : !scope.test(href) - ) + !isInScope(href) ) { return state; } push = true; - url.preventDefault(); + e.preventDefault(); url = link.href.replace(location.origin, ''); - } else if (typeof url === 'string') { + } else if (typeof e === 'string') { push = true; - } else if (url && url.url) { - push = !url.replace; - url = url.url; + } else if (e && 'url' in e) { + push = !e.replace; + url = e.url; } else { url = location.pathname + location.search; } @@ -77,11 +94,13 @@ export const exec = (url, route, matches = {}) => { }; /** - * @type {import('./router.d.ts').LocationProvider} + * @param {Object} props + * @param {string | RegExp} [props.scope] + * @param {import('preact').ComponentChildren} [props.children] */ export function LocationProvider(props) { // @ts-expect-error - props.url is not implemented correctly & will be removed in the future - const [url, route] = useReducer(UPDATE, props.url || location.pathname + location.search); + const [url, route] = useReducer(handleNav, props.url || location.pathname + location.search); if (props.scope) scope = props.scope; const wasPush = push === true; From 21f0fc47d1810949722b28cff1ec4ee878e882cb Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Wed, 25 Jun 2025 01:00:18 -0500 Subject: [PATCH 2/2] refactor: Improve name, drop dead branch --- src/router.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/router.js b/src/router.js index 7b72c52..803bd7f 100644 --- a/src/router.js +++ b/src/router.js @@ -25,18 +25,18 @@ function isInScope(href) { /** * @param {string} state - * @param {MouseEvent | PopStateEvent | string | { url: string, replace?: boolean }} e + * @param {MouseEvent | PopStateEvent | { url: string, replace?: boolean }} action */ -function handleNav(state, e) { +function handleNav(state, action) { let url = ''; push = undefined; - if (e && e.type === 'click') { + if (action && action.type === 'click') { // ignore events the browser takes care of already: - if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button !== 0) { + if (action.ctrlKey || action.metaKey || action.altKey || action.shiftKey || action.button !== 0) { return state; } - const link = e.composedPath().find(el => el.nodeName == 'A' && el.href), + const link = action.composedPath().find(el => el.nodeName == 'A' && el.href), href = link && link.getAttribute('href'); if ( !link || @@ -49,13 +49,11 @@ function handleNav(state, e) { } push = true; - e.preventDefault(); + action.preventDefault(); url = link.href.replace(location.origin, ''); - } else if (typeof e === 'string') { - push = true; - } else if (e && 'url' in e) { - push = !e.replace; - url = e.url; + } else if (action && action.url) { + push = !action.replace; + url = action.url; } else { url = location.pathname + location.search; }