fix(popover): popover id calculation + scroll consistency
This commit is contained in:
		@@ -9,10 +9,7 @@ async function mouseEnterHandler(
 | 
				
			|||||||
  this: HTMLAnchorElement,
 | 
					  this: HTMLAnchorElement,
 | 
				
			||||||
  { clientX, clientY }: { clientX: number; clientY: number },
 | 
					  { clientX, clientY }: { clientX: number; clientY: number },
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  clearActivePopover()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const link = this
 | 
					  const link = this
 | 
				
			||||||
  const id = randomIdNonSecure()
 | 
					 | 
				
			||||||
  if (link.dataset.noPopover === "true") {
 | 
					  if (link.dataset.noPopover === "true") {
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -27,23 +24,33 @@ async function mouseEnterHandler(
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const prevPopoverElement = document.getElementById(`popover-${id}`)
 | 
					  function showPopover(popoverElement: HTMLElement) {
 | 
				
			||||||
  const hasAlreadyBeenFetched = () => !!document.getElementById(`popover-${id}`)
 | 
					    popoverElement.classList.add("active-popover")
 | 
				
			||||||
 | 
					    setPosition(popoverElement as HTMLElement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // dont refetch if there's already a popover
 | 
					    if (hash !== "") {
 | 
				
			||||||
  if (hasAlreadyBeenFetched()) {
 | 
					      const targetAnchor = `#popover-internal-${hash.slice(1)}`
 | 
				
			||||||
    setPosition(prevPopoverElement as HTMLElement)
 | 
					      const heading = popoverInner.querySelector(targetAnchor) as HTMLElement | null
 | 
				
			||||||
    prevPopoverElement?.classList.add("active-popover")
 | 
					      if (heading) {
 | 
				
			||||||
    return
 | 
					        // leave ~12px of buffer when scrolling to a heading
 | 
				
			||||||
 | 
					        popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const thisUrl = new URL(document.location.href)
 | 
					 | 
				
			||||||
  thisUrl.hash = ""
 | 
					 | 
				
			||||||
  thisUrl.search = ""
 | 
					 | 
				
			||||||
  const targetUrl = new URL(link.href)
 | 
					  const targetUrl = new URL(link.href)
 | 
				
			||||||
  const hash = decodeURIComponent(targetUrl.hash)
 | 
					  const hash = decodeURIComponent(targetUrl.hash)
 | 
				
			||||||
  targetUrl.hash = ""
 | 
					  targetUrl.hash = ""
 | 
				
			||||||
  targetUrl.search = ""
 | 
					  targetUrl.search = ""
 | 
				
			||||||
 | 
					  const popoverId = `popover-${link.dataset.slug ?? randomIdNonSecure()}`
 | 
				
			||||||
 | 
					  const prevPopoverElement = document.getElementById(popoverId)
 | 
				
			||||||
 | 
					  const hasAlreadyBeenFetched = () => !!document.getElementById(popoverId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // dont refetch if there's already a popover
 | 
				
			||||||
 | 
					  if (hasAlreadyBeenFetched()) {
 | 
				
			||||||
 | 
					    showPopover(prevPopoverElement as HTMLElement)
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const response = await fetchCanonical(targetUrl).catch((err) => {
 | 
					  const response = await fetchCanonical(targetUrl).catch((err) => {
 | 
				
			||||||
    console.error(err)
 | 
					    console.error(err)
 | 
				
			||||||
@@ -59,12 +66,12 @@ async function mouseEnterHandler(
 | 
				
			|||||||
  const [contentTypeCategory, typeInfo] = contentType.split("/")
 | 
					  const [contentTypeCategory, typeInfo] = contentType.split("/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const popoverElement = document.createElement("div")
 | 
					  const popoverElement = document.createElement("div")
 | 
				
			||||||
 | 
					  popoverElement.id = popoverId
 | 
				
			||||||
  popoverElement.classList.add("popover")
 | 
					  popoverElement.classList.add("popover")
 | 
				
			||||||
  const popoverInner = document.createElement("div")
 | 
					  const popoverInner = document.createElement("div")
 | 
				
			||||||
  popoverInner.classList.add("popover-inner")
 | 
					  popoverInner.classList.add("popover-inner")
 | 
				
			||||||
  popoverElement.appendChild(popoverInner)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  popoverInner.dataset.contentType = contentType ?? undefined
 | 
					  popoverInner.dataset.contentType = contentType ?? undefined
 | 
				
			||||||
 | 
					  popoverElement.appendChild(popoverInner)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (contentTypeCategory) {
 | 
					  switch (contentTypeCategory) {
 | 
				
			||||||
    case "image":
 | 
					    case "image":
 | 
				
			||||||
@@ -100,19 +107,8 @@ async function mouseEnterHandler(
 | 
				
			|||||||
      elts.forEach((elt) => popoverInner.appendChild(elt))
 | 
					      elts.forEach((elt) => popoverInner.appendChild(elt))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setPosition(popoverElement)
 | 
					 | 
				
			||||||
  popoverElement.id = `popover-${id}`
 | 
					 | 
				
			||||||
  popoverElement.classList.add("active-popover")
 | 
					 | 
				
			||||||
  document.body.appendChild(popoverElement)
 | 
					  document.body.appendChild(popoverElement)
 | 
				
			||||||
 | 
					  showPopover(popoverElement)
 | 
				
			||||||
  if (hash !== "") {
 | 
					 | 
				
			||||||
    const targetAnchor = `#popover-internal-${hash.slice(1)}`
 | 
					 | 
				
			||||||
    const heading = popoverInner.querySelector(targetAnchor) as HTMLElement | null
 | 
					 | 
				
			||||||
    if (heading) {
 | 
					 | 
				
			||||||
      // leave ~12px of buffer when scrolling to a heading
 | 
					 | 
				
			||||||
      popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function clearActivePopover() {
 | 
					function clearActivePopover() {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user