1var WEBFORM_MAX_TOTAL_FILE_SIZE_KB = 25000; 2 3function formatWebformLimitMb(maxSizeKb) { 4 var mb = Number(maxSizeKb) / 1000; 5 if (!Number.isFinite(mb) || mb <= 0) { 6 mb = WEBFORM_MAX_TOTAL_FILE_SIZE_KB / 1000; 7 } 8 return (Math.round(mb * 100) / 100).toString().replace(/\.0+$/, '').replace(/(\.\d*[1-9])0+$/, '$1'); 9} 10 11function getWebformFileSizeErrorText(maxSizeKb) { 12 return 'ÐбÑий Ð²ÐµÑ Ñайлов не более ' + formatWebformLimitMb(maxSizeKb) + ' мб'; 13} 14 15function renderWebformFileSizeError(form, message) { 16 if (!form || !form.querySelector) return; 17 18 var attachedError = form.querySelector('#attachedError, #attachedErrorBreeders'); 19 if (attachedError) { 20 attachedError.innerHTML = message; 21 attachedError.style.display = 'block'; 22 attachedError.style.color = '#E33F3F'; 23 return; 24 } 25 26 var fileInput = form.querySelector('input[type="file"]'); 27 var fileContainer = fileInput && fileInput.closest ? fileInput.closest('div[title]') : null; 28 var fileError = fileContainer ? fileContainer.querySelector('.js-form-error') : null; 29 if (fileError) { 30 fileError.innerHTML = message; 31 fileError.style.display = 'block'; 32 fileError.style.color = '#E33F3F'; 33 return; 34 } 35 36 var fallback = form.querySelector('.js-form-error'); 37 if (fallback) { 38 fallback.innerHTML = message; 39 fallback.style.display = 'block'; 40 fallback.style.color = '#E33F3F'; 41 } 42} 43 44function initWebformFileSizeHint() { 45 var forms = document.querySelectorAll('.js-form-container form'); 46 if (!forms.length) return; 47 48 forms.forEach(function (form) { 49 if (!form.querySelector('input[type="file"]')) return; 50 var currentMaxSizeKb = WEBFORM_MAX_TOTAL_FILE_SIZE_KB; 51 var fileInputs = form.querySelectorAll('input[type="file"]'); 52 for (var i = 0; i < fileInputs.length; i++) { 53 var inputLimitKb = parseFloat(fileInputs[i].dataset ? fileInputs[i].dataset.maxsizekb : ''); 54 if (!Number.isNaN(inputLimitKb) && inputLimitKb > 0) { 55 currentMaxSizeKb = inputLimitKb; 56 break; 57 } 58 } 59 var text = getWebformFileSizeErrorText(currentMaxSizeKb); 60 var attachedError = form.querySelector('#attachedError, #attachedErrorBreeders'); 61 if (attachedError) { 62 attachedError.innerHTML = text; 63 attachedError.style.display = 'block'; 64 attachedError.style.color = '#262626'; 65 return; 66 } 67 68 var fileInput = form.querySelector('input[type="file"]'); 69 var fileContainer = fileInput && fileInput.closest ? fileInput.closest('div[title]') : null; 70 var fileError = fileContainer ? fileContainer.querySelector('.js-form-error') : null; 71 if (fileError) { 72 fileError.innerHTML = text; 73 fileError.style.display = 'block'; 74 fileError.style.color = '#262626'; 75 } 76 }); 77} 78 79document.addEventListener('DOMContentLoaded', initWebformFileSizeHint); 80 81function validateWebformFilesSize(form) { 82 if (!form || !form.querySelectorAll) return {valid: true}; 83 84 var fileInputs = form.querySelectorAll('input[type="file"]'); 85 if (!fileInputs.length) return {valid: true}; 86 87 var maxSizeKb = WEBFORM_MAX_TOTAL_FILE_SIZE_KB; 88 for (var i = 0; i < fileInputs.length; i++) { 89 var inputLimitKb = parseFloat(fileInputs[i].dataset ? fileInputs[i].dataset.maxsizekb : ''); 90 if (!Number.isNaN(inputLimitKb) && inputLimitKb > 0) { 91 maxSizeKb = inputLimitKb; 92 break; 93 } 94 } 95 96 var totalBytes = 0; 97 fileInputs.forEach(function (fileInput) { 98 if (!fileInput.files || !fileInput.files.length) return; 99 for (var idx = 0; idx < fileInput.files.length; idx++) { 100 totalBytes += fileInput.files[idx].size || 0; 101 } 102 }); 103 104 var totalKb = Math.round(totalBytes / 1000); 105 if (totalKb > maxSizeKb) { 106 return {valid: false, message: getWebformFileSizeErrorText(maxSizeKb)}; 107 } 108 109 return {valid: true}; 110} 111 112if (!window.jQuery) { 113 console.warn('[forms] jQuery not found; using native submit2 handler'); 114 var captchaDebugEnabled = !!(window.CAPTCHA_CONFIG && window.CAPTCHA_CONFIG.debug); 115 116 function appendCaptchaData(form, data) { 117 if (!form || !form.dataset || !data) return; 118 var provider = form.dataset.captchaProvider || ''; 119 var token = form.dataset.captchaToken || ''; 120 if (!token) return; 121 data.set('captcha-token', token); 122 if (provider) { 123 data.set('captcha-provider', provider); 124 } 125 if (provider === 'google') { 126 data.set('g-recaptcha-response', token); 127 } else if (provider === 'yandex') { 128 data.set('smart-token', token); 129 } 130 } 131 132 function toggleWebformSubmitLoader(form, isLoading) { 133 if (!form || !form.querySelector) return; 134 var submitBtn = form.querySelector('input[name="web_form_submit"]'); 135 if (!submitBtn) return; 136 137 if (isLoading) { 138 if (submitBtn.dataset.loaderActive === '1') return; 139 submitBtn.dataset.loaderActive = '1'; 140 submitBtn.dataset.loaderValue = submitBtn.value || ''; 141 submitBtn.dataset.loaderWasDisabled = submitBtn.disabled ? '1' : '0'; 142 submitBtn.dataset.loaderColor = submitBtn.style.color || ''; 143 144 submitBtn.value = 'ÐагÑÑзка'; 145 submitBtn.style.backgroundImage = 'url("/local/templates/premier_ru/img/loader.gif")'; 146 submitBtn.style.backgroundPosition = 'calc(50% + 60px) center'; 147 submitBtn.style.backgroundRepeat = 'no-repeat'; 148 submitBtn.style.backgroundSize = '16px 16px'; 149 submitBtn.style.backgroundColor = '#fff'; 150 submitBtn.style.color = '#000'; 151 submitBtn.disabled = true; 152 return; 153 } 154 155 if (submitBtn.dataset.loaderActive !== '1') return; 156 submitBtn.dataset.loaderActive = '0'; 157 submitBtn.value = submitBtn.dataset.loaderValue || submitBtn.value; 158 submitBtn.style.backgroundImage = ''; 159 submitBtn.style.backgroundPosition = ''; 160 submitBtn.style.backgroundRepeat = ''; 161 submitBtn.style.backgroundSize = ''; 162 submitBtn.style.backgroundColor = ''; 163 submitBtn.style.color = submitBtn.dataset.loaderColor || ''; 164 submitBtn.disabled = submitBtn.dataset.loaderWasDisabled === '1'; 165 } 166 167 document.addEventListener('submit2', function (e) { 168 var form = e.target; 169 if (!form || !form.matches || !form.matches('.js-form-container form')) return; 170 171 var method = form.getAttribute('method') || 'POST'; 172 var action = '/local/ajax/webform_submit.php'; 173 var data = new FormData(form); 174 var popup = form.closest('.i-popup'); 175 var popupId = popup ? popup.id : null; 176 177 178 var submitBtn = form.querySelector('input[type=submit]'); 179 if (submitBtn) { 180 data.append(submitBtn.name, submitBtn.value); 181 } 182 appendCaptchaData(form, data); 183 184 var filesValidation = validateWebformFilesSize(form); 185 if (!filesValidation.valid) { 186 renderWebformFileSizeError(form, filesValidation.message); 187 return; 188 } 189 190 toggleWebformSubmitLoader(form, true); 191 192 function renderErrors(errors) { 193 Object.keys(errors || {}
193).forEach(function (key) { 194 var value = errors[key]; 195 var input = form.querySelector('div[title="' + key + '"]'); 196 if (input) { 197 input.classList.add('is-error'); 198 var span = input.querySelector('.js-form-error'); 199 if (span) { 200 span.innerHTML = value; 201 span.style.display = 'block'; 202 } 203 } else if (value) { 204 var fallback = form.querySelector('.js-form-error'); 205 if (fallback) { 206 fallback.innerHTML = value; 207 fallback.style.display = 'block'; 208 } 209 } 210 }); 211 } 212 213 fetch(action, { 214 method: method, 215 body: data, 216 headers: {'X-Requested-With': 'XMLHttpRequest'} 217 }).then(function (res) { 218 return res.json(); 219 }).then(function (data) { 220 if (captchaDebugEnabled && data && data.captcha_debug) { 221 console.info('[captcha][server]', data.captcha_debug); 222 } 223 if (data.success === false) { 224 renderErrors(data.errors || {}); 225 refreshCaptchaToken(popupId); 226 } else if (data.success === true) { 227 document.dispatchEvent(new CustomEvent('webform:submit-success', { 228 detail: { 229 popupId: popupId || null, 230 webFormId: form.querySelector('[name="WEB_FORM_ID"]') ? form.querySelector('[name="WEB_FORM_ID"]').value : null, 231 formName: form.getAttribute('name') || null 232 } 233 })); 234 form.reset(); 235 if (e.detail && e.detail.hasOwnProperty('callback')) { 236 e.detail.callback(); 237 } 238 } 239 }).catch(function (err) { 240 console.error('[forms] ajax error (native)', err); 241 }).then(function () { 242 toggleWebformSubmitLoader(form, false); 243 }); 244 }); 245} else { 246 $(document).ready(function () { 247 var forms = findForms(); 248 forms.forEach(function (e) { 249 formSubscribe(e); 250 }); 251 formWeb(); 252 }); 253} 254 255function findForms() { 256 return $('.js-form').toArray(); 257} 258 259function formSubscribe(form) { 260 var popupId = $(form).data('popup-id'); 261 var popup = document.getElementById(popupId); 262 var closePop = popup.querySelector(".i-popup__close"); 263 closePop.addEventListener("click", function () { 264 return closePopup(popupId); 265 }); 266 $(form).on('submit', function (e) { 267 e.preventDefault(); 268 269 var component = $(this).data("c"); 270 var action = $(this).data("action"); 271 var mode = $(this).data("mode"); 272 var errorText = $(this).data("error"); 273 var site = $(this).data('site'); 274 275 var $submitButton = $(':input[type = submit]'); 276 277 let data = $(this).serializeArray(); 278 279 data.push({ 280 name: "language", 281 value: $('html')[0].lang 282 }); 283 284 $submitButton.prop('disabled', true); 285 286 let query = { 287 c: component, 288 action: action, 289 mode: mode, 290 'SITE_ID': site 291 }; 292 let request = $.ajax({ 293 url: '/bitrix/services/main/ajax.php?' + $.param(query, true), 294 method: 'POST', 295 data: { 296 data: data 297 } 298 }); 299 request.done(function (response) { 300 var $error = $(e.target).find(".js-form-error"); 301 $error.parent().removeClass("is-error"); 302 $submitButton.prop('disabled', false); 303 var message = ''; 304 305 if (response.status === "error") { 306 if (response.data != null) { 307 if (response.data.component === component) { 308 response.errors.forEach(function (e) { 309 message += e.message + '<br>'; 310 }) 311 $error.html(message); 312 $error.parent().addClass("is-error"); 313 } 314 } else { 315 $error.html(errorText); 316 $error.parent().addClass("is-error"); 317 } 318 } else if (response.status === "success") { 319 $(form).trigger("reset"); 320 openPopup(popupId); 321 } 322 }); 323 }); 324} 325 326function getBrowserScrollbarWidth() { 327 return window.innerWidth - document.documentElement.getBoundingClientRect().width; 328} 329 330function formWeb() { 331 var captchaDebugEnabled = !!(window.CAPTCHA_CONFIG && window.CAPTCHA_CONFIG.debug); 332 function toggleWebformSubmitLoader(formElement, isLoading) { 333 if (!formElement || !formElement.querySelector) return; 334 var submitBtn = formElement.querySelector('input[name="web_form_submit"]'); 335 if (!submitBtn) return; 336 337 if (isLoading) { 338 if (submitBtn.dataset.loaderActive === '1') return; 339 submitBtn.dataset.loaderActive = '1'; 340 submitBtn.dataset.loaderValue = submitBtn.value || ''; 341 submitBtn.dataset.loaderWasDisabled = submitBtn.disabled ? '1' : '0'; 342 submitBtn.dataset.loaderColor = submitBtn.style.color || ''; 343 344 submitBtn.value = 'ÐагÑÑзка'; 345 submitBtn.style.backgroundImage = 'url("/local/templates/premier_ru/img/loader.gif")'; 346 submitBtn.style.backgroundPosition = 'calc(50% + 60px) center'; 347 submitBtn.style.backgroundRepeat = 'no-repeat'; 348 submitBtn.style.backgroundSize = '16px 16px'; 349 submitBtn.style.backgroundColor = '#fff'; 350 submitBtn.style.color = '#000'; 351 submitBtn.disabled = true; 352 return; 353 } 354 355 if (submitBtn.dataset.loaderActive !== '1') return; 356 submitBtn.dataset.loaderActive = '0'; 357 submitBtn.value = submitBtn.dataset.loaderValue || submitBtn.value; 358 submitBtn.style.backgroundImage = ''; 359 submitBtn.style.backgroundPosition = ''; 360 submitBtn.style.backgroundRepeat = ''; 361 submitBtn.style.backgroundSize = ''; 362 submitBtn.style.backgroundColor = ''; 363 submitBtn.style.color = submitBtn.dataset.loaderColor || ''; 364 submitBtn.disabled = submitBtn.dataset.loaderWasDisabled === '1'; 365 } 366 367 function appendCaptchaData(formElement, data) { 368 if (!formElement || !formElement.dataset || !data) return; 369 var provider = formElement.dataset.captchaProvider || ''; 370 var token = formElement.dataset.captchaToken || ''; 371 if (!token) return; 372 data.set('captcha-token', token); 373 if (provider) { 374 data.set('captcha-provider', provider); 375 } 376 if (provider === 'google') { 377 data.set('g-recaptcha-response', token); 378 } else if (provider === 'yandex') { 379 data.set('smart-token', token); 380 } 381 } 382 383 $(document).on('submit2', '.js-form-container form', function (e) { 384 let form = $(this), 385 method = form.attr('method'), 386 action = '/local/ajax/webform_submit.php', 387 data = new FormData(form.get(0)), 388 popupId = form.parents('.i-popup').attr('id'); 389 390 391 let submitBtn = form.find("input[type=submit]")[0]; 392 if (submitBtn) { 393 data.append(submitBtn.name, submitBtn.value); 394 } 395 appendCaptchaData(form.get(0), data); 396 397 var filesValidation = validateWebformFilesSize(form.get(0)); 398 if (!filesValidation.valid) { 399 renderWebformFileSizeError(form.get(0), filesValidation.message); 400 return; 401 } 402 403 toggleWebformSubmitLoader(form.get(0), true); 404 405 e.preventDefault(); 406 $.ajax({ 407 type: method, 408 url: action, 409 data: data, 410 dataType: "json", 411 headers: {'X-Requested-With': 'XMLHttpRequest'}, 412 processData: false, 413 contentType: false, 414 success: function (data, status, xhr) { 415 if (captchaDebugEnabled && data && data.captcha_debug) { 416 console.info('[captcha][server]', data.captcha_debug); 417 } 418 if (data.success === false) { 419 $.each(data.errors, function (key, value) { 420 var input = form.find("div[title=" + key + "]"); 421 if (input && input.length) { 422 input.addClass("is-error"); 423 var span = input.find(".js-form-error"); 424 span.html(value); 425 span.show(); 426 } else if (value) { 427 var fallback = form.find(".js-form-error").first(); 428 if (fallback.length) { 429 fallback.html(value); 430 fallback.show(); 431 } 432 } 433 }); 434 refreshCaptchaToken(popupId); 435 436 } else if (data.success === true) { 437 document.dispatchEvent(new CustomEvent('webform:submit-success', { 438 detail: { 439 popupId: popupId || null, 440 webFormId: form.find('[name="WEB_FORM_ID"]').length ? form.find('[name="WEB_FORM_ID"]').val() : null, 441 formName: form.attr('name') || null 442 } 443 })); 444 form.trigger('reset'); 445 if (e.detail && e.detail.hasOwnProperty('callback')) { 446 e.detail.callback(); 447 } 448 } 449 }, 450 error: function (xhr, status, err) { 451 console.error('[forms] ajax error', {status, err, response: xhr && xhr.responseText}); 452 }, 453 complete: function () { 454 toggleWebformSubmitLoader(form.get(0), false); 455 } 456 }); 457 458 }); 459} 460 461function refreshCaptchaToken(popupId) { 462 if (window.smartCaptchaExecuteForPopup) { 463 window.smartCaptchaExecuteForPopup(popupId); 464 } 465} 466 467function openPopup(id) { 468 var body = document.body; 469 var popup = document.getElementById(id); 470 body.style.paddingRight = getBrowserScrollbarWidth() + 'px'; 471 body.classList.add('has-popup'); 472 popup.classList.add('display'); 473 popup.classList.add('show'); 474} 475 476function closePopup(id) { 477 var body = document.body; 478 var popup = document.getElementById(id); 479 body.style.paddingRight = null; 480 popup.classList.remove('show'); 481 popup.classList.remove('display'); 482 body.classList.remove('has-popup'); 483}
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.