PageSourceSearch

https://zuomod.com/wp-content/mu-plugins/helpers/wiz-preparing-overlay.js?ver=7a1628df

js zuomod.com collected 2026-09-25 18:43:18 UTC 5,926 bytes, 170 lines download raw bytes

1/**
2 * Shared full-page preparing overlay (checkout, quote edit, sign-in, search, etc.).
3 * Fail-open: missing DOM is created on demand. navigate() always shows this
4 * overlay — it no longer defers to WizSkeletons for skeleton routes.
5 */
6(function (global) {
7    'use strict';
8
9    // This file can be printed into an AJAX fragment (WizVariantSwitcher/render.php,
10    // WizQuoteDiscard, WizQuoteResubmit, WizQuoteEndStatusCta) and re-executed when
11    // jQuery .html() inserts the response. Keep the first instance so module state
12    // and the pageshow listener are not duplicated.
13    if (global.WizPreparingOverlay && global.WizPreparingOverlay.__wizOverlayInit) {
14        return;
15    }
16
17    const DEFAULT_ID = 'wiz-preparing-overlay';
18    const LEGACY_ID = 'wiz-quote-preparing-checkout';
19    const DEFAULT_LABEL = 'Proceeding to checkout...';
20    const DEFAULT_NAV_LABEL = 'Loading...';
21    const ALL_SELECTOR = '#' + DEFAULT_ID + ', #' + LEGACY_ID + ', .wiz-preparing, .wiz-quote-preparing';
22    let previousOverflow = null;
23    /**
24     * The node show() last opened. More than one widget on a page renders its
25     * own overlay markup (e.g. the header's WizQuoteResubmit plus the page's
26     * own widget), so the document can hold several #wiz-preparing-overlay
27     * elements. getElementById returns whichever comes first in document
28     * order — and show() moves its node to the end of <body>, which flips that
29     * order. Without this handle hide() resolved a *different* node and left
30     * the visible overlay open, freezing the page behind a click-eating
31     * backdrop.
32     */
33    let activeEl = null;
34
35    function allEls() {
36        return Array.prototype.slice.call(document.querySelectorAll(ALL_SELECTOR));
37    }
38
39    function getEl() {
40        if (activeEl && activeEl.isConnected) {
41            return activeEl;
42        }
43        const els = allEls();
44        if (!els.length) {
45            return null;
46        }
47        // Prefer one already open, so a stray second copy never shadows it.
48        for (let i = 0; i < els.length; i += 1) {
49            if (els[i].classList.contains('is-open')) {
50                return els[i];
51            }
52        }
53        return els[0];
54    }
55
56    function ensureEl() {
57        let el = getEl();
58        if (el) {
59            return el;
60        }
61        if (!document.body) {
62            return null;
63        }
64        el = document.createElement('div');
65        el.id = DEFAULT_ID;
66        el.className = 'wiz-preparing';
67        el.hidden = true;
68        el.setAttribute('aria-hidden', 'true');
69
70        const backdrop = document.createElement('div');
71        backdrop.className = 'wiz-preparing__backdrop';
72        backdrop.setAttribute('aria-hidden', 'true');
73
74        const toast = document.createElement('div');
75        toast.className = 'wiz-preparing__toast';
76        toast.setAttribute('role', 'status');
77        toast.setAttribute('aria-live', 'polite');
78
79        const spinner = document.createElement('span');
80        spinner.className = 'wiz-preparing__spinner';
81        spinner.setAttribute('aria-hidden', 'true');
82
83        const textEl = document.createElement('span');
84        textEl.className = 'wiz-preparing__text';
85        textEl.textContent = DEFAULT_NAV_LABEL;
86
87        toast.appendChild(spinner);
88        toast.appendChild(textEl);
89        el.appendChild(backdrop);
90        el.appendChild(toast);
91        document.body.appendChild(el);
92        return el;
93    }
94
95    function portalToBody(el) {
96        if (!el || el.parentNode === document.body) {
97            return;
98        }
99        document.body.appendChild(el);
100    }
101
102    function show(label) {
103        const el = ensureEl();
104        if (!el) {
105            return false;
106        }
107        if (typeof label === 'string' && label.trim()) {
108            const textEl = el.querySelector('.wiz-preparing__text, .wiz-quote-preparing__text');
109            if (textEl) {
110                textEl.textContent = label.trim();
111            }
112        }
113        portalToBody(el);
114        activeEl = el;
115        el.hidden = false;
116        el.setAttribute('aria-hidden', 'false');
117        el.classList.add('is-open');
118        if (previousOverflow === null) {
119            previousOverflow = document.body.style.overflow;
120        }
121        document.body.style.overflow = 'hidden';
122        return true;
123    }
124
125    function hide() {
126        // Close every copy, not just the one getEl() resolves to — a duplicate
127        // left open is nearly invisible (translucent backdrop) but eats clicks.
128        allEls().forEach(function (el) {
129            el.classList.remove('is-open');
130            el.hidden = true;
131            el.setAttribute('aria-hidden', 'true');
132        });
133        activeEl = null;
134        if (previousOverflow !== null) {
135            document.body.style.overflow = previousOverflow;
136            previousOverflow = null;
137        }
138    }
139
140    function navigate(url, label) {
141        const next = (url || '').toString().trim();
142        if (!next) {
143            return false;
144        }
145        show(label || DEFAULT_NAV_LABEL);
146        global.location.href = next;
147        return true;
148    }
149
150    // bfcache restore: the DOM snapshot was frozen with the overlay up and body
151    // scroll locked. No script re-runs on restore, so clear it here. Gated on
152    // event.persisted so a normal forward load does not fight a show() a widget
153    // legitimately called during page init.
154    if (typeof global.addEventListener === 'function') {
155        global.addEventListener('pageshow', function (event) {
156            if (event && event.persisted) {
157                hide();
158            }
159        });
160    }
161
162    global.WizPreparingOverlay = {
163        show: show,
164        hide: hide,
165        navigate: navigate,
166        DEFAULT_LABEL: DEFAULT_LABEL,
167        DEFAULT_NAV_LABEL: DEFAULT_NAV_LABEL,
168        __wizOverlayInit: true,
169    };
170}(typeof window !== 'undefined' ? window : this));

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.