fix(popover): properly clear popover on racing fetch

This commit is contained in:
Jacky Zhao 2025-04-21 23:55:38 -07:00
parent c238dd16d9
commit 6dd772bf00

View file

@ -3,12 +3,13 @@ import { normalizeRelativeURLs } from "../../util/path"
import { fetchCanonical } from "./util" import { fetchCanonical } from "./util"
const p = new DOMParser() const p = new DOMParser()
let activeAnchor: HTMLAnchorElement | null = null
async function mouseEnterHandler( async function mouseEnterHandler(
this: HTMLAnchorElement, this: HTMLAnchorElement,
{ clientX, clientY }: { clientX: number; clientY: number }, { clientX, clientY }: { clientX: number; clientY: number },
) { ) {
const link = this const link = (activeAnchor = this)
if (link.dataset.noPopover === "true") { if (link.dataset.noPopover === "true") {
return return
} }
@ -44,10 +45,9 @@ async function mouseEnterHandler(
targetUrl.search = "" targetUrl.search = ""
const popoverId = `popover-${link.pathname}` const popoverId = `popover-${link.pathname}`
const prevPopoverElement = document.getElementById(popoverId) const prevPopoverElement = document.getElementById(popoverId)
const hasAlreadyBeenFetched = () => !!document.getElementById(popoverId)
// dont refetch if there's already a popover // dont refetch if there's already a popover
if (hasAlreadyBeenFetched()) { if (!!document.getElementById(popoverId)) {
showPopover(prevPopoverElement as HTMLElement) showPopover(prevPopoverElement as HTMLElement)
return return
} }
@ -56,11 +56,6 @@ async function mouseEnterHandler(
console.error(err) console.error(err)
}) })
// bailout if another popover exists
if (hasAlreadyBeenFetched()) {
return
}
if (!response) return if (!response) return
const [contentType] = response.headers.get("Content-Type")!.split(";") const [contentType] = response.headers.get("Content-Type")!.split(";")
const [contentTypeCategory, typeInfo] = contentType.split("/") const [contentTypeCategory, typeInfo] = contentType.split("/")
@ -107,11 +102,20 @@ async function mouseEnterHandler(
elts.forEach((elt) => popoverInner.appendChild(elt)) elts.forEach((elt) => popoverInner.appendChild(elt))
} }
if (!!document.getElementById(popoverId)) {
return
}
document.body.appendChild(popoverElement) document.body.appendChild(popoverElement)
if (activeAnchor !== this) {
return
}
showPopover(popoverElement) showPopover(popoverElement)
} }
function clearActivePopover() { function clearActivePopover() {
activeAnchor = null
const allPopoverElements = document.querySelectorAll(".popover") const allPopoverElements = document.querySelectorAll(".popover")
allPopoverElements.forEach((popoverElement) => popoverElement.classList.remove("active-popover")) allPopoverElements.forEach((popoverElement) => popoverElement.classList.remove("active-popover"))
} }