PageSourceSearch

https://www.blog-nouvelles-technologies.fr/wp-content/themes/blogn…/assets/js/blognt-header.js?ver=1783173592

js blog-nouvelles-technologies.fr collected 2026-10-02 04:11:12 UTC 12,417 bytes, 315 lines download raw bytes

1(function () {
2    'use strict';
3
4    if (document.body.classList.contains('wp-admin')) {
5        return;
6    }
7
8    var config = window.BLOGNT_HEADER || {};
9    var ajaxUrl = config.ajaxUrl || '';
10    var ajaxNonce = config.nonce || '';
11    var themeStorageKey = config.themeStorageKey || 'blognt-theme';
12    var hubLoadErrorMessage = config.hubLoadErrorMessage || 'Chargement en cours…';
13    var hubLoadWaitingHtml = config.hubLoadWaitingHtml || '<span class="blognt-hub-panel__loading-icon" aria-hidden="true">✨</span><strong class="blognt-hub-panel__loading-title">On prépare cette rubrique</strong><span class="blognt-hub-panel__loading-text">Le contenu arrive dans un instant.</span>';
14    var darkLabel = config.darkLabel || 'Activer le mode sombre';
15    var lightLabel = config.lightLabel || 'Activer le mode clair';
16
17    var hubTriggers = Array.prototype.slice.call(document.querySelectorAll('[data-blognt-hub-trigger]'));
18    var hubPanel = document.getElementById('blognt-hub-panel');
19    var hubClose = document.querySelector('[data-blognt-hub-close]');
20    var hubTabs = Array.prototype.slice.call(document.querySelectorAll('.blognt-hub-tab'));
21    var hubSections = Array.prototype.slice.call(document.querySelectorAll('.blognt-hub-panel'));
22    var hubHideTimer = null;
23    var hubPanelRequest = null;
24    var hubReturnFocus = null;
25
26    function getFocusable(root) {
27        if (!root) {
28            return [];
29        }
30        return Array.prototype.slice.call(root.querySelectorAll([
31            'a[href]',
32            'button:not([disabled])',
33            'input:not([disabled])',
34            'select:not([disabled])',
35            'textarea:not([disabled])',
36            '[tabindex]:not([tabindex="-1"])'
37        ].join(','))).filter(function (node) {
38            return !node.hidden && node.offsetParent !== null;
39        });
40    }
41
42    function initHub() {
43        if (!hubTriggers.length || !hubPanel) {
44            return;
45        }
46
47        function setPanelLoading(panel, loading) {
48            if (!panel) {
49                return;
50            }
51            panel.classList.toggle('is-loading', !!loading);
52        }
53
54        function loadHubPanel(tab) {
55            var target = tab.getAttribute('data-hub-target');
56            var panel = target ? document.getElementById(target) : null;
57            var termId = panel ? panel.getAttribute('data-hub-term-id') : '';
58
59            if (!panel || !termId || panel.getAttribute('data-loaded') === 'true' || !ajaxUrl) {
60                return Promise.resolve(panel);
61            }
62
63            if (hubPanelRequest) {
64                hubPanelRequest.abort();
65                hubPanelRequest = null;
66            }
67
68            setPanelLoading(panel, true);
69
70            var params = new URLSearchParams({
71                action: 'blognt_load_hub_panel',
72                term_id: termId,
73                nonce: ajaxNonce
74            });
75
76            hubPanelRequest = new AbortController();
77
78            return fetch(ajaxUrl + '?' + params.toString(), {
79                credentials: 'same-origin',
80                signal: hubPanelRequest.signal
81            })
82                .then(function (response) { return response.json(); })
83                .then(function (payload) {
84                    if (!payload || !payload.success || !payload.data || !payload.data.html) {
85                        throw new Error('hub-load-failed');
86                    }
87
88                    var wrapper = document.createElement('div');
89                    wrapper.innerHTML = payload.data.html;
90                    var freshPanel = wrapper.firstElementChild;
91
92                    if (freshPanel && freshPanel.classList && freshPanel.classList.contains('blognt-hub-panel') && panel.parentNode) {
93                        panel.parentNode.replaceChild(freshPanel, panel);
94                        hubSections = Array.prototype.slice.call(document.querySelectorAll('.blognt-hub-panel'));
95                        panel = freshPanel;
96                    }
97
98                    return panel;
99                })
100                .catch(function () {
101                    var loadingNode = panel ? panel.querySelector('.blognt-hub-panel__loading') : null;
102                    if (loadingNode) {
103                        loadingNode.innerHTML = hubLoadWaitingHtml;
104                        loadingNode.setAttribute('aria-live', 'polite');
105                        loadingNode.setAttribute('aria-label', hubLoadErrorMessage);
106                    }
107                    return panel;
108                })
109                .finally(function () {
110                    setPanelLoading(panel, false);
111                    hubPanelRequest = null;
112                });
113        }
114
115        function setHub(open, restoreFocus) {
116            hubTriggers.forEach(function (trigger) {
117                trigger.setAttribute('aria-expanded', open ? 'true' : 'false');
118            });
119            document.body.classList.toggle('blognt-hub-open', open);
120
121            var mainContent = document.getElementById('main-content');
122            if (mainContent) {
123                if (open) {
124                    mainContent.setAttribute('inert', '');
125                } else {
126                    mainContent.removeAttribute('inert');
127                }
128            }
129
130            if (hubHideTimer) {
131                clearTimeout(hubHideTimer);
132                hubHideTimer = null;
133            }
134
135            if (open) {
136                hubReturnFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
137                hubPanel.hidden = false;
138                window.requestAnimationFrame(function () {
139                    hubPanel.classList.add('is-visible');
140                });
141                document.documentElement.classList.add('blognt-hub-locked');
142                window.setTimeout(function () {
143                    var focusTarget = hubClose || hubTabs[0] || getFocusable(hubPanel)[0];
144                    if (focusTarget) {
145                        focusTarget.focus();
146                    }
147                }, 0);
148                return;
149            }
150
151            hubPanel.classList.remove('is-visible');
152            document.documentElement.classList.remove('blognt-hub-locked');
153            hubHideTimer = window.setTimeout(function () {
154                hubPanel.hidden = true;
155                if (restoreFocus !== false && hubReturnFocus && document.contains(hubReturnFocus)) {
156                    hubReturnFocus.focus();
157                }
158                hubReturnFocus = null;
159            }, 180);
160        }
161
162        function activateTab(tab) {
163            var target = tab.getAttribute('data-hub-target');
164            hubTabs.forEach(function (candidate) {
165                var active = candidate === tab;
166                candidate.classList.toggle('is-active', active);
167                candidate.setAttribute('aria-selected', active ? 'true' : 'false');
168                candidate.setAttribute('tabindex', active ? '0' : '-1');
169            });
170
171            hubSections.forEach(function (section) {
172                var active = section.id === target;
173                section.classList.toggle('is-active', active);
174                section.hidden = !active;
175            });
176
177            loadHubPanel(tab).then(function (panel) {
178                if (!panel) {
179                    return;
180                }
181                hubSections.forEach(function (section) {
182                    var active = section.id === target;
183                    section.classList.toggle('is-active', active);
184                    section.hidden = !active;
185                });
186            });
187        }
188
189        setHub(false);
190
191        hubTriggers.forEach(function (trigger) {
192            trigger.addEventListener('click', function (event) {
193                event.preventDefault();
194                setHub(hubPanel.hidden);
195            });
196        });
197
198        if (hubClose) {
199            hubClose.addEventListener('click', function () {
200                setHub(false);
201            });
202        }
203
204        document.addEventListener('click', function (event) {
205            if (hubPanel.hidden) {
206                return;
207            }
208            var clickedTrigger = hubTriggers.some(function (trigger) {
209                return trigger.contains(event.target);
210            });
211            if (!hubPanel.contains(event.target) && !clickedTrigger) {
212                setHub(false);
213            }
214        });
215
216        document.addEventListener('keydown', function (event) {
217            if (hubPanel.hidden) {
218                return;
219            }
220            if (event.key === 'Escape') {
221                event.preventDefault();
222                setHub(false);
223                return;
224            }
225            if (event.key === 'Tab') {
226                var focusable = getFocusable(hubPanel);
227                if (!focusable.length) {
228                    return;
229                }
230                var first = focusable[0];
231                var last = focusable[focusable.length - 1];
232                if (event.shiftKey && document.activeElement === first) {
233                    event.preventDefault();
234                    last.focus();
235                } else if (!event.shiftKey && document.activeElement === last) {
236                    event.preventDefault();
237                    first.focus();
238                }
239            }
240        });
241
242        hubTabs.forEach(function (tab) {
243            tab.addEventListener('click', function () { activateTab(tab); });
244            tab.addEventListener('mouseenter', function () { activateTab(tab); });
245            tab.addEventListener('focus', function () { activateTab(tab); });
246        });
247
248        /* ── Navigation clavier ARIA APG — Tab pattern ─────────────────────── */
249        var hubTabList = document.querySelector('.blognt-hub-nav[role="tablist"]');
250        if (hubTabList) {
251            hubTabList.addEventListener('keydown', function (event) {
252                var idx = hubTabs.indexOf(document.activeElement);
253                if (idx === -1) return;
254
255                var next = null;
256                if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
257                    next = hubTabs[(idx + 1) % hubTabs.length];
258                } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
259                    next = hubTabs[(idx - 1 + hubTabs.length) % hubTabs.length];
260                } else if (event.key === 'Home') {
261                    next = hubTabs[0];
262                } else if (event.key === 'End') {
263                    next = hubTabs[hubTabs.length - 1];
264                }
265
266                if (next) {
267                    event.preventDefault();
268                    next.focus();
269                    activateTab(next);
270                }
271            });
272        }
273    }
274
275    function initThemeToggle() {
276        var toggles = Array.prototype.slice.call(document.querySelectorAll('[data-blognt-theme-toggle]'));
277        if (!toggles.length) {
278            return;
279        }
280
281        var root = document.documentElement;
282
283        function applyTheme(theme) {
284            root.setAttribute('data-blognt-theme', theme);
285            root.style.colorScheme = theme;
286            toggles.forEach(function (toggle) {
287                var isDark = theme === 'dark';
288                toggle.setAttribute('aria-pressed', isDark ? 'true' : 'false');
289                toggle.setAttribute('aria-label', isDark ? lightLabel : darkLabel);
290            });
291            /* H12 — retirer l'attribut media de la feuille dark-theme si l'utilisateur
292               bascule manuellement en dark (sinon le CSS ne s'applique pas en mode clair) */
293            var darkSheet = document.getElementById('blognt-dark-theme-style-css');
294            if (darkSheet && theme === 'dark') {
295                darkSheet.removeAttribute('media');
296            }
297        }
298
299        var current = root.getAttribute('data-blognt-theme') === 'dark' ? 'dark' : 'light';
300        applyTheme(current);
301
302        toggles.forEach(function (toggle) {
303            toggle.addEventListener('click', function () {
304                current = current === 'dark' ? 'light' : 'dark';
305                applyTheme(current);
306                try {
307                    window.localStorage.setItem(themeStorageKey, current);
308                } catch (error) {}
309            });
310        });
311    }
312
313    initHub();
314    initThemeToggle();
315})();

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.