PageSourceSearch

https://offthepress.com/chrome.js

js offthepress.com collected 2026-09-24 09:39:11 UTC 3,582 bytes, 77 lines download raw bytes

1// Lightweight interactivity for secondary pages — mobile drawer + newsletter form.
2// (Main page uses main.js which is heavier and includes feed loading.)
3(function() {
4  document.addEventListener('DOMContentLoaded', function() {
5    // Mobile drawer toggle
6    var trigger  = document.getElementById('mobileTrigger');
7    var drawer   = document.getElementById('mobileDrawer');
8    var closeBtn = document.getElementById('mobileMenuClose');
9    var overlay  = document.getElementById('mobileOverlay');
10
11    // NOTE: the overlay state class is 'active' — that's what style.css defines
12    // (.mobile-overlay.active), and what main.js uses on the homepage. Keep the
13    // two in sync: a mismatch here leaves the scrim display:none, which also
14    // makes it unclickable and silently kills tap-outside-to-close below.
15    function openDrawer() {
16      if (drawer) drawer.classList.add('open');
17      if (overlay) overlay.classList.add('active');
18      document.body.style.overflow = 'hidden';
19    }
20    function closeDrawer() {
21      if (drawer) drawer.classList.remove('open');
22      if (overlay) overlay.classList.remove('active');
23      document.body.style.overflow = '';
24    }
25    if (trigger)  trigger.addEventListener('click', openDrawer);
26    if (closeBtn) closeBtn.addEventListener('click', closeDrawer);
27    if (overlay)  overlay.addEventListener('click', closeDrawer);
28    // Escape closes the drawer, matching main.js on the homepage. Without this
29    // there is no keyboard route out of the drawer once it's open.
30    document.addEventListener('keydown', function(e) {
31      if (e.key === 'Escape') closeDrawer();
32    });
33  });
34
35  // Newsletter form. This MUST post for real: every secondary page (about,
36  // whats-new, privacy-policy, newsletter-signup) loads chrome.js and NOT
37  // main.js, so this is the only handler behind their header/drawer forms.
38  // It was previously a placeholder that flipped the button to 'SUBSCRIBED'
39  // and reset the form without sending anything, so those pages silently
40  // discarded every signup while telling the reader it had worked.
41  // Mirrors main.js's handler — keep the two in sync.
42  var SUBSCRIBE = 'https://offthepressdashboard.com/subscribe';
43
44  window.handleNewsletter = function(e) {
45    e.preventDefault();
46    var form  = e.target;
47    var input = form.querySelector('input[type="email"]');
48    var email = ((input && input.value) || '').trim();
49    var btn   = form.querySelector('button[type="submit"]') || form.querySelector('button');
50    if (!btn) return;
51    if (!email) { if (input) input.focus(); return; }
52
53    var orig = btn.textContent;
54    btn.textContent = 'SUBSCRIBING...';
55    btn.disabled    = true;
56    function done(msg, ok) {
57      btn.textContent      = msg;
58      btn.style.background = ok ? '#2a7a3b' : '#a3282b';
59      if (ok && form.reset) form.reset();
60      setTimeout(function() {
61        btn.textContent = orig;
62        btn.style.background = '';
63        btn.disabled = false;
64      }, 3000);
65    }
66    // Form-encoded body keeps this a CORS-simple request (no preflight); the
67    // relay still returns JSON {ok:...} we can read when the origin is allowed.
68    fetch(SUBSCRIBE, {
69      method: 'POST',
70      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
71      body: 'email=' + encodeURIComponent(email)
72    })
73    .then(function(r) { return r.json().catch(function() { return { ok: r.ok }; }); })
74    .then(function(d) { done((d && d.ok) ? '✓ SUBSCRIBED!' : 'TRY AGAIN', !!(d && d.ok)); })
75    .catch(function() { done('TRY AGAIN', false); });
76  };
77})();

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.