PageSourceSearch

https://www.leiflist.com/utils/theme-boot.js

js leiflist.com collected 2026-10-02 01:34:10 UTC 3,171 bytes, 71 lines download raw bytes

1/* ============================================================================
2   theme-boot.js — site-wide theme switch (runtime, no duplicate pages)
3   ----------------------------------------------------------------------------
4   Include this FIRST in <head> of every page, as a BLOCKING script (no defer),
5   so the theme class lands on <html> before first paint (no flash-of-unstyled).
6
7   How theming works site-wide:
8     • ALL new "editorial/navy" styling is written scoped under `.ed-theme`,
9       in a stylesheet loaded LAST on the page. This script adds/removes that
10       one class on <html>, so:
11         flag "editorial" → <html class="ed-theme"> → new look
12         flag "legacy"    → class removed          → original look (rules inert)
13
14   The flag (persisted, survives navigation + restarts):
15       localStorage['leif_theme'] = 'editorial' | 'legacy'   (default: editorial)
16
17   Ways to flip it:
18       • URL (also persists):   ?theme=legacy    ?theme=editorial
19       • Console:               leifTheme.toggle()
20                                leifTheme.set('legacy')  /  leifTheme.set('editorial')
21                                leifTheme.get()
22   Note: CSS re-themes live on toggle; page scripts that do one-time cosmetic
23   work (e.g. the homepage logo swap) fully apply on next reload.
24   ============================================================================ */
25(function () {
26  'use strict';
27  var KEY = 'leif_theme';
28  var DEFAULT = 'editorial';
29
30  function read() {
31    try { return localStorage.getItem(KEY) || DEFAULT; } catch (e) { return DEFAULT; }
32  }
33  function apply(t) {
34    var el = document.documentElement;
35    if (t !== 'legacy') el.classList.add('ed-theme');
36    else el.classList.remove('ed-theme');
37  }
38
39  // URL override (?theme=…) wins and persists so it sticks across pages.
40  try {
41    var q = new URLSearchParams(location.search).get('theme');
42    if (q === 'legacy' || q === 'editorial') localStorage.setItem(KEY, q);
43  } catch (e) {}
44
45  apply(read());
46
47  /* Session hint (layout only, never trusted for auth).
48     ------------------------------------------------------------------------
49     Firebase persists its session in IndexedDB, which is async — so at first
50     paint the page cannot know whether a signed-in-only section like the
51     homepage's "Recommended for You" rail will end up visible. Left to
52     display:none it pops in a full row later and shoves everything below it
53     down the page. This flag, written by the auth listener on every state
54     change, lets CSS reserve that row's height up front for returning users
55     and reserve nothing for signed-out ones. Worst case it is one load stale,
56     which costs a reserved-but-unused row — never wrong content. */
57  try {
58    if (localStorage.getItem('leif_had_session') === '1') {
59      document.documentElement.classList.add('leif-had-session');
60    }
61  } catch (e) {}
62
63  window.leifTheme = {
64    get: read,
65    set: function (t) {
66      try { localStorage.setItem(KEY, t); } catch (e) {}
67      apply(read());
68    },
69    toggle: function () { this.set(read() === 'legacy' ? 'editorial' : 'legacy'); }
70  };
71})();

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.