|
|
--- |
|
|
|
|
|
--- |
|
|
|
|
|
<div class="sidenote-container"> |
|
|
<aside class="sidenote"> |
|
|
<slot /> |
|
|
</aside> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
const initSidenotes = () => { |
|
|
const containers = document.querySelectorAll(".sidenote-container"); |
|
|
|
|
|
containers.forEach((container) => { |
|
|
|
|
|
if (container.closest(".sidenote-wrapper")) { |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
let previousElement = |
|
|
container.previousElementSibling as HTMLElement | null; |
|
|
|
|
|
|
|
|
if (!previousElement && container.parentNode) { |
|
|
const parent = container.parentNode as HTMLElement; |
|
|
|
|
|
if (parent.children.length === 1 && parent.previousElementSibling) { |
|
|
previousElement = parent.previousElementSibling as HTMLElement; |
|
|
} |
|
|
} |
|
|
|
|
|
if ( |
|
|
previousElement && |
|
|
previousElement.parentNode && |
|
|
container.parentNode |
|
|
) { |
|
|
|
|
|
const wrapper = document.createElement("div"); |
|
|
wrapper.className = "sidenote-wrapper"; |
|
|
|
|
|
const parent = container.parentNode; |
|
|
|
|
|
|
|
|
if (previousElement.parentNode === parent) { |
|
|
parent.insertBefore(wrapper, previousElement); |
|
|
wrapper.appendChild(previousElement); |
|
|
wrapper.appendChild(container); |
|
|
} else { |
|
|
|
|
|
const prevParent = previousElement.parentNode; |
|
|
prevParent.insertBefore(wrapper, previousElement); |
|
|
wrapper.appendChild(previousElement); |
|
|
parent.removeChild(container); |
|
|
wrapper.appendChild(container); |
|
|
} |
|
|
|
|
|
|
|
|
wrapper.style.position = "relative"; |
|
|
wrapper.style.display = "block"; |
|
|
|
|
|
|
|
|
const sidenoteContainer = container as HTMLElement; |
|
|
sidenoteContainer.style.position = "absolute"; |
|
|
sidenoteContainer.style.top = "0"; |
|
|
sidenoteContainer.style.right = "-292px"; |
|
|
sidenoteContainer.style.width = "260px"; |
|
|
|
|
|
|
|
|
sidenoteContainer.style.display = "block"; |
|
|
sidenoteContainer.style.opacity = "0"; |
|
|
|
|
|
|
|
|
requestAnimationFrame(() => { |
|
|
requestAnimationFrame(() => { |
|
|
sidenoteContainer.style.opacity = "1"; |
|
|
}); |
|
|
}); |
|
|
} else { |
|
|
|
|
|
const sidenoteContainer = container as HTMLElement; |
|
|
sidenoteContainer.style.display = "block"; |
|
|
sidenoteContainer.style.opacity = "1"; |
|
|
} |
|
|
}); |
|
|
}; |
|
|
|
|
|
|
|
|
const verifyStylesApplied = () => { |
|
|
const wrappers = document.querySelectorAll(".sidenote-wrapper"); |
|
|
let allApplied = true; |
|
|
|
|
|
wrappers.forEach((wrapper) => { |
|
|
const sidenote = wrapper.querySelector( |
|
|
".sidenote-container", |
|
|
) as HTMLElement; |
|
|
if (sidenote) { |
|
|
const computed = window.getComputedStyle(sidenote); |
|
|
|
|
|
if (computed.position !== "absolute" && window.innerWidth > 768) { |
|
|
allApplied = false; |
|
|
|
|
|
sidenote.style.position = "absolute"; |
|
|
sidenote.style.top = "0"; |
|
|
sidenote.style.right = "-292px"; |
|
|
sidenote.style.width = "260px"; |
|
|
sidenote.style.display = "block"; |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
return allApplied; |
|
|
}; |
|
|
|
|
|
|
|
|
const startInit = () => { |
|
|
|
|
|
initSidenotes(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
verifyStylesApplied(); |
|
|
}, 50); |
|
|
|
|
|
|
|
|
|
|
|
const containers = document.querySelectorAll(".sidenote-container"); |
|
|
|
|
|
if (containers.length === 0) { |
|
|
|
|
|
const observer = new MutationObserver((mutations, obs) => { |
|
|
const newContainers = document.querySelectorAll(".sidenote-container"); |
|
|
if (newContainers.length > 0) { |
|
|
|
|
|
initSidenotes(); |
|
|
|
|
|
setTimeout(() => { |
|
|
verifyStylesApplied(); |
|
|
}, 50); |
|
|
|
|
|
setTimeout(() => { |
|
|
obs.disconnect(); |
|
|
}, 5000); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const targetNode = document.querySelector("main") || document.body; |
|
|
if (targetNode) { |
|
|
observer.observe(targetNode, { |
|
|
childList: true, |
|
|
subtree: true, |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
observer.disconnect(); |
|
|
}, 10000); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
const waitForFullLoad = () => { |
|
|
|
|
|
const idleOrTimeout = (callback: () => void, timeout: number) => { |
|
|
if (typeof (window as any).requestIdleCallback === "function") { |
|
|
(window as any).requestIdleCallback(callback, { timeout }); |
|
|
} else { |
|
|
setTimeout(callback, timeout); |
|
|
} |
|
|
}; |
|
|
|
|
|
if (document.readyState === "loading") { |
|
|
|
|
|
document.addEventListener( |
|
|
"DOMContentLoaded", |
|
|
() => { |
|
|
idleOrTimeout(startInit, 300); |
|
|
}, |
|
|
{ once: true }, |
|
|
); |
|
|
|
|
|
|
|
|
window.addEventListener( |
|
|
"load", |
|
|
() => { |
|
|
setTimeout(() => { |
|
|
initSidenotes(); |
|
|
verifyStylesApplied(); |
|
|
}, 100); |
|
|
}, |
|
|
{ once: true }, |
|
|
); |
|
|
} else if (document.readyState === "interactive") { |
|
|
|
|
|
idleOrTimeout(startInit, 300); |
|
|
|
|
|
|
|
|
window.addEventListener( |
|
|
"load", |
|
|
() => { |
|
|
setTimeout(() => { |
|
|
initSidenotes(); |
|
|
verifyStylesApplied(); |
|
|
}, 100); |
|
|
}, |
|
|
{ once: true }, |
|
|
); |
|
|
} else { |
|
|
|
|
|
idleOrTimeout(startInit, 300); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
initSidenotes(); |
|
|
verifyStylesApplied(); |
|
|
}, 500); |
|
|
} |
|
|
}; |
|
|
|
|
|
waitForFullLoad(); |
|
|
</script> |
|
|
|
|
|
<style is:global> |
|
|
.sidenote-wrapper { |
|
|
|
|
|
position: relative; |
|
|
display: block; |
|
|
} |
|
|
|
|
|
.sidenote-container { |
|
|
|
|
|
display: none; |
|
|
margin: 0; |
|
|
|
|
|
transition: opacity 0.3s ease-in-out; |
|
|
} |
|
|
|
|
|
.sidenote { |
|
|
border-radius: 8px; |
|
|
padding: 0 30px; |
|
|
font-size: 0.9rem; |
|
|
color: var(--muted-color); |
|
|
margin: 0; |
|
|
} |
|
|
|
|
|
@media (--bp-content-collapse) { |
|
|
.sidenote-wrapper { |
|
|
|
|
|
position: static !important; |
|
|
} |
|
|
|
|
|
.sidenote-container { |
|
|
position: static !important; |
|
|
width: auto !important; |
|
|
right: auto !important; |
|
|
top: auto !important; |
|
|
margin-top: 8px; |
|
|
|
|
|
display: block !important; |
|
|
opacity: 1 !important; |
|
|
} |
|
|
|
|
|
.sidenote { |
|
|
padding: 0; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
|