1document.addEventListener('DOMContentLoaded', () => { 2 3 const style = document.createElement('style'); 4 style.type = 'text/css'; 5 style.innerHTML = ` 6 .custom-error { 7 border: 1px solid red !important; 8 } 9`; 10 document.head.appendChild(style); 11 12 function clearInput(button) { 13 const input = button.parentNode.querySelector('input'); 14 input.value = ''; 15 toggleClearButton(button); 16 } 17 18 function toggleClearButton(button) { 19 const input = button.parentNode.querySelector('input'); 20 const clearButton = button; 21 if (input.value.length > 0) { 22 clearButton.style.display = 'block'; 23 } else { 24 clearButton.style.display = 'none'; 25 } 26 } 27 28 const clearInputButtons = document.querySelectorAll('.input-clear'); 29 clearInputButtons.forEach(button => { 30 const input = button.parentNode.querySelector('input'); 31 input.addEventListener('input', () => toggleClearButton(button)); 32 toggleClearButton(button); 33 button.addEventListener('click', () => clearInput(button)); 34 }); 35 36 ;[].forEach.call( 37 document.querySelectorAll('input[type=tel]'), 38 function (input) { 39 let keyCode 40 function mask(event) { 41 event.keyCode && (keyCode = event.keyCode) 42 let pos = this.selectionStart 43 if (pos < 3) event.preventDefault() 44 let matrix = '+7 (___) ___-__-__', 45 i = 0, 46 def = matrix.replace(/\D/g, ''), 47 val = this.value.replace(/\D/g, ''), 48 new_value = matrix.replace(/[_\d]/g, function (a) { 49 return i < val.length ? val.charAt(i++) || def.charAt(i) : a 50 }) 51 i = new_value.indexOf('_') 52 if (i != -1) { 53 i < 5 && (i = 3) 54 new_value = new_value.slice(0, i) 55 } 56 let reg = matrix 57 .substr(0, this.value.length) 58 .replace(/_+/g, function (a) { 59 return '\\d{1,' + a.length + '}' 60 }) 61 .replace(/[+()]/g, '\\$&') 62 reg = new RegExp('^' + reg + '$') 63 if ( 64 !reg.test(this.value) || 65 this.value.length < 5 || 66 (keyCode > 47 && keyCode < 58) 67 ) 68 this.value = new_value 69 if (event.type == 'blur' && this.value.length < 5) this.value = '' 70 } 71 input.addEventListener('input', mask, false) 72 input.addEventListener('focus', mask, false) 73 input.addEventListener('blur', mask, false) 74 input.addEventListener('keydown', mask, false) 75 } 76 ) 77 function GetYMCID() { 78 var match = document.cookie.match('(?:^|;)\\s*_ym_uid=([^;]*)'); 79 return (match) ? decodeURIComponent(match[1]) : false; 80 } 81 const formButtons = document.querySelectorAll('button[type="submit"]'); 82 83 let key = mes = ''; 84 const ajaxSend = async (formData) => { 85 const response = await fetch("/netcat_template/ajax/hash-check.php", { 86 method: "POST", 87 body: formData 88 }); 89 if (!response.ok) { 90 throw new Error(`ÐÑибка по адÑеÑÑ hash-check, ÑÑаÑÑÑ Ð¾Ñибки ${response.status}`); 91 } 92 return await response.text(); 93 }; 94 const formData = new FormData(); 95 if (document.querySelectorAll('input[name=mes]').length > 0) { 96 mes = document.querySelectorAll('input[name=mes]')[document.querySelectorAll('input[name=mes]').length - 1].value; 97 } 98 formData.append('checker', 1); 99 formData.append('mes', mes); 100 ajaxSend(formData) 101 .then((response) => { 102 key = response; 103 return key; 104 }) 105 .catch((err) => console.error(err)); 106 107 formButtons.forEach(button => { 108 const formObj = button.parentNode; 109 const divWrap = document.createElement('div'); 110 divWrap.style.display = 'none'; 111 divWrap.innerHTML = 112 `<input name="trafficSource" type="hidden" value=""> 113 <input name="istochnik" type="hidden" value=""> 114 <input name="clientID" type="hidden" value="${GetYMCID()}">`; 115 formObj.appendChild(divWrap); 116 117 if (typeof sbjs !== 'undefined') { 118 sbjs.init(divWrap); 119 formObj.querySelector("input[name=trafficSource]").value = sbjs.get.current.typ; 120 formObj.querySelector("input[name=istochnik]").value = sbjs.get.current.src; 121 } 122 123 function getRandomNumber(min, max) { 124 return Math.ceil(Math.random() * (max - min)) + min - 1; 125 } 126 setTimeout(function () { 127 if (key != '') { 128 const input = document.createElement('input'); 129 input.name = 'f_haystack'; 130 input.type = 'hidden'; 131 input.value = key; 132 formObj.appendChild(input); 133 } 134 }, getRandomNumber(5000, 7000)); 135 const responeModalOk = document.querySelector('[data-modal-ok]'); 136 const responeModalError = document.querySelector('[data-modal-err]'); 137 button.addEventListener('click', async function (event) { 138 event.preventDefault(); 139 const form = this.closest('form'); 140 modalOpen = responeModalOk.dataset.modalOpen; 141 const fields = {}; 142 const inputs = form.querySelectorAll('input[type="tel"], textarea, input[type="text"]');
143 inputs.forEach(input => { 144 if (input.hasAttribute('required')) { 145 fields[input.name] = { 146 type: input.type, 147 value: input.value 148 }; 149 } 150 }) 151 if (responeModalOk === responeModalError) { 152 modalOk = modalErr = responeModalOk.querySelector('.' + responeModalOk.dataset.modalOk); 153 } else { 154 modalOk = responeModalOk.querySelector('.' + responeModalOk.dataset.modalOk); 155 modalErr = responeModalError.querySelector('.' + responeModalError.dataset.modalErr); 156 } 157 const resultWrappers = { 158 success: modalOk, 159 error: modalErr 160 }; 161 if (validateInputs(fields)) { 162 await handleSubmission(this, form, resultWrappers, modalOpen); 163 } else { 164 markErrors(form); 165 } 166 }); 167 168 const urlInputs = document.querySelectorAll("input[name='urlMessage'], input[name='title_url_message']"); 169 urlInputs.forEach(input => { 170 const cleanUrl = `${window.location.origin}${window.location.pathname}`; 171 input.value = input.name === 'urlMessage' ? cleanUrl : document.title; 172 }); 173 }); 174 175 async function handleSubmission(button, form, resultWrappers, modalOpen) { 176 const originalText = button.innerText; 177 button.innerHTML = "ÐÑпÑавление"; 178 button.disabled = true; 179 try { 180 const response = await fetch(`/netcat_template/ajax/request.php`, { 181 method: 'POST', 182 body: new FormData(form) 183 }); 184 const responseText = await response.text(); 185 const isSuccess = response.ok; 186 openModal(isSuccess ? resultWrappers.success : resultWrappers.error, responseText, modalOpen); 187 188 } catch (error) { 189 openModal(resultWrappers.error, error.message, modalOpen); 190 } finally { 191 resetButton(button, originalText); 192 } 193 } 194 195 function openModal(wrapper, content, modalOpen) { 196 197 const modal = wrapper.closest('.popup'); 198 wrapper.innerHTML = content; 199 const classes = modalOpen.split(' '); 200 classes.forEach(item => { 201 modal.classList.add(item); 202 }); 203 } 204 function resetButton(button, buttonText) { 205 button.innerText = buttonText; 206 button.disabled = false; 207 } 208 209 function markErrors(form) { 210 const inputs = form.querySelectorAll('input[type="tel"], textarea, input[type="text"]'); 211 inputs.forEach(input => { 212 switch (input.type) { 213 case 'tel': 214 const phoneNumber = input.value.replace(/\D/g, ''); 215 if (phoneNumber.length < 11) { 216 addErrorStyleNotification(input, "ÐведиÑе веÑнÑй Ð½Ð¾Ð¼ÐµÑ ÑелеÑона"); 217 setTimeout(() => { 218 removeErrorStyleNotification(input); 219 }, 2000); 220 } 221 break; 222 case 'textarea': 223 case 'text': 224 if (!/[а-ÑÐ-ЯÑÐ]/.test(input.value) || input.value.trim().length <= 2) { 225 addErrorStyleNotification(input, "ТекÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ ÑодеÑжаÑÑ ÑÑÑÑкие бÑквÑ"); 226 setTimeout(() => { 227 removeErrorStyleNotification(input); 228 }, 2000); 229 } 230 break; 231 default: 232 addErrorStyleNotification(input, "Ðоле не заполнено"); 233 setTimeout(() => { 234 removeErrorStyleNotification(input); 235 }, 1000); 236 break; 237 } 238 }) 239 } 240 241 function validateInputs(fields) { 242 let isValid = true; 243 for (let fieldName in fields) { 244 const field = fields[fieldName]; 245 switch (field.type) { 246 case 'tel': 247 const phoneNumber = field.value.replace(/\D/g, ''); 248 if (phoneNumber.length < 11) { 249 isValid = false;
250 } 251 break; 252 case 'textarea': 253 case 'text': 254 if (!/[а-ÑÐ-ЯÑÐ]/.test(field.value) || field.value.trim().length <= 2) { 255 isValid = false; 256 } 257 break; 258 default: 259 isValid = false; 260 break; 261 } 262 } 263 return isValid; 264 } 265 function addErrorStyleNotification(input, text) { 266 input.classList.add('custom-error'); 267 input.setCustomValidity(text); 268 input.reportValidity(); 269 } 270 function removeErrorStyleNotification(input) { 271 input.setCustomValidity('') 272 input.classList.remove('custom-error'); 273 } 274});
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.