Implement link preview

This commit is contained in:
Ole Eskild Steensen 2022-12-19 23:06:07 +01:00
parent 3e6d8b5a66
commit 766993cebc
5 changed files with 159 additions and 9 deletions

View File

@ -6,5 +6,6 @@ exports.ALL_NOTE_SETTINGS= [
"dgShowInlineTitle",
"dgShowFileTree",
"dgEnableSearch",
"dgShowToc"
"dgShowToc",
"dgLinkPreview"
];

View File

@ -0,0 +1,137 @@
<!-- All credit for this implementation goes to https://github.com/maximevaillancourt/digital-garden-jekyll-template/blob/master/_includes/link-previews.html -->
<style>
#tooltip-wrapper {
background: var(--background-primary);
padding: 1em;
border-radius: 4px;
overflow: hidden;
position: fixed;
width: 80%;
max-width: 400px;
height: auto;
max-height: 300px;
font-size: 0.8em;
box-shadow: 0 5px 10px rgba(0,0,0,0.1);
opacity: 0;
transition: opacity 100ms;
unicode-bidi: plaintext;
overflow-y: scroll;
z-index: 10;
}
#tooltip-wrapper:after {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
pointer-events: none;
width: 100%;
unicode-bidi: plaintext;
height: 75px;
}
</style>
<div style="opacity: 0; display: none;" id='tooltip-wrapper'>
<div id='tooltip-content'>
</div>
</div>
<iframe style="display: none; height: 0; width: 0;" id='link-preview-iframe' src="">
</iframe>
<script>
var opacityTimeout;
var contentTimeout;
var transitionDurationMs = 100;
var iframe = document.getElementById('link-preview-iframe')
var tooltipWrapper = document.getElementById('tooltip-wrapper')
var tooltipContent = document.getElementById('tooltip-content')
var linkHistories = {};
function hideTooltip() {
opacityTimeout = setTimeout(function () {
tooltipWrapper.style.opacity = 0;
contentTimeout = setTimeout(function () {
tooltipContent.innerHTML = '';
tooltipWrapper.style.display = 'none';
}, transitionDurationMs + 1);
}, transitionDurationMs)
}
function showTooltip(event) {
var elem = event.target;
var elem_props = elem.getClientRects()[elem.getClientRects().length - 1];
var top = window.pageYOffset || document.documentElement.scrollTop;
if (event.target.getAttribute("href").indexOf("http") === -1 || event.target.getAttribute("href").indexOf(window.location.host) !== -1) {
if (!linkHistories[event.target.getAttribute("href")]) {
iframe.src = event.target.getAttribute("href")
iframe.onload = function () {
tooltipContentHtml = ''
tooltipContentHtml += '<div style="font-weight: bold; unicode-bidi: plaintext;">' + iframe.contentWindow.document.querySelector('h1').innerHTML + '</div>'
tooltipContentHtml += iframe.contentWindow.document.querySelector('.content').innerHTML
tooltipContent.innerHTML = tooltipContentHtml
linkHistories[event.target.getAttribute("href")] = tooltipContentHtml
tooltipWrapper.style.display = 'block';
tooltipWrapper.scrollTop = 0;
setTimeout(function () {
tooltipWrapper.style.opacity = 1;
}, 1)
}
} else {
tooltipContent.innerHTML = linkHistories[event.target.getAttribute("href")]
tooltipWrapper.style.display = 'block';
setTimeout(function () {
tooltipWrapper.style.opacity = 1;
}, 1)
}
function getInnerWidth(elem) {
var style = window.getComputedStyle(elem);
return elem.offsetWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight) - parseFloat(style.borderLeft) - parseFloat(style.borderRight) - parseFloat(style.marginLeft) - parseFloat(style.marginRight);
}
tooltipWrapper.style.left = elem_props.left - (tooltipWrapper.offsetWidth / 2) + (elem_props.width / 2) + "px";
if ((window.innerHeight - elem_props.top) < (tooltipWrapper.offsetHeight)) {
tooltipWrapper.style.top = elem_props.top + top - tooltipWrapper.offsetHeight - 10 + "px";
} else if ((window.innerHeight - elem_props.top) > (tooltipWrapper.offsetHeight)) {
tooltipWrapper.style.top = elem_props.top + top + 35 + "px";
}
if ((elem_props.left + (elem_props.width / 2)) < (tooltipWrapper.offsetWidth / 2)) {
tooltipWrapper.style.left = "10px";
} else if ((document.body.clientWidth - elem_props.left - (elem_props.width / 2)) < (tooltipWrapper.offsetWidth / 2)) {
tooltipWrapper.style.left = document.body.clientWidth - tooltipWrapper.offsetWidth - 20 + "px";
}
}
}
function setupListeners(linkElement) {
linkElement.addEventListener('mouseleave', function (_event) {
hideTooltip();
});
tooltipWrapper.addEventListener('mouseleave', function (_event) {
hideTooltip();
});
linkElement.addEventListener('mouseenter', function (event) {
clearTimeout(opacityTimeout);
clearTimeout(contentTimeout);
showTooltip(event);
});
tooltipWrapper.addEventListener('mouseenter', function (event) {
clearTimeout(opacityTimeout);
clearTimeout(contentTimeout);
});
}
window.addEventListener("load", function(event)
{
document.querySelectorAll('.internal-link').forEach(setupListeners);
document.querySelectorAll('.backlink-card a').forEach(setupListeners);
});
</script>

View File

@ -26,10 +26,14 @@ permalink: "notes/{{ page.fileSlug | slugify }}/"
<h1>{{ page.fileSlug }}</h1>
{% endif %}
{{ content | link | highlight | safe}}
</div>
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%}
{%include "components/sidebar.njk"%}
{% endif %}
</div>
{% if settings.dgLinkPreview === true %}
{%include "components/linkPreview.njk"%}
{% endif %}
</body>
</html>

View File

@ -22,11 +22,14 @@
{%- for garden in collections.gardenEntry -%}
{{garden.templateContent | link | highlight | safe }}
{%- endfor -%}
</div>
{% if settings.dgShowBacklinks === true or settings.dgShowLocalGraph === true or settings.dgShowToc === true%}
{%include "components/sidebar.njk" %}
{%endif%}
</div>
{% if settings.dgLinkPreview === true %}
{%include "components/linkPreview.njk"%}
{% endif %}
</body>
</html>

View File

@ -13,6 +13,7 @@ body {
font-size: 22px;
line-height: 1.5;
margin-top: 90px;
position: relative;
@media(max-width: 800px) {
margin-top: 150px;
@ -212,6 +213,8 @@ ul.task-list {
transform: none;
border-radius: 4px;
margin-top: 50px;
max-width: 800px;
margin: auto;
}
.graph {
@ -224,6 +227,8 @@ ul.task-list {
.backlinks {
margin-top: 0;
border-top: 3px solid var(--background-secondary);
border-radius: 0;
}
}