@@ -7,8 +7,6 @@ import { useContext, useMemo, useReducer, useLayoutEffect, useRef } from 'preact
77 * @typedef {import('./internal.d.ts').VNode } VNode
88 */
99
10- /** @type {boolean } */
11- let push ;
1210/** @type {string | RegExp | undefined } */
1311let scope ;
1412
@@ -23,45 +21,23 @@ function isInScope(href) {
2321 ) ;
2422}
2523
24+
2625/**
2726 * @param {string } state
28- * @param {MouseEvent | PopStateEvent | { url: string, replace?: boolean } } action
27+ * @param {NavigateEvent } e
2928 */
30- function handleNav ( state , action ) {
31- let url = '' ;
32- push = undefined ;
33- if ( action && action . type === 'click' ) {
34- // ignore events the browser takes care of already:
35- if ( action . ctrlKey || action . metaKey || action . altKey || action . shiftKey || action . button !== 0 ) {
36- return state ;
37- }
38-
39- const link = action . composedPath ( ) . find ( el => el . nodeName == 'A' && el . href ) ,
40- href = link && link . getAttribute ( 'href' ) ;
41- if (
42- ! link ||
43- link . origin != location . origin ||
44- / ^ # / . test ( href ) ||
45- ! / ^ ( _ ? s e l f ) ? $ / i. test ( link . target ) ||
46- ! isInScope ( href )
47- ) {
48- return state ;
49- }
29+ function handleNav ( state , e ) {
30+ if ( ! e . canIntercept ) return state ;
31+ if ( e . hashChange || e . downloadRequest !== null ) return state ;
5032
51- push = true ;
52- action . preventDefault ( ) ;
53- url = link . href . replace ( location . origin , '' ) ;
54- } else if ( action && action . url ) {
55- push = ! action . replace ;
56- url = action . url ;
57- } else {
58- url = location . pathname + location . search ;
33+ const url = new URL ( e . destination . url ) ;
34+ if ( ! isInScope ( url . href ) ) {
35+ return state ;
5936 }
6037
61- if ( push === true ) history . pushState ( null , '' , url ) ;
62- else if ( push === false ) history . replaceState ( null , '' , url ) ;
63- return url ;
64- } ;
38+ e . intercept ( ) ;
39+ return url . href . replace ( url . origin , '' ) ;
40+ }
6541
6642export const exec = ( url , route , matches = { } ) => {
6743 url = url . split ( '/' ) . filter ( Boolean ) ;
@@ -99,7 +75,6 @@ export const exec = (url, route, matches = {}) => {
9975export function LocationProvider ( props ) {
10076 const [ url , route ] = useReducer ( handleNav , location . pathname + location . search ) ;
10177 if ( props . scope ) scope = props . scope ;
102- const wasPush = push === true ;
10378
10479 const value = useMemo ( ( ) => {
10580 const u = new URL ( url , location . origin ) ;
@@ -110,18 +85,14 @@ export function LocationProvider(props) {
11085 path,
11186 pathParams : { } ,
11287 searchParams : Object . fromEntries ( u . searchParams ) ,
113- route : ( url , replace ) => route ( { url, replace } ) ,
114- wasPush
11588 } ;
11689 } , [ url ] ) ;
11790
11891 useLayoutEffect ( ( ) => {
119- addEventListener ( 'click' , route ) ;
120- addEventListener ( 'popstate' , route ) ;
92+ navigation . addEventListener ( 'navigate' , route ) ;
12193
12294 return ( ) => {
123- removeEventListener ( 'click' , route ) ;
124- removeEventListener ( 'popstate' , route ) ;
95+ navigation . removeEventListener ( 'navigate' , route ) ;
12596 } ;
12697 } , [ ] ) ;
12798
@@ -133,7 +104,7 @@ const RESOLVED = Promise.resolve();
133104export function Router ( props ) {
134105 const [ c , update ] = useReducer ( c => c + 1 , 0 ) ;
135106
136- const { url, path, pathParams, searchParams, wasPush } = useLocation ( ) ;
107+ const { url, path, pathParams, searchParams } = useLocation ( ) ;
137108 if ( ! url ) {
138109 throw new Error ( `preact-iso's <Router> must be used within a <LocationProvider>, see: https://github.com/preactjs/preact-iso#locationprovider` ) ;
139110 }
@@ -257,15 +228,15 @@ export function Router(props) {
257228
258229 // The route is loaded and rendered.
259230 if ( prevRoute . current !== path ) {
260- if ( wasPush ) scrollTo ( 0 , 0 ) ;
231+ scrollTo ( 0 , 0 ) ;
261232 if ( props . onRouteChange ) props . onRouteChange ( url ) ;
262233
263234 prevRoute . current = path ;
264235 }
265236
266237 if ( props . onLoadEnd && isLoading . current ) props . onLoadEnd ( url ) ;
267238 isLoading . current = false ;
268- } , [ path , wasPush , c ] ) ;
239+ } , [ path , c ] ) ;
269240
270241 // Note: cur MUST render first in order to set didSuspend & prev.
271242 return routeChanged
@@ -282,7 +253,7 @@ const RenderRef = ({ r }) => r.current;
282253Router . Provider = LocationProvider ;
283254
284255LocationProvider . ctx = createContext (
285- /** @type {import('./router.d.ts').LocationHook & { wasPush: boolean } } */ ( { } )
256+ /** @type {import('./router.d.ts').LocationHook }} */ ( { } )
286257) ;
287258const RouterContext = createContext (
288259 /** @type {{ rest: string } } */ ( { } )
0 commit comments