1document.addEventListener('DOMContentLoaded', function() { 2 3 function showResponseMessage(wrapper, message) { 4 const responseMsg = wrapper.querySelector('.mailinglist-response-message'); 5 const overlay = wrapper.querySelector('.overlay_mailinglist'); 6 7 // Set the message text 8 responseMsg.querySelector('.response-message-text').textContent = message; 9 10 // Show the overlay and the message 11 overlay.style.display = 'block'; 12 responseMsg.style.display = 'block'; 13 14 // Hide them after 5 seconds 15 setTimeout(function() { 16 overlay.style.display = 'none'; 17 responseMsg.style.display = 'none'; 18 }, 5000); 19 } 20 21 document.querySelectorAll('.mailing-list-wrapper .close_mailinglist-response-message').forEach(button => { 22 button.addEventListener('click', function(event) { 23 const wrapper = event.target.closest('.mailing-list-wrapper'); 24 if (wrapper) { 25 wrapper.querySelector('.overlay_mailinglist').style.display = 'none'; 26 wrapper.querySelector('.mailinglist-response-message').style.display = 'none'; 27 } 28 }); 29 }); 30 31 document.querySelectorAll('.mailing-list-wrapper .mailing-list-form').forEach(form => { 32 // Add a flag directly on the form to check the submission status 33 form.isSubmitting = false; 34 35 form.addEventListener('submit', async function(event) { 36 event.preventDefault(); 37 const wrapper = form.closest('.mailing-list-wrapper'); 38 39 if (form.isSubmitting) { 40 //console.log('Formulaire already being soumis'); 41 return; 42 } 43 44 form.isSubmitting = true; 45 46 try { 47 const csrf_token_newsletter = await fetchCSRFToken('newsletter'); 48 form.querySelector('input[name="csrf_token"]').value = csrf_token_newsletter 49 50 const formData = new FormData(form); 51 52 const responseBody = JSON.stringify({ 53 pseudo: formData.get('pseudo'), 54 sexe: formData.get('sexe'), 55 email: formData.get('email'), 56 csrf_token_newsletter: csrf_token_newsletter, 57 lang: formData.get('lang') 58 }); 59 60 const responseHeaders = { 'Content-Type': 'application/json' }; 61 62 let response = await fetch('/newsletter/subscribe.html', { 63 method: 'POST', 64 body: responseBody, 65 headers: responseHeaders 66 }); 67 68 let responseText = await response.text(); 69 70 let data; 71 try { 72 data = JSON.parse(responseText); 73 } catch (e) { 74 showResponseMessage(wrapper, responseText || 'Error'); 75 form.isSubmitting = false; 76 return; 77 } 78 79 // PATCH ici : Gestion si CSRF expiré 80 if (data && (data.error_code === 'csrf_expired' || data.error_code === 'missing_token')) { 81 // ð¥ Nouveau token + resoumission automatique 82 const newToken = await fetchCSRFToken('newsletter'); 83 form.querySelector('input[name="csrf_token"]').value = newToken; 84 85 // Resoumission une seule fois 86 const retryResponse = await fetch('/newsletter/subscribe.html', { 87 method: 'POST', 88 body: JSON.stringify({ 89 pseudo: formData.get('pseudo'), 90 sexe: formData.get('sexe'), 91 email: formData.get('email'), 92 csrf_token_newsletter: newToken, 93 lang: formData.get('lang') 94 }), 95 headers: responseHeaders 96 }); 97 98 const retryResponseText = await retryResponse.text(); 99 let retryData; 100 try { 101 retryData = JSON.parse(retryResponseText); 102 showResponseMessage(wrapper, retryData.message || 'Inscription réussie.'); 103 form.reset(); 104 } catch (e) { 105 showResponseMessage(wrapper, retryResponseText || 'Erreur inattendue après refresh token.'); 106 } 107 108 form.isSubmitting = false; 109 return; 110 } 111 112 showResponseMessage(wrapper, data.message || 'Email already exist'); 113 form.reset(); 114 115 } catch (error) { 116 //console.error('Error:', error); 117 //showResponseMessage(wrapper, 'An error occurred, please try again.'); 118 } finally { 119 form.isSubmitting = false; 120 } 121 }); 122 });
123}); 124 125document.addEventListener('DOMContentLoaded', function() { 126 const domains = [ 127 "gmail.com", "gmail.fr", "yahoo.fr", "yahoo.com", "icloud.com", "me.com", 128 "hotmail.fr", "hotmail.com", "outlook.fr", "outlook.com", "msn.com", "live.fr", 129 "orange.fr", "wanadoo.fr", "free.fr", "sfr.fr", "neuf.fr", "bbox.fr", 130 "laposte.net", "gmx.fr", "proton.me" 131 ]; 132 133 const newsletterForms = document.querySelectorAll('.mailing-list-form'); 134 135 newsletterForms.forEach(form => { 136 const emailInput = form.querySelector('input[name="email"]'); 137 if (!emailInput) return; 138 139 let suggestionList = form.querySelector('.email-suggestions'); 140 if (!suggestionList) { 141 suggestionList = document.createElement('div'); 142 suggestionList.className = 'email-suggestions'; 143 emailInput.parentNode.insertBefore(suggestionList, emailInput.nextSibling); 144 } 145 146 // --- GESTION CLAVIER : Initialisation de l'index --- 147 let activeIndex = -1; 148 149 emailInput.addEventListener('input', function() { 150 const val = this.value; 151 const atIndex = val.indexOf("@"); 152 activeIndex = -1; // Reset l'index à chaque modification 153 154 if (atIndex > -1) { 155 const prefix = val.substring(0, atIndex); 156 const query = val.substring(atIndex + 1); 157 const matches = domains.filter(d => d.startsWith(query)); 158 159 if (matches.length > 0 && prefix.length > 0) { 160 suggestionList.innerHTML = matches.map(d => `<div>${prefix}@${d}</div>`).join(""); 161 suggestionList.style.display = "block"; 162 } else { 163 suggestionList.style.display = "none"; 164 } 165 } else { 166 suggestionList.style.display = "none"; 167 } 168 }); 169 170 // --- GESTION CLAVIER : Navigation et Validation --- 171 emailInput.addEventListener('keydown', function(e) { 172 const items = suggestionList.querySelectorAll('div'); 173 if (suggestionList.style.display === "none" || items.length === 0) return; 174 175 if (e.key === "ArrowDown") { 176 e.preventDefault(); 177 activeIndex = (activeIndex + 1) % items.length; 178 updateSelection(items); 179 } else if (e.key === "ArrowUp") { 180 e.preventDefault(); 181 activeIndex = (activeIndex - 1 + items.length) % items.length; 182 updateSelection(items); 183 } else if (e.key === "Enter" && activeIndex > -1) { 184 e.preventDefault(); 185 items[activeIndex].click(); // Utilise ta logique de clic existante 186 } else if (e.key === "Escape") { 187 suggestionList.style.display = "none"; 188 } 189 }); 190 191 function updateSelection(items) { 192 items.forEach((item, i) => { 193 // Style minimal pour le focus clavier (modifiable en CSS via .active) 194 item.style.backgroundColor = (i === activeIndex) ? "#f0f0f0" : ""; 195 }); 196 } 197 198 suggestionList.addEventListener('click', function(e) { 199 if (e.target.tagName === 'DIV' || e.target.parentNode.className === 'email-suggestions') { 200 emailInput.value = e.target.innerText; 201 suggestionList.style.display = "none"; 202 emailInput.focus(); 203 } 204 }); 205 }); 206 207 document.addEventListener('click', function(e) { 208 if (!e.target.classList.contains('email-suggestions') && e.target.name !== 'email') { 209 document.querySelectorAll('.email-suggestions').forEach(el => el.style.display = 'none'); 210 } 211 }); 212});
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.