Adjusted the path to style.css to be dynamically set using 'data-static-path' attribute. This change allows stylesheets to be fetched from the correct path based on the consumed API.
		
			
				
	
	
		
			204 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| (function (document) {
 | ||
|     const captchaBlocks = document.querySelectorAll('div.captcha-service-kor-elf');
 | ||
|     captchaBlocks.forEach(function (element) {
 | ||
|         const shadow = element.attachShadow({ mode: 'closed' });
 | ||
|         const button = document.createElement("button");
 | ||
|         const style = document.createElement('link');
 | ||
|         const domain = element.getAttribute('data-domain');
 | ||
|         const token = element.getAttribute('data-token');
 | ||
|         const staticPath = element.getAttribute('data-static-path');
 | ||
| 
 | ||
|         let windowCaptcha = null;
 | ||
| 
 | ||
|         style.rel = 'stylesheet';
 | ||
|         style.type = 'text/css';
 | ||
|         style.href = staticPath + '/style.css';
 | ||
|         shadow.appendChild(style);
 | ||
| 
 | ||
|         button.textContent = 'Я не робот!';
 | ||
|         button.type = 'button';
 | ||
|         button.classList.add('button-open-window-captcha');
 | ||
|         shadow.appendChild(button);
 | ||
|         button.addEventListener('click', function () {
 | ||
|             if (windowCaptcha === null) {
 | ||
|                 windowCaptcha = createWindowCaptcha(shadow, domain, token);
 | ||
|             }
 | ||
|             windowCaptcha.style.display = 'block';
 | ||
|             actionGetCaptcha(windowCaptcha, domain, token, shadow);
 | ||
|         });
 | ||
|     });
 | ||
| 
 | ||
|     function createWindowCaptcha (shadow, domain, token) {
 | ||
|         const windowCaptcha = document.createElement('div');
 | ||
|         windowCaptcha.classList.add('window-captcha');
 | ||
|         windowCaptcha.innerHTML = `<div class="window-captcha__content">
 | ||
|             <div class="window-captcha__content__header">Я не робот! <button type="button" class="window-captcha__reload"></button><button type="button" class="window-captcha__close">X</button></div>
 | ||
|             <div class="window-captcha__content__body"></div>
 | ||
|         </div>`;
 | ||
|         shadow.appendChild(windowCaptcha);
 | ||
| 
 | ||
|         windowCaptcha.addEventListener('click', function (event) {
 | ||
|             if (event.target !== windowCaptcha) {
 | ||
|                 return null;
 | ||
|             }
 | ||
|             actionClose(windowCaptcha);
 | ||
|         });
 | ||
| 
 | ||
|         windowCaptcha.querySelector('button.window-captcha__close').addEventListener('click', function () {
 | ||
|             actionClose(windowCaptcha);
 | ||
|         });
 | ||
| 
 | ||
|         windowCaptcha.querySelector('button.window-captcha__reload').addEventListener('click', function () {
 | ||
|             actionGetCaptcha(windowCaptcha, domain, token, shadow);
 | ||
|         });
 | ||
| 
 | ||
|         return windowCaptcha;
 | ||
|     }
 | ||
| 
 | ||
|     function actionClose(windowCaptcha)
 | ||
|     {
 | ||
|         windowCaptcha.style.display = 'none';
 | ||
|     }
 | ||
| 
 | ||
|     function actionGetCaptcha(windowCaptcha, domain, token, shadow)
 | ||
|     {
 | ||
|         let bodyBlock = windowCaptcha.querySelector('div.window-captcha__content__body');
 | ||
|         if (bodyBlock.querySelectorAll('.loading').length > 0) {
 | ||
|             return null;
 | ||
|         }
 | ||
|         bodyBlock.innerHTML = '<div class="loading"></div>';
 | ||
|         fetch(domain + '/api/v1/captcha', {
 | ||
|             headers: {
 | ||
|                 'Content-Type': 'application/json',
 | ||
|                 'Accept': 'application/json',
 | ||
|                 'public-token': token
 | ||
|             }
 | ||
|         })
 | ||
|             .then(response => response.json())
 | ||
|             .then(function (data) {
 | ||
|                 let originalWidth = data.image_body.width;
 | ||
|                 let originalHeight = data.image_body.height;
 | ||
|                 bodyBlock.innerHTML = `
 | ||
|                 <form method="post">
 | ||
|                     <div class="window-captcha__content__body__head"><img src="${ data.image_head.base64 }" width="100%"></div>
 | ||
|                     <p>Выберите значение в том порядке, на котором на картинке выше:</p>
 | ||
|                     <div class="window-captcha__content__body__coordinator"><img src="${ data.image_body.base64 }" width="100%" /></div>
 | ||
|                     <input type="hidden" name="captcha_key" class="captcha_key" value="${ data.captcha_key }" />
 | ||
|                     <button type="button" class="window-captcha__content__body__button">Я не робот!</button>
 | ||
|                 </form>
 | ||
|            `;
 | ||
|                 let blockCoordinator = bodyBlock.querySelector('div.window-captcha__content__body__coordinator');
 | ||
|                 let blockCoordinatorImg = blockCoordinator.querySelector('img');
 | ||
|                 blockCoordinatorImg.addEventListener('click', function (event) {
 | ||
|                     let pointer = document.createElement('div');
 | ||
|                     pointer.style.left = ( event.offsetX / blockCoordinatorImg.width * 100 ) + '%';
 | ||
|                     pointer.style.top = ( event.offsetY / blockCoordinatorImg.height * 100 ) + '%';
 | ||
|                     pointer.classList.add('pointer');
 | ||
| 
 | ||
|                     let coordinatorX = event.offsetX * (originalWidth / blockCoordinatorImg.width)
 | ||
|                     let coordinatorY = event.offsetY * (originalHeight / blockCoordinatorImg.height)
 | ||
| 
 | ||
|                     let pointerNumber = blockCoordinator.querySelectorAll('.pointer').length + 1
 | ||
|                     pointer.innerHTML = `
 | ||
|                     <span class="pounter__number">${ pointerNumber }</span>
 | ||
|                     <input type="hidden" class="x" name="pointer[][x]" value="${ Math.round(coordinatorX) }" />
 | ||
|                     <input type="hidden" class="y" name="pointer[][y]" value="${ Math.round(coordinatorY) }" />
 | ||
|                 `;
 | ||
| 
 | ||
|                     pointer.addEventListener('click', function () {
 | ||
|                         pointer.remove();
 | ||
|                         blockCoordinator.querySelectorAll('.pointer').forEach(function (elementPointer, pointIndex) {
 | ||
|                             elementPointer.querySelector('span.pounter__number').textContent = pointIndex + 1;
 | ||
|                         });
 | ||
|                     });
 | ||
| 
 | ||
|                     blockCoordinator.appendChild(pointer);
 | ||
|                 });
 | ||
| 
 | ||
|                 bodyBlock.querySelector('.window-captcha__content__body__button').addEventListener('click', function () {
 | ||
|                     checkingCaptcha(bodyBlock, domain, token, shadow);
 | ||
|                 });
 | ||
|             })
 | ||
|             .catch(error => {
 | ||
|                 bodyBlock.innerHTML = `<div class="window-captcha__content__body__error">Произошла ошибка, сервис с каптчей не ответил. Попробуйте ещё раз!</div>`;
 | ||
|             });
 | ||
|     }
 | ||
| 
 | ||
|     function checkingCaptcha (bodyBlock, domain, token, shadow) {
 | ||
|         let button = bodyBlock.querySelector('button.window-captcha__content__body__button');
 | ||
|         if (button.querySelectorAll('.loading').length > 0) {
 | ||
|             return null;
 | ||
|         }
 | ||
|         let loadingSpan = document.createElement('span');
 | ||
|         loadingSpan.classList.add('loading');
 | ||
|         button.appendChild(loadingSpan);
 | ||
| 
 | ||
|         let data = {
 | ||
|             captcha_key: bodyBlock.querySelector('.captcha_key').value,
 | ||
|             verification: []
 | ||
|         };
 | ||
|         bodyBlock.querySelectorAll('.pointer').forEach(function (elementPointer) {
 | ||
|             data["verification"].push({
 | ||
|                 x: elementPointer.querySelector('.x').value,
 | ||
|                 y: elementPointer.querySelector('.y').value
 | ||
|             });
 | ||
|         });
 | ||
| 
 | ||
|         fetch(domain + '/api/v1/captcha', {
 | ||
|             method: 'POST',
 | ||
|             headers: {
 | ||
|                 'Content-Type': 'application/json',
 | ||
|                 'Accept': 'application/json',
 | ||
|                 'public-token': token
 | ||
|             },
 | ||
|             body: JSON.stringify(data)
 | ||
|         })
 | ||
|             .then(response => {
 | ||
|                 if (response.status === 429) {
 | ||
|                     setError('Вы превысили количество попыток. Обновите каптчу.', button);
 | ||
|                     return
 | ||
|                 }
 | ||
|                 return response.json();
 | ||
|             })
 | ||
|             .then(function (data) {
 | ||
|                 if (typeof data.errors !== 'undefined') {
 | ||
|                     let errorMessage = '';
 | ||
|                     for (let key in data.errors) {
 | ||
|                         errorMessage += data.errors[key] + '<br>';
 | ||
|                     }
 | ||
|                     if (errorMessage === '') {
 | ||
|                         errorMessage = data.message;
 | ||
|                     }
 | ||
|                     setError(errorMessage, button);
 | ||
|                     return
 | ||
|                 }
 | ||
|                 if (typeof data.captcha_key === 'undefined') {
 | ||
|                     setError('Произошла ошибка!', button);
 | ||
|                     return
 | ||
|                 }
 | ||
|                 shadow.querySelector('button.button-open-window-captcha').remove();
 | ||
|                 let captchaVerified = document.createElement('div');
 | ||
|                 captchaVerified.innerHTML = `<span class="captcha-verified">Ура!!! Проверку прошли!</span><input type="hidden" name="captcha-verified" value="${ data.captcha_key }">`;
 | ||
|                 shadow.appendChild(captchaVerified);
 | ||
|                 shadow.querySelector('.window-captcha').remove();
 | ||
|             })
 | ||
|             .catch(error => {
 | ||
|                 setError('Произошла ошибка!', button)
 | ||
|             }).finally(function () {
 | ||
|             loadingSpan.remove();
 | ||
|         });
 | ||
|     }
 | ||
| 
 | ||
|     function setError(message, button) {
 | ||
|         let errorBlock = document.createElement('div');
 | ||
|         errorBlock.classList.add("error-message");
 | ||
|         errorBlock.innerHTML = message;
 | ||
|         button.before(errorBlock);
 | ||
| 
 | ||
|         setTimeout( function () {
 | ||
|             errorBlock.remove();
 | ||
|         }, 3000);
 | ||
|     }
 | ||
| 
 | ||
| })(document);
 |