Немає опису редагування
Мітка: Ручний відкіт
Немає опису редагування
Рядок 106: Рядок 106:
//OVERLAY  
//OVERLAY  
(function() {
(function() {
     // Функция для создания кастомного overlay (только для обычных картинок без MediaViewer)
    'use strict';
     function showCustomOverlay(url) {
   
    // Конфигурация - легко настраивается
    const config = {
        overlayBg: 'rgba(0,0,0,0.92)',
        maxWidth: '95%',
        maxHeight: '95%',
        closeBtnText: '✕ Закрити',
        closeBtnStyle: {
            background: '#d32f2f',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            padding: '12px 24px',
            fontSize: '16px',
            cursor: 'pointer',
            marginTop: '20px',
            transition: 'background 0.3s ease'
        },
        imageStyle: {
            borderRadius: '8px',
            boxShadow: '0 4px 20px rgba(0,0,0,0.3)'
        },
        // Исключения - классы/атрибуты, которые не должны открывать оверлей
        excludeSelectors: [
            '.no-overlay',
            '[data-no-overlay]',
            '.mw-editsection img',
            '.sprite',
            '.icon'
        ]
    };
 
    let currentOverlay = null;
 
     // Функция создания оверлея
     function createOverlay() {
         const overlay = document.createElement('div');
         const overlay = document.createElement('div');
         overlay.style.position = 'fixed';
         overlay.className = 'custom-image-overlay';
         overlay.style.top = 0;
         overlay.style.cssText = `
        overlay.style.left = 0;
            position: fixed;
        overlay.style.width = '100%';
            top: 0;
        overlay.style.height = '100%';
            left: 0;
        overlay.style.background = 'rgba(0,0,0,0.85)';
            width: 100%;
        overlay.style.display = 'flex';
            height: 100%;
         overlay.style.justifyContent = 'center';
            background: ${config.overlayBg};
         overlay.style.alignItems = 'center';
            display: none;
        overlay.style.flexDirection = 'column';
            justify-content: center;
         overlay.style.zIndex = 9999;
            align-items: center;
            flex-direction: column;
            z-index: 10000;
            cursor: pointer;
        `;
 
         const imgContainer = document.createElement('div');
         imgContainer.style.cssText = `
            position: relative;
            max-width: ${config.maxWidth};
            max-height: ${config.maxHeight};
            display: flex;
            justify-content: center;
            align-items: center;
         `;


         const img = document.createElement('img');
         const img = document.createElement('img');
         img.src = url;
         img.style.cssText = `
        img.style.maxWidth = '90%';
            max-width: 100%;
        img.style.maxHeight = '90%';
            max-height: 100%;
        overlay.appendChild(img);
            object-fit: contain;
            ${Object.entries(config.imageStyle).map(([key, value]) =>
                `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`).join('')}
        `;


         const closeBtn = document.createElement('button');
         const closeBtn = document.createElement('button');
         closeBtn.innerText = 'Закрити';
         closeBtn.innerHTML = config.closeBtnText;
         closeBtn.style.marginTop = '20px';
         closeBtn.style.cssText = Object.entries(config.closeBtnStyle).map(([key, value]) =>
        closeBtn.style.padding = '10px 20px';
            `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`).join('');
        closeBtn.style.fontSize = '18px';
       
         closeBtn.style.cursor = 'pointer';
        // Добавляем hover эффект для кнопки
        closeBtn.style.background = '#f44336';
         closeBtn.onmouseover = () => closeBtn.style.background = '#b71c1c';
         closeBtn.style.color = 'white';
         closeBtn.onmouseout = () => closeBtn.style.background = config.closeBtnStyle.background;
        closeBtn.style.border = 'none';
 
        closeBtn.style.borderRadius = '5px';
         imgContainer.appendChild(img);
         closeBtn.addEventListener('click', () => overlay.remove());
        overlay.appendChild(imgContainer);
         overlay.appendChild(closeBtn);
         overlay.appendChild(closeBtn);
        // Закрытие по клику на оверлей или кнопку
        const closeOverlay = () => {
            overlay.style.display = 'none';
            document.body.style.overflow = 'auto';
            currentOverlay = null;
        };
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) closeOverlay();
        });
        closeBtn.addEventListener('click', closeOverlay);
        // Закрытие по ESC
        document.addEventListener('keydown', function escHandler(e) {
            if (e.key === 'Escape' && currentOverlay) {
                closeOverlay();
                document.removeEventListener('keydown', escHandler);
            }
        });


         document.body.appendChild(overlay);
         document.body.appendChild(overlay);
        return { overlay, img };
     }
     }


     // Перехватываем клики на обычные картинки (без MediaViewer)
     // Проверка, должна ли картинка открываться в оверлее
    function shouldOpenInOverlay(element) {
        // Проверяем исключения
        if (config.excludeSelectors.some(selector => element.matches(selector) || element.closest(selector))) {
            return false;
        }
 
        // Игнорируем маленькие картинки (иконки)
        if (element.width < 50 || element.height < 50) {
            return false;
        }
 
        // Игнорируем картинки внутри ссылок, которые ведут не на изображения
        const parentLink = element.closest('a');
        if (parentLink) {
            const href = parentLink.href;
            if (href && !href.match(/\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/i)) {
                return false;
            }
        }
 
        return true;
    }
 
    // Показ кастомного оверлея
    function showCustomOverlay(url, alt = '') {
        if (!currentOverlay) {
            currentOverlay = createOverlay();
        }
 
        currentOverlay.img.src = url;
        currentOverlay.img.alt = alt;
        currentOverlay.overlay.style.display = 'flex';
       
        // Блокируем прокрутку body
        document.body.style.overflow = 'hidden';
    }
 
    // Обработчик кликов
     document.body.addEventListener('click', function(e) {
     document.body.addEventListener('click', function(e) {
         const target = e.target;
         const target = e.target;


         // Если картинка не часть MediaViewer overlay и нет ссылки на /w/images/
         // Клик на картинку
         if (target.tagName === 'IMG' && !target.closest('.mediaViewerOverlay')) {
         if (target.tagName === 'IMG' && shouldOpenInOverlay(target)) {
             const parentLink = target.closest('a[href*="/w/images/"]');
             // Проверяем, не является ли это частью MediaViewer или других компонентов
            if (!parentLink) {
            if (!target.closest('.mediaViewerOverlay, .mwe-popups, .gallery, .thumb')) {
                 e.preventDefault();
                 e.preventDefault();
                 e.stopPropagation();
                 e.stopPropagation();
                 showCustomOverlay(target.src);
                 showCustomOverlay(target.src, target.alt);
             }
             }
         }
         }


         // Ссылки на файлы, где MediaViewer не срабатывает
         // Клик на ссылку с изображением
         if (target.tagName === 'A' && target.href && target.href.includes('/w/images/')) {
         if (target.tagName === 'A' && target.href) {
            // проверка: если кликнули на миниатюру с MediaViewer, не блокируем
            const img = target.querySelector('img');
             if (!target.closest('.thumb')) {
             if (img && shouldOpenInOverlay(img)) {
                 e.preventDefault();
                 e.preventDefault();
                 e.stopPropagation();
                 e.stopPropagation();
                 showCustomOverlay(target.href);
                 showCustomOverlay(target.href, img.alt);
             }
             }
         }
         }
     }, true);
     }, true);


     // Функция добавления кнопки "Закрити" к MediaViewer overlay
     // Улучшенный MutationObserver для MediaViewer
     function addCloseButtonToMediaViewer() {
     function enhanceMediaViewer() {
         const overlay = document.querySelector('.mediaViewerOverlay, .mwe-popups');
         const overlay = document.querySelector('.mediaViewerOverlay');
         if (!overlay || overlay.dataset.closeBtnAdded) return;
         if (overlay && !overlay.dataset.enhanced) {
        overlay.dataset.closeBtnAdded = true;
            overlay.dataset.enhanced = true;
 
            const closeBtn = document.createElement('button');
            closeBtn.innerHTML = config.closeBtnText;
            closeBtn.style.cssText = `
                position: absolute;
                top: 20px;
                right: 20px;
                z-index: 10001;
                ${Object.entries(config.closeBtnStyle).map(([key, value]) =>
                    `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`).join('')}
            `;
 
            closeBtn.addEventListener('click', () => {
                overlay.style.display = 'none';
            });


        const closeBtn = document.createElement('button');
            overlay.appendChild(closeBtn);
        closeBtn.innerText = 'Закрити';
        closeBtn.style.position = 'absolute';
        closeBtn.style.top = '20px';
        closeBtn.style.right = '20px';
        closeBtn.style.padding = '10px 20px';
        closeBtn.style.fontSize = '18px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.background = '#f44336';
        closeBtn.style.color = 'white';
        closeBtn.style.border = 'none';
        closeBtn.style.borderRadius = '5px';
        closeBtn.addEventListener('click', () => {
            overlay.style.display = 'none';
        });


        overlay.appendChild(closeBtn);
            // Добавляем закрытие по ESC для MediaViewer
            overlay.addEventListener('keydown', (e) => {
                if (e.key === 'Escape') {
                    overlay.style.display = 'none';
                }
            });
        }
     }
     }


     // MutationObserver отслеживает появление overlay MediaViewer
     // Более эффективный observer
     const observer = new MutationObserver(() => addCloseButtonToMediaViewer());
     const observer = new MutationObserver((mutations) => {
     observer.observe(document.body, { childList: true, subtree: true });
        for (const mutation of mutations) {
            if (mutation.type === 'childList') {
                for (const node of mutation.addedNodes) {
                    if (node.nodeType === 1) { // Element node
                        if (node.classList && node.classList.contains('mediaViewerOverlay')) {
                            enhanceMediaViewer();
                        } else if (node.querySelector) {
                            const mediaViewer = node.querySelector('.mediaViewerOverlay');
                            if (mediaViewer) enhanceMediaViewer();
                        }
                    }
                }
            }
        }
    });
 
     observer.observe(document.body, {  
        childList: true,  
        subtree: true  
    });
 
    // Инициализация при загрузке DOM
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', enhanceMediaViewer);
    } else {
        enhanceMediaViewer();
    }


})();
})();