astro/examples/snowpack/public/js/index.js
Matthew Phillips 2082001ff8
Add snowpack as an example project. (#11)
* Initial tests set up

This adds tests using uvu (we can switch if people want) and restructures things a bit so that it's easier to test.

Like in snowpack you set up a little project. In our tests you can say:

```js
const result = await runtime.load('/blog/hello-world')
```

And analyze the result. I included a `test-helpers.js` which has a function that will turn HTML into a cheerio instance, for inspecting the result HTML.

* Bring snowpack example in

* Formatting
2021-03-19 17:17:38 -04:00

115 lines
3.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Debounce functions for better performance
* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Function} fn The function to debounce
*/
function debounce(fn) {
// Setup a timer
var timeout;
// Return a function to run debounced
return function () {
// Setup the arguments
var context = this;
var args = arguments;
// If there's a timer, cancel it
if (timeout) {
window.cancelAnimationFrame(timeout);
}
// Setup the new requestAnimationFrame()
timeout = window.requestAnimationFrame(function () {
fn.apply(context, args);
});
};
}
function isScrolledIntoView(el) {
const { top } = el.getBoundingClientRect();
const halfHeight = window.innerHeight / 2;
const isVisible = top <= halfHeight;
return isVisible;
}
function setActiveToc() {
if (window.innerWidth < 1240) {
return;
}
if (!tableOfContentsEl) {
return;
}
const headings = [
...document.querySelectorAll(
'.content-body h1, .content-body h2, .content-body h3, .content-body h4',
),
].filter((el) => !!el.id);
const scrolledToBeginning = window.scrollY === 0;
const scrolledToEnd =
Math.ceil(window.innerHeight + window.scrollY) >=
Math.ceil(document.body.getBoundingClientRect().height);
let el;
if (scrolledToBeginning) {
el = headings[0]; // if were at the top of the page, highlight the first item
} else if (scrolledToEnd) {
el = headings[headings.length - 1]; // if were at the end of the page, highlight the last item
} else {
el = headings.reverse().find(isScrolledIntoView); // otherwise highlight the one thats at least halfway up the page
}
if (!el) return;
const elId = el.id;
const href = `#${elId}`;
const tocEl = tableOfContentsEl.querySelector(`a[href="${href}"]`);
// only add the active class once, which will also prevent scroll from re-triggering while scrolling to the same element
if (!tocEl || tocEl.classList.contains('active')) {
return;
}
tableOfContentsEl.querySelectorAll(`a.active`).forEach((aEl) => {
if (aEl.getAttribute('href') !== href) aEl.classList.remove('active');
});
tocEl.classList.add('active');
// // update nav on desktop
// if (window.innerWidth >= 860) {
// tocEl.scrollIntoView({behavior: 'smooth'});
// }
// {
// top:
// tocEl.getBoundingClientRect().top + gridTocEl.scrollTop - PADDING_TOP,
// behavior: 'smooth',
// });
}
const tableOfContentsEl = document.querySelector('.toc');
window.addEventListener('scroll', debounce(setActiveToc));
/* May not be needed:
window.addEventListener('DOMContentLoaded', (event) => {
if (!window.location.hash) {
return;
}
const elNeedingScroll = document.getElementById(window.location.hash.substring(1));
if (!elNeedingScroll) {
return;
}
elNeedingScroll.scrollIntoView();
elNeedingScroll.classList.add('highlighted');
});
*/
window.addEventListener('DOMContentLoaded', (event) => {
if (!tableOfContentsEl) {
return;
}
document.querySelectorAll('.content h3, .content h4').forEach((headerEl) => {
const linkEl = document.createElement('a');
// linkEl.setAttribute('target', "_blank");
linkEl.setAttribute('href', '#' + headerEl.id);
linkEl.classList.add('header-link');
linkEl.innerText = '#';
headerEl.appendChild(linkEl);
});
setActiveToc();
});