PageSourceSearch

https://tank-pool.com/wp-content/themes/thehulk89-wp-faq-single-box/popup/banner-popup.js?ver=1.0.0

js tank-pool.com collected 2026-10-10 02:27:43 UTC 5,925 bytes, 152 lines download raw bytes

1/* Popup-only behavior. No jQuery, cookies, storage or replacement of theme handlers. */
2(function () {
3    'use strict';
4
5    function initBannerPopup() {
6        var overlay = document.getElementById('apibet-hulk-banner-popup');
7        if (!overlay || overlay.getAttribute('data-apibet-popup-ready') === '1') {
8            return;
9        }
10        var dialog = overlay.querySelector('.apibet-popup__dialog');
11        var closeButton = overlay.querySelector('.apibet-popup__close');
12        var image = overlay.querySelector('.apibet-popup__image');
13        if (!dialog || !closeButton || !image) {
14            return;
15        }
16        overlay.setAttribute('data-apibet-popup-ready', '1');
17
18        // If a stylesheet failed to load, do not reveal an unstyled page-blocking box.
19        if (window.getComputedStyle(overlay).position !== 'fixed') {
20            return;
21        }
22        var isOpen = false;
23        var previousFocus = null;
24        var savedOverflow = [];
25
26        function focusWithoutScrolling(element) {
27            if (!element || typeof element.focus !== 'function') {
28                return;
29            }
30            try {
31                element.focus({ preventScroll: true });
32            } catch (error) {
33                element.focus();
34            }
35        }
36
37        function lockBackground() {
38            [document.documentElement, document.body].forEach(function (element) {
39                savedOverflow.push({
40                    element: element,
41                    x: element.style.getPropertyValue('overflow-x'),
42                    y: element.style.getPropertyValue('overflow-y'),
43                    xPriority: element.style.getPropertyPriority('overflow-x'),
44                    yPriority: element.style.getPropertyPriority('overflow-y'),
45                    hadStyle: element.hasAttribute('style')
46                });
47                element.style.setProperty('overflow', 'hidden', 'important');
48            });
49        }
50
51        function unlockBackground() {
52            savedOverflow.forEach(function (state) {
53                // Leave newer changes from another component alone.
54                if (state.element.style.getPropertyValue('overflow') !== 'hidden' ||
55                    state.element.style.getPropertyPriority('overflow') !== 'important') {
56                    return;
57                }
58                state.element.style.removeProperty('overflow');
59                if (state.x) {
60                    state.element.style.setProperty('overflow-x', state.x, state.xPriority);
61                }
62                if (state.y) {
63                    state.element.style.setProperty('overflow-y', state.y, state.yPriority);
64                }
65                if (!state.hadStyle && !state.element.getAttribute('style')) {
66                    state.element.removeAttribute('style');
67                }
68            });
69            savedOverflow = [];
70        }
71
72        function closePopup() {
73            if (!isOpen) {
74                return;
75            }
76            isOpen = false;
77            overlay.hidden = true;
78            unlockBackground();
79            document.removeEventListener('keydown', onKeyDown, true);
80            document.removeEventListener('focusin', onFocusIn, true);
81            if (previousFocus && document.documentElement.contains(previousFocus)) {
82                focusWithoutScrolling(previousFocus);
83            }
84        }
85
86        function onKeyDown(event) {
87            if (!isOpen) {
88                return;
89            }
90            if (event.key === 'Escape' || event.key === 'Esc') {
91                event.preventDefault();
92                event.stopPropagation();
93                closePopup();
94                return;
95            }
96            if (event.key !== 'Tab') {
97                return;
98            }
99            var items = Array.prototype.filter.call(
100                dialog.querySelectorAll('a[href],button:not([disabled]),[tabindex]:not([tabindex="-1"])'),
101                function (element) { return element.getClientRects().length > 0; }
102            );
103            if (!items.length) {
104                event.preventDefault();
105                focusWithoutScrolling(dialog);
106                return;
107            }
108            var first = items[0];
109            var last = items[items.length - 1];
110            if (event.shiftKey && (document.activeElement === first || !dialog.contains(document.activeElement))) {
111                event.preventDefault();
112                focusWithoutScrolling(last);
113            } else if (!event.shiftKey && (document.activeElement === last || !dialog.contains(document.activeElement))) {
114                event.preventDefault();
115                focusWithoutScrolling(first);
116            }
117        }
118
119        function onFocusIn(event) {
120            if (isOpen && !dialog.contains(event.target)) {
121                focusWithoutScrolling(closeButton);
122            }
123        }
124
125        closeButton.addEventListener('click', closePopup);
126        overlay.addEventListener('click', function (event) {
127            if (event.target === overlay) {
128                closePopup();
129            }
130        });
131        image.addEventListener('error', closePopup);
132
133        // A broken upload must not leave a broken-image modal blocking the site.
134        if (image.complete && image.naturalWidth === 0) {
135            return;
136        }
137        previousFocus = document.activeElement;
138        overlay.hidden = false;
139        isOpen = true;
140        lockBackground();
141        document.addEventListener('keydown', onKeyDown, true);
142        document.addEventListener('focusin', onFocusIn, true);
143        focusWithoutScrolling(closeButton);
144        // Display on each new page load, just like the supplied TXT; no persistent dismissal.
145    }
146
147    if (document.readyState === 'loading') {
148        document.addEventListener('DOMContentLoaded', initBannerPopup);
149    } else {
150        initBannerPopup();
151    }
152}());

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.