mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-05-18 22:44:14 +02:00
Compare commits
3 Commits
685c06ce2e
...
ee8c1dc968
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ee8c1dc968 | ||
![]() |
bb24cd13c7 | ||
![]() |
d61fb266c7 |
@ -1,33 +1,40 @@
|
|||||||
import { computePosition, flip, inline, shift } from "@floating-ui/dom"
|
import { computePosition, flip, inline, shift } from "@floating-ui/dom"
|
||||||
import { normalizeRelativeURLs } from "../../util/path"
|
import { normalizeRelativeURLs } from "../../util/path"
|
||||||
import { fetchCanonical } from "./util"
|
import { fetchCanonical } from "./util"
|
||||||
|
import { randomIdNonSecure } from "../../util/random"
|
||||||
|
|
||||||
const p = new DOMParser()
|
const p = new DOMParser()
|
||||||
|
|
||||||
async function mouseEnterHandler(
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setPosition(popoverElement: HTMLElement) {
|
async function setPosition(popoverElement: HTMLElement) {
|
||||||
const { x, y } = await computePosition(link, popoverElement, {
|
const { x, y } = await computePosition(link, popoverElement, {
|
||||||
|
strategy: "fixed",
|
||||||
middleware: [inline({ x: clientX, y: clientY }), shift(), flip()],
|
middleware: [inline({ x: clientX, y: clientY }), shift(), flip()],
|
||||||
})
|
})
|
||||||
Object.assign(popoverElement.style, {
|
Object.assign(popoverElement.style, {
|
||||||
left: `${x}px`,
|
transform: `translate(${x}px, ${y}px)`,
|
||||||
top: `${y}px`,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasAlreadyBeenFetched = () =>
|
const prevPopoverElement = document.getElementById(`popover-${id}`)
|
||||||
[...link.children].some((child) => child.classList.contains("popover"))
|
const hasAlreadyBeenFetched = () => !!document.getElementById(`popover-${id}`)
|
||||||
|
|
||||||
// dont refetch if there's already a popover
|
// dont refetch if there's already a popover
|
||||||
if (hasAlreadyBeenFetched()) {
|
if (hasAlreadyBeenFetched()) {
|
||||||
return setPosition(link.lastChild as HTMLElement)
|
setPosition(prevPopoverElement as HTMLElement)
|
||||||
|
prevPopoverElement?.classList.add("active-popover")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const thisUrl = new URL(document.location.href)
|
const thisUrl = new URL(document.location.href)
|
||||||
@ -82,8 +89,11 @@ async function mouseEnterHandler(
|
|||||||
const contents = await response.text()
|
const contents = await response.text()
|
||||||
const html = p.parseFromString(contents, "text/html")
|
const html = p.parseFromString(contents, "text/html")
|
||||||
normalizeRelativeURLs(html, targetUrl)
|
normalizeRelativeURLs(html, targetUrl)
|
||||||
// strip all IDs from elements to prevent duplicates
|
// prepend all IDs inside popovers to prevent duplicates
|
||||||
html.querySelectorAll("[id]").forEach((el) => el.removeAttribute("id"))
|
html.querySelectorAll("[id]").forEach((el) => {
|
||||||
|
const targetID = `popover-internal-${el.id}`
|
||||||
|
el.id = targetID
|
||||||
|
})
|
||||||
const elts = [...html.getElementsByClassName("popover-hint")]
|
const elts = [...html.getElementsByClassName("popover-hint")]
|
||||||
if (elts.length === 0) return
|
if (elts.length === 0) return
|
||||||
|
|
||||||
@ -91,10 +101,13 @@ async function mouseEnterHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPosition(popoverElement)
|
setPosition(popoverElement)
|
||||||
link.appendChild(popoverElement)
|
popoverElement.id = `popover-${id}`
|
||||||
|
popoverElement.classList.add("active-popover")
|
||||||
|
document.body.appendChild(popoverElement)
|
||||||
|
|
||||||
if (hash !== "") {
|
if (hash !== "") {
|
||||||
const heading = popoverInner.querySelector(hash) as HTMLElement | null
|
const targetAnchor = `#popover-internal-${hash.slice(1)}`
|
||||||
|
const heading = popoverInner.querySelector(targetAnchor) as HTMLElement | null
|
||||||
if (heading) {
|
if (heading) {
|
||||||
// leave ~12px of buffer when scrolling to a heading
|
// leave ~12px of buffer when scrolling to a heading
|
||||||
popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
|
popoverInner.scroll({ top: heading.offsetTop - 12, behavior: "instant" })
|
||||||
@ -102,10 +115,23 @@ async function mouseEnterHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearActivePopover() {
|
||||||
|
const allPopoverElements = document.querySelectorAll(".popover")
|
||||||
|
if (allPopoverElements) {
|
||||||
|
allPopoverElements.forEach((popoverElement) =>
|
||||||
|
popoverElement.classList.remove("active-popover"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("nav", () => {
|
document.addEventListener("nav", () => {
|
||||||
const links = [...document.getElementsByClassName("internal")] as HTMLAnchorElement[]
|
const links = [...document.getElementsByClassName("internal")] as HTMLAnchorElement[]
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
|
link.addEventListener("mouseleave", clearActivePopover)
|
||||||
link.addEventListener("mouseenter", mouseEnterHandler)
|
link.addEventListener("mouseenter", mouseEnterHandler)
|
||||||
window.addCleanup(() => link.removeEventListener("mouseenter", mouseEnterHandler))
|
window.addCleanup(() => {
|
||||||
|
link.removeEventListener("mouseenter", mouseEnterHandler)
|
||||||
|
link.removeEventListener("mouseleave", clearActivePopover)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > ul {
|
& > ul.overflow {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
|
max-height: calc(100% - 2rem);
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
|
||||||
& > li {
|
& > li {
|
||||||
& > a {
|
& > a {
|
||||||
|
@ -118,6 +118,7 @@ button.desktop-explorer {
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
|
||||||
& li > a {
|
& li > a {
|
||||||
color: var(--dark);
|
color: var(--dark);
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
.popover {
|
.popover {
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
& > .popover-inner {
|
& > .popover-inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -35,6 +38,7 @@
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 6px 6px 36px 0 rgba(0, 0, 0, 0.25);
|
box-shadow: 6px 6px 36px 0 rgba(0, 0, 0, 0.25);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -77,7 +81,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover .popover,
|
.active-popover,
|
||||||
.popover:hover {
|
.popover:hover {
|
||||||
animation: dropin 0.3s ease;
|
animation: dropin 0.3s ease;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
|
@ -3,18 +3,11 @@
|
|||||||
.toc {
|
.toc {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
min-height: 1.2rem;
|
min-height: 1.4rem;
|
||||||
flex: 0 1 auto;
|
flex: 0 0.5 auto;
|
||||||
&:has(button.toc-header.collapsed) {
|
&:has(button.toc-header.collapsed) {
|
||||||
flex: 0 1 1.2rem;
|
flex: 0 1 1.4rem;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and not ($mobile) {
|
|
||||||
.toc-header {
|
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,13 +38,15 @@ button.toc-header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.toc-content {
|
ul.toc-content.overflow {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
max-height: calc(100% - 2rem);
|
||||||
|
overscroll-behavior: contain;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
& > li > a {
|
& > li > a {
|
||||||
color: var(--dark);
|
color: var(--dark);
|
||||||
opacity: 0.35;
|
opacity: 0.35;
|
||||||
|
@ -191,8 +191,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
|
|||||||
const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture
|
const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture
|
||||||
|
|
||||||
const [fp, anchor] = splitAnchor(`${rawFp ?? ""}${rawHeader ?? ""}`)
|
const [fp, anchor] = splitAnchor(`${rawFp ?? ""}${rawHeader ?? ""}`)
|
||||||
const blockRef = Boolean(rawHeader?.match(/^#?\^/)) ? "^" : ""
|
const displayAnchor = anchor ? `#${anchor.trim().replace(/^#+/, "")}` : ""
|
||||||
const displayAnchor = anchor ? `#${blockRef}${anchor.trim().replace(/^#+/, "")}` : ""
|
|
||||||
const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? ""
|
const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? ""
|
||||||
const embedDisplay = value.startsWith("!") ? "!" : ""
|
const embedDisplay = value.startsWith("!") ? "!" : ""
|
||||||
|
|
||||||
|
@ -238,6 +238,7 @@ a {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
& > * {
|
& > * {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
max-height: 24rem;
|
||||||
}
|
}
|
||||||
& > .toc {
|
& > .toc {
|
||||||
display: none;
|
display: none;
|
||||||
@ -577,7 +578,7 @@ ol.overflow {
|
|||||||
clear: both;
|
clear: both;
|
||||||
|
|
||||||
& > li.overflow-end {
|
& > li.overflow-end {
|
||||||
height: 1rem;
|
height: 0.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user