Немає опису редагування
Немає опису редагування
Рядок 108: Рядок 108:
     'use strict';
     'use strict';
      
      
     // Конфигурация
     // Конфигурация в стиле MediaViewer
     const config = {
     const config = {
         overlayBg: 'rgba(0,0,0,0.85)',
         overlayBg: 'rgba(0,0,0,0.95)',
         imageMaxWidth: '90%',
         imageMaxWidth: '90%',
         imageMaxHeight: '90%',
         imageMaxHeight: '90%',
         closeBtnText: 'Закрити',
         closeBtnText: '×',
         closeBtnStyle: {
         closeBtnStyle: {
             background: '#f44336',
             background: 'rgba(0,0,0,0.7)',
             color: 'white',
             color: 'white',
             border: 'none',
             border: 'none',
             borderRadius: '5px',
             borderRadius: '50%',
             padding: '10px 20px',
             width: '40px',
             fontSize: '18px',
            height: '40px',
             fontSize: '24px',
             cursor: 'pointer',
             cursor: 'pointer',
             marginTop: '20px'
             position: 'absolute',
            top: '20px',
            right: '20px'
        },
        zoomBtnStyle: {
            background: 'rgba(0,0,0,0.7)',
            color: 'white',
            border: 'none',
            borderRadius: '50%',
            width: '40px',
            height: '40px',
            fontSize: '20px',
            cursor: 'pointer',
            position: 'absolute',
            right: '20px'
         }
         }
     };
     };


     // Функция для создания кастомного overlay (улучшенная версия)
    let currentScale = 1;
    const minScale = 0.5;
    const maxScale = 3;
    const scaleStep = 0.25;
 
     // Функция для создания оверлея в стиле MediaViewer
     function showCustomOverlay(url) {
     function showCustomOverlay(url) {
         const overlay = document.createElement('div');
         const overlay = document.createElement('div');
Рядок 138: Рядок 158:
         overlay.style.justifyContent = 'center';
         overlay.style.justifyContent = 'center';
         overlay.style.alignItems = 'center';
         overlay.style.alignItems = 'center';
        overlay.style.flexDirection = 'column';
         overlay.style.zIndex = '10000';
         overlay.style.zIndex = '10000';
         overlay.style.cursor = 'pointer';
         overlay.style.cursor = 'default';


        // Контейнер для изображения и кнопок
        const container = document.createElement('div');
        container.style.position = 'relative';
        container.style.display = 'flex';
        container.style.justifyContent = 'center';
        container.style.alignItems = 'center';
        container.style.maxWidth = '95vw';
        container.style.maxHeight = '95vh';
        // Изображение
         const img = document.createElement('img');
         const img = document.createElement('img');
         img.src = url;
         img.src = url;
Рядок 148: Рядок 177:
         img.style.objectFit = 'contain';
         img.style.objectFit = 'contain';
         img.style.borderRadius = '8px';
         img.style.borderRadius = '8px';
         overlay.appendChild(img);
         img.style.boxShadow = '0 10px 30px rgba(0,0,0,0.5)';
        img.style.transition = 'transform 0.3s ease';
        img.style.cursor = 'default'; // Убираем курсор лупы


        // Кнопка закрытия (как в MediaViewer)
         const closeBtn = document.createElement('button');
         const closeBtn = document.createElement('button');
         closeBtn.innerText = config.closeBtnText;
         closeBtn.innerHTML = config.closeBtnText;
         closeBtn.style.marginTop = config.closeBtnStyle.marginTop;
        closeBtn.title = 'Закрити (Esc)';
         closeBtn.style.padding = config.closeBtnStyle.padding;
         closeBtn.style.cssText = Object.entries(config.closeBtnStyle).map(([key, value]) =>
         closeBtn.style.fontSize = config.closeBtnStyle.fontSize;
            `${key}: ${value};`).join('');
         closeBtn.style.cursor = config.closeBtnStyle.cursor;
         closeBtn.style.zIndex = '10001';
         closeBtn.style.background = config.closeBtnStyle.background;
 
         closeBtn.style.color = config.closeBtnStyle.color;
        // Кнопки зума
         closeBtn.style.border = config.closeBtnStyle.border;
        const zoomInBtn = document.createElement('button');
         closeBtn.style.borderRadius = config.closeBtnStyle.borderRadius;
        zoomInBtn.innerHTML = '+';
          
        zoomInBtn.title = 'Збільшити (Ctrl + +)';
         // Закрытие по клику на оверлей или кнопку
        zoomInBtn.style.cssText = Object.entries(config.zoomBtnStyle).map(([key, value]) =>
            `${key}: ${value};`).join('');
        zoomInBtn.style.top = '70px';
        zoomInBtn.style.zIndex = '10001';
 
        const zoomOutBtn = document.createElement('button');
        zoomOutBtn.innerHTML = '−';
        zoomOutBtn.title = 'Зменшити (Ctrl + -)';
         zoomOutBtn.style.cssText = Object.entries(config.zoomBtnStyle).map(([key, value]) =>
            `${key}: ${value};`).join('');
        zoomOutBtn.style.top = '120px';
         zoomOutBtn.style.zIndex = '10001';
 
        const resetZoomBtn = document.createElement('button');
        resetZoomBtn.innerHTML = '1:1';
        resetZoomBtn.title = 'Скинути масштаб';
         resetZoomBtn.style.cssText = Object.entries(config.zoomBtnStyle).map(([key, value]) =>
            `${key}: ${value};`).join('');
         resetZoomBtn.style.top = '170px';
        resetZoomBtn.style.zIndex = '10001';
         resetZoomBtn.style.fontSize = '16px';
 
        // Функции зума
        function zoomImage(scale) {
            currentScale = Math.max(minScale, Math.min(maxScale, scale));
            img.style.transform = `scale(${currentScale})`;
            updateZoomButtons();
         }
 
        function updateZoomButtons() {
            zoomInBtn.disabled = currentScale >= maxScale;
            zoomOutBtn.disabled = currentScale <= minScale;
           
            zoomInBtn.style.opacity = zoomInBtn.disabled ? '0.5' : '1';
            zoomOutBtn.style.opacity = zoomOutBtn.disabled ? '0.5' : '1';
        }
 
        // Обработчики зума
        zoomInBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            zoomImage(currentScale + scaleStep);
        });
 
        zoomOutBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            zoomImage(currentScale - scaleStep);
        });
 
        resetZoomBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            currentScale = 1;
            img.style.transform = 'scale(1)';
            updateZoomButtons();
         });
 
         // Закрытие оверлея
         const closeOverlay = () => {
         const closeOverlay = () => {
             document.body.removeChild(overlay);
             document.body.removeChild(overlay);
             document.body.style.overflow = 'auto';
             document.body.style.overflow = 'auto';
            currentScale = 1; // Сбрасываем масштаб
         };
         };
        closeBtn.addEventListener('click', closeOverlay);
          
          
        // Закрытие по клику на фон (но не на изображение или кнопки)
         overlay.addEventListener('click', (e) => {
         overlay.addEventListener('click', (e) => {
             if (e.target === overlay) closeOverlay();
             if (e.target === overlay) closeOverlay();
         });
         });
       
 
        closeBtn.addEventListener('click', closeOverlay);
       
         // Закрытие по ESC
         // Закрытие по ESC
         const keyHandler = (e) => {
         const keyHandler = (e) => {
             if (e.key === 'Escape') closeOverlay();
             if (e.key === 'Escape') {
                closeOverlay();
                document.removeEventListener('keydown', keyHandler);
            } else if (e.ctrlKey) {
                if (e.key === '+' || e.key === '=') {
                    e.preventDefault();
                    zoomImage(currentScale + scaleStep);
                } else if (e.key === '-') {
                    e.preventDefault();
                    zoomImage(currentScale - scaleStep);
                } else if (e.key === '0') {
                    e.preventDefault();
                    currentScale = 1;
                    img.style.transform = 'scale(1)';
                    updateZoomButtons();
                }
            }
         };
         };
         document.addEventListener('keydown', keyHandler);
         document.addEventListener('keydown', keyHandler);
       
 
         // Удаляем обработчик после закрытия
         // Hover эффекты для кнопок
         overlay.addEventListener('click', function handler() {
         [closeBtn, zoomInBtn, zoomOutBtn, resetZoomBtn].forEach(btn => {
            document.removeEventListener('keydown', keyHandler);
            btn.addEventListener('mouseenter', () => {
             overlay.removeEventListener('click', handler);
                btn.style.background = 'rgba(0,0,0,0.9)';
                btn.style.transform = 'scale(1.1)';
            });
             btn.addEventListener('mouseleave', () => {
                btn.style.background = config.zoomBtnStyle.background;
                btn.style.transform = 'scale(1)';
            });
         });
         });


         overlay.appendChild(closeBtn);
        // Сборка интерфейса
        container.appendChild(img);
        container.appendChild(closeBtn);
        container.appendChild(zoomInBtn);
        container.appendChild(zoomOutBtn);
        container.appendChild(resetZoomBtn);
         overlay.appendChild(container);
       
         document.body.appendChild(overlay);
         document.body.appendChild(overlay);
        document.body.style.overflow = 'hidden';
          
          
         // Блокируем прокрутку страницы
         // Инициализация кнопок зума
         document.body.style.overflow = 'hidden';
         updateZoomButtons();
     }
     }


