Add support for image popovers (#854)
* feat(popover): Add support for images * fix: run prettier * feat(popover): use switch logic for content types & adjust styles * feat(popover): Add content type data tag for popover-inner class
This commit is contained in:
		@@ -8,6 +8,8 @@ By default, Quartz only fetches previews for pages inside your vault due to [COR
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover.
 | 
					When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Similar to Obsidian, [[quartz layout.png|images referenced using wikilinks]] can also be viewed as popups.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Configuration
 | 
					## Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
 | 
					- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,29 +37,47 @@ async function mouseEnterHandler(
 | 
				
			|||||||
  targetUrl.hash = ""
 | 
					  targetUrl.hash = ""
 | 
				
			||||||
  targetUrl.search = ""
 | 
					  targetUrl.search = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const contents = await fetch(`${targetUrl}`)
 | 
					  const response = await fetch(`${targetUrl}`).catch((err) => {
 | 
				
			||||||
    .then((res) => res.text())
 | 
					    console.error(err)
 | 
				
			||||||
    .catch((err) => {
 | 
					  })
 | 
				
			||||||
      console.error(err)
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // bailout if another popover exists
 | 
					  // bailout if another popover exists
 | 
				
			||||||
  if (hasAlreadyBeenFetched()) {
 | 
					  if (hasAlreadyBeenFetched()) {
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!contents) return
 | 
					  if (!response) return
 | 
				
			||||||
  const html = p.parseFromString(contents, "text/html")
 | 
					  const contentType = response.headers.get("Content-Type")
 | 
				
			||||||
  normalizeRelativeURLs(html, targetUrl)
 | 
					  const contentTypeCategory = contentType?.split("/")[0] ?? "text"
 | 
				
			||||||
  const elts = [...html.getElementsByClassName("popover-hint")]
 | 
					 | 
				
			||||||
  if (elts.length === 0) return
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const popoverElement = document.createElement("div")
 | 
					  const popoverElement = document.createElement("div")
 | 
				
			||||||
  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)
 | 
					  popoverElement.appendChild(popoverInner)
 | 
				
			||||||
  elts.forEach((elt) => popoverInner.appendChild(elt))
 | 
					
 | 
				
			||||||
 | 
					  popoverInner.dataset.contentType = contentTypeCategory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (contentTypeCategory) {
 | 
				
			||||||
 | 
					    case "image":
 | 
				
			||||||
 | 
					      const img = document.createElement("img")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      response.blob().then((blob) => {
 | 
				
			||||||
 | 
					        img.src = URL.createObjectURL(blob)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      img.alt = targetUrl.pathname
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      popoverInner.appendChild(img)
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      const contents = await response.text()
 | 
				
			||||||
 | 
					      const html = p.parseFromString(contents, "text/html")
 | 
				
			||||||
 | 
					      normalizeRelativeURLs(html, targetUrl)
 | 
				
			||||||
 | 
					      const elts = [...html.getElementsByClassName("popover-hint")]
 | 
				
			||||||
 | 
					      if (elts.length === 0) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      elts.forEach((elt) => popoverInner.appendChild(elt))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setPosition(popoverElement)
 | 
					  setPosition(popoverElement)
 | 
				
			||||||
  link.appendChild(popoverElement)
 | 
					  link.appendChild(popoverElement)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,17 @@
 | 
				
			|||||||
    white-space: normal;
 | 
					    white-space: normal;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & > .popover-inner[data-content-type="image"] {
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    max-height: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    img {
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      border-radius: 0;
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  h1 {
 | 
					  h1 {
 | 
				
			||||||
    font-size: 1.5rem;
 | 
					    font-size: 1.5rem;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user