Skip to content

Commit

Permalink
rockmanvnx6's popup preview ppeetteerrs#48
Browse files Browse the repository at this point in the history
  • Loading branch information
janeilagan committed Aug 24, 2023
1 parent c519770 commit 8bf8cff
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
25 changes: 25 additions & 0 deletions zola/sass/components/_preview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.preview {
position: fixed;
max-height: 300px;
min-height: 100px;
width: 400px;
padding: 0;
overflow-y: auto;
border-bottom: none;
background-color: #ffffff;
border: 1px solid #f5f6f8;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 6px;
color: black;
padding: 15px 30px;
font-size: 15px;
overscroll-behavior: contain;
z-index: 9999999;
}

body.dark .preview {
background-color: #212529;
border: 1px solid #39383b;
box-shadow: 0 2px 8px gba(0, 0, 0, 0.3);;
color: white;
}
1 change: 1 addition & 0 deletions zola/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@import "components/doks";

// @import "components/syntax";
@import "components/preview";
@import "components/code";
@import "components/alerts";
@import "components/buttons";
Expand Down
132 changes: 132 additions & 0 deletions zola/static/js/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
const cache = new Map();

function showPreview(mouseEvent, link) {
const { clientX, clientY } = mouseEvent;
let previewDiv = createPreview();

previewDiv.innerHTML = "Loading...";

const html = cache.get(link.href);
if (!html) {
fetch(`${link.href}`)
.then((res) => res.text())
.then((html) => {
let doc = new DOMParser().parseFromString(html, "text/html");
let docContent = doc.querySelector(".docs-content");
previewDiv.innerHTML = docContent.innerHTML;

let blockId = link.href.match(/(?<=#).{6}/);

if (blockId != null) {
blockId = [blockId];
const blockContent = [
...docContent.querySelectorAll(
"p, li, h1, h2, h3, h4, h5, h6"
),
].findLast((e) => {
return e.textContent.includes(`^${blockId}`);
});

previewDiv.innerHTML = blockContent.outerHTML;
}
cache.set(link.href, previewDiv.innerHTML);
initPreview(`.${getPreviewUniqueClass(previewDiv)} a`);
});
} else {
previewDiv.innerHTML = html;
initPreview(`.${getPreviewUniqueClass(previewDiv)} a`);
}

const { top, right } = getPreviewPosition(clientX, clientY);
previewDiv.style.top = `${top}px`;
previewDiv.style.right = `${right}px`;

previewDiv.addEventListener("mouseleave", () => {
handleMouseLeave();
});

link.addEventListener(
"mouseleave",
() => {
setTimeout(() => {
if (!previewDiv.matches(":hover")) {
hidePreview(previewDiv);
}
}, 200);
},
false
);
}

function getPreviewPosition(clientX, clientY) {
const offset = 10,
previewDivWidth = 400,
previewDivHeight = 100;
const boundaryX = window.innerWidth,
boundaryY = window.innerHeight;
const overflowRight = clientX + offset + previewDivWidth > boundaryX;
const overflowLeft = clientX - offset - previewDivWidth < 0;
const overflowBottom = clientY + offset + previewDivHeight > boundaryY;
const position = { top: offset, right: offset };

if (!overflowRight) {
position.right = boundaryX - clientX - offset - previewDivWidth;
} else if (!overflowLeft) {
position.right = boundaryX - clientX - offset;
}

if (!overflowBottom) {
position.top = clientY + offset;
} else {
position.top = clientY - offset - previewDivHeight;
}

return position;
}

function handleMouseLeave() {
setTimeout(() => {
const allPreviews = document.querySelectorAll(".preview");
for (let i = allPreviews.length - 1; i >= 0; i--) {
const curr = allPreviews[i];
if (curr.matches(":hover")) {
break;
}
hidePreview(curr);
}
}, 300);
}

function getPreviewUniqueClass(previewDiv) {
return previewDiv.classList.item(previewDiv.classList.length - 1);
}

function isDocLink(href) {
const test = new URL(href);
return test.pathname.startsWith("/docs/");
}

function hidePreview(previewDiv) {
try {
document.body.removeChild(previewDiv);
} catch (e) {}
}

function createPreview() {
const previewDiv = document.createElement("div");
const uniqueClassName = (Math.random() + 1).toString(36).substring(7);
previewDiv.classList.add("preview");
previewDiv.classList.add(`preview_${uniqueClassName}`);
document.querySelector("body").appendChild(previewDiv);
return previewDiv;
}

function initPreview(query = ".docs-content a") {
document.querySelectorAll(query).forEach((a) => {
if (isDocLink(a.href)) {
a.addEventListener("mouseover", (e) => showPreview(e, a), false);
}
});
}

initPreview();
1 change: 1 addition & 0 deletions zola/templates/macros/javascript.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% macro javascript() %}
<script src="{{ get_url(path="js/settings.js") | safe }}" defer></script>
<script src="{{ get_url(path="js/main.js") | safe }}" defer></script>
<script src="{{ get_url(path="js/preview.js") | safe }}" defer></script>
{% if config.build_search_index %}
<script src="{{ get_url(path="plugins/elasticlunr.min.js") | safe }}" defer></script>
<script src="{{ get_url(path="search_index." ~ lang ~ ".js") | safe }}" defer></script>
Expand Down

0 comments on commit 8bf8cff

Please sign in to comment.