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.