1document.addEventListener('DOMContentLoaded', function() { 2 // Only run on contact page 3 const form = document.getElementById('contact-form'); 4 const notification = document.getElementById('captcha-notification'); 5 if (!form) { 6 return; 7 } 8 9 if(notification) { 10 notification.classList.add('d-none'); 11 } 12 13 // Endpoint is emitted by BewedCaptcha::hookDisplayHeader(). 14 if (typeof bewedCaptchaEndpoint === 'undefined') { 15 console.error('bewedCaptchaEndpoint not defined'); 16 return; 17 } 18 19 let isSubmitting = false; 20 const submitButton = document.getElementById('contact-form-submit'); 21 const originalButtonText = submitButton ? submitButton.innerHTML : 'Send'; 22 23 // Add progress indicator element 24 const progressIndicator = document.createElement('div'); 25 progressIndicator.id = 'captcha-progress'; 26 progressIndicator.style.display = 'none'; 27 progressIndicator.style.marginTop = '10px'; 28 progressIndicator.style.textAlign = 'center'; 29 progressIndicator.style.color = '#666'; 30 if (submitButton && submitButton.parentNode) { 31 submitButton.parentNode.insertBefore(progressIndicator, submitButton); 32 } 33 34 if (form && submitButton) { 35 form.addEventListener('submit', async function(e) { 36 // Skip if already submitting or if this is a programmatic submit after captcha 37 if (isSubmitting || form.dataset.captchaSolved === 'true') { 38 return; 39 } 40 41 e.preventDefault(); 42 isSubmitting = true; 43 44 try { 45 // Show progress 46 submitButton.innerHTML = bewedCaptchaProcessing; 47 submitButton.disabled = true; 48 49 // widget.js is loaded with `defer`, so it has already run by now. 50 // If it failed to load, fall through to the catch below. 51 if (typeof window.Cap === 'undefined') { 52 throw new Error('cap widget script not loaded'); 53 } 54 55 // Solve captcha 56 const cap = new window.Cap({apiEndpoint: bewedCaptchaEndpoint}); 57 const solution = await cap.solve(); 58 59 // Add token to form 60 let tokenInput = form.querySelector('input[name="cap_token"]'); 61 if (!tokenInput) { 62 tokenInput = document.createElement('input'); 63 tokenInput.type = 'hidden'; 64 tokenInput.name = 'cap_token'; 65 form.appendChild(tokenInput); 66 } 67 tokenInput.value = solution.token; 68 69 // Mark captcha as solved and submit form 70 form.dataset.captchaSolved = 'true'; 71 submitButton.innerHTML = bewedCaptchaSending; 72 // Submit the form programmatically 73 form.submit(); 74 75 } catch (error) { 76 77 // Reset form state 78 submitButton.innerHTML = originalButtonText; 79 submitButton.disabled = false; 80 isSubmitting = false; 81 form.dataset.captchaSolved = 'false'; 82 if(notification) { 83 notification.classList.remove('d-none'); 84 } 85 } 86 }); 87 } 88});
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.