Add link previews on hover

This commit is contained in:
Maxime Vaillancourt 2020-07-21 21:05:19 -04:00
parent d8b794908f
commit b6849b30aa
11 changed files with 181 additions and 16 deletions

View File

@ -1 +1 @@
This is the footer. Include anything you'd like here, like a link to an <a href="/about">About</a> page. This is the footer. Include anything you'd like here, like a link to an <a class="internal-link" href="/about">About</a> page.

View File

@ -0,0 +1,119 @@
<!-- That file is not particularly elegant. This will need a refactor at some point. -->
<style>
content a.internal-link {
border-color: #8b88e6;
}
#tooltip-wrapper {
background: white;
padding: 1em;
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
position: absolute;
width: 400px;
height: 250px;
font-size: 0.8em;
box-shadow: 0 5px 10px rgba(0,0,0,0.1);
opacity: 0;
transition: opacity 100ms;
}
#tooltip-wrapper:after {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
pointer-events: none;
background-image: linear-gradient(to bottom, rgba(255,255,255, 0), rgba(255,255,255, 1) 90%);
width: 100%;
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')
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.host === window.location.host) {
iframe.src = event.target.href
iframe.onload = function() {
tooltipContentHtml = ''
tooltipContentHtml += '<div style="font-weight: bold;">' + iframe.contentWindow.document.querySelector('h1').innerHTML + '</div>'
tooltipContentHtml += iframe.contentWindow.document.querySelector('content').innerHTML
tooltipContent.innerHTML = tooltipContentHtml
tooltipWrapper.style.display = 'block';
setTimeout(function() {
tooltipWrapper.style.opacity = 1;
}, 1)
}
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);
});
}
document.querySelectorAll('{{ include.wrapperQuerySelector }} a').forEach(setupListeners);
</script>

View File

@ -1,3 +1,3 @@
<div> <div>
<a href="/"><b>{{ site.title }}</b></a> <a class="internal-link" href="/"><b>{{ site.title }}</b></a>
</div> </div>

View File

@ -7,5 +7,7 @@
<main>{{ content }}</main> <main>{{ content }}</main>
<footer>{% include footer.html %}</footer> <footer>{% include footer.html %}</footer>
</div> </div>
{% include link-previews.html wrapperQuerySelector="content" %}
</body> </body>
</html> </html>

View File

@ -22,7 +22,7 @@ layout: default
<div style="display: grid; grid-gap: 1em; grid-template-columns: repeat(1fr);"> <div style="display: grid; grid-gap: 1em; grid-template-columns: repeat(1fr);">
{% for backlink in page.backlinks %} {% for backlink in page.backlinks %}
<div class="backlink-box"> <div class="backlink-box">
<a href="{{ backlink.url }}">{{ backlink.title }}</a><br> <a class="internal-link" href="{{ backlink.url }}">{{ backlink.title }}</a><br>
<div style="font-size: 0.9em">{{ backlink.excerpt | strip_html | truncatewords: 20 }}</div> <div style="font-size: 0.9em">{{ backlink.excerpt | strip_html | truncatewords: 20 }}</div>
</div> </div>
{% endfor %} {% endfor %}
@ -37,5 +37,5 @@ layout: default
{% endif %} {% endif %}
</side> </side>
</div> </div>
</article> </article>

7
_layouts/page.html Normal file
View File

@ -0,0 +1,7 @@
---
layout: default
---
<content>
{{ content }}
</content>

View File

@ -4,4 +4,4 @@ title: Consistency is key
Show up. Do the work. Be consistent. Show up. Do the work. Be consistent.
Then go take a look at the [first note](/your-first-note). Then go take a look at the [first note](/your-first-note){: .internal-link}.

View File

@ -3,14 +3,36 @@ title: Your first seed
image: /assets/image.jpg image: /assets/image.jpg
--- ---
This is your first note. ### Welcome!
To link to another note, use regular Markdown syntax for links, with a relative link to the other note, like this: [this is a link to a note about cats](/cats). This is your first note. You'll find it in the `notes/` directory.
You can also use Roam-style link syntax by wrapping a note's title in double brackets, like this: [[A note about cats]]. If the Roam-style link does not point to a valid note's title, the double brackets will still be shown, like this: [[This note does not exist]]. ### Link syntax
To link to another note, you can use regular [Markdown syntax](https://www.markdownguide.org/getting-started/) for links, with a relative link to the other note, like this: [this is a link to a note about cats](/cats){: .internal-link}. Don't forget to use the `.internal-link` class to make sure the link is styled as an internal link.
Since the Web is all about HTML, you can always use plain HTML if you want, like this: <a class="internal-link" href="/cats">This is the same note about cats as above</a>.
Of course, you can also link to external websites, like this: [this is a link to Wikipedia](https://wikipedia.org/). Again, you can use plain HTML if you prefer.
Additionally, you can use Roam/wiki-style link syntax by wrapping a note's title in double brackets, like this: [[A note about cats]]. If the Roam-style link does not point to a valid note's title, the double brackets will still be shown, like this: [[There is no note with this title]].
### Automatic bi-directional links
Notice in the "Notes mentioning this note" section that there is another note linking to this note. This is a bi-directional link, and those are automatically created when you create links to other notes. Notice in the "Notes mentioning this note" section that there is another note linking to this note. This is a bi-directional link, and those are automatically created when you create links to other notes.
You can display images using Markdown's image tag, like this: ### Link previews
If you're on a device with mouse support, try hovering your mouse on internal links to preview the notes: [[A note about cats]]
### Images
Finally, you can display images using Markdown syntax, like this:
![]({{page.image}}) ![]({{page.image}})
### Next steps
If this template is useful to you in any way, consider [donating](https://github.com/sponsors/maximevaillancourt) to support my work.
Go forth, have fun, and learn new something every day! ✌️

View File

@ -1,9 +1,9 @@
--- ---
layout: default layout: page
title: About title: About
permalink: /about permalink: /about
--- ---
*This is an about page.* *This is an about page.*
Feel free to tell the world about what you love! 😍 Feel free to tell the world about what you love! 😍

View File

@ -1,11 +1,10 @@
--- ---
layout: default layout: page
title: Home title: Home
id: home id: home
permalink: / permalink: /
--- ---
<div> # Welcome! 🌱
<h1>Welcome! 🌱</h1>
<p>This is your digital garden. Here's [[Your first seed]] to get started on your exploration.</p> This is your digital garden. Here's [[Your first seed]] to get started on your exploration.
</div>

View File

@ -83,6 +83,16 @@ a {
color: black !important; color: black !important;
background: #fffaf1; background: #fffaf1;
} }
&:after {
position: relative;
top: -0.5em;
font-size: 0.7em;
content: "";
color: #aaaaaa;
}
&.internal-link:after {
content: "";
}
} }
*:focus { *:focus {
@ -116,3 +126,9 @@ ul {
padding: 1em; padding: 1em;
border-radius: $border-radius; border-radius: $border-radius;
} }
code {
background: #f5f5f5;
padding: 0.1em 0.2em;
border-radius: 4px;
}