feat(route): expose decoded hash

pull/277/head
Eduardo San Martin Morote 5 years ago
parent fa1616ac4e
commit 7185fa6c92

@ -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.

Loading…
Cancel
Save