2023-10-30 21:05:02 +00:00
|
|
|
import { isChangingPage } from '../components/utils'
|
|
|
|
import { useRouter } from '../composables/router'
|
|
|
|
import { defineNuxtPlugin } from '../nuxt'
|
2023-04-10 11:33:14 +00:00
|
|
|
|
|
|
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
|
|
if (!document.startViewTransition) { return }
|
|
|
|
|
|
|
|
let finishTransition: undefined | (() => void)
|
|
|
|
let abortTransition: undefined | (() => void)
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
2023-07-14 13:49:57 +00:00
|
|
|
router.beforeResolve((to, from) => {
|
2023-10-27 14:32:09 +00:00
|
|
|
if (!isChangingPage(to, from)) {
|
2023-07-14 13:49:57 +00:00
|
|
|
return
|
|
|
|
}
|
2023-04-10 11:33:14 +00:00
|
|
|
const promise = new Promise<void>((resolve, reject) => {
|
|
|
|
finishTransition = resolve
|
|
|
|
abortTransition = reject
|
|
|
|
})
|
|
|
|
|
|
|
|
let changeRoute: () => void
|
|
|
|
const ready = new Promise<void>(resolve => (changeRoute = resolve))
|
|
|
|
|
|
|
|
const transition = document.startViewTransition!(() => {
|
|
|
|
changeRoute()
|
|
|
|
return promise
|
|
|
|
})
|
|
|
|
|
|
|
|
transition.finished.then(() => {
|
|
|
|
abortTransition = undefined
|
|
|
|
finishTransition = undefined
|
|
|
|
})
|
|
|
|
|
|
|
|
return ready
|
|
|
|
})
|
|
|
|
|
|
|
|
nuxtApp.hook('vue:error', () => {
|
|
|
|
abortTransition?.()
|
|
|
|
abortTransition = undefined
|
|
|
|
})
|
|
|
|
|
|
|
|
nuxtApp.hook('page:finish', () => {
|
|
|
|
finishTransition?.()
|
|
|
|
finishTransition = undefined
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface Document {
|
|
|
|
startViewTransition?: (callback: () => Promise<void> | void) => {
|
|
|
|
finished: Promise<void>
|
|
|
|
updateCallbackDone: Promise<void>
|
|
|
|
ready: Promise<void>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|