Skip to content

Commit

Permalink
refactor: Do not use inline scripts (#173)
Browse files Browse the repository at this point in the history
* fix: Move loading JavaScript to the top of the page, don't use inline scripts for the theme switcher (fixes #145)

* fix: Do not use an inline script for HTTPS redirect

* chore: Actually remove the inline script from page head

* chore: Use scratch again (a private one) and fix lunr search

* fix: Move third-party scripts back to the bottom of the page

BREAKING CHANGE: custom.js is loaded at the top of the page now, before the page elements are available
  • Loading branch information
palant authored May 26, 2020
1 parent 3f098d0 commit f160158
Show file tree
Hide file tree
Showing 15 changed files with 292 additions and 285 deletions.
20 changes: 11 additions & 9 deletions assets/js/back-to-top.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const backToTop = document.getElementById('back-to-top');
window.addEventListener("DOMContentLoaded", event => {
const backToTop = document.getElementById('back-to-top');

if (backToTop !== null) {
window.addEventListener(
'scroll',
throttle(function() {
window.scrollY > 100 ? backToTop.classList.add('show') : backToTop.classList.remove('show');
}, delayTime)
);
}
if (backToTop !== null) {
window.addEventListener(
'scroll',
throttle(function() {
window.scrollY > 100 ? backToTop.classList.add('show') : backToTop.classList.remove('show');
}, delayTime)
);
}
}, {once: true});
16 changes: 9 additions & 7 deletions assets/js/comments.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const commentsToggle = document.getElementById('load-comments');
window.addEventListener("DOMContentLoaded", event => {
const commentsToggle = document.getElementById('load-comments');

if (commentsToggle !== null) {
commentsToggle.addEventListener('click', function () {
loadComments();
this.style = "display: none";
});
}
if (commentsToggle !== null) {
commentsToggle.addEventListener('click', function () {
loadComments();
this.style = "display: none";
});
}
}, {once: true});
112 changes: 57 additions & 55 deletions assets/js/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,73 @@
// 1. https://tomspencer.dev/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/
// 2. https://www.dannyguo.com/blog/how-to-add-copy-to-clipboard-buttons-to-code-blocks-in-hugo/

const copyText = '{{ i18n "copy" }}';
const copiedText = '{{ i18n "copied" }}';
window.addEventListener("DOMContentLoaded", event => {
const copyText = '{{ i18n "copy" }}';
const copiedText = '{{ i18n "copied" }}';

document.querySelectorAll('.post-body > pre').forEach((e) => {
e.outerHTML = `<div style="position: relative">${e.outerHTML}</div>`;
});
document.querySelectorAll('.post-body > pre').forEach((e) => {
e.outerHTML = `<div style="position: relative">${e.outerHTML}</div>`;
});

function addCopyButtons(clipboard) {
const divs = document.querySelectorAll('table.lntable, .highlight > pre, .post-body > div > pre');
function addCopyButtons(clipboard) {
const divs = document.querySelectorAll('table.lntable, .highlight > pre, .post-body > div > pre');

divs.forEach((containerEl) => {
containerEl.parentNode.style.position = 'relative';
divs.forEach((containerEl) => {
containerEl.parentNode.style.position = 'relative';

const button = document.createElement('button');
button.className = 'copy-button';
button.type = 'button';
button.innerText = copyText;
const button = document.createElement('button');
button.className = 'copy-button';
button.type = 'button';
button.innerText = copyText;

if (containerEl.classList.contains('lntable')) {
var codeBlock = containerEl.querySelectorAll('.lntd')[1];
} else {
var codeBlock = containerEl.querySelector('code');
}
if (containerEl.classList.contains('lntable')) {
var codeBlock = containerEl.querySelectorAll('.lntd')[1];
} else {
var codeBlock = containerEl.querySelector('code');
}

button.addEventListener('click', () => {
clipboard.writeText(codeBlock.innerText).then(() => {
/* Chrome doesn't seem to blur automatically,
leaving the button in a focused state. */
button.blur();
button.addEventListener('click', () => {
clipboard.writeText(codeBlock.innerText).then(() => {
/* Chrome doesn't seem to blur automatically,
leaving the button in a focused state. */
button.blur();

button.innerText = copiedText;
button.innerText = copiedText;

setTimeout(() => {
button.innerText = copyText;
}, 1000);
}).catch((error) => {
button.innerText = 'Error';
setTimeout(() => {
button.innerText = copyText;
}, 1000);
}).catch((error) => {
button.innerText = 'Error';

console.error(error);
console.error(error);
});
});
});

containerEl.appendChild(button);
containerEl.appendChild(button);

{{ if .Site.Params.enableCopyAutoHide }}
containerEl.parentNode.addEventListener('mouseover', () => {
button.style = 'visibility: visible; opacity: 1';
});
{{ if .Site.Params.enableCopyAutoHide }}
containerEl.parentNode.addEventListener('mouseover', () => {
button.style = 'visibility: visible; opacity: 1';
});

containerEl.parentNode.addEventListener('mouseout', () => {
button.style = 'visibility: hidden; opacity: 0';
});
{{ end }}
});
}

if (navigator && navigator.clipboard) {
addCopyButtons(navigator.clipboard);
} else {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/clipboard-polyfill.min.js';
script.defer = true;
script.onload = function() {
addCopyButtons(clipboard);
};

document.body.appendChild(script);
}
containerEl.parentNode.addEventListener('mouseout', () => {
button.style = 'visibility: hidden; opacity: 0';
});
{{ end }}
});
}

if (navigator && navigator.clipboard) {
addCopyButtons(navigator.clipboard);
} else {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/clipboard-polyfill.min.js';
script.defer = true;
script.onload = function() {
addCopyButtons(clipboard);
};

document.head.appendChild(script);
}
}, {once: true});
50 changes: 31 additions & 19 deletions assets/js/dark-mode.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
// Back to Previous Mode & Respect System Preferences

changeMode();

// Reactive Dark Mode
// https://web.dev/prefers-color-scheme/#reacting-on-dark-mode-changes
// https://twitter.com/ChromeDevTools/status/1197175265643745282

const userPrefers = localStorage.getItem('theme');
if (userPrefers === 'dark') {
changeModeMeta('dark');
} else if (userPrefers === 'light') {
changeModeMeta('light');
}

window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => {
changeMode();
});

// Theme Switcher
// https://derekkedziora.com/blog/dark-mode
window.addEventListener("DOMContentLoaded", event => {
// Update meta tags and code highlighting
changeMode();

const themeSwitcher = document.getElementById('theme-switcher');
// Theme Switcher
// https://derekkedziora.com/blog/dark-mode

if (themeSwitcher) {
themeSwitcher.addEventListener('click', (e) => {
e.preventDefault();
if (getCurrentTheme() == "dark") {
changeModeMeta('light');
} else {
changeModeMeta('dark');
}
changeMode();
storePrefers();
});
}
const themeSwitcher = document.getElementById('theme-switcher');

if (themeSwitcher) {
themeSwitcher.addEventListener('click', (e) => {
e.preventDefault();
if (getCurrentTheme() == "dark") {
changeModeMeta('light');
} else {
changeModeMeta('dark');
}
changeMode();
storePrefers();
});
}
}, {once: true});

// Sync Across Tabs
// https://codepen.io/tevko/pen/GgWYpg
Expand All @@ -46,6 +54,10 @@ function getCurrentTheme() {
return JSON.parse(window.getComputedStyle(document.documentElement, null).getPropertyValue("--theme-name"));
}

function changeModeMeta(theme) {
document.documentElement.setAttribute('data-theme', theme);
}

function changeMode() {
const isDark = getCurrentTheme() === 'dark';

Expand Down
6 changes: 6 additions & 0 deletions assets/js/force-https.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{ $url := urls.Parse .Site.BaseURL }}
{{ $host := $url.Host }}

if (window.location.host == "{{ $host }}" && window.location.protocol != "https:") {
window.location.protocol = "https";
}
6 changes: 3 additions & 3 deletions assets/js/header.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Measure header height for the scrolling fix
{
window.addEventListener("DOMContentLoaded", event => {
// Measure header height for the scrolling fix
const header = document.querySelector('.header');
if (header) {
const headerHeight = window.getComputedStyle(header, null).getPropertyValue('height');
document.documentElement.style.setProperty('--header-height', headerHeight);
}
}
}, {once: true});
15 changes: 7 additions & 8 deletions assets/js/lunr-search.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(function initLunr() {
window.addEventListener("DOMContentLoaded", event => {
let index = null;
let lookup = null;
let queuedTerm = null;
Expand All @@ -17,11 +17,9 @@
startSearch(term, false);
}, false);

window.addEventListener("load", function(event) {
if (history.state && history.state.type == "search") {
startSearch(history.state.term, true);
}
});
if (history.state && history.state.type == "search") {
startSearch(history.state.term, true);
}

window.addEventListener("popstate", function(event) {
if (event.state && event.state.type == "search") {
Expand Down Expand Up @@ -160,7 +158,8 @@
}

{{ if .Site.Params.enableNavToggle }}
if (navToggleLabel.classList.contains("open")) {
let navToggleLabel = document.querySelector('.nav-toggle');
if (navToggleLabel && navToggleLabel.classList.contains("open")) {
document.getElementById(navToggleLabel.getAttribute("for")).click();
}
{{ end }}
Expand Down Expand Up @@ -198,4 +197,4 @@
}
return result;
}
})();
}, {once: true});
22 changes: 12 additions & 10 deletions assets/js/multilingual.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
const langSwitcher = document.getElementById('lang-switcher');
window.addEventListener("DOMContentLoaded", event => {
const langSwitcher = document.getElementById('lang-switcher');

if (langSwitcher) {
const langs = document.getElementById('langs');
if (langSwitcher) {
const langs = document.getElementById('langs');

langSwitcher.addEventListener('mouseover', function() {
langs.style = 'display: block';
});
langSwitcher.addEventListener('mouseover', function() {
langs.style = 'display: block';
});

langSwitcher.addEventListener('mouseout', function() {
langs.style = 'display: none';
});
}
langSwitcher.addEventListener('mouseout', function() {
langs.style = 'display: none';
});
}
}, {once: true});
Loading

0 comments on commit f160158

Please sign in to comment.