PageSourceSearch

https://illinoisfamily.org/wp-content/plugins/ifi-promotions/popup.js?ver=1.0.4

js illinoisfamily.org collected 2026-10-02 05:45:45 UTC 4,307 bytes, 94 lines download raw bytes

1/* Native dialog keeps keyboard focus inside the popup and the background inert. */
2'use strict';
3{
4    const dialog = document.getElementById('ifi-promotions');
5    if (dialog && typeof dialog.showModal === 'function') {
6        const preview = dialog.dataset.preview === '1';
7        // Old cookies combined clicks and closes; this key records only explicit dismissal.
8        const cookie = `ifi_promotions_dismissed_${dialog.dataset.campaign}`;
9        let priorFocus;
10        let openTimer;
11
12        function rememberDismissal() {
13            if (preview) return;
14            const seconds = Number(dialog.dataset.days) * 86400;
15            const secure = location.protocol === 'https:' ? '; Secure' : '';
16            document.cookie = `${cookie}=1; Max-Age=${seconds}; Path=/; SameSite=Lax${secure}`;
17        }
18
19        function isDismissed() {
20            return document.cookie.split(';').some(value => value.trim() === `${cookie}=1`);
21        }
22
23        function dismissPopup() {
24            rememberDismissal();
25            document.documentElement.classList.remove('ifi-promotions-open');
26            dialog.close();
27        }
28
29        function openPopup() {
30            if ((!preview && isDismissed()) || document.querySelector('dialog[open]')) return;
31            // Do not interrupt someone already filling a form during the delay.
32            if (!preview && document.activeElement?.matches('input, textarea, select, [contenteditable="true"]')) return;
33            const template = dialog.querySelector('template');
34            if (template) template.replaceWith(template.content.cloneNode(true));
35            priorFocus = document.activeElement;
36            dialog.showModal();
37            document.documentElement.classList.add('ifi-promotions-open');
38        }
39
40        function start(immediate = false) {
41            window.clearTimeout(openTimer);
42            if (!preview && isDismissed()) {
43                if (dialog.open) dialog.close();
44                return;
45            }
46            const historyReturn = performance.getEntriesByType('navigation')[0]?.type === 'back_forward';
47            if (preview || immediate || historyReturn) openPopup();
48            else openTimer = window.setTimeout(openPopup, Number(dialog.dataset.delay) * 1000);
49        }
50
51        function keepFocus(event) {
52            if (event.key !== 'Tab') return;
53            const controls = [...dialog.querySelectorAll('button:not([disabled]), a[href]')];
54            const first = controls[0];
55            const last = controls[controls.length - 1];
56            // Native modal inertness does not prevent Tab from reaching browser chrome.
57            if (event.shiftKey && document.activeElement === first) {
58                event.preventDefault();
59                last.focus();
60            } else if (!event.shiftKey && document.activeElement === last) {
61                event.preventDefault();
62                first.focus();
63            }
64        }
65
66        dialog.addEventListener('keydown', keepFocus);
67        dialog.querySelector('.ifi-promotions-close').addEventListener('click', dismissPopup);
68        dialog.addEventListener('cancel', event => {
69            event.preventDefault();
70            dismissPopup();
71        });
72        dialog.addEventListener('click', event => {
73            if (event.target !== dialog) return;
74            const rect = dialog.getBoundingClientRect();
75            if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) {
76                dismissPopup();
77            }
78        });
79        dialog.addEventListener('close', () => {
80            if (dialog.open) return;
81            document.documentElement.classList.remove('ifi-promotions-open');
82            if (priorFocus instanceof HTMLElement) priorFocus.focus({preventScroll: true});
83        });
84        window.addEventListener('pagehide', () => {
85            // Leave the modal intact for cached Back; leaving is not a dismissal.
86            window.clearTimeout(openTimer);
87        });
88        window.addEventListener('pageshow', event => {
89            if (event.persisted) start(true);
90        });
91        if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => start(), {once: true});
92        else start();
93    }
94}

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.