(function(){ let RECAPTCHA_TOKEN_NAME = "recaptcha"; let RECAPTCHA_TOKEN_TTL = 90000; let RECAPTCHA_API_CLIENT_KEY = "6LddVcoUAAAAAFlmmt09ROXX7ofVMgBJSPg3U1c1"; let RECAPTCHA_API_CLIENT_URL = "https://www.google.com/recaptcha/api.js?render=6LddVcoUAAAAAFlmmt09ROXX7ofVMgBJSPg3U1c1"; if (typeof jQuery === 'undefined') { alert(['Ошибка подключения reCAPTCHA.', 'Не подключена библиотека jQuery.'].join('\n')); } else { let tokenCache = '', tokenTime = 0; $.getScript(RECAPTCHA_API_CLIENT_URL, function() { $(function() { if (!RECAPTCHA_API_CLIENT_KEY) { alert(['Ошибка подключения reCAPTCHA.', 'Не задан ключ для текущего домена.'].join('\n')); } let forms = $('form.recaptcha3'); forms .append('') .submit(function(event) { let form = $(this); submitForm(form, event); }); function getValidToken() { let lifetime = Date.now() - tokenTime; let outdated = lifetime > RECAPTCHA_TOKEN_TTL; return !outdated ? tokenCache : ''; } function requestToken(callback) { let token = getValidToken(); if (token) { if (callback) { callback(token); } return; } try { grecaptcha.ready(function() { grecaptcha.execute(RECAPTCHA_API_CLIENT_KEY, {action: 'common'}) .then(function(token) { tokenCache = token; tokenTime = Date.now(); if (callback) { callback(tokenCache); } }); }); } catch (error) { error = 'Ошибка подключения к серверу reCAPTCHA.\n' + error; alert(error); } } function submitForm(form, event) { let tokenInput = form.find('input[name="' + RECAPTCHA_TOKEN_NAME + '"]'); let submitButton = form.find('[type="submit"]').eq(0); let token = getValidToken(); let assigned = (token === tokenInput.val()); let ready = (token && assigned); if (!ready) { event.preventDefault(); formSetProcessing(forms, true); requestToken(function(token) { formSetProcessing(forms, false); tokenInput.val(token); setTimeout(function() { submitButton.click(); }, 100); }); } } function elementsSetPropertiesStyles(elements, properties, styles) { properties = properties || {}; styles = styles || {}; $(elements).each(function() { let element = this; for (let key in properties) { let backupKey = 'backup_property_' + key; if (!element.dataset[backupKey]) { element.dataset[backupKey] = JSON.stringify(element[key]); } element[key] = properties[key]; } for (let key in styles) { let styleKey = 'backup_style_' + key; if (!element.dataset[styleKey]) { element.dataset[styleKey] = JSON.stringify(element.style[key]); } element.style[key] = styles[key]; } }); } function elementsRestorePropertiesStyles(elements) { $(elements).each(function() { let element = this; for (let key in element.dataset) { let value = undefined; try { value = JSON.parse(element.dataset[key]); } catch(e) { } let propertyKey = (key.match(/^backup_property_(.*)/) || [])[1]; if (propertyKey) { element[propertyKey] = value; delete element.dataset[key]; } let styleKey = (key.match(/^backup_style_(.*)/) || [])[1]; if (styleKey) { element.style[styleKey] = value; delete element.dataset[key]; } } }); } function formSetProcessing(form, processing) { let cursor = 'wait'; let opacity = '0.5'; let body = $('document.body'); let submit = form.find('[type="submit"]'); let controls = form.find('input, textarea, select, button'); if (processing) { elementsSetPropertiesStyles(body, {}, {cursor: cursor}); elementsSetPropertiesStyles(form, {disabled: true}, {opacity: opacity}); elementsSetPropertiesStyles(submit, {disabled: true}, {cursor: cursor}); elementsSetPropertiesStyles(controls, {readonly: true}, {cursor: cursor}); } else { elementsRestorePropertiesStyles(body); elementsRestorePropertiesStyles(form); elementsRestorePropertiesStyles(submit); elementsRestorePropertiesStyles(controls); } } requestToken(function(token) { forms.find('input[name="' + RECAPTCHA_TOKEN_NAME + '"]').val(token); }); }); }); } })();