@tanstack/react-router 1.84.0 → 1.84.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +1 -1
- package/dist/cjs/Transitioner.cjs +9 -3
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +6 -6
- package/dist/cjs/router.cjs +6 -3
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +5 -0
- package/dist/cjs/scroll-restoration.cjs +2 -2
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/esm/Matches.d.ts +1 -1
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/Transitioner.js +9 -3
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/route.d.ts +6 -6
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +5 -0
- package/dist/esm/router.js +6 -3
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.js +2 -2
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.tsx +7 -7
- package/src/Transitioner.tsx +6 -0
- package/src/route.ts +29 -17
- package/src/router.ts +11 -3
- package/src/scroll-restoration.tsx +2 -2
|
@@ -61,7 +61,7 @@ function useScrollRestoration(options) {
|
|
|
61
61
|
document.addEventListener("scroll", onScroll, true);
|
|
62
62
|
}
|
|
63
63
|
const unsubOnBeforeLoad = router.subscribe("onBeforeLoad", (event) => {
|
|
64
|
-
if (event.
|
|
64
|
+
if (event.hrefChanged) {
|
|
65
65
|
const restoreKey = getKey(event.fromLocation);
|
|
66
66
|
for (const elementSelector in cache.state.next) {
|
|
67
67
|
const entry = cache.state.next[elementSelector];
|
|
@@ -91,7 +91,7 @@ function useScrollRestoration(options) {
|
|
|
91
91
|
const unsubOnBeforeRouteMount = router.subscribe(
|
|
92
92
|
"onBeforeRouteMount",
|
|
93
93
|
(event) => {
|
|
94
|
-
if (event.
|
|
94
|
+
if (event.hrefChanged) {
|
|
95
95
|
if (!router.resetNextScroll) {
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-restoration.js","sources":["../../src/scroll-restoration.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport { functionalUpdate } from './utils'\nimport type { ParsedLocation } from './location'\nimport type { NonNullableUpdater } from './utils'\n\nconst useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nconst windowKey = 'window'\nconst delimiter = '___'\n\nlet weakScrolledElements = new WeakSet<any>()\n\ntype CacheValue = Record<string, { scrollX: number; scrollY: number }>\ntype CacheState = {\n cached: CacheValue\n next: CacheValue\n}\n\ntype Cache = {\n state: CacheState\n set: (updater: NonNullableUpdater<CacheState>) => void\n}\n\nconst sessionsStorage = typeof window !== 'undefined' && window.sessionStorage\n\nconst cache: Cache = sessionsStorage\n ? (() => {\n const storageKey = 'tsr-scroll-restoration-v2'\n\n const state: CacheState = JSON.parse(\n window.sessionStorage.getItem(storageKey) || 'null',\n ) || { cached: {}, next: {} }\n\n return {\n state,\n set: (updater) => {\n cache.state = functionalUpdate(updater, cache.state)\n window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state))\n },\n }\n })()\n : (undefined as any)\n\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n}\n\n/**\n * The default `getKey` function for `useScrollRestoration`.\n * It returns the `key` from the location state or the `href` of the location.\n *\n * The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render.\n */\nconst defaultGetKey = (location: ParsedLocation) => {\n return location.state.key! || location.href\n}\n\nexport function useScrollRestoration(options?: ScrollRestorationOptions) {\n const router = useRouter()\n\n useLayoutEffect(() => {\n const getKey = options?.getKey || defaultGetKey\n\n const { history } = window\n history.scrollRestoration = 'manual'\n\n const onScroll = (event: Event) => {\n if (weakScrolledElements.has(event.target)) return\n weakScrolledElements.add(event.target)\n\n let elementSelector = ''\n\n if (event.target === document || event.target === window) {\n elementSelector = windowKey\n } else {\n const attrId = (event.target as Element).getAttribute(\n 'data-scroll-restoration-id',\n )\n\n if (attrId) {\n elementSelector = `[data-scroll-restoration-id=\"${attrId}\"]`\n } else {\n elementSelector = getCssSelector(event.target)\n }\n }\n\n if (!cache.state.next[elementSelector]) {\n cache.set((c) => ({\n ...c,\n next: {\n ...c.next,\n [elementSelector]: {\n scrollX: NaN,\n scrollY: NaN,\n },\n },\n }))\n }\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('scroll', onScroll, true)\n }\n\n const unsubOnBeforeLoad = router.subscribe('onBeforeLoad', (event) => {\n if (event.pathChanged) {\n const restoreKey = getKey(event.fromLocation)\n for (const elementSelector in cache.state.next) {\n const entry = cache.state.next[elementSelector]!\n if (elementSelector === windowKey) {\n entry.scrollX = window.scrollX || 0\n entry.scrollY = window.scrollY || 0\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n entry.scrollX = element?.scrollLeft || 0\n entry.scrollY = element?.scrollTop || 0\n }\n\n cache.set((c) => {\n const next = { ...c.next }\n delete next[elementSelector]\n\n return {\n ...c,\n next,\n cached: {\n ...c.cached,\n [[restoreKey, elementSelector].join(delimiter)]: entry,\n },\n }\n })\n }\n }\n })\n\n const unsubOnBeforeRouteMount = router.subscribe(\n 'onBeforeRouteMount',\n (event) => {\n if (event.pathChanged) {\n if (!router.resetNextScroll) {\n return\n }\n\n router.resetNextScroll = true\n\n const restoreKey = getKey(event.toLocation)\n let windowRestored = false\n\n for (const cacheKey in cache.state.cached) {\n const entry = cache.state.cached[cacheKey]!\n const [key, elementSelector] = cacheKey.split(delimiter)\n if (key === restoreKey) {\n if (elementSelector === windowKey) {\n windowRestored = true\n window.scrollTo(entry.scrollX, entry.scrollY)\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n element.scrollLeft = entry.scrollX\n element.scrollTop = entry.scrollY\n }\n }\n }\n }\n\n if (!windowRestored) {\n window.scrollTo(0, 0)\n }\n\n cache.set((c) => ({ ...c, next: {} }))\n weakScrolledElements = new WeakSet<any>()\n }\n },\n )\n\n return () => {\n document.removeEventListener('scroll', onScroll)\n unsubOnBeforeLoad()\n unsubOnBeforeRouteMount()\n }\n }, [options?.getKey, router])\n}\n\nexport function ScrollRestoration(props: ScrollRestorationOptions) {\n useScrollRestoration(props)\n return null\n}\n\nexport function useElementScrollRestoration(\n options: (\n | {\n id: string\n getElement?: () => Element | undefined | null\n }\n | {\n id?: string\n getElement: () => Element | undefined | null\n }\n ) & {\n getKey?: (location: ParsedLocation) => string\n },\n) {\n const router = useRouter()\n const getKey = options.getKey || defaultGetKey\n\n let elementSelector = ''\n\n if (options.id) {\n elementSelector = `[data-scroll-restoration-id=\"${options.id}\"]`\n } else {\n const element = options.getElement?.()\n if (!element) {\n return\n }\n elementSelector = getCssSelector(element)\n }\n\n const restoreKey = getKey(router.latestLocation)\n const cacheKey = [restoreKey, elementSelector].join(delimiter)\n return cache.state.cached[cacheKey]\n}\n\nfunction getCssSelector(el: any): string {\n const path = []\n let parent\n while ((parent = el.parentNode)) {\n path.unshift(\n `${el.tagName}:nth-child(${\n ([].indexOf as any).call(parent.children, el) + 1\n })`,\n )\n el = parent\n }\n return `${path.join(' > ')}`.toLowerCase()\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scroll-restoration.js","sources":["../../src/scroll-restoration.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useRouter } from './useRouter'\nimport { functionalUpdate } from './utils'\nimport type { ParsedLocation } from './location'\nimport type { NonNullableUpdater } from './utils'\n\nconst useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nconst windowKey = 'window'\nconst delimiter = '___'\n\nlet weakScrolledElements = new WeakSet<any>()\n\ntype CacheValue = Record<string, { scrollX: number; scrollY: number }>\ntype CacheState = {\n cached: CacheValue\n next: CacheValue\n}\n\ntype Cache = {\n state: CacheState\n set: (updater: NonNullableUpdater<CacheState>) => void\n}\n\nconst sessionsStorage = typeof window !== 'undefined' && window.sessionStorage\n\nconst cache: Cache = sessionsStorage\n ? (() => {\n const storageKey = 'tsr-scroll-restoration-v2'\n\n const state: CacheState = JSON.parse(\n window.sessionStorage.getItem(storageKey) || 'null',\n ) || { cached: {}, next: {} }\n\n return {\n state,\n set: (updater) => {\n cache.state = functionalUpdate(updater, cache.state)\n window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state))\n },\n }\n })()\n : (undefined as any)\n\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n}\n\n/**\n * The default `getKey` function for `useScrollRestoration`.\n * It returns the `key` from the location state or the `href` of the location.\n *\n * The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render.\n */\nconst defaultGetKey = (location: ParsedLocation) => {\n return location.state.key! || location.href\n}\n\nexport function useScrollRestoration(options?: ScrollRestorationOptions) {\n const router = useRouter()\n\n useLayoutEffect(() => {\n const getKey = options?.getKey || defaultGetKey\n\n const { history } = window\n history.scrollRestoration = 'manual'\n\n const onScroll = (event: Event) => {\n if (weakScrolledElements.has(event.target)) return\n weakScrolledElements.add(event.target)\n\n let elementSelector = ''\n\n if (event.target === document || event.target === window) {\n elementSelector = windowKey\n } else {\n const attrId = (event.target as Element).getAttribute(\n 'data-scroll-restoration-id',\n )\n\n if (attrId) {\n elementSelector = `[data-scroll-restoration-id=\"${attrId}\"]`\n } else {\n elementSelector = getCssSelector(event.target)\n }\n }\n\n if (!cache.state.next[elementSelector]) {\n cache.set((c) => ({\n ...c,\n next: {\n ...c.next,\n [elementSelector]: {\n scrollX: NaN,\n scrollY: NaN,\n },\n },\n }))\n }\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('scroll', onScroll, true)\n }\n\n const unsubOnBeforeLoad = router.subscribe('onBeforeLoad', (event) => {\n if (event.hrefChanged) {\n const restoreKey = getKey(event.fromLocation)\n for (const elementSelector in cache.state.next) {\n const entry = cache.state.next[elementSelector]!\n if (elementSelector === windowKey) {\n entry.scrollX = window.scrollX || 0\n entry.scrollY = window.scrollY || 0\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n entry.scrollX = element?.scrollLeft || 0\n entry.scrollY = element?.scrollTop || 0\n }\n\n cache.set((c) => {\n const next = { ...c.next }\n delete next[elementSelector]\n\n return {\n ...c,\n next,\n cached: {\n ...c.cached,\n [[restoreKey, elementSelector].join(delimiter)]: entry,\n },\n }\n })\n }\n }\n })\n\n const unsubOnBeforeRouteMount = router.subscribe(\n 'onBeforeRouteMount',\n (event) => {\n if (event.hrefChanged) {\n if (!router.resetNextScroll) {\n return\n }\n\n router.resetNextScroll = true\n\n const restoreKey = getKey(event.toLocation)\n let windowRestored = false\n\n for (const cacheKey in cache.state.cached) {\n const entry = cache.state.cached[cacheKey]!\n const [key, elementSelector] = cacheKey.split(delimiter)\n if (key === restoreKey) {\n if (elementSelector === windowKey) {\n windowRestored = true\n window.scrollTo(entry.scrollX, entry.scrollY)\n } else if (elementSelector) {\n const element = document.querySelector(elementSelector)\n if (element) {\n element.scrollLeft = entry.scrollX\n element.scrollTop = entry.scrollY\n }\n }\n }\n }\n\n if (!windowRestored) {\n window.scrollTo(0, 0)\n }\n\n cache.set((c) => ({ ...c, next: {} }))\n weakScrolledElements = new WeakSet<any>()\n }\n },\n )\n\n return () => {\n document.removeEventListener('scroll', onScroll)\n unsubOnBeforeLoad()\n unsubOnBeforeRouteMount()\n }\n }, [options?.getKey, router])\n}\n\nexport function ScrollRestoration(props: ScrollRestorationOptions) {\n useScrollRestoration(props)\n return null\n}\n\nexport function useElementScrollRestoration(\n options: (\n | {\n id: string\n getElement?: () => Element | undefined | null\n }\n | {\n id?: string\n getElement: () => Element | undefined | null\n }\n ) & {\n getKey?: (location: ParsedLocation) => string\n },\n) {\n const router = useRouter()\n const getKey = options.getKey || defaultGetKey\n\n let elementSelector = ''\n\n if (options.id) {\n elementSelector = `[data-scroll-restoration-id=\"${options.id}\"]`\n } else {\n const element = options.getElement?.()\n if (!element) {\n return\n }\n elementSelector = getCssSelector(element)\n }\n\n const restoreKey = getKey(router.latestLocation)\n const cacheKey = [restoreKey, elementSelector].join(delimiter)\n return cache.state.cached[cacheKey]\n}\n\nfunction getCssSelector(el: any): string {\n const path = []\n let parent\n while ((parent = el.parentNode)) {\n path.unshift(\n `${el.tagName}:nth-child(${\n ([].indexOf as any).call(parent.children, el) + 1\n })`,\n )\n el = parent\n }\n return `${path.join(' > ')}`.toLowerCase()\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Matches.tsx
CHANGED
|
@@ -136,13 +136,13 @@ export type MakeRouteMatchFromRoute<TRoute extends AnyRoute> = RouteMatch<
|
|
|
136
136
|
>
|
|
137
137
|
|
|
138
138
|
export interface RouteMatch<
|
|
139
|
-
TRouteId,
|
|
140
|
-
TFullPath,
|
|
141
|
-
TAllParams,
|
|
142
|
-
TFullSearchSchema,
|
|
143
|
-
TLoaderData,
|
|
144
|
-
TAllContext,
|
|
145
|
-
TLoaderDeps,
|
|
139
|
+
out TRouteId,
|
|
140
|
+
out TFullPath,
|
|
141
|
+
out TAllParams,
|
|
142
|
+
out TFullSearchSchema,
|
|
143
|
+
out TLoaderData,
|
|
144
|
+
out TAllContext,
|
|
145
|
+
out TLoaderDeps,
|
|
146
146
|
> {
|
|
147
147
|
id: string
|
|
148
148
|
routeId: TRouteId
|
package/src/Transitioner.tsx
CHANGED
|
@@ -84,12 +84,14 @@ export function Transitioner() {
|
|
|
84
84
|
const toLocation = router.state.location
|
|
85
85
|
const fromLocation = router.state.resolvedLocation
|
|
86
86
|
const pathChanged = fromLocation.pathname !== toLocation.pathname
|
|
87
|
+
const hrefChanged = fromLocation.href !== toLocation.href
|
|
87
88
|
|
|
88
89
|
router.emit({
|
|
89
90
|
type: 'onLoad', // When the new URL has committed, when the new matches have been loaded into state.matches
|
|
90
91
|
fromLocation,
|
|
91
92
|
toLocation,
|
|
92
93
|
pathChanged,
|
|
94
|
+
hrefChanged,
|
|
93
95
|
})
|
|
94
96
|
}
|
|
95
97
|
}, [previousIsLoading, router, isLoading])
|
|
@@ -100,12 +102,14 @@ export function Transitioner() {
|
|
|
100
102
|
const toLocation = router.state.location
|
|
101
103
|
const fromLocation = router.state.resolvedLocation
|
|
102
104
|
const pathChanged = fromLocation.pathname !== toLocation.pathname
|
|
105
|
+
const hrefChanged = fromLocation.href !== toLocation.href
|
|
103
106
|
|
|
104
107
|
router.emit({
|
|
105
108
|
type: 'onBeforeRouteMount',
|
|
106
109
|
fromLocation,
|
|
107
110
|
toLocation,
|
|
108
111
|
pathChanged,
|
|
112
|
+
hrefChanged,
|
|
109
113
|
})
|
|
110
114
|
}
|
|
111
115
|
}, [isPagePending, previousIsPagePending, router])
|
|
@@ -116,12 +120,14 @@ export function Transitioner() {
|
|
|
116
120
|
const toLocation = router.state.location
|
|
117
121
|
const fromLocation = router.state.resolvedLocation
|
|
118
122
|
const pathChanged = fromLocation.pathname !== toLocation.pathname
|
|
123
|
+
const hrefChanged = fromLocation.href !== toLocation.href
|
|
119
124
|
|
|
120
125
|
router.emit({
|
|
121
126
|
type: 'onResolved',
|
|
122
127
|
fromLocation,
|
|
123
128
|
toLocation,
|
|
124
129
|
pathChanged,
|
|
130
|
+
hrefChanged,
|
|
125
131
|
})
|
|
126
132
|
|
|
127
133
|
router.__store.setState((s) => ({
|
package/src/route.ts
CHANGED
|
@@ -127,17 +127,17 @@ export type ResolveParams<TPath extends string> =
|
|
|
127
127
|
? Record<ParsePathParams<TPath>, string>
|
|
128
128
|
: Record<ParsePathParams<TPath>, string> & SplatParams
|
|
129
129
|
|
|
130
|
-
export type ParseParamsFn<TPath extends string, TParams> = (
|
|
130
|
+
export type ParseParamsFn<in out TPath extends string, in out TParams> = (
|
|
131
131
|
rawParams: ResolveParams<TPath>,
|
|
132
132
|
) => TParams extends Record<ParsePathParams<TPath>, any>
|
|
133
133
|
? TParams
|
|
134
134
|
: Record<ParsePathParams<TPath>, any>
|
|
135
135
|
|
|
136
|
-
export type StringifyParamsFn<TPath extends string, TParams> = (
|
|
136
|
+
export type StringifyParamsFn<in out TPath extends string, in out TParams> = (
|
|
137
137
|
params: TParams,
|
|
138
138
|
) => ResolveParams<TPath>
|
|
139
139
|
|
|
140
|
-
export type ParamsOptions<TPath extends string, TParams> = {
|
|
140
|
+
export type ParamsOptions<in out TPath extends string, in out TParams> = {
|
|
141
141
|
params?: {
|
|
142
142
|
parse?: ParseParamsFn<TPath, TParams>
|
|
143
143
|
stringify?: StringifyParamsFn<TPath, TParams>
|
|
@@ -1083,12 +1083,11 @@ export class Route<
|
|
|
1083
1083
|
this._ssr = options?.ssr ?? opts.defaultSsr ?? true
|
|
1084
1084
|
}
|
|
1085
1085
|
|
|
1086
|
-
addChildren<
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
|
1090
|
-
|
|
1091
|
-
children: TNewChildren,
|
|
1086
|
+
addChildren<const TNewChildren>(
|
|
1087
|
+
children: Constrain<
|
|
1088
|
+
TNewChildren,
|
|
1089
|
+
ReadonlyArray<AnyRoute> | Record<string, AnyRoute>
|
|
1090
|
+
>,
|
|
1092
1091
|
): Route<
|
|
1093
1092
|
TParentRoute,
|
|
1094
1093
|
TPath,
|
|
@@ -1104,7 +1103,21 @@ export class Route<
|
|
|
1104
1103
|
TLoaderFn,
|
|
1105
1104
|
TNewChildren
|
|
1106
1105
|
> {
|
|
1107
|
-
return this._addFileChildren(children)
|
|
1106
|
+
return this._addFileChildren(children) as Route<
|
|
1107
|
+
TParentRoute,
|
|
1108
|
+
TPath,
|
|
1109
|
+
TFullPath,
|
|
1110
|
+
TCustomId,
|
|
1111
|
+
TId,
|
|
1112
|
+
TSearchValidator,
|
|
1113
|
+
TParams,
|
|
1114
|
+
TRouterContext,
|
|
1115
|
+
TRouteContextFn,
|
|
1116
|
+
TBeforeLoadFn,
|
|
1117
|
+
TLoaderDeps,
|
|
1118
|
+
TLoaderFn,
|
|
1119
|
+
TNewChildren
|
|
1120
|
+
>
|
|
1108
1121
|
}
|
|
1109
1122
|
|
|
1110
1123
|
_addFileChildren<const TNewChildren>(
|
|
@@ -1302,7 +1315,7 @@ export function createRoute<
|
|
|
1302
1315
|
>(options)
|
|
1303
1316
|
}
|
|
1304
1317
|
|
|
1305
|
-
export type AnyRootRoute = RootRoute<any, any, any, any, any, any, any>
|
|
1318
|
+
export type AnyRootRoute = RootRoute<any, any, any, any, any, any, any, any>
|
|
1306
1319
|
|
|
1307
1320
|
export type RootRouteOptions<
|
|
1308
1321
|
TSearchValidator = undefined,
|
|
@@ -1408,12 +1421,11 @@ export class RootRoute<
|
|
|
1408
1421
|
super(options as any)
|
|
1409
1422
|
}
|
|
1410
1423
|
|
|
1411
|
-
addChildren<
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
|
1415
|
-
|
|
1416
|
-
children: TNewChildren,
|
|
1424
|
+
addChildren<const TNewChildren>(
|
|
1425
|
+
children: Constrain<
|
|
1426
|
+
TNewChildren,
|
|
1427
|
+
ReadonlyArray<AnyRoute> | Record<string, AnyRoute>
|
|
1428
|
+
>,
|
|
1417
1429
|
): RootRoute<
|
|
1418
1430
|
TSearchValidator,
|
|
1419
1431
|
TRouterContext,
|
package/src/router.ts
CHANGED
|
@@ -614,30 +614,35 @@ export type RouterEvents = {
|
|
|
614
614
|
fromLocation: ParsedLocation
|
|
615
615
|
toLocation: ParsedLocation
|
|
616
616
|
pathChanged: boolean
|
|
617
|
+
hrefChanged: boolean
|
|
617
618
|
}
|
|
618
619
|
onBeforeLoad: {
|
|
619
620
|
type: 'onBeforeLoad'
|
|
620
621
|
fromLocation: ParsedLocation
|
|
621
622
|
toLocation: ParsedLocation
|
|
622
623
|
pathChanged: boolean
|
|
624
|
+
hrefChanged: boolean
|
|
623
625
|
}
|
|
624
626
|
onLoad: {
|
|
625
627
|
type: 'onLoad'
|
|
626
628
|
fromLocation: ParsedLocation
|
|
627
629
|
toLocation: ParsedLocation
|
|
628
630
|
pathChanged: boolean
|
|
631
|
+
hrefChanged: boolean
|
|
629
632
|
}
|
|
630
633
|
onResolved: {
|
|
631
634
|
type: 'onResolved'
|
|
632
635
|
fromLocation: ParsedLocation
|
|
633
636
|
toLocation: ParsedLocation
|
|
634
637
|
pathChanged: boolean
|
|
638
|
+
hrefChanged: boolean
|
|
635
639
|
}
|
|
636
640
|
onBeforeRouteMount: {
|
|
637
641
|
type: 'onBeforeRouteMount'
|
|
638
642
|
fromLocation: ParsedLocation
|
|
639
643
|
toLocation: ParsedLocation
|
|
640
644
|
pathChanged: boolean
|
|
645
|
+
hrefChanged: boolean
|
|
641
646
|
}
|
|
642
647
|
}
|
|
643
648
|
|
|
@@ -1900,7 +1905,8 @@ export class Router<
|
|
|
1900
1905
|
try {
|
|
1901
1906
|
const next = this.latestLocation
|
|
1902
1907
|
const prevLocation = this.state.resolvedLocation
|
|
1903
|
-
const
|
|
1908
|
+
const hrefChanged = prevLocation.href !== next.href
|
|
1909
|
+
const pathChanged = prevLocation.pathname !== next.pathname
|
|
1904
1910
|
|
|
1905
1911
|
// Cancel any pending matches
|
|
1906
1912
|
this.cancelMatches()
|
|
@@ -1934,7 +1940,8 @@ export class Router<
|
|
|
1934
1940
|
type: 'onBeforeNavigate',
|
|
1935
1941
|
fromLocation: prevLocation,
|
|
1936
1942
|
toLocation: next,
|
|
1937
|
-
pathChanged
|
|
1943
|
+
pathChanged,
|
|
1944
|
+
hrefChanged,
|
|
1938
1945
|
})
|
|
1939
1946
|
}
|
|
1940
1947
|
|
|
@@ -1942,7 +1949,8 @@ export class Router<
|
|
|
1942
1949
|
type: 'onBeforeLoad',
|
|
1943
1950
|
fromLocation: prevLocation,
|
|
1944
1951
|
toLocation: next,
|
|
1945
|
-
pathChanged
|
|
1952
|
+
pathChanged,
|
|
1953
|
+
hrefChanged,
|
|
1946
1954
|
})
|
|
1947
1955
|
|
|
1948
1956
|
await this.loadMatches({
|
|
@@ -105,7 +105,7 @@ export function useScrollRestoration(options?: ScrollRestorationOptions) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
const unsubOnBeforeLoad = router.subscribe('onBeforeLoad', (event) => {
|
|
108
|
-
if (event.
|
|
108
|
+
if (event.hrefChanged) {
|
|
109
109
|
const restoreKey = getKey(event.fromLocation)
|
|
110
110
|
for (const elementSelector in cache.state.next) {
|
|
111
111
|
const entry = cache.state.next[elementSelector]!
|
|
@@ -138,7 +138,7 @@ export function useScrollRestoration(options?: ScrollRestorationOptions) {
|
|
|
138
138
|
const unsubOnBeforeRouteMount = router.subscribe(
|
|
139
139
|
'onBeforeRouteMount',
|
|
140
140
|
(event) => {
|
|
141
|
-
if (event.
|
|
141
|
+
if (event.hrefChanged) {
|
|
142
142
|
if (!router.resetNextScroll) {
|
|
143
143
|
return
|
|
144
144
|
}
|