ScrollToPosition,
ScrollPosition,
scrollToPosition,
+ saveScrollOnLeave,
+ getScrollKey,
+ getSavedScroll,
} from './utils/scroll'
import { createRouterMatcher } from './matcher'
import { createRouterError, ErrorTypes, NavigationError } from './errors'
// TODO: this doesn't work on first load. Moving it to RouterView could allow automatically handling transitions too maybe
// TODO: refactor with a state getter
const state = isPush || !isClient ? {} : window.history.state
- handleScroll(toLocation, from, state && state.scroll).catch(err =>
- triggerError(err, false)
- )
+ const savedScroll = getSavedScroll(getScrollKey(toLocation.fullPath, 0))
+ handleScroll(
+ toLocation,
+ from,
+ savedScroll || (state && state.scroll)
+ ).catch(err => triggerError(err, false))
// navigation is confirmed, call afterGuards
for (const guard of afterGuards.list()) guard(toLocation, from)
pendingLocation = toLocation
const from = currentRoute.value
+ saveScrollOnLeave(getScrollKey(from.fullPath, info.distance))
+
try {
await navigate(toLocation, from)
finalizeNavigation(
window.scrollTo(normalizedPosition.x, normalizedPosition.y)
}
}
+
+/**
+ * TODO: refactor the scroll behavior so it can be tree shaken
+ */
+
+export const scrollPositions = new Map<string, ScrollToPosition>()
+
+export function getScrollKey(path: string, distance: number): string {
+ const position: number = history.state
+ ? history.state.position - distance
+ : -1
+ return position + path
+}
+
+export function saveScrollOnLeave(key: string) {
+ scrollPositions.set(key, computeScrollPosition())
+}
+
+export function getSavedScroll(key: string) {
+ return scrollPositions.get(key)
+}