From 6c8023463d0e4ea68be3216c454775fd87d3e370 Mon Sep 17 00:00:00 2001 From: David Fischer Date: Wed, 14 Feb 2024 21:41:13 +0100 Subject: [PATCH] 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 --- docs/features/popover previews.md | 2 ++ quartz/components/scripts/popover.inline.ts | 40 +++++++++++++++------ quartz/components/styles/popover.scss | 11 ++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/docs/features/popover previews.md b/docs/features/popover previews.md index f882224..0666047 100644 --- a/docs/features/popover previews.md +++ b/docs/features/popover previews.md @@ -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. +Similar to Obsidian, [[quartz layout.png|images referenced using wikilinks]] can also be viewed as popups. + ## Configuration - Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`. diff --git a/quartz/components/scripts/popover.inline.ts b/quartz/components/scripts/popover.inline.ts index 0251834..d0346b0 100644 --- a/quartz/components/scripts/popover.inline.ts +++ b/quartz/components/scripts/popover.inline.ts @@ -37,29 +37,47 @@ async function mouseEnterHandler( targetUrl.hash = "" targetUrl.search = "" - const contents = await fetch(`${targetUrl}`) - .then((res) => res.text()) - .catch((err) => { - console.error(err) - }) + const response = await fetch(`${targetUrl}`).catch((err) => { + console.error(err) + }) // bailout if another popover exists if (hasAlreadyBeenFetched()) { return } - if (!contents) return - const html = p.parseFromString(contents, "text/html") - normalizeRelativeURLs(html, targetUrl) - const elts = [...html.getElementsByClassName("popover-hint")] - if (elts.length === 0) return + if (!response) return + const contentType = response.headers.get("Content-Type") + const contentTypeCategory = contentType?.split("/")[0] ?? "text" const popoverElement = document.createElement("div") popoverElement.classList.add("popover") const popoverInner = document.createElement("div") popoverInner.classList.add("popover-inner") 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) link.appendChild(popoverElement) diff --git a/quartz/components/styles/popover.scss b/quartz/components/styles/popover.scss index e46292a..141b89d 100644 --- a/quartz/components/styles/popover.scss +++ b/quartz/components/styles/popover.scss @@ -38,6 +38,17 @@ white-space: normal; } + & > .popover-inner[data-content-type="image"] { + padding: 0; + max-height: 100%; + + img { + margin: 0; + border-radius: 0; + display: block; + } + } + h1 { font-size: 1.5rem; }