@@ -7,38 +7,53 @@ import { useContext, useMemo, useReducer, useLayoutEffect, useRef } from 'preact
77 * @typedef {import('./internal.d.ts').VNode } VNode
88 */
99
10- let push , scope ;
11- const UPDATE = ( state , url ) => {
10+ /** @type {boolean } */
11+ let push ;
12+ /** @type {string | RegExp | undefined } */
13+ let scope ;
14+
15+ /**
16+ * @param {string } href
17+ * @returns {boolean }
18+ */
19+ function isInScope ( href ) {
20+ return ! scope || ( typeof scope == 'string'
21+ ? href . startsWith ( scope )
22+ : scope . test ( href )
23+ ) ;
24+ }
25+
26+ /**
27+ * @param {string } state
28+ * @param {MouseEvent | PopStateEvent | { url: string, replace?: boolean } } action
29+ */
30+ function handleNav ( state , action ) {
31+ let url = '' ;
1232 push = undefined ;
13- if ( url && url . type === 'click' ) {
33+ if ( action && action . type === 'click' ) {
1434 // ignore events the browser takes care of already:
15- if ( url . ctrlKey || url . metaKey || url . altKey || url . shiftKey || url . button !== 0 ) {
35+ if ( action . ctrlKey || action . metaKey || action . altKey || action . shiftKey || action . button !== 0 ) {
1636 return state ;
1737 }
1838
19- const link = url . composedPath ( ) . find ( el => el . nodeName == 'A' && el . href ) ,
39+ const link = action . composedPath ( ) . find ( el => el . nodeName == 'A' && el . href ) ,
2040 href = link && link . getAttribute ( 'href' ) ;
2141 if (
2242 ! link ||
2343 link . origin != location . origin ||
2444 / ^ # / . test ( href ) ||
2545 ! / ^ ( _ ? s e l f ) ? $ / i. test ( link . target ) ||
26- scope && ( typeof scope == 'string'
27- ? ! href . startsWith ( scope )
28- : ! scope . test ( href )
29- )
46+ ! isInScope ( href )
3047 ) {
3148 return state ;
3249 }
3350
3451 push = true ;
35- url . preventDefault ( ) ;
52+ action . preventDefault ( ) ;
3653 url = link . href . replace ( location . origin , '' ) ;
37- } else if ( typeof url === 'string' ) {
38- push = true ;
39- } else if ( url && url . url ) {
40- push = ! url . replace ;
41- url = url . url ;
54+ } else if ( action && action . url ) {
55+ push = ! action . replace ;
56+ url = action . url ;
4257 } else {
4358 url = location . pathname + location . search ;
4459 }
@@ -77,11 +92,13 @@ export const exec = (url, route, matches = {}) => {
7792} ;
7893
7994/**
80- * @type {import('./router.d.ts').LocationProvider }
95+ * @param {Object } props
96+ * @param {string | RegExp } [props.scope]
97+ * @param {import('preact').ComponentChildren } [props.children]
8198 */
8299export function LocationProvider ( props ) {
83100 // @ts -expect-error - props.url is not implemented correctly & will be removed in the future
84- const [ url , route ] = useReducer ( UPDATE , props . url || location . pathname + location . search ) ;
101+ const [ url , route ] = useReducer ( handleNav , props . url || location . pathname + location . search ) ;
85102 if ( props . scope ) scope = props . scope ;
86103 const wasPush = push === true ;
87104
0 commit comments