Рядок 208: Рядок 327:
         // Ссылки на файлы, где MediaViewer не срабатывает
         // Ссылки на файлы, где MediaViewer не срабатывает
         if (target.tagName === 'A' && target.href && target.href.includes('/w/images/')) {
         if (target.tagName === 'A' && target.href && target.href.includes('/w/images/')) {
            // проверка: если кликнули на миниатюру с MediaViewer, не блокируем
             if (!target.closest('.thumb')) {
             if (!target.closest('.thumb')) {
                 e.preventDefault();
                 e.preventDefault();
Рядок 217: Рядок 335:
     }, true);
     }, true);


     // Функция добавления кнопки "Закрити" к MediaViewer overlay (улучшенная)
     // Функция добавления кнопки "Закрити" к MediaViewer overlay
     function addCloseButtonToMediaViewer() {
     function addCloseButtonToMediaViewer() {
         const overlay = document.querySelector('.mediaViewerOverlay, .mwe-popups');
         const overlay = document.querySelector('.mediaViewerOverlay, .mwe-popups');
Рядок 224: Рядок 342:


         const closeBtn = document.createElement('button');
         const closeBtn = document.createElement('button');
         closeBtn.innerText = config.closeBtnText;
         closeBtn.innerText = 'Закрити';
         closeBtn.style.position = 'absolute';
         closeBtn.style.position = 'absolute';
         closeBtn.style.top = '20px';
         closeBtn.style.top = '20px';
         closeBtn.style.right = '20px';
         closeBtn.style.right = '20px';
         closeBtn.style.padding = config.closeBtnStyle.padding;
         closeBtn.style.padding = '10px 20px';
         closeBtn.style.fontSize = config.closeBtnStyle.fontSize;
         closeBtn.style.fontSize = '18px';
         closeBtn.style.cursor = config.closeBtnStyle.cursor;
         closeBtn.style.cursor = 'pointer';
         closeBtn.style.background = config.closeBtnStyle.background;
         closeBtn.style.background = '#f44336';
         closeBtn.style.color = config.closeBtnStyle.color;
         closeBtn.style.color = 'white';
         closeBtn.style.border = config.closeBtnStyle.border;
         closeBtn.style.border = 'none';
         closeBtn.style.borderRadius = config.closeBtnStyle.borderRadius;
         closeBtn.style.borderRadius = '5px';
         closeBtn.style.zIndex = '10001';
         closeBtn.style.zIndex = '10001';
          
          
Рядок 242: Рядок 360:


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


     // MutationObserver отслеживает появление overlay MediaViewer
     // MutationObserver отслеживает появление overlay MediaViewer
     const observer = new MutationObserver((mutations) => {
     const observer = new MutationObserver(() => addCloseButtonToMediaViewer());
        for (let mutation of mutations) {
            if (mutation.type === 'childList') {
                for (let node of mutation.addedNodes) {
                    if (node.nodeType === 1) { // Element node
                        if (node.classList &&
                            (node.classList.contains('mediaViewerOverlay') ||
                            node.classList.contains('mwe-popups'))) {
                            // Даем время для полной инициализации MediaViewer
                            setTimeout(addCloseButtonToMediaViewer, 100);
                        }
                    }
                }
            }
        }
    });
   
     observer.observe(document.body, { childList: true, subtree: true });
     observer.observe(document.body, { childList: true, subtree: true });


     // Добавляем стили для улучшения внешнего вида
     // Стили для улучшения внешнего вида
     const style = document.createElement('style');
     const style = document.createElement('style');
     style.textContent = `
     style.textContent = `
         .custom-overlay-img {
         button {
             transition: transform 0.2s ease;
             transition: all 0.2s ease !important;
         }
         }
          
          
         .custom-overlay-img:hover {
         button:hover:not(:disabled) {
             transform: scale(1.02);
             transform: scale(1.1) !important;
            background: rgba(0,0,0,0.9) !important;
         }
         }
          
          
         button:hover {
         button:disabled {
             opacity: 0.9;
             cursor: not-allowed !important;
             transform: scale(1.05);
        }
            transition: all 0.2s ease;
       
        @media (max-width: 768px) {
             button {
                width: 35px !important;
                height: 35px !important;
                font-size: 18px !important;
            }
         }
         }
     `;
     `;