PageSourceSearch

https://scholeacademy.com/wp-content/themes/Divi/js/landing/home-update.js?ver=1791366705

js scholeacademy.com collected 2026-10-07 12:10:11 UTC 9,657 bytes, 287 lines download raw bytes

1/* Landing page: home-update — accordions */
2(function () {
3    function setupAccordion(itemSelector, arrowSelector, exclusive) {
4        var items = document.querySelectorAll(itemSelector);
5
6        function setArrow(item, isOpen) {
7            var arrow = item.querySelector(arrowSelector);
8            if (arrow) {
9                arrow.innerHTML = isOpen ? '▲' : '▼';
10            }
11        }
12
13        items.forEach(function (item) {
14            item.addEventListener('click', function (e) {
15                // Let CTA links inside the panel work normally
16                if (e.target.closest('a')) {
17                    return;
18                }
19                var isOpen = item.classList.toggle('is-open');
20                setArrow(item, isOpen);
21                if (exclusive && isOpen) {
22                    items.forEach(function (other) {
23                        if (other !== item && other.classList.contains('is-open')) {
24                            other.classList.remove('is-open');
25                            setArrow(other, false);
26                        }
27                    });
28                }
29            });
30        });
31    }
32
33    setupAccordion('.sa-landing--home-update .lp-faq-item', '.lp-faq-arrow', false);
34    setupAccordion('.sa-landing--home-update .lp-offer', '.lp-offer-arrow', true);
35
36    /* Swap the side image when an offer card is opened.
37       Each .lp-offer may define data-image (URL) and data-image-alt.
38       Until images are provided, the placeholder label updates instead. */
39    (function () {
40        var imageBox = document.getElementById('lp-offer-image');
41        if (!imageBox) {
42            return;
43        }
44
45        function applyImage(src, alt) {
46            if (src) {
47                var img = imageBox.querySelector('img');
48                if (!img) {
49                    imageBox.textContent = '';
50                    img = document.createElement('img');
51                    img.className = 'lp-offer-img';
52                    imageBox.appendChild(img);
53                    imageBox.classList.add('has-image');
54                }
55                img.src = src;
56                img.alt = alt;
57            } else {
58                imageBox.classList.remove('has-image');
59                imageBox.innerHTML = '';
60                imageBox.textContent = '[ Image: ' + (alt || 'coming soon') + ' ]';
61            }
62        }
63
64        function showImageFor(card) {
65            applyImage(card.getAttribute('data-image'), card.getAttribute('data-image-alt') || '');
66        }
67
68        // Preload all accordion images up front so switches are instant
69        document.querySelectorAll('.sa-landing--home-update .lp-offer[data-image]').forEach(function (card) {
70            var src = card.getAttribute('data-image');
71            if (src) {
72                (new Image()).src = src;
73            }
74        });
75
76        var cards = document.querySelectorAll('.sa-landing--home-update .lp-offer');
77        cards.forEach(function (card) {
78            card.addEventListener('click', function (e) {
79                if (e.target.closest('a')) {
80                    return;
81                }
82                if (card.classList.contains('is-open')) {
83                    showImageFor(card);
84                }
85            });
86        });
87
88        // Initialize with the card that starts open
89        var openCard = document.querySelector('.sa-landing--home-update .lp-offer.is-open');
90        if (openCard && (openCard.getAttribute('data-image') || openCard.getAttribute('data-image-alt'))) {
91            showImageFor(openCard);
92        }
93    })();
94
95    /* Countdown to first day of classes. Live when data-live="1"; otherwise
96       preview with ?show-countdown=1. Hides itself once the target date hits. */
97    (function () {
98        var root = document.getElementById('lp-countdown');
99        if (!root) {
100            return;
101        }
102
103        var live = root.getAttribute('data-live') === '1';
104        var preview = false;
105        try {
106            preview = /(?:^|[?&])show-countdown=1(?:&|$)/.test(window.location.search);
107        } catch (e) {}
108
109        if (!live && !preview) {
110            return;
111        }
112
113        if (preview) {
114            root.removeAttribute('hidden');
115        }
116
117        var targetMs = Date.parse(root.getAttribute('data-target') || '');
118        if (!targetMs) {
119            return;
120        }
121
122        var values = {
123            days: root.querySelector('[data-unit="days"]'),
124            hours: root.querySelector('[data-unit="hours"]'),
125            minutes: root.querySelector('[data-unit="minutes"]'),
126            seconds: root.querySelector('[data-unit="seconds"]')
127        };
128
129        function pad(n) {
130            return n < 10 ? '0' + n : String(n);
131        }
132
133        function render(diff) {
134            var total = Math.floor(diff / 1000);
135            var days = Math.floor(total / 86400);
136            total %= 86400;
137            var hours = Math.floor(total / 3600);
138            total %= 3600;
139            var minutes = Math.floor(total / 60);
140            var seconds = total % 60;
141
142            if (values.days) {
143                values.days.textContent = String(days);
144            }
145            if (values.hours) {
146                values.hours.textContent = pad(hours);
147            }
148            if (values.minutes) {
149                values.minutes.textContent = pad(minutes);
150            }
151            if (values.seconds) {
152                values.seconds.textContent = pad(seconds);
153            }
154        }
155
156        function tick() {
157            var diff = targetMs - Date.now();
158            if (diff <= 0) {
159                window.clearInterval(intervalId);
160                root.setAttribute('hidden', '');
161                return;
162            }
163            render(diff);
164        }
165
166        var intervalId = window.setInterval(tick, 1000);
167        tick();
168    })();
169
170    /* Awards popup: homepage only, once per browser. Append ?show-popup=1
171       to preview without writing the seen flag. */
172    (function () {
173        var popup = document.getElementById('lp-awards-popup');
174        if (!popup) {
175            return;
176        }
177
178        var STORAGE_KEY = 'sa-home-awards-popup-seen';
179        var DELAY_MS = 3000;
180        var dialog = popup.querySelector('.lp-popup-dialog');
181        var closeEls = popup.querySelectorAll('[data-lp-popup-close]');
182        var lastFocus = null;
183        var preview = false;
184
185        var countdownPreview = false;
186        try {
187            preview = window.location.search.indexOf('show-popup=1') !== -1;
188            countdownPreview = /(?:^|[?&])show-countdown=1(?:&|$)/.test(window.location.search);
189        } catch (e) {}
190
191        // Keep the awards popup out of the way while reviewing the countdown.
192        if (countdownPreview) {
193            return;
194        }
195
196        function storageGet() {
197            try { return window.localStorage.getItem(STORAGE_KEY); } catch (e) { return '1'; }
198        }
199
200        function storageSet() {
201            if (preview) {
202                return;
203            }
204            try { window.localStorage.setItem(STORAGE_KEY, '1'); } catch (e) {}
205        }
206
207        function focusables() {
208            return dialog.querySelectorAll('a[href], button:not([disabled])');
209        }
210
211        function openPopup() {
212            lastFocus = document.activeElement;
213            popup.removeAttribute('hidden');
214            document.body.classList.add('lp-popup-open');
215            window.requestAnimationFrame(function () {
216                popup.classList.add('is-open');
217                var closeBtn = popup.querySelector('.lp-popup-close');
218                if (closeBtn) {
219                    closeBtn.focus();
220                }
221            });
222        }
223
224        function closePopup() {
225            popup.classList.remove('is-open');
226            document.body.classList.remove('lp-popup-open');
227            storageSet();
228            window.setTimeout(function () {
229                popup.setAttribute('hidden', '');
230                if (lastFocus && typeof lastFocus.focus === 'function') {
231                    lastFocus.focus();
232                }
233            }, 200);
234        }
235
236        if (!preview && storageGet()) {
237            return;
238        }
239
240        var reduceMotion = false;
241        try {
242            reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
243        } catch (e) {}
244
245        window.setTimeout(openPopup, reduceMotion ? 0 : DELAY_MS);
246
247        closeEls.forEach(function (el) {
248            el.addEventListener('click', function (e) {
249                e.preventDefault();
250                closePopup();
251            });
252        });
253
254        popup.addEventListener('click', function (e) {
255            if (e.target.closest('.lp-btn')) {
256                storageSet();
257            }
258        });
259
260        document.addEventListener('keydown', function (e) {
261            if (popup.hasAttribute('hidden')) {
262                return;
263            }
264            if (e.key === 'Escape') {
265                e.preventDefault();
266                closePopup();
267                return;
268            }
269            if (e.key !== 'Tab') {
270                return;
271            }
272            var nodes = focusables();
273            if (!nodes.length) {
274                return;
275            }
276            var first = nodes[0];
277            var last = nodes[nodes.length - 1];
278            if (e.shiftKey && document.activeElement === first) {
279                e.preventDefault();
280                last.focus();
281            } else if (!e.shiftKey && document.activeElement === last) {
282                e.preventDefault();
283                first.focus();
284            }
285        });
286    })();
287})();

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.