PageSourceSearch

https://www5.usp.br/wp-content/plugins/simple-cloudflare-turnstile…/elementor-forms.js?x34176&ver=2.8

js usp.br collected 2026-09-24 06:28:08 UTC 10,876 bytes, 250 lines download raw bytes

1function cfturnstile_elementor_set_submit(btn, enabled) {
2  if (!btn) return;
3  btn.style.pointerEvents = enabled ? 'auto' : 'none';
4  btn.style.opacity     = enabled ? '1'    : '0.5';
5}
6
7function cfturnstile_init_elementor_forms() {
8  var settings = window.cfturnstileElementorSettings || {};
9  var sitekey = settings.sitekey || '';
10  var position = settings.position || 'before';
11  var mode = settings.mode || 'turnstile';
12  var recaptchaSiteKey = settings.recaptchaSiteKey || '';
13  var disableSubmit = settings.disableSubmit || false;
14  var widgetSize = settings.size || 'normal';
15  
16  if (!window._cft_elementor_idx) { window._cft_elementor_idx = 0; }
17  var elementorForms = document.querySelectorAll('.elementor-form:not(.cft-processed)');
18  elementorForms.forEach(function(form) {
19    var index = window._cft_elementor_idx++;
20    if (form.querySelector('.cf-turnstile') || form.querySelector('.g-recaptcha') || form.querySelector('input[name="cfturnstile_failsafe"]')) {
21      form.classList.add('cft-processed');
22      return;
23    }
24    
25    var submitButton = form.querySelector('button[type="submit"]');
26
27    // Failsafe modes: inject marker and optionally reCAPTCHA widget.
28    if (submitButton && (mode === 'allow' || mode === 'recaptcha')) {
29      var marker = document.createElement('input');
30      marker.type = 'hidden';
31      marker.name = 'cfturnstile_failsafe';
32      marker.value = mode;
33      form.appendChild(marker);
34
35      if (mode === 'recaptcha' && recaptchaSiteKey) {
36        var recaptchaDiv = document.createElement('div');
37        recaptchaDiv.className = 'g-recaptcha';
38        recaptchaDiv.setAttribute('data-sitekey', recaptchaSiteKey);
39        recaptchaDiv.style.cssText = 'display: block; margin: 10px 0 15px 0; width: 100%;';
40
41        if (position === 'after') {
42          submitButton.parentNode.insertBefore(recaptchaDiv, submitButton.nextSibling);
43        } else if (position === 'afterform') {
44          form.appendChild(recaptchaDiv);
45        } else {
46          submitButton.parentNode.insertBefore(recaptchaDiv, submitButton);
47        }
48      }
49
50      form.classList.add('cft-processed');
51      return;
52    }
53
54    if (submitButton && window.turnstile && sitekey) {
55      // Disable submit button if option is enabled
56      if (disableSubmit) {
57        cfturnstile_elementor_set_submit(submitButton, false);
58      }
59
60      var labelEl = null;
61      if (settings.labelEnable && settings.labelText) {
62        labelEl = document.createElement('p');
63        labelEl.className = 'cfturnstile-widget-label';
64        labelEl.style.cssText = 'font-size: 14px; margin: 0 0 6px 0; width: 100%;';
65        if ((settings.appearance || 'always') === 'interaction-only') {
66          labelEl.className += ' cfturnstile-widget-label-interaction';
67          labelEl.style.display = 'none';
68        }
69        var smallEl = document.createElement('small');
70        smallEl.textContent = settings.labelText;
71        labelEl.appendChild(smallEl);
72      }
73
74      var turnstileDiv = document.createElement('div');
75      turnstileDiv.className = 'elementor-turnstile-field cf-turnstile';
76      turnstileDiv.id = 'cf-turnstile-elementor-fallback-' + index;
77      turnstileDiv.style.cssText = 'display: block; margin: 10px 0 15px 0; width: 100%;';
78
79      if (position === 'after') {
80        if (labelEl) submitButton.parentNode.insertBefore(labelEl, submitButton.nextSibling);
81        submitButton.parentNode.insertBefore(turnstileDiv, labelEl ? labelEl.nextSibling : submitButton.nextSibling);
82      } else if (position === 'afterform') {
83        if (labelEl) form.appendChild(labelEl);
84        form.appendChild(turnstileDiv);
85      } else {
86        if (labelEl) submitButton.parentNode.insertBefore(labelEl, submitButton);
87        submitButton.parentNode.insertBefore(turnstileDiv, submitButton);
88      }
89      
90      turnstile.render('#cf-turnstile-elementor-fallback-' + index, {
91        sitekey: sitekey,
92        theme: settings.theme || 'auto',
93        size: widgetSize,
94        appearance: settings.appearance || 'always',
95        callback: function(token) {
96          // Re-enable submit button when Turnstile is complete
97          if (disableSubmit && submitButton) {
98            cfturnstile_elementor_set_submit(submitButton, true);
99          }
100          if (typeof turnstileElementorCallback === 'function') {
101            turnstileElementorCallback(token);
102          }
103        },
104        'error-callback': function() {
105          if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
106        },
107        'expired-callback': function() {
108          if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
109        }
110      });
111
112      if (labelEl && labelEl.classList.contains('cfturnstile-widget-label-interaction') && typeof window.cfturnstileInitInteractionLabels === 'function') {
113        window.cfturnstileInitInteractionLabels();
114      }
115
116      form.classList.add('cft-processed');
117    }
118  });
119}
120
121document.addEventListener('DOMContentLoaded', function() {
122  cfturnstile_init_elementor_forms();
123});
124
125// Listen to Elementor frontend init to handle cached elements
126jQuery(window).on('elementor/frontend/init', function() {
127  cfturnstile_init_elementor_forms();
128
129  // Hook into Elementor's widget ready system for forms loaded dynamically (e.g. in popups)
130  if (window.elementorFrontend && elementorFrontend.hooks) {
131    elementorFrontend.hooks.addAction('frontend/element_ready/form.default', function($scope) {
132      cfturnstile_init_elementor_forms();
133    });
134    elementorFrontend.hooks.addAction('frontend/element_ready/login.default', function($scope) {
135      cfturnstile_init_elementor_forms();
136    });
137  }
138});
139
140// Re-render Turnstile only after Elementor reports a submit error (e.g. failed validation)
141function cfturnstile_elementor_rerender(form) {
142  if (!form || !window.turnstile) return;
143  var settings = window.cfturnstileElementorSettings || {};
144  var widget = form.querySelector('.cf-turnstile');
145  if (!widget) return;
146  var submitButton = form.querySelector('button[type="submit"]');
147  var disableSubmit = settings.disableSubmit || false;
148  if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
149  try { turnstile.remove(widget); } catch (e) {}
150  turnstile.render(widget, {
151    sitekey: settings.sitekey,
152    theme: settings.theme || 'auto',
153    size: settings.size || 'normal',
154    appearance: settings.appearance || 'always',
155    callback: function(token) {
156      if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, true); }
157      if (typeof turnstileElementorCallback === 'function') {
158        turnstileElementorCallback(token);
159      }
160    },
161    'error-callback': function() {
162      if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
163    },
164    'expired-callback': function() {
165      if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
166    }
167  });
168}
169
170jQuery(document).on('submit_error submit_success', '.elementor-form', function() {
171  var settings = window.cfturnstileElementorSettings || {};
172  if ((settings.mode || 'turnstile') !== 'turnstile') return;
173  cfturnstile_elementor_rerender(this);
174});
175
176// Block submission until Turnstile is completed (client-side guard).
177// Server-side validation in cfturnstile_elementor_check is the source of truth;
178// this just avoids a wasted round-trip and gives immediate feedback.
179document.addEventListener('submit', function(event) {
180  var form = event.target;
181  if (!form.classList || !form.classList.contains('elementor-form')) return;
182  var settings = window.cfturnstileElementorSettings || {};
183  if ((settings.mode || 'turnstile') !== 'turnstile' || !window.turnstile) return;
184
185  var widget = form.querySelector('.cf-turnstile');
186  if (!widget) return;
187  var token = '';
188  try { token = turnstile.getResponse(widget) || ''; } catch (e) {}
189  if (!token) {
190    var responseInput = form.querySelector('[name="cf-turnstile-response"]');
191    token = responseInput ? (responseInput.value || '') : '';
192  }
193  if (!token) {
194    event.preventDefault();
195    event.stopImmediatePropagation();
196    try { widget.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch (e) {}
197  }
198}, true);
199
200// Handle Elementor popup show events (jQuery event - must use jQuery to listen)
201jQuery(document).on('elementor/popup/show', function(event, id, instance) {
202  setTimeout(function() {
203    // First, inject Turnstile into any unprocessed forms inside the popup
204    cfturnstile_init_elementor_forms();
205
206    var settings = window.cfturnstileElementorSettings || {};
207    var mode = settings.mode || 'turnstile';
208    var disableSubmit = settings.disableSubmit || false;
209    if (mode !== 'turnstile' || !window.turnstile) {
210      return;
211    }
212
213    // Re-render all Turnstile widgets inside popup modals (they need explicit render after DOM insertion)
214    var popupTurnstiles = document.querySelectorAll('.elementor-popup-modal .cf-turnstile');
215    popupTurnstiles.forEach(function(widget) {
216      var failedText = widget.parentNode ? widget.parentNode.querySelector('.cf-turnstile-failed-text') : null;
217      if (failedText) {
218        failedText.style.display = 'none';
219      }
220
221      // Find the form and submit button for this widget
222      var form = widget.closest('.elementor-form');
223      var submitButton = form ? form.querySelector('button[type="submit"]') : null;
224
225      // Disable submit button if option is enabled
226      if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
227      
228      turnstile.remove(widget);
229      turnstile.render(widget, {
230        sitekey: cfturnstileElementorSettings.sitekey,
231        appearance: cfturnstileElementorSettings.appearance || 'always',
232        callback: function(token) {
233          // Re-enable submit button when Turnstile is complete
234          if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, true); }
235          if (typeof turnstileElementorCallback === 'function') {
236            turnstileElementorCallback(token);
237          }
238        },
239        'error-callback': function() {
240          if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
241        },
242        'expired-callback': function() {
243          if (disableSubmit && submitButton) { cfturnstile_elementor_set_submit(submitButton, false); }
244        },
245        theme: cfturnstileElementorSettings.theme || 'auto',
246        size: cfturnstileElementorSettings.size || 'normal'
247      });
248    });
249  }, 500);
250});

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.