PageSourceSearch

https://www.thegatewaypundit.com/wp-content/plugins/gp-dark-mode/assets/js/dark-mode-toggle.js?ver=1.6.7

js thegatewaypundit.com collected 2026-09-24 08:27:35 UTC 4,915 bytes, 167 lines download raw bytes

1/**
2 * GP Dark Mode — toggle behavior (loaded in the footer).
3 *
4 * The initial theme is already applied by the inline head script, which also
5 * exposes its config on window.ogmGpdm. This script wires up the toggle button
6 * and, when configured, keeps unsaved visitors in sync with their OS theme.
7 */
8(function () {
9  var html = document.documentElement;
10  // Bind every toggle on the page (menu bar + any [gp_dark_mode_toggle]
11  // shortcodes), not just the first one by id.
12  var toggles = document.querySelectorAll('.dm-toggle');
13
14  var cfg = window.ogmGpdm || {};
15  var respectSystem = !!cfg.respectSystem;
16  var defaultTheme = cfg.defaultTheme === 'dark' ? 'dark' : 'light';
17
18  // ---------- Storage helpers (localStorage + cookie fallback) ----------
19
20  function storageAvailable() {
21    try {
22      var k = '__theme_test__';
23      localStorage.setItem(k, '1');
24      localStorage.removeItem(k);
25      return true;
26    } catch (e) {
27      return false;
28    }
29  }
30
31  var hasLocalStorage = storageAvailable();
32
33  function getCookie(name) {
34    try {
35      var m = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)'));
36      return m ? decodeURIComponent(m[1]) : null;
37    } catch (e) {
38      return null;
39    }
40  }
41
42  function setCookie(name, value, days) {
43    try {
44      var expires = '';
45      if (typeof days === 'number') {
46        var d = new Date();
47        d.setTime(d.getTime() + days * 864e5);
48        expires = '; expires=' + d.toUTCString();
49      }
50      document.cookie =
51        name + '=' + encodeURIComponent(value) +
52        expires +
53        '; path=/' +
54        '; samesite=lax';
55    } catch (e) {}
56  }
57
58  function deleteCookie(name) {
59    setCookie(name, '', -1);
60  }
61
62  // The visitor's saved override ('dark' | 'light' | null).
63  function getPref() {
64    try {
65      if (hasLocalStorage) return localStorage.getItem('theme');
66    } catch (e) {}
67    return getCookie('theme');
68  }
69
70  function setPref(valueOrNull) {
71    try {
72      if (hasLocalStorage) {
73        if (valueOrNull === null) localStorage.removeItem('theme');
74        else localStorage.setItem('theme', valueOrNull);
75        return;
76      }
77    } catch (e) {}
78
79    if (valueOrNull === null) deleteCookie('theme');
80    else setCookie('theme', valueOrNull, 365);
81  }
82
83  function hasSavedPref() {
84    var p = getPref();
85    return p === 'dark' || p === 'light';
86  }
87
88  // ---------- Theme logic ----------
89
90  function isDarkNow() {
91    return html.getAttribute('data-theme') === 'dark';
92  }
93
94  function refreshDisqusIfPresent() {
95    if (!document.getElementById('disqus_thread')) return;
96    if (window.DISQUS && typeof window.DISQUS.reset === 'function') {
97      window.DISQUS.reset({ reload: true });
98    }
99  }
100
101  function syncToggles(isDark) {
102    for (var i = 0; i < toggles.length; i++) {
103      toggles[i].setAttribute('aria-checked', isDark ? 'true' : 'false');
104    }
105  }
106
107  function apply(theme, persist) {
108    var isDark = theme === 'dark';
109
110    html.setAttribute('data-theme', isDark ? 'dark' : 'light');
111    syncToggles(isDark);
112
113    if (persist) setPref(isDark ? 'dark' : 'light');
114
115    refreshDisqusIfPresent();
116  }
117
118  function toggleTheme() {
119    apply(isDarkNow() ? 'light' : 'dark', true);
120  }
121
122  // Wire each toggle once (the data flag guards against double-binding).
123  for (var t = 0; t < toggles.length; t++) {
124    (function (btn) {
125      if (btn.getAttribute('data-gpdm-bound') === '1') {
126        return;
127      }
128      btn.setAttribute('data-gpdm-bound', '1');
129      btn.setAttribute('aria-checked', isDarkNow() ? 'true' : 'false');
130
131      btn.addEventListener('click', toggleTheme);
132
133      btn.addEventListener('keydown', function (e) {
134        var key = e.key || e.code;
135        if (key === ' ' || key === 'Spacebar' || key === 'Enter') {
136          e.preventDefault();
137          toggleTheme();
138        }
139      });
140    })(toggles[t]);
141  }
142
143  // Follow live OS theme changes — but only for visitors who haven't chosen,
144  // and only when the site is configured to respect the system preference.
145  if (respectSystem && window.matchMedia) {
146    var mq = window.matchMedia('(prefers-color-scheme: dark)');
147    var onChange = function () {
148      if (hasSavedPref()) return;
149      // Mirror the head script's three-way resolution: a runtime drop to
150      // "no OS preference" falls back to the configured default, not light.
151      var theme;
152      if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
153        theme = 'dark';
154      } else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
155        theme = 'light';
156      } else {
157        theme = defaultTheme;
158      }
159      apply(theme, false);
160    };
161    if (typeof mq.addEventListener === 'function') {
162      mq.addEventListener('change', onChange);
163    } else if (typeof mq.addListener === 'function') {
164      mq.addListener(onChange); // Older Safari.
165    }
166  }
167})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.