fix: take `<a>` in SVG into account (#1850)

pull/1862/head
翠 / green 3 years ago committed by GitHub
parent e0e8c6643f
commit 010b3e5ad9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -73,32 +73,40 @@ export function usePrefetch() {
}) })
rIC(() => { rIC(() => {
document.querySelectorAll<HTMLAnchorElement>('#app a').forEach((link) => { document
const { target, hostname, pathname } = link .querySelectorAll<HTMLAnchorElement | SVGAElement>('#app a')
const extMatch = pathname.match(/\.\w+$/) .forEach((link) => {
if (extMatch && extMatch[0] !== '.html') { const { target } = link
return const { hostname, pathname } = new URL(
} link.href instanceof SVGAnimatedString
? link.href.animVal
: link.href,
link.baseURI
)
const extMatch = pathname.match(/\.\w+$/)
if (extMatch && extMatch[0] !== '.html') {
return
}
if ( if (
// only prefetch same tab navigation, since a new tab will load // only prefetch same tab navigation, since a new tab will load
// the lean js chunk instead. // the lean js chunk instead.
target !== `_blank` && target !== `_blank` &&
// only prefetch inbound links // only prefetch inbound links
hostname === location.hostname hostname === location.hostname
) { ) {
if (pathname !== location.pathname) { if (pathname !== location.pathname) {
observer!.observe(link) observer!.observe(link)
} else { } else {
// No need to prefetch chunk for the current page, but also mark // No need to prefetch chunk for the current page, but also mark
// it as already fetched. This is because the initial page uses its // it as already fetched. This is because the initial page uses its
// lean chunk, and if we don't mark it, navigation to another page // lean chunk, and if we don't mark it, navigation to another page
// with a link back to the first page will fetch its full chunk // with a link back to the first page will fetch its full chunk
// which isn't needed. // which isn't needed.
hasFetched.add(pathname) hasFetched.add(pathname)
}
} }
} })
})
}) })
} }

@ -153,9 +153,21 @@ export function createRouter(
const button = (e.target as Element).closest('button') const button = (e.target as Element).closest('button')
if (button) return if (button) return
const link = (e.target as Element).closest('a') const link = (e.target as Element | SVGElement).closest<
if (link && !link.closest('.vp-raw') && !link.download) { HTMLAnchorElement | SVGAElement
const { href, origin, pathname, hash, search, target } = link >('a')
if (
link &&
!link.closest('.vp-raw') &&
(link instanceof SVGElement || !link.download)
) {
const { target } = link
const { href, origin, pathname, hash, search } = new URL(
link.href instanceof SVGAnimatedString
? link.href.animVal
: link.href,
link.baseURI
)
const currentUrl = window.location const currentUrl = window.location
const extMatch = pathname.match(/\.\w+$/) const extMatch = pathname.match(/\.\w+$/)
// only intercept inbound links // only intercept inbound links
@ -217,8 +229,8 @@ export function useRoute(): Route {
return useRouter().route return useRouter().route
} }
function scrollTo(el: HTMLElement, hash: string, smooth = false) { function scrollTo(el: HTMLElement | SVGElement, hash: string, smooth = false) {
let target: HTMLElement | null = null let target: HTMLElement | SVGElement | null = null
try { try {
target = el.classList.contains('header-anchor') target = el.classList.contains('header-anchor')

Loading…
Cancel
Save