Files
kupshop/web/common/static/wpj/wpj.recaptcha.js
2025-08-02 16:30:27 +02:00

153 lines
4.4 KiB
JavaScript

/* global grecaptcha, onRecaptchaLoad */
window.loadInvisibleRecaptchaScript = function() {
var url = 'https://www.google.com/recaptcha/api.js?render=explicit&onload=onInvisibleRecaptchaLoad';
$.getScript(url);
}
/* init recaptcha render on script load */
window.onInvisibleRecaptchaLoad = function() {
if (typeof grecaptcha !== 'undefined') {
$('[data-recaptcha="btn"]').each(function() {
var el = this;
var $form = $(this).closest('form');
var siteKey = $(this).data('sitekey');
grecaptcha.render(el, {
sitekey: siteKey,
callback: function(token) {
$form.find('.g-recaptcha-response').val(token);
$form.submit();
grecaptcha.reset();
}
});
});
}
};
/* lazy load recaptcha on first form input */
$('body').one('input', 'form[data-recaptcha-lazy] input', function() {
if (typeof grecaptcha === 'undefined') {
window.loadInvisibleRecaptchaScript();
} else {
window.onInvisibleRecaptchaLoad();
}
});
window.wpjCaptchaLoaded = function () {
wpj.onReady.push(function() {
// Hm ... bohužel to musím opozdit o vteřinu, protože pokud nebyl daný kus HTML vidět, nerenderovalo se to správně.
// A když je to uvnitř focusu, spustí se JS když se script načte, ale je třeba spustit render až když se skutečně zobrazí
setTimeout(function() {
window.wpj.captcha.onWpjCaptchaLoad();
}, 1000);
});
};
// Cloudflare CAPTCHA
window.wpj.captcha = {
_isFormSubmitting: false,
_formRef: null,
onWpjCaptchaLoad: function () {
if (typeof turnstile === 'undefined') {
return;
}
$('.wpj-captcha').each(function (index, el) {
if (!$(this).is(':empty')) {
return;
}
turnstile.render(el, {
"response-field-name": 'wpj-captcha-response',
callback: function(token) {
console.log("Challenge Success", token);
},
});
});
},
onWpjLazyCaptchaLoad: function ($form) {
if (typeof turnstile === 'undefined') {
return;
}
let action = $form.data('wpj-captcha-lazy') || 'form';
let $btn = $form.find('[data-wpj-captcha="btn"]');
const submitButton = $form.find('[type="submit"]');
if (!$btn.length) {
$btn = $('<div data-wpj-captcha="btn"></div>');
$form.append($btn);
}
if (!$btn.is(':empty')) {
return;
}
wpj.captcha._formRef = $form;
let token = turnstile.render($btn[0], {
action: action,
sitekey: window.wpj.data.captcha.sitekey,
"response-field-name": 'wpj-captcha-invisible-response',
callback: function(token) {
console.log("Challenge Success", token);
if (wpj.captcha._isFormSubmitting) {
wpj.captcha._isFormSubmitting = false;
wpj.captcha._formRef.submit();
turnstile.reset($btn[0]);
turnstile.execute($btn[0]);
}
},
});
$form.on('submit', function (e) {
// disable submit button to prevent multiple submits
Array.from(submitButton).forEach((button) => ($(button).prop('disabled', true)));
if (!turnstile.getResponse(token)) {
e.preventDefault();
wpj.captcha._isFormSubmitting = true;
turnstile.reset(token);
turnstile.execute(token);
}
});
},
retrySubmit: function($form, token) {
if(typeof turnstile === 'undefined') {
return;
}
setTimeout(() => {
if (!turnstile.getResponse(token)) {
wpj.captcha.retrySubmit();
}else {
$($form).submit();
}
}, 1000);
},
loadCaptchaScript: function(onSuccess) {
var url = 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=wpjCaptchaLoaded';
$.getScript(url, onSuccess);
},
initializeCaptcha: function ($form) {
if (typeof turnstile === 'undefined') {
wpj.captcha.loadCaptchaScript(() => wpj.captcha.onWpjLazyCaptchaLoad($form));
} else {
wpj.captcha.onWpjLazyCaptchaLoad($form);
}
}
};
/* lazy load recaptcha on first form input */
$('body').one('input', 'form[data-wpj-captcha-lazy] input', function(e) {
let $form = $(this).closest('form');
wpj.captcha.initializeCaptcha($form);
});