PageSourceSearch

https://onlinepolicingsolutions.com/assets/js/ada-banner.js?v=3

js onlinepolicingsolutions.com collected 2026-10-01 23:45:17 UTC 6,576 bytes, 230 lines download raw bytes

1/**
2 * OPS-ADA-BANNER
3 * Config: window.__OPS_ADA_BANNER__ from data/ada-banner-data.js
4 * Dismiss sets a 7-day cookie. Admin clear bumps version.
5 * Test: index.html?ada=show
6 */
7(function () {
8  var banner = document.getElementById('ops-ada-banner');
9  if (!banner) return;
10
11  var cfg = window.__OPS_ADA_BANNER__;
12  if (!cfg || typeof cfg !== 'object') return;
13
14  var DISMISS_SECONDS = 7 * 24 * 60 * 60;
15
16  function cookieKey() {
17    return 'opsAdaBannerDismissed_v' + String(cfg.version || 1);
18  }
19
20  function getParam(name) {
21    try {
22      return new URLSearchParams(window.location.search).get(name);
23    } catch (e) {
24      return null;
25    }
26  }
27
28  function cookieString() {
29    try {
30      return String(window.document.cookie || '');
31    } catch (e) {
32      return '';
33    }
34  }
35
36  function readCookie(name) {
37    try {
38      var parts = cookieString().split(';');
39      for (var i = 0; i < parts.length; i++) {
40        var p = parts[i].trim();
41        if (p.indexOf(name + '=') === 0) {
42          return decodeURIComponent(p.slice(name.length + 1));
43        }
44      }
45    } catch (e) { /* ignore */ }
46    return null;
47  }
48
49  function writeCookie(name, value, maxAgeSeconds) {
50    try {
51      var secure = location.protocol === 'https:' ? '; Secure' : '';
52      window.document.cookie =
53        name +
54        '=' +
55        encodeURIComponent(value) +
56        '; path=/' +
57        '; max-age=' +
58        Math.max(0, maxAgeSeconds) +
59        '; SameSite=Lax' +
60        secure;
61    } catch (e) { /* ignore */ }
62  }
63
64  function clearAllDismissCookies() {
65    try {
66      var parts = cookieString().split(';');
67      for (var i = 0; i < parts.length; i++) {
68        var p = parts[i].trim();
69        var eq = p.indexOf('=');
70        var name = eq >= 0 ? p.slice(0, eq) : p;
71        if (name.indexOf('opsAdaBannerDismissed_v') === 0) {
72          writeCookie(name, '', 0);
73        }
74      }
75    } catch (e) { /* ignore */ }
76    try {
77      for (var v = 1; v < 50; v++) {
78        localStorage.removeItem('opsAdaBannerDismissed_v' + v);
79      }
80    } catch (e2) { /* ignore */ }
81  }
82
83  function dismissed() {
84    return readCookie(cookieKey()) === '1';
85  }
86
87  function setDismissed() {
88    writeCookie(cookieKey(), '1', DISMISS_SECONDS);
89  }
90
91  function hide() {
92    banner.setAttribute('hidden', '');
93    banner.classList.remove('is-visible', 'is-revealed', 'is-expanded');
94    document.body.classList.remove('has-ada-banner');
95    var moreBtn = document.getElementById('ops-ada-more');
96    if (moreBtn) {
97      moreBtn.setAttribute('aria-expanded', 'false');
98      moreBtn.textContent = 'Read full notice';
99    }
100  }
101
102  function show() {
103    banner.removeAttribute('hidden');
104    banner.classList.add('is-visible');
105    document.body.classList.add('has-ada-banner');
106    var delay = window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 2000;
107    setTimeout(function () {
108      if (!banner.classList.contains('is-visible')) return;
109      banner.classList.add('is-revealed');
110    }, delay);
111  }
112
113  function setText(id, value) {
114    var el = document.getElementById(id);
115    if (el && value != null && value !== '') el.textContent = value;
116  }
117
118  function setHtml(id, value) {
119    var el = document.getElementById(id);
120    if (el && value != null && value !== '') el.innerHTML = value;
121  }
122
123  function applyConfig() {
124    setText('ops-ada-badge', cfg.badge);
125    setText('ops-ada-head-label', cfg.headLabel);
126    setText('ops-ada-deadline-label', cfg.deadlineLabel);
127    setText('ops-ada-issuer', cfg.issuer);
128    setText('ops-ada-title', cfg.title);
129    setText('ops-ada-body', cfg.body);
130    setHtml('ops-ada-fine', cfg.fineHtml);
131    setText('ops-ada-dismiss-label', cfg.dismissLabel);
132    var cta = document.getElementById('ops-ada-cta');
133    if (cta) {
134      if (cfg.ctaLabel) cta.textContent = cfg.ctaLabel;
135      if (cfg.ctaHref) cta.setAttribute('href', cfg.ctaHref);
136    }
137  }
138
139  function pad(n, len) {
140    var s = String(Math.max(0, n));
141    while (s.length < (len || 2)) s = '0' + s;
142    return s;
143  }
144
145  function tick() {
146    var el = document.getElementById('ops-ada-countdown');
147    if (!el) return;
148    var deadline = new Date(cfg.deadline || '2027-04-26T23:59:59-04:00').getTime();
149    if (isNaN(deadline)) return;
150    var left = Math.max(0, deadline - Date.now());
151    var days = Math.floor(left / 86400000);
152    left %= 86400000;
153    var hours = Math.floor(left / 3600000);
154    left %= 3600000;
155    var mins = Math.floor(left / 60000);
156    left %= 60000;
157    var secs = Math.floor(left / 1000);
158    el.textContent =
159      pad(days, days >= 100 ? 3 : 2) +
160      'd ' +
161      pad(hours) +
162      ':' +
163      pad(mins) +
164      ':' +
165      pad(secs);
166  }
167
168  function isEnabled() {
169    if (cfg.enabled === false || cfg.enabled === 0 || cfg.enabled === '0' || cfg.enabled === 'false') {
170      return false;
171    }
172    return true;
173  }
174
175  applyConfig();
176
177  var adaParam = getParam('ada');
178  var forcePreview = adaParam === 'show' || adaParam === '1';
179
180  if (forcePreview) clearAllDismissCookies();
181  if (adaParam === 'hide' || adaParam === '0') {
182    setDismissed();
183    hide();
184    return;
185  }
186  if (!isEnabled() && !forcePreview) {
187    hide();
188    return;
189  }
190  if (dismissed() && !forcePreview) {
191    hide();
192    return;
193  }
194
195  show();
196  tick();
197  setInterval(tick, 1000);
198
199  banner.querySelectorAll('[data-ada-dismiss]').forEach(function (btn) {
200    btn.addEventListener('click', function () {
201      setDismissed();
202      hide();
203    });
204  });
205
206  var more = document.getElementById('ops-ada-more');
207  if (more) {
208    more.addEventListener('click', function () {
209      var expanded = banner.classList.toggle('is-expanded');
210      more.setAttribute('aria-expanded', expanded ? 'true' : 'false');
211      more.textContent = expanded ? 'Show less' : 'Read full notice';
212    });
213  }
214
215  try {
216    fetch('data/ada-banner.json', { cache: 'no-store', credentials: 'same-origin' })
217      .then(function (res) {
218        return res.ok ? res.json() : null;
219      })
220      .then(function (data) {
221        if (!data || typeof data !== 'object' || Array.isArray(data)) return;
222        if (data.version != null) cfg.version = data.version;
223        if ('enabled' in data) {
224          cfg.enabled = data.enabled;
225          if (!isEnabled() && !forcePreview) hide();
226        }
227      })
228      .catch(function () {});
229  } catch (e) {}
230})();

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.