feat: migrate to ES6 modules + Hugo's JS build system

The latest Hugo version, v0.78, enables support for JS ES6 module build support within Hugo/Go modules.

Initial refactor to ES6 modules with imports/exports. Further refactoring todo.

Refactor to use Hugo's new approach to JS param injection.

Refactor theming code from JQuery to vanilla JS.

Add fix for browser deprecation of the MediaQueryList listener.

Requires Hugo 0.78+

See #1929
See #1930
See #1402
This commit is contained in:
George Cushen committed 2020-11-15 16:12:52 +00:00
1 parent 9ee65a120f
commit 786b0341ee
8 files changed
+772 -783

No files matched your search

-47
View File
@@ -1,47 +0,0 @@
(function () {
function getThemeMode() {
return parseInt(localStorage.getItem('dark_mode') || 2);
}
function canChangeTheme() {
// If var is set, then user is allowed to change the theme variation.
return Boolean(window.wcDarkLightEnabled);
}
function initThemeVariation() {
if (!canChangeTheme()) {
return;
}
let currentThemeMode = getThemeMode();
let isDarkTheme;
switch (currentThemeMode) {
case 0:
isDarkTheme = false;
break;
case 1:
isDarkTheme = true;
break;
default:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the dark variation is allowed by admin.
isDarkTheme = false;
} else {
// Use the site's default theme variation based on `light` in the theme file.
isDarkTheme = isSiteThemeDark;
}
break;
}
if (isDarkTheme) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}
// Initialize theme variation.
initThemeVariation();
})();
+24
View File
@@ -0,0 +1,24 @@
/*************************************************
* Wowchemy
* https://github.com/wowchemy/wowchemy-hugo-modules
*
* Wowchemy Animation
**************************************************/
function fadeIn(element, duration = 600) {
element.style.display = '';
element.style.opacity = '0';
let last = +new Date();
let tick = function() {
element.style.opacity = (+element.style.opacity + (new Date() - last) / duration).toString();
last = +new Date();
if (+element.style.opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
}
export {
fadeIn,
};
+18
View File
@@ -0,0 +1,18 @@
/*************************************************
* Wowchemy
* https://github.com/wowchemy/wowchemy-hugo-modules
*
* Wowchemy Initialization
**************************************************/
import {initThemeVariation} from './wowchemy-theming';
import {wcDarkLightEnabled, wcIsSiteThemeDark} from '@params';
window.wc = {
darkLightEnabled: wcDarkLightEnabled,
isSiteThemeDark: wcIsSiteThemeDark,
}
// Initialize theme variation.
initThemeVariation();
+191
View File
@@ -0,0 +1,191 @@
/*************************************************
* Wowchemy
* https://github.com/wowchemy/wowchemy-hugo-modules
*
* Wowchemy Theming System
* Supported Modes: {0: Day, 1: Night, 2: Auto}
**************************************************/
import {fadeIn} from './wowchemy-animation';
function getThemeMode() {
return parseInt(localStorage.getItem('dark_mode') || 2);
}
function canChangeTheme() {
// If var is set, then user is allowed to change the theme variation.
return Boolean(window.wc.darkLightEnabled);
}
function initThemeVariation() {
if (!canChangeTheme()) {
return;
}
let currentThemeMode = getThemeMode();
let isDarkTheme;
switch (currentThemeMode) {
case 0:
isDarkTheme = false;
break;
case 1:
isDarkTheme = true;
break;
default:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the dark variation is allowed by admin.
isDarkTheme = false;
} else {
// Use the site's default theme variation based on `light` in the theme file.
isDarkTheme = window.wc.isSiteThemeDark;
}
break;
}
if (isDarkTheme) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}
function changeThemeModeClick(newMode) {
if (!canChangeTheme()) {
console.info('Cannot set theme - admin disabled theme selector.');
return;
}
let isDarkTheme;
switch (newMode) {
case 0:
localStorage.setItem('dark_mode', '1');
isDarkTheme = true;
console.info('User changed theme variation to Dark.');
showActiveTheme(0);
break;
case 1:
localStorage.setItem('dark_mode', '2');
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
// The visitor prefers dark themes and switching to the dark variation is allowed by admin.
isDarkTheme = true;
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
// The visitor prefers light themes and switching to the dark variation is allowed by admin.
isDarkTheme = false;
} else {
isDarkTheme = window.wc.isSiteThemeDark; // Use the site's default theme variation based on `light` in the theme file.
}
console.info('User changed theme variation to Auto.');
showActiveTheme(1);
break;
default:
localStorage.setItem('dark_mode', '0');
isDarkTheme = false;
console.info('User changed theme variation to Light.');
showActiveTheme(2);
break;
}
renderThemeVariation(isDarkTheme);
}
function showActiveTheme(mode) {
let linkLight = document.querySelector('.js-set-theme-light');
let linkDark = document.querySelector('.js-set-theme-dark');
let linkAuto = document.querySelector('.js-set-theme-auto');
switch (mode) {
case 0:
// Dark.
linkLight.classList.remove('dropdown-item-active');
linkDark.classList.add('dropdown-item-active');
linkAuto.classList.remove('dropdown-item-active');
break;
case 1:
// Auto.
linkLight.classList.remove('dropdown-item-active');
linkDark.classList.remove('dropdown-item-active');
linkAuto.classList.add('dropdown-item-active');
break;
default:
// Light.
linkLight.classList.add('dropdown-item-active');
linkDark.classList.remove('dropdown-item-active');
linkAuto.classList.remove('dropdown-item-active');
break;
}
}
/**
* Render theme variation (day or night).
*
* @param {boolean} isDarkTheme
* @param {boolean} init
* @returns {undefined}
*/
function renderThemeVariation(isDarkTheme, init = false) {
// Is code highlighting enabled in site config?
const codeHlLight = document.querySelector('link[title=hl-light]');
const codeHlDark = document.querySelector('link[title=hl-dark]');
const codeHlEnabled = codeHlLight || codeHlDark;
const diagramEnabled = document.querySelector('script[title=mermaid]');
const body = document.body;
// Check if re-render required.
if (!init) {
// If request to render light when light variation already rendered, return.
// If request to render dark when dark variation already rendered, return.
if ((isDarkTheme === false && !body.classList.contains('dark')) || (isDarkTheme === true && body.classList.contains('dark'))) {
return;
}
}
if (isDarkTheme === false) {
if (!init) {
// Only fade in the page when changing the theme variation.
//$('body').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 500);
Object.assign(document.body.style, {opacity: 0, visibility: 'visible'});
fadeIn(document.body, 600);
}
body.classList.remove('dark');
if (codeHlEnabled) {
codeHlLight.disabled = false;
codeHlDark.disabled = true;
}
if (diagramEnabled) {
if (init) {
/** @namespace window.mermaid **/
window.mermaid.initialize({theme: 'default', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
} else if (isDarkTheme === true) {
if (!init) {
// Only fade in the page when changing the theme variation.
Object.assign(document.body.style, {opacity: 0, visibility: 'visible'});
fadeIn(document.body, 600);
}
body.classList.add("dark");
if (codeHlEnabled) {
codeHlLight.disabled = true;
codeHlDark.disabled = false;
}
if (diagramEnabled) {
if (init) {
/** @namespace window.mermaid **/
window.mermaid.initialize({theme: 'dark', securityLevel: 'loose'});
} else {
// Have to reload to re-initialise Mermaid with the new theme and re-parse the Mermaid code blocks.
location.reload();
}
}
}
}
export {
canChangeTheme,
initThemeVariation,
changeThemeModeClick,
renderThemeVariation,
};
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -8,7 +8,7 @@ outputFormats:
rel: manifest
module:
hugoVersion:
min: '0.73.0'
min: '0.78.0'
extended: true
mounts:
- source: content
+6 -12
View File
@@ -8,18 +8,12 @@
{{- $highlight_active_link := site.Params.main_menu.highlight_active_link | default true -}}
<body id="top" data-spy="scroll" {{ if $show_navbar }}data-offset="70"{{end}} data-target="{{ if or .IsHome (eq .Type "widget_page") | and $highlight_active_link }}#navbar-main{{else}}#TableOfContents{{end}}" class="page-wrapper {{ if not (.Scratch.Get "light") }}dark{{end}} {{ if not $show_navbar }}no-navbar{{end}}">
{{/* Load day/night theme. */}}
{{/* Initialise default theme. */}}
{{ if site.Params.day_night }}
<script>window.wcDarkLightEnabled = true;</script>
{{ end }}
{{ if eq (.Scratch.Get "light") true }}
<script>const isSiteThemeDark = false;</script>
{{ else }}
<script>const isSiteThemeDark = true;</script>
{{ end }}
{{ $load_theme := resources.Get "js/load-theme.js" }}
<script src="{{ $load_theme.RelPermalink }}"></script>
{{/* Initialise theme variation. */}}
{{ $wcDarkLightEnabled := site.Params.day_night | default false }}
{{ $wcIsSiteThemeDark := not (.Scratch.Get "light") | default false }}
{{ $js_params := dict "wcDarkLightEnabled" $wcDarkLightEnabled "wcIsSiteThemeDark" $wcIsSiteThemeDark }}
{{ $js_file := resources.Get "js/wowchemy-init.js" | js.Build (dict "params" $js_params) }}
<script src="{{ $js_file.RelPermalink }}"></script>
{{ partial "search" . }}
+1 -1
View File
@@ -155,7 +155,7 @@
{{ $js_comment := printf "/* Wowchemy v%s | https://wowchemy.com/ */\n" site.Data.wowchemy.version }}
{{ $js_bundle_head := $js_comment | resources.FromString "js/bundle-head.js" }}
{{ $js_linebreak := "\n" | resources.FromString "js/linebreak.js" }}{{/* Fix no line break after Bootstrap JS causing error. */}}
{{ $js_academic := resources.Get "js/wowchemy.js" }}
{{ $js_academic := resources.Get "js/wowchemy.js" | js.Build }}
{{ $js_academic_search := resources.Get "js/wowchemy-search.js" }}
{{ $js_algolia_search := resources.Get "js/algolia-search.js" }}
{{ $js_bootstrap := resources.Get "js/_vendor/bootstrap.bundle.js" }}