|
|
@ -4,6 +4,7 @@ import { PageData } from '../../../types/shared'
|
|
|
|
|
|
|
|
|
|
|
|
export interface Route {
|
|
|
|
export interface Route {
|
|
|
|
path: string
|
|
|
|
path: string
|
|
|
|
|
|
|
|
hash: string
|
|
|
|
data: PageData
|
|
|
|
data: PageData
|
|
|
|
component: Component | null
|
|
|
|
component: Component | null
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -21,6 +22,7 @@ const fakeHost = `http://a.com`
|
|
|
|
|
|
|
|
|
|
|
|
const getDefaultRoute = (): Route => ({
|
|
|
|
const getDefaultRoute = (): Route => ({
|
|
|
|
path: '/',
|
|
|
|
path: '/',
|
|
|
|
|
|
|
|
hash: '',
|
|
|
|
component: null,
|
|
|
|
component: null,
|
|
|
|
// this will be set upon initial page load, which is before
|
|
|
|
// this will be set upon initial page load, which is before
|
|
|
|
// the app is mounted, so it's guaranteed to be available in
|
|
|
|
// the app is mounted, so it's guaranteed to be available in
|
|
|
@ -60,6 +62,7 @@ export function createRouter(
|
|
|
|
async function loadPage(href: string, scrollPosition = 0) {
|
|
|
|
async function loadPage(href: string, scrollPosition = 0) {
|
|
|
|
const targetLoc = new URL(href, fakeHost)
|
|
|
|
const targetLoc = new URL(href, fakeHost)
|
|
|
|
const pendingPath = (latestPendingPath = targetLoc.pathname)
|
|
|
|
const pendingPath = (latestPendingPath = targetLoc.pathname)
|
|
|
|
|
|
|
|
const pendingHash = decodeURIComponent(targetLoc.hash)
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
let page = loadPageModule(pendingPath)
|
|
|
|
let page = loadPageModule(pendingPath)
|
|
|
|
// only await if it returns a Promise - this allows sync resolution
|
|
|
|
// only await if it returns a Promise - this allows sync resolution
|
|
|
@ -76,17 +79,16 @@ export function createRouter(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
route.path = pendingPath
|
|
|
|
route.path = pendingPath
|
|
|
|
|
|
|
|
route.hash = pendingHash
|
|
|
|
route.component = markRaw(comp)
|
|
|
|
route.component = markRaw(comp)
|
|
|
|
route.data = readonly(JSON.parse(__pageData)) as PageData
|
|
|
|
route.data = readonly(JSON.parse(__pageData)) as PageData
|
|
|
|
|
|
|
|
|
|
|
|
if (inBrowser) {
|
|
|
|
if (inBrowser) {
|
|
|
|
nextTick(() => {
|
|
|
|
nextTick(() => {
|
|
|
|
if (targetLoc.hash && !scrollPosition) {
|
|
|
|
if (pendingHash && !scrollPosition) {
|
|
|
|
const target = document.querySelector(
|
|
|
|
const target = document.querySelector(pendingHash) as HTMLElement
|
|
|
|
decodeURIComponent(targetLoc.hash)
|
|
|
|
|
|
|
|
) as HTMLElement
|
|
|
|
|
|
|
|
if (target) {
|
|
|
|
if (target) {
|
|
|
|
scrollTo(target, targetLoc.hash)
|
|
|
|
scrollTo(target, pendingHash)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -101,6 +103,7 @@ export function createRouter(
|
|
|
|
if (latestPendingPath === pendingPath) {
|
|
|
|
if (latestPendingPath === pendingPath) {
|
|
|
|
latestPendingPath = null
|
|
|
|
latestPendingPath = null
|
|
|
|
route.path = pendingPath
|
|
|
|
route.path = pendingPath
|
|
|
|
|
|
|
|
route.hash = pendingHash
|
|
|
|
route.component = fallbackComponent ? markRaw(fallbackComponent) : null
|
|
|
|
route.component = fallbackComponent ? markRaw(fallbackComponent) : null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -171,12 +174,12 @@ export function useRoute(): Route {
|
|
|
|
return useRouter().route
|
|
|
|
return useRouter().route
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function scrollTo(el: HTMLElement, hash: string, smooth = false) {
|
|
|
|
function scrollTo(el: HTMLElement, selector: string, smooth = false) {
|
|
|
|
const pageOffset = (document.querySelector('.nav-bar') as HTMLElement)
|
|
|
|
const pageOffset = (document.querySelector('.nav-bar') as HTMLElement)
|
|
|
|
.offsetHeight
|
|
|
|
.offsetHeight
|
|
|
|
const target = el.classList.contains('.header-anchor')
|
|
|
|
const target = el.classList.contains('.header-anchor')
|
|
|
|
? el
|
|
|
|
? el
|
|
|
|
: document.querySelector(decodeURIComponent(hash))
|
|
|
|
: document.querySelector(selector)
|
|
|
|
if (target) {
|
|
|
|
if (target) {
|
|
|
|
const targetTop = (target as HTMLElement).offsetTop - pageOffset - 15
|
|
|
|
const targetTop = (target as HTMLElement).offsetTop - pageOffset - 15
|
|
|
|
// only smooth scroll if distance is smaller than screen height.
|
|
|
|
// only smooth scroll if distance is smaller than screen height.
|
|
|
|