aboutsummaryrefslogtreecommitdiff
path: root/themes/hugo-pt2021/assets/script.js
blob: b879f640de02253ed62296f4d3010c40cacb2d4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
'use strict';

//
// script.js - script which handles:
//
// - check/set dark mode (added 2024-05-27)
// - enable burger menu support
//
// original notes regarding burger menu and minification are in the
// "burger menu" section below
//
// burker menu (2024-05-27)
// ------------------------
// does the following:
//
// 1. checks for user setting and use that, if present.
// 2. otherwise check browser for preferred color scheme and use that.
//
// this works in conjunction with the styles in `assets/dark.sass` and
// has one minor quirk: there is a brief flash when the user transitions
// to a new page and has dark mode enabled.  this can be removed by
// uncommenting the block at the top of `dark.sass`, but doing this
// currently breaks the light color scheme :/.
//
// refs:
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
// https://www.smashingmagazine.com/2024/03/setting-persisting-color-scheme-preferences-css-javascript/
// https://css-tricks.com/approaches-media-queries-sass/
// https://stackoverflow.com/questions/59621784/how-to-detect-prefers-color-scheme-change-in-javascript
//
// burker menu
// -----------
// src: https://bulma.io/documentation/components/navbar/
//
// Note (2022-03-05): I initially switched from Array.prototype.slice()
// to Array.from() and added "const D = document;" to shrink the
// minified, uncompressed code from 307 bytes to 292 bytes for a ~4.9%
// (15 bytes) size reduction.
//
// Then, I dropped Array.from() entirely, since all modern browsers (see
// URL below) support NodeList.forEach().
//
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach
//
// This shrunk the minified, uncompressed size to 280 bytes, for a
// ~8.8% (27 bytes) cumulative size reduction.
//
// I also tried switching from forEach to for..of, but that increased
// the minified, uncompressed size by a two bytes.
//

// aliases
const D = document,
      C = D.body.parentElement.classList,
      L = localStorage,
      M = window.matchMedia,
      on = (el, id, fn) => el.addEventListener(id, fn);

// use theme if set, otherwise fall back to browser preference
// FIXME: move to DOMContentLoaded?
if (L && L.theme && L.theme === 'dark') {
  C.add('dark'); // theme set to "dark"
} else if ((!L || !L.theme) && M && M('(prefers-color-scheme: dark)').matches) {
  C.add('dark'); // prefers dark color scheme
}

document.addEventListener('DOMContentLoaded', () => {
  // theme toggle event handler
  on(D.querySelector('.navbar-item[data-id="theme"]'), 'click', (e) => {
    e.preventDefault(); // stop event
    L.theme = C.toggle('dark') ? 'dark' : 'light'; // toggle
  });

  // iterate through burgers, bind to click events
  D.querySelectorAll('.navbar-burger').forEach(e => on(e, 'click', () => {
    // then toggle is-active on burger and menu
    [e, D.getElementById(e.dataset.target)].forEach(
      e => e.classList.toggle('is-active')
    )
  }));
});