1function cfturnstile_init_elementor_forms() { 2 var settings = window.cfturnstileElementorSettings || {}; 3 var sitekey = settings.sitekey || ''; 4 var position = settings.position || 'before'; 5 var mode = settings.mode || 'turnstile'; 6 var recaptchaSiteKey = settings.recaptchaSiteKey || ''; 7 8 var elementorForms = document.querySelectorAll('.elementor-form:not(.cft-processed)'); 9 elementorForms.forEach(function(form, index) { 10 if (form.querySelector('.cf-turnstile') || form.querySelector('.g-recaptcha') || form.querySelector('input[name="cfturnstile_failsafe"]')) { 11 form.classList.add('cft-processed'); 12 return; 13 } 14 15 var submitButton = form.querySelector('button[type="submit"]'); 16 17 // Failsafe modes: inject marker and optionally reCAPTCHA widget. 18 if (submitButton && (mode === 'allow' || mode === 'recaptcha')) { 19 var marker = document.createElement('input'); 20 marker.type = 'hidden'; 21 marker.name = 'cfturnstile_failsafe'; 22 marker.value = mode; 23 form.appendChild(marker); 24 25 if (mode === 'recaptcha' && recaptchaSiteKey) { 26 var recaptchaDiv = document.createElement('div'); 27 recaptchaDiv.className = 'g-recaptcha'; 28 recaptchaDiv.setAttribute('data-sitekey', recaptchaSiteKey); 29 recaptchaDiv.style.cssText = 'display: block; margin: 10px 0 15px 0; width: 100%;'; 30 31 if (position === 'after') { 32 submitButton.parentNode.insertBefore(recaptchaDiv, submitButton.nextSibling); 33 } else if (position === 'afterform') { 34 form.appendChild(recaptchaDiv); 35 } else { 36 submitButton.parentNode.insertBefore(recaptchaDiv, submitButton); 37 } 38 } 39 40 form.classList.add('cft-processed'); 41 return; 42 } 43 44 if (submitButton && window.turnstile && sitekey) { 45 var turnstileDiv = document.createElement('div'); 46 turnstileDiv.className = 'elementor-turnstile-field cf-turnstile'; 47 turnstileDiv.id = 'cf-turnstile-elementor-fallback-' + index; 48 turnstileDiv.style.cssText = 'display: block; margin: 10px 0 15px 0; width: 100%;'; 49 50 if (position === 'after') { 51 submitButton.parentNode.insertBefore(turnstileDiv, submitButton.nextSibling); 52 } else if (position === 'afterform') { 53 form.appendChild(turnstileDiv); 54 } else { 55 submitButton.parentNode.insertBefore(turnstileDiv, submitButton); 56 } 57 58 turnstile.render('#cf-turnstile-elementor-fallback-' + index, { 59 sitekey: sitekey, 60 theme: settings.theme || 'auto', 61 callback: function(token) { 62 if (typeof turnstileElementorCallback === 'function') { 63 turnstileElementorCallback(token); 64 } 65 } 66 }); 67 68 form.classList.add('cft-processed'); 69 } 70 }); 71} 72 73document.addEventListener('DOMContentLoaded', function() { 74 cfturnstile_init_elementor_forms(); 75}); 76 77// Listen to Elementor frontend init to handle cached elements 78document.addEventListener('elementor/frontend/init', function() { 79 cfturnstile_init_elementor_forms(); 80}); 81 82// Handle form submit button clicks for re-rendering 83document.addEventListener('click', function(event) { 84 if (event.target.matches('.elementor-form button[type="submit"]')) { 85 var settings = window.cfturnstileElementorSettings || {}; 86 var mode = settings.mode || 'turnstile'; 87 if (mode !== 'turnstile' || !window.turnstile) { 88 return; 89 } 90 var submittedForm = event.target.closest('.elementor-form'); 91 92 setTimeout(function() { 93 if (!window.turnstile) { 94 return; 95 } 96 turnstile.remove('.elementor-form .cf-turnstile'); 97 turnstile.render('.elementor-form .cf-turnstile', { 98 sitekey: cfturnstileElementorSettings.sitekey, 99 callback: 'turnstileCallback', 100 theme: cfturnstileElementorSettings.theme || 'auto' 101 }); 102 }, 2000); 103 } 104}); 105 106// Handle Elementor popup show events 107document.addEventListener('elementor/popup/show', function(event) { 108 setTimeout(function() { 109 var settings = window.cfturnstileElementorSettings || {}; 110 var mode = settings.mode || 'turnstile'; 111 if (mode !== 'turnstile' || !window.turnstile) { 112 return; 113 } 114 var popupTurnstile = document.querySelector('.elementor-popup-modal .cf-turnstile'); 115 if (!popupTurnstile) { 116 return; 117 } 118 119 var failedText = document.querySelector('.cf-turnstile-failed-text'); 120 if (failedText) { 121 failedText.style.display = 'none'; 122 } 123 124 turnstile.remove('.elementor-popup-modal .cf-turnstile'); 125 126 turnstile.render('.elementor-popup-modal .cf-turnstile', { 127 sitekey: cfturnstileElementorSettings.sitekey, 128 callback: 'turnstileCallback', 129 theme: cfturnstileElementorSettings.theme || 'auto' 130 });
131 132 popupTurnstile.style.marginTop = '-5px'; 133 popupTurnstile.style.marginBottom = '20px'; 134 135 }, 1000); 136});
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.