@tanstack/router-core 1.171.14 → 1.171.15
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/router.cjs +1 -4
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +1 -1
- package/dist/cjs/scroll-restoration.cjs +27 -34
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/esm/router.d.ts +1 -1
- package/dist/esm/router.js +2 -4
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.js +27 -34
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/package.json +1 -1
- package/src/router.ts +4 -8
- package/src/scroll-restoration.ts +40 -56
package/dist/cjs/router.d.cts
CHANGED
|
@@ -585,7 +585,6 @@ export declare function getLocationChangeInfo(location: ParsedLocation, resolved
|
|
|
585
585
|
hrefChanged: boolean;
|
|
586
586
|
hashChanged: boolean;
|
|
587
587
|
};
|
|
588
|
-
export declare const locationHistoryActions: WeakMap<ParsedLocation<{}>, HistoryAction>;
|
|
589
588
|
export type CreateRouterFn = <TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption = 'never', TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>>(options: undefined extends number ? 'strictNullChecks must be enabled in tsconfig.json' : RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>) => RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>;
|
|
590
589
|
declare global {
|
|
591
590
|
var __TSR_CACHE__: {
|
|
@@ -607,6 +606,7 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
|
|
|
607
606
|
tempLocationKey: string | undefined;
|
|
608
607
|
_scroll: {
|
|
609
608
|
next: boolean;
|
|
609
|
+
hash?: boolean;
|
|
610
610
|
restoring?: boolean;
|
|
611
611
|
restoration?: boolean;
|
|
612
612
|
reset?: boolean;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const require_router = require("./router.cjs");
|
|
2
1
|
let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
|
|
3
2
|
//#region src/scroll-restoration.ts
|
|
4
3
|
function getSafeSessionStorage() {
|
|
@@ -67,11 +66,11 @@ function getElement(selector) {
|
|
|
67
66
|
} catch {}
|
|
68
67
|
}
|
|
69
68
|
function getScrollToTopElements(scrollToTopSelectors) {
|
|
70
|
-
const elements =
|
|
69
|
+
const elements = /* @__PURE__ */ new Set();
|
|
71
70
|
for (const selector of scrollToTopSelectors) {
|
|
72
71
|
if (selector === windowScrollTarget) continue;
|
|
73
72
|
const element = getElement(selector);
|
|
74
|
-
if (element) elements.
|
|
73
|
+
if (element) elements.add(element);
|
|
75
74
|
}
|
|
76
75
|
return elements;
|
|
77
76
|
}
|
|
@@ -81,35 +80,29 @@ function setupScrollRestoration(router, force) {
|
|
|
81
80
|
if (shouldSetupScrollRestoration) scroll.restoring = true;
|
|
82
81
|
if (_tanstack_router_core_isServer.isServer ?? router.isServer) return;
|
|
83
82
|
const getKey = router.options.getScrollRestorationKey || defaultGetScrollRestorationKey;
|
|
84
|
-
const
|
|
85
|
-
const setTrackedScrollEntry = (target, scrollX, scrollY) => {
|
|
86
|
-
const entry = trackedScrollEntries.get(target) || {};
|
|
87
|
-
entry.scrollX = scrollX;
|
|
88
|
-
entry.scrollY = scrollY;
|
|
89
|
-
trackedScrollEntries.set(target, entry);
|
|
90
|
-
};
|
|
91
|
-
const onScroll = (event) => {
|
|
92
|
-
if (ignoreScroll || !scroll.restoring) return;
|
|
93
|
-
if (event.target === document) setTrackedScrollEntry(windowScrollTarget, scrollX, scrollY);
|
|
94
|
-
else {
|
|
95
|
-
const target = event.target;
|
|
96
|
-
setTrackedScrollEntry(target, target.scrollLeft, target.scrollTop);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
83
|
+
const trackedScrollTargets = /* @__PURE__ */ new Set();
|
|
99
84
|
const snapshotCurrentScrollTargets = (restoreKey) => {
|
|
100
|
-
if (!scroll.restoring) return;
|
|
101
85
|
const keyEntry = scrollRestorationCache[restoreKey] ||= {};
|
|
102
|
-
for (const
|
|
103
|
-
|
|
86
|
+
for (const target of trackedScrollTargets) if (target === document) keyEntry[windowScrollTarget] = {
|
|
87
|
+
scrollX,
|
|
88
|
+
scrollY
|
|
89
|
+
};
|
|
90
|
+
else if (target.isConnected) keyEntry[getScrollRestorationSelector(target)] = {
|
|
91
|
+
scrollX: target.scrollLeft,
|
|
92
|
+
scrollY: target.scrollTop
|
|
93
|
+
};
|
|
104
94
|
};
|
|
105
95
|
if (shouldSetupScrollRestoration && !scroll.restoration) {
|
|
106
96
|
scroll.restoration = true;
|
|
107
97
|
ignoreScroll = false;
|
|
108
98
|
history.scrollRestoration = "manual";
|
|
109
|
-
document.addEventListener("scroll",
|
|
99
|
+
document.addEventListener("scroll", (event) => {
|
|
100
|
+
if (ignoreScroll) return;
|
|
101
|
+
trackedScrollTargets.add(event.target);
|
|
102
|
+
}, true);
|
|
110
103
|
router.subscribe("onBeforeLoad", (event) => {
|
|
111
104
|
if (event.fromLocation) snapshotCurrentScrollTargets(getKey(event.fromLocation));
|
|
112
|
-
|
|
105
|
+
trackedScrollTargets.clear();
|
|
113
106
|
});
|
|
114
107
|
addEventListener("pagehide", () => {
|
|
115
108
|
snapshotCurrentScrollTargets(getKey(router.stores.resolvedLocation.get() ?? router.stores.location.get()));
|
|
@@ -122,9 +115,11 @@ function setupScrollRestoration(router, force) {
|
|
|
122
115
|
const behavior = router.options.scrollRestorationBehavior;
|
|
123
116
|
const scrollToTopSelectors = router.options.scrollToTopSelectors;
|
|
124
117
|
const shouldResetScroll = scroll.next;
|
|
118
|
+
const hashNavigation = scroll.hash;
|
|
125
119
|
let scrollToTopElements;
|
|
126
|
-
|
|
127
|
-
|
|
120
|
+
trackedScrollTargets.clear();
|
|
121
|
+
scroll.next = true;
|
|
122
|
+
scroll.hash = false;
|
|
128
123
|
if (typeof router.options.scrollRestoration === "function" && !router.options.scrollRestoration({ location: router.latestLocation })) return;
|
|
129
124
|
const cacheKey = getKey(event.toLocation);
|
|
130
125
|
const fromCacheKey = event.fromLocation && getKey(event.fromLocation);
|
|
@@ -140,7 +135,7 @@ function setupScrollRestoration(router, force) {
|
|
|
140
135
|
if (!element) continue;
|
|
141
136
|
if (shouldResetScroll && scrollToTopSelectors) {
|
|
142
137
|
scrollToTopElements ??= getScrollToTopElements(scrollToTopSelectors);
|
|
143
|
-
if (scrollToTopElements.
|
|
138
|
+
if (scrollToTopElements.has(element)) continue;
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
141
|
if (!toElementEntries) toElementEntries = scrollRestorationCache[cacheKey] = {};
|
|
@@ -154,8 +149,8 @@ function setupScrollRestoration(router, force) {
|
|
|
154
149
|
const hashScrollIntoViewOptions = event.toLocation.state.__hashScrollIntoViewOptions ?? true;
|
|
155
150
|
let windowRestored = false;
|
|
156
151
|
if (shouldResetScroll) {
|
|
157
|
-
|
|
158
|
-
const skipWindowRestore = hash && hashScrollIntoViewOptions &&
|
|
152
|
+
if (!hash && scrollToTopSelectors) scrollToTopElements ??= getScrollToTopElements(scrollToTopSelectors);
|
|
153
|
+
const skipWindowRestore = hash && hashScrollIntoViewOptions && hashNavigation;
|
|
159
154
|
const elementEntries = scroll.restoring ? scrollRestorationCache[cacheKey] : void 0;
|
|
160
155
|
if (elementEntries) for (const elementSelector in elementEntries) {
|
|
161
156
|
const { scrollX, scrollY } = elementEntries[elementSelector];
|
|
@@ -172,20 +167,18 @@ function setupScrollRestoration(router, force) {
|
|
|
172
167
|
if (element) {
|
|
173
168
|
element.scrollLeft = scrollX;
|
|
174
169
|
element.scrollTop = scrollY;
|
|
170
|
+
scrollToTopElements?.delete(element);
|
|
175
171
|
}
|
|
176
172
|
}
|
|
177
173
|
}
|
|
178
|
-
if (!
|
|
174
|
+
if (!hash) {
|
|
179
175
|
const scrollOptions = {
|
|
180
176
|
top: 0,
|
|
181
177
|
left: 0,
|
|
182
178
|
behavior
|
|
183
179
|
};
|
|
184
|
-
scrollTo(scrollOptions);
|
|
185
|
-
if (
|
|
186
|
-
scrollToTopElements ??= getScrollToTopElements(scrollToTopSelectors);
|
|
187
|
-
for (const element of scrollToTopElements) element.scrollTo(scrollOptions);
|
|
188
|
-
}
|
|
180
|
+
if (!windowRestored) scrollTo(scrollOptions);
|
|
181
|
+
if (scrollToTopElements) for (const element of scrollToTopElements) element.scrollTo(scrollOptions);
|
|
189
182
|
}
|
|
190
183
|
}
|
|
191
184
|
if (!windowRestored && hash && hashScrollIntoViewOptions) document.getElementById(hash)?.scrollIntoView(hashScrollIntoViewOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-restoration.cjs","names":[],"sources":["../../src/scroll-restoration.ts"],"sourcesContent":["import { isServer } from '@tanstack/router-core/isServer'\nimport { locationHistoryActions } from './router'\nimport type { AnyRouter } from './router'\nimport type { ParsedLocation } from './location'\n\nexport type ScrollRestorationEntry = { scrollX: number; scrollY: number }\n\ntype ScrollRestorationByElement = Record<string, ScrollRestorationEntry>\n\ntype ScrollRestorationByKey = Record<string, ScrollRestorationByElement>\n\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n scrollBehavior?: ScrollToOptions['behavior']\n}\n\nfunction getSafeSessionStorage() {\n try {\n // Accessing sessionStorage itself can throw SecurityError in locked-down\n // contexts, e.g. sandboxed/opaque origins or blocked storage policies.\n return sessionStorage\n } catch {\n return\n }\n}\n\n// SessionStorage key used to store scroll positions across navigations.\nexport const storageKey = 'tsr-scroll-restoration-v1_3'\nconst safeSessionStorage = getSafeSessionStorage()\n\nfunction createScrollRestorationCache() {\n try {\n return JSON.parse(\n safeSessionStorage?.getItem(storageKey) || '{}',\n ) as ScrollRestorationByKey\n } catch {\n // ignore invalid session storage payloads\n return {}\n }\n}\n\nfunction persistScrollRestorationCache() {\n try {\n safeSessionStorage?.setItem(\n storageKey,\n JSON.stringify(scrollRestorationCache),\n )\n } catch {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[ts-router] Could not persist scroll restoration state to sessionStorage.',\n )\n }\n }\n}\n\nconst scrollRestorationCache = /* @__PURE__ */ createScrollRestorationCache()\nconst scrollRestorationIdAttribute = 'data-scroll-restoration-id'\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 */\nexport const defaultGetScrollRestorationKey = (location: ParsedLocation) => {\n return location.state.__TSR_key! || location.href\n}\n\nfunction getScrollRestorationSelector(element: Element): string {\n const attrId = element.getAttribute(scrollRestorationIdAttribute)\n if (attrId) {\n return `[${scrollRestorationIdAttribute}=\"${attrId}\"]`\n }\n\n let selector = ''\n let el: any = element\n let parent: HTMLElement\n\n while ((parent = el.parentNode)) {\n let index = 1\n let sibling = el\n while ((sibling = sibling.previousElementSibling)) {\n index++\n }\n\n const part = `${el.localName}:nth-child(${index})`\n selector = selector ? `${part} > ${selector}` : part\n el = parent\n }\n\n return selector\n}\n\nexport function getElementScrollRestorationEntry(\n router: AnyRouter,\n options: (\n | {\n id: string\n getElement?: () => Window | Element | undefined | null\n }\n | {\n id?: string\n getElement: () => Window | Element | undefined | null\n }\n ) & {\n getKey?: (location: ParsedLocation) => string\n },\n): ScrollRestorationEntry | undefined {\n const getKey = options.getKey || defaultGetScrollRestorationKey\n const restoreKey = getKey(router.latestLocation)\n const entries = scrollRestorationCache[restoreKey]\n\n if (!entries) {\n return\n }\n\n if (options.id) {\n return entries[`[${scrollRestorationIdAttribute}=\"${options.id}\"]`]\n }\n\n const element = options.getElement?.()\n if (!element) {\n return\n }\n\n return entries[\n element === window\n ? windowScrollTarget\n : getScrollRestorationSelector(element as Element)\n ]\n}\n\nlet ignoreScroll = false\nconst windowScrollTarget = 'window'\ntype ScrollTarget = typeof windowScrollTarget | Element\n\nfunction getElement(selector: string | (() => Element | null | undefined)) {\n try {\n return typeof selector === 'function'\n ? selector()\n : document.querySelector(selector)\n } catch {}\n return\n}\n\nfunction getScrollToTopElements(\n scrollToTopSelectors: NonNullable<\n AnyRouter['options']['scrollToTopSelectors']\n >,\n): Array<Element> {\n const elements: Array<Element> = []\n\n for (const selector of scrollToTopSelectors) {\n if (selector === windowScrollTarget) {\n continue\n }\n\n const element = getElement(selector)\n if (element) {\n elements.push(element)\n }\n }\n\n return elements\n}\n\nexport function setupScrollRestoration(router: AnyRouter, force?: boolean) {\n // Keep hash/top scrolling active even when sessionStorage is unavailable.\n const shouldSetupScrollRestoration = force ?? router.options.scrollRestoration\n const scroll = router._scroll\n\n if (shouldSetupScrollRestoration) {\n scroll.restoring = true\n }\n\n if (isServer ?? router.isServer) {\n return\n }\n\n const getKey =\n router.options.getScrollRestorationKey || defaultGetScrollRestorationKey\n const trackedScrollEntries = new Map<ScrollTarget, ScrollRestorationEntry>()\n const setTrackedScrollEntry = (\n target: ScrollTarget,\n scrollX: number,\n scrollY: number,\n ) => {\n const entry =\n trackedScrollEntries.get(target) || ({} as ScrollRestorationEntry)\n entry.scrollX = scrollX\n entry.scrollY = scrollY\n trackedScrollEntries.set(target, entry)\n }\n\n const onScroll = (event: Event) => {\n if (ignoreScroll || !scroll.restoring) {\n return\n }\n\n if (event.target === document) {\n setTrackedScrollEntry(windowScrollTarget, scrollX, scrollY)\n } else {\n const target = event.target as Element\n setTrackedScrollEntry(target, target.scrollLeft, target.scrollTop)\n }\n }\n\n // Snapshot the current page's tracked scroll targets before navigation or unload.\n const snapshotCurrentScrollTargets = (restoreKey: string) => {\n if (!scroll.restoring) {\n return\n }\n\n const keyEntry = (scrollRestorationCache[restoreKey] ||=\n {} as ScrollRestorationByElement)\n\n for (const [target, position] of trackedScrollEntries) {\n if (target === windowScrollTarget) {\n keyEntry[windowScrollTarget] = position\n } else if (target.isConnected) {\n keyEntry[getScrollRestorationSelector(target)] = position\n }\n }\n }\n\n if (shouldSetupScrollRestoration && !scroll.restoration) {\n scroll.restoration = true\n ignoreScroll = false\n\n history.scrollRestoration = 'manual'\n\n document.addEventListener('scroll', onScroll, true)\n router.subscribe('onBeforeLoad', (event) => {\n if (event.fromLocation) {\n snapshotCurrentScrollTargets(getKey(event.fromLocation))\n }\n trackedScrollEntries.clear()\n })\n addEventListener('pagehide', () => {\n snapshotCurrentScrollTargets(\n getKey(\n router.stores.resolvedLocation.get() ?? router.stores.location.get(),\n ),\n )\n persistScrollRestorationCache()\n })\n }\n\n if (scroll.reset) {\n return\n }\n\n scroll.reset = true\n\n // Restore destination scroll after the new route has rendered.\n router.subscribe('onRendered', (event) => {\n const behavior = router.options.scrollRestorationBehavior\n const scrollToTopSelectors = router.options.scrollToTopSelectors\n const shouldResetScroll = scroll.next\n let scrollToTopElements: Array<Element> | undefined\n trackedScrollEntries.clear()\n\n if (!shouldResetScroll) {\n scroll.next = true\n }\n\n if (\n typeof router.options.scrollRestoration === 'function' &&\n !router.options.scrollRestoration({ location: router.latestLocation })\n ) {\n return\n }\n\n const cacheKey = getKey(event.toLocation)\n const fromCacheKey = event.fromLocation && getKey(event.fromLocation)\n\n if (scroll.restoring && fromCacheKey && fromCacheKey !== cacheKey) {\n const fromElementEntries = scrollRestorationCache[fromCacheKey]\n\n if (fromElementEntries) {\n let toElementEntries = scrollRestorationCache[cacheKey]\n\n for (const elementSelector in fromElementEntries) {\n if (elementSelector === windowScrollTarget) {\n if (shouldResetScroll) {\n continue\n }\n } else {\n const element = getElement(elementSelector)\n if (!element) {\n continue\n }\n\n if (shouldResetScroll && scrollToTopSelectors) {\n scrollToTopElements ??=\n getScrollToTopElements(scrollToTopSelectors)\n if (scrollToTopElements.includes(element)) {\n continue\n }\n }\n }\n\n if (!toElementEntries) {\n toElementEntries = scrollRestorationCache[cacheKey] =\n {} as ScrollRestorationByElement\n }\n\n toElementEntries[elementSelector] ??=\n fromElementEntries[elementSelector]!\n }\n }\n }\n\n ignoreScroll = true\n\n try {\n const hash = event.toLocation.hash\n const hashScrollIntoViewOptions =\n event.toLocation.state.__hashScrollIntoViewOptions ?? true\n let windowRestored = false\n\n if (shouldResetScroll) {\n const action = locationHistoryActions.get(event.toLocation)\n const skipWindowRestore =\n hash &&\n hashScrollIntoViewOptions &&\n (action === 'PUSH' || action === 'REPLACE')\n\n const elementEntries = scroll.restoring\n ? scrollRestorationCache[cacheKey]\n : undefined\n\n if (elementEntries) {\n for (const elementSelector in elementEntries) {\n const { scrollX, scrollY } = elementEntries[elementSelector]!\n\n if (elementSelector === windowScrollTarget) {\n if (skipWindowRestore) {\n continue\n }\n\n scrollTo({\n top: scrollY,\n left: scrollX,\n behavior,\n })\n windowRestored = true\n } else {\n const element = getElement(elementSelector)\n if (element) {\n element.scrollLeft = scrollX\n element.scrollTop = scrollY\n }\n }\n }\n }\n\n if (!windowRestored && !hash) {\n const scrollOptions = {\n top: 0,\n left: 0,\n behavior,\n }\n\n scrollTo(scrollOptions)\n if (scrollToTopSelectors) {\n scrollToTopElements ??= getScrollToTopElements(scrollToTopSelectors)\n for (const element of scrollToTopElements) {\n element.scrollTo(scrollOptions)\n }\n }\n }\n }\n\n if (!windowRestored && hash && hashScrollIntoViewOptions) {\n document.getElementById(hash)?.scrollIntoView(hashScrollIntoViewOptions)\n }\n } finally {\n ignoreScroll = false\n }\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scroll-restoration.cjs","names":[],"sources":["../../src/scroll-restoration.ts"],"sourcesContent":["import { isServer } from '@tanstack/router-core/isServer'\nimport type { AnyRouter } from './router'\nimport type { ParsedLocation } from './location'\n\nexport type ScrollRestorationEntry = { scrollX: number; scrollY: number }\n\ntype ScrollRestorationByElement = Record<string, ScrollRestorationEntry>\n\ntype ScrollRestorationByKey = Record<string, ScrollRestorationByElement>\n\nexport type ScrollRestorationOptions = {\n getKey?: (location: ParsedLocation) => string\n scrollBehavior?: ScrollToOptions['behavior']\n}\n\nfunction getSafeSessionStorage() {\n try {\n // Accessing sessionStorage itself can throw SecurityError in locked-down\n // contexts, e.g. sandboxed/opaque origins or blocked storage policies.\n return sessionStorage\n } catch {\n return\n }\n}\n\n// SessionStorage key used to store scroll positions across navigations.\nexport const storageKey = 'tsr-scroll-restoration-v1_3'\nconst safeSessionStorage = getSafeSessionStorage()\n\nfunction createScrollRestorationCache() {\n try {\n return JSON.parse(\n safeSessionStorage?.getItem(storageKey) || '{}',\n ) as ScrollRestorationByKey\n } catch {\n // ignore invalid session storage payloads\n return {}\n }\n}\n\nfunction persistScrollRestorationCache() {\n try {\n safeSessionStorage?.setItem(\n storageKey,\n JSON.stringify(scrollRestorationCache),\n )\n } catch {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[ts-router] Could not persist scroll restoration state to sessionStorage.',\n )\n }\n }\n}\n\nconst scrollRestorationCache = /* @__PURE__ */ createScrollRestorationCache()\nconst scrollRestorationIdAttribute = 'data-scroll-restoration-id'\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 */\nexport const defaultGetScrollRestorationKey = (location: ParsedLocation) => {\n return location.state.__TSR_key! || location.href\n}\n\nfunction getScrollRestorationSelector(element: Element): string {\n const attrId = element.getAttribute(scrollRestorationIdAttribute)\n if (attrId) {\n return `[${scrollRestorationIdAttribute}=\"${attrId}\"]`\n }\n\n let selector = ''\n let el: any = element\n let parent: HTMLElement\n\n while ((parent = el.parentNode)) {\n let index = 1\n let sibling = el\n while ((sibling = sibling.previousElementSibling)) {\n index++\n }\n\n const part = `${el.localName}:nth-child(${index})`\n selector = selector ? `${part} > ${selector}` : part\n el = parent\n }\n\n return selector\n}\n\nexport function getElementScrollRestorationEntry(\n router: AnyRouter,\n options: (\n | {\n id: string\n getElement?: () => Window | Element | undefined | null\n }\n | {\n id?: string\n getElement: () => Window | Element | undefined | null\n }\n ) & {\n getKey?: (location: ParsedLocation) => string\n },\n): ScrollRestorationEntry | undefined {\n const getKey = options.getKey || defaultGetScrollRestorationKey\n const restoreKey = getKey(router.latestLocation)\n const entries = scrollRestorationCache[restoreKey]\n\n if (!entries) {\n return\n }\n\n if (options.id) {\n return entries[`[${scrollRestorationIdAttribute}=\"${options.id}\"]`]\n }\n\n const element = options.getElement?.()\n if (!element) {\n return\n }\n\n return entries[\n element === window\n ? windowScrollTarget\n : getScrollRestorationSelector(element as Element)\n ]\n}\n\nlet ignoreScroll = false\nconst windowScrollTarget = 'window'\n\nfunction getElement(selector: string | (() => Element | null | undefined)) {\n try {\n return typeof selector === 'function'\n ? selector()\n : document.querySelector(selector)\n } catch {}\n return\n}\n\nfunction getScrollToTopElements(\n scrollToTopSelectors: NonNullable<\n AnyRouter['options']['scrollToTopSelectors']\n >,\n) {\n const elements = new Set<Element>()\n\n for (const selector of scrollToTopSelectors) {\n if (selector === windowScrollTarget) {\n continue\n }\n\n const element = getElement(selector)\n if (element) {\n elements.add(element)\n }\n }\n\n return elements\n}\n\nexport function setupScrollRestoration(router: AnyRouter, force?: boolean) {\n // Keep hash/top scrolling active even when sessionStorage is unavailable.\n const shouldSetupScrollRestoration = force ?? router.options.scrollRestoration\n const scroll = router._scroll\n\n if (shouldSetupScrollRestoration) {\n scroll.restoring = true\n }\n\n if (isServer ?? router.isServer) {\n return\n }\n\n const getKey =\n router.options.getScrollRestorationKey || defaultGetScrollRestorationKey\n const trackedScrollTargets = new Set<Document | Element>()\n\n // Snapshot the current page's tracked scroll targets before navigation or unload.\n const snapshotCurrentScrollTargets = (restoreKey: string) => {\n const keyEntry = (scrollRestorationCache[restoreKey] ||=\n {} as ScrollRestorationByElement)\n\n for (const target of trackedScrollTargets) {\n if (target === document) {\n keyEntry[windowScrollTarget] = { scrollX, scrollY }\n } else if ((target as Element).isConnected) {\n keyEntry[getScrollRestorationSelector(target as Element)] = {\n scrollX: (target as Element).scrollLeft,\n scrollY: (target as Element).scrollTop,\n }\n }\n }\n }\n\n if (shouldSetupScrollRestoration && !scroll.restoration) {\n scroll.restoration = true\n ignoreScroll = false\n\n history.scrollRestoration = 'manual'\n\n document.addEventListener(\n 'scroll',\n (event) => {\n if (ignoreScroll) {\n return\n }\n trackedScrollTargets.add(event.target as Document | Element)\n },\n true,\n )\n router.subscribe('onBeforeLoad', (event) => {\n if (event.fromLocation) {\n snapshotCurrentScrollTargets(getKey(event.fromLocation))\n }\n trackedScrollTargets.clear()\n })\n addEventListener('pagehide', () => {\n snapshotCurrentScrollTargets(\n getKey(\n router.stores.resolvedLocation.get() ?? router.stores.location.get(),\n ),\n )\n persistScrollRestorationCache()\n })\n }\n\n if (scroll.reset) {\n return\n }\n\n scroll.reset = true\n\n // Restore destination scroll after the new route has rendered.\n router.subscribe('onRendered', (event) => {\n const behavior = router.options.scrollRestorationBehavior\n const scrollToTopSelectors = router.options.scrollToTopSelectors\n const shouldResetScroll = scroll.next\n const hashNavigation = scroll.hash\n let scrollToTopElements: Set<Element> | undefined\n trackedScrollTargets.clear()\n scroll.next = true\n scroll.hash = false\n\n if (\n typeof router.options.scrollRestoration === 'function' &&\n !router.options.scrollRestoration({ location: router.latestLocation })\n ) {\n return\n }\n\n const cacheKey = getKey(event.toLocation)\n const fromCacheKey = event.fromLocation && getKey(event.fromLocation)\n\n if (scroll.restoring && fromCacheKey && fromCacheKey !== cacheKey) {\n const fromElementEntries = scrollRestorationCache[fromCacheKey]\n\n if (fromElementEntries) {\n let toElementEntries = scrollRestorationCache[cacheKey]\n\n for (const elementSelector in fromElementEntries) {\n if (elementSelector === windowScrollTarget) {\n if (shouldResetScroll) {\n continue\n }\n } else {\n const element = getElement(elementSelector)\n if (!element) {\n continue\n }\n\n if (shouldResetScroll && scrollToTopSelectors) {\n scrollToTopElements ??=\n getScrollToTopElements(scrollToTopSelectors)\n if (scrollToTopElements.has(element)) {\n continue\n }\n }\n }\n\n if (!toElementEntries) {\n toElementEntries = scrollRestorationCache[cacheKey] =\n {} as ScrollRestorationByElement\n }\n\n toElementEntries[elementSelector] ??=\n fromElementEntries[elementSelector]!\n }\n }\n }\n\n ignoreScroll = true\n\n try {\n const hash = event.toLocation.hash\n const hashScrollIntoViewOptions =\n event.toLocation.state.__hashScrollIntoViewOptions ?? true\n let windowRestored = false\n\n if (shouldResetScroll) {\n if (!hash && scrollToTopSelectors) {\n scrollToTopElements ??= getScrollToTopElements(scrollToTopSelectors)\n }\n\n const skipWindowRestore =\n hash && hashScrollIntoViewOptions && hashNavigation\n\n const elementEntries = scroll.restoring\n ? scrollRestorationCache[cacheKey]\n : undefined\n\n if (elementEntries) {\n for (const elementSelector in elementEntries) {\n const { scrollX, scrollY } = elementEntries[elementSelector]!\n\n if (elementSelector === windowScrollTarget) {\n if (skipWindowRestore) {\n continue\n }\n\n scrollTo({\n top: scrollY,\n left: scrollX,\n behavior,\n })\n windowRestored = true\n } else {\n const element = getElement(elementSelector)\n if (element) {\n element.scrollLeft = scrollX\n element.scrollTop = scrollY\n scrollToTopElements?.delete(element)\n }\n }\n }\n }\n\n if (!hash) {\n const scrollOptions = {\n top: 0,\n left: 0,\n behavior,\n }\n\n if (!windowRestored) {\n scrollTo(scrollOptions)\n }\n if (scrollToTopElements) {\n for (const element of scrollToTopElements) {\n element.scrollTo(scrollOptions)\n }\n }\n }\n }\n\n if (!windowRestored && hash && hashScrollIntoViewOptions) {\n document.getElementById(hash)?.scrollIntoView(hashScrollIntoViewOptions)\n }\n } finally {\n ignoreScroll = false\n }\n })\n}\n"],"mappings":";;AAeA,SAAS,wBAAwB;CAC/B,IAAI;EAGF,OAAO;CACT,QAAQ;EACN;CACF;AACF;AAGA,MAAa,aAAa;AAC1B,MAAM,qBAAqB,sBAAsB;AAEjD,SAAS,+BAA+B;CACtC,IAAI;EACF,OAAO,KAAK,MACV,oBAAoB,QAAA,6BAAkB,KAAK,IAC7C;CACF,QAAQ;EAEN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,gCAAgC;CACvC,IAAI;EACF,oBAAoB,QAClB,YACA,KAAK,UAAU,sBAAsB,CACvC;CACF,QAAQ;EACN,IAAA,QAAA,IAAA,aAA6B,cAC3B,QAAQ,KACN,2EACF;CAEJ;AACF;AAEA,MAAM,yBAAyC,6CAA6B;AAC5E,MAAM,+BAA+B;;;;;;;AAQrC,MAAa,kCAAkC,aAA6B;CAC1E,OAAO,SAAS,MAAM,aAAc,SAAS;AAC/C;AAEA,SAAS,6BAA6B,SAA0B;CAC9D,MAAM,SAAS,QAAQ,aAAa,4BAA4B;CAChE,IAAI,QACF,OAAO,IAAI,6BAA6B,IAAI,OAAO;CAGrD,IAAI,WAAW;CACf,IAAI,KAAU;CACd,IAAI;CAEJ,OAAQ,SAAS,GAAG,YAAa;EAC/B,IAAI,QAAQ;EACZ,IAAI,UAAU;EACd,OAAQ,UAAU,QAAQ,wBACxB;EAGF,MAAM,OAAO,GAAG,GAAG,UAAU,aAAa,MAAM;EAChD,WAAW,WAAW,GAAG,KAAK,KAAK,aAAa;EAChD,KAAK;CACP;CAEA,OAAO;AACT;AAEA,SAAgB,iCACd,QACA,SAYoC;CAGpC,MAAM,UAAU,wBAFD,QAAQ,UAAU,gCACP,OAAO,cACM;CAEvC,IAAI,CAAC,SACH;CAGF,IAAI,QAAQ,IACV,OAAO,QAAQ,IAAI,6BAA6B,IAAI,QAAQ,GAAG;CAGjE,MAAM,UAAU,QAAQ,aAAa;CACrC,IAAI,CAAC,SACH;CAGF,OAAO,QACL,YAAY,SACR,qBACA,6BAA6B,OAAkB;AAEvD;AAEA,IAAI,eAAe;AACnB,MAAM,qBAAqB;AAE3B,SAAS,WAAW,UAAuD;CACzE,IAAI;EACF,OAAO,OAAO,aAAa,aACvB,SAAS,IACT,SAAS,cAAc,QAAQ;CACrC,QAAQ,CAAC;AAEX;AAEA,SAAS,uBACP,sBAGA;CACA,MAAM,2BAAW,IAAI,IAAa;CAElC,KAAK,MAAM,YAAY,sBAAsB;EAC3C,IAAI,aAAa,oBACf;EAGF,MAAM,UAAU,WAAW,QAAQ;EACnC,IAAI,SACF,SAAS,IAAI,OAAO;CAExB;CAEA,OAAO;AACT;AAEA,SAAgB,uBAAuB,QAAmB,OAAiB;CAEzE,MAAM,+BAA+B,SAAS,OAAO,QAAQ;CAC7D,MAAM,SAAS,OAAO;CAEtB,IAAI,8BACF,OAAO,YAAY;CAGrB,IAAI,+BAAA,YAAY,OAAO,UACrB;CAGF,MAAM,SACJ,OAAO,QAAQ,2BAA2B;CAC5C,MAAM,uCAAuB,IAAI,IAAwB;CAGzD,MAAM,gCAAgC,eAAuB;EAC3D,MAAM,WAAY,uBAAuB,gBACvC,CAAC;EAEH,KAAK,MAAM,UAAU,sBACnB,IAAI,WAAW,UACb,SAAS,sBAAsB;GAAE;GAAS;EAAQ;OAC7C,IAAK,OAAmB,aAC7B,SAAS,6BAA6B,MAAiB,KAAK;GAC1D,SAAU,OAAmB;GAC7B,SAAU,OAAmB;EAC/B;CAGN;CAEA,IAAI,gCAAgC,CAAC,OAAO,aAAa;EACvD,OAAO,cAAc;EACrB,eAAe;EAEf,QAAQ,oBAAoB;EAE5B,SAAS,iBACP,WACC,UAAU;GACT,IAAI,cACF;GAEF,qBAAqB,IAAI,MAAM,MAA4B;EAC7D,GACA,IACF;EACA,OAAO,UAAU,iBAAiB,UAAU;GAC1C,IAAI,MAAM,cACR,6BAA6B,OAAO,MAAM,YAAY,CAAC;GAEzD,qBAAqB,MAAM;EAC7B,CAAC;EACD,iBAAiB,kBAAkB;GACjC,6BACE,OACE,OAAO,OAAO,iBAAiB,IAAI,KAAK,OAAO,OAAO,SAAS,IAAI,CACrE,CACF;GACA,8BAA8B;EAChC,CAAC;CACH;CAEA,IAAI,OAAO,OACT;CAGF,OAAO,QAAQ;CAGf,OAAO,UAAU,eAAe,UAAU;EACxC,MAAM,WAAW,OAAO,QAAQ;EAChC,MAAM,uBAAuB,OAAO,QAAQ;EAC5C,MAAM,oBAAoB,OAAO;EACjC,MAAM,iBAAiB,OAAO;EAC9B,IAAI;EACJ,qBAAqB,MAAM;EAC3B,OAAO,OAAO;EACd,OAAO,OAAO;EAEd,IACE,OAAO,OAAO,QAAQ,sBAAsB,cAC5C,CAAC,OAAO,QAAQ,kBAAkB,EAAE,UAAU,OAAO,eAAe,CAAC,GAErE;EAGF,MAAM,WAAW,OAAO,MAAM,UAAU;EACxC,MAAM,eAAe,MAAM,gBAAgB,OAAO,MAAM,YAAY;EAEpE,IAAI,OAAO,aAAa,gBAAgB,iBAAiB,UAAU;GACjE,MAAM,qBAAqB,uBAAuB;GAElD,IAAI,oBAAoB;IACtB,IAAI,mBAAmB,uBAAuB;IAE9C,KAAK,MAAM,mBAAmB,oBAAoB;KAChD,IAAI,oBAAoB;UAClB,mBACF;KAAA,OAEG;MACL,MAAM,UAAU,WAAW,eAAe;MAC1C,IAAI,CAAC,SACH;MAGF,IAAI,qBAAqB,sBAAsB;OAC7C,wBACE,uBAAuB,oBAAoB;OAC7C,IAAI,oBAAoB,IAAI,OAAO,GACjC;MAEJ;KACF;KAEA,IAAI,CAAC,kBACH,mBAAmB,uBAAuB,YACxC,CAAC;KAGL,iBAAiB,qBACf,mBAAmB;IACvB;GACF;EACF;EAEA,eAAe;EAEf,IAAI;GACF,MAAM,OAAO,MAAM,WAAW;GAC9B,MAAM,4BACJ,MAAM,WAAW,MAAM,+BAA+B;GACxD,IAAI,iBAAiB;GAErB,IAAI,mBAAmB;IACrB,IAAI,CAAC,QAAQ,sBACX,wBAAwB,uBAAuB,oBAAoB;IAGrE,MAAM,oBACJ,QAAQ,6BAA6B;IAEvC,MAAM,iBAAiB,OAAO,YAC1B,uBAAuB,YACvB,KAAA;IAEJ,IAAI,gBACF,KAAK,MAAM,mBAAmB,gBAAgB;KAC5C,MAAM,EAAE,SAAS,YAAY,eAAe;KAE5C,IAAI,oBAAoB,oBAAoB;MAC1C,IAAI,mBACF;MAGF,SAAS;OACP,KAAK;OACL,MAAM;OACN;MACF,CAAC;MACD,iBAAiB;KACnB,OAAO;MACL,MAAM,UAAU,WAAW,eAAe;MAC1C,IAAI,SAAS;OACX,QAAQ,aAAa;OACrB,QAAQ,YAAY;OACpB,qBAAqB,OAAO,OAAO;MACrC;KACF;IACF;IAGF,IAAI,CAAC,MAAM;KACT,MAAM,gBAAgB;MACpB,KAAK;MACL,MAAM;MACN;KACF;KAEA,IAAI,CAAC,gBACH,SAAS,aAAa;KAExB,IAAI,qBACF,KAAK,MAAM,WAAW,qBACpB,QAAQ,SAAS,aAAa;IAGpC;GACF;GAEA,IAAI,CAAC,kBAAkB,QAAQ,2BAC7B,SAAS,eAAe,IAAI,GAAG,eAAe,yBAAyB;EAE3E,UAAU;GACR,eAAe;EACjB;CACF,CAAC;AACH"}
|
package/dist/esm/router.d.ts
CHANGED
|
@@ -585,7 +585,6 @@ export declare function getLocationChangeInfo(location: ParsedLocation, resolved
|
|
|
585
585
|
hrefChanged: boolean;
|
|
586
586
|
hashChanged: boolean;
|
|
587
587
|
};
|
|
588
|
-
export declare const locationHistoryActions: WeakMap<ParsedLocation<{}>, HistoryAction>;
|
|
589
588
|
export type CreateRouterFn = <TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption = 'never', TDefaultStructuralSharingOption extends boolean = false, TRouterHistory extends RouterHistory = RouterHistory, TDehydrated extends Record<string, any> = Record<string, any>>(options: undefined extends number ? 'strictNullChecks must be enabled in tsconfig.json' : RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>) => RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>;
|
|
590
589
|
declare global {
|
|
591
590
|
var __TSR_CACHE__: {
|
|
@@ -607,6 +606,7 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
|
|
|
607
606
|
tempLocationKey: string | undefined;
|
|
608
607
|
_scroll: {
|
|
609
608
|
next: boolean;
|
|
609
|
+
hash?: boolean;
|
|
610
610
|
restoring?: boolean;
|
|
611
611
|
restoration?: boolean;
|
|
612
612
|
reset?: boolean;
|
package/dist/esm/router.js
CHANGED
|
@@ -49,7 +49,6 @@ function getLocationChangeInfo(location, resolvedLocation) {
|
|
|
49
49
|
hashChanged: fromLocation?.hash !== toLocation.hash
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
const locationHistoryActions = /* @__PURE__ */ new WeakMap();
|
|
53
52
|
/**
|
|
54
53
|
* Core, framework-agnostic router engine that powers TanStack Router.
|
|
55
54
|
*
|
|
@@ -541,8 +540,7 @@ var RouterCore = class {
|
|
|
541
540
|
this.startTransition(async () => {
|
|
542
541
|
try {
|
|
543
542
|
this.beforeLoad();
|
|
544
|
-
if (historyAction)
|
|
545
|
-
else locationHistoryActions.delete(this.latestLocation);
|
|
543
|
+
if (historyAction) this._scroll.hash = historyAction === "PUSH" || historyAction === "REPLACE";
|
|
546
544
|
const next = this.latestLocation;
|
|
547
545
|
const locationChangeInfo = getLocationChangeInfo(next, this.stores.resolvedLocation.get());
|
|
548
546
|
if (!this.stores.redirect.get()) this.emit({
|
|
@@ -1186,6 +1184,6 @@ function extractStrictParams(route, accumulatedParams) {
|
|
|
1186
1184
|
}
|
|
1187
1185
|
}
|
|
1188
1186
|
//#endregion
|
|
1189
|
-
export { PathParamError, RouterCore, SearchParamError, defaultSerializeError, getInitialRouterState, getLocationChangeInfo, getMatchedRoutes, lazyFn,
|
|
1187
|
+
export { PathParamError, RouterCore, SearchParamError, defaultSerializeError, getInitialRouterState, getLocationChangeInfo, getMatchedRoutes, lazyFn, trailingSlashOptions };
|
|
1190
1188
|
|
|
1191
1189
|
//# sourceMappingURL=router.js.map
|