MediaWiki:Common.js: відмінності між версіями
Wiki (обговорення | внесок) Немає опису редагування |
Wiki (обговорення | внесок) Немає опису редагування |
||
| Рядок 108: | Рядок 108: | ||
'use strict'; | 'use strict'; | ||
// Конфигурация | // Конфигурация | ||
const config = { | const config = { | ||
overlayBg: 'rgba(0,0,0,0.85)', | |||
overlayBg: 'rgba(0,0,0,0. | imageMaxWidth: '90%', | ||
imageMaxHeight: '90%', | |||
closeBtnText: 'Закрити', | |||
closeBtnStyle: { | |||
imageMaxWidth: ' | background: '#f44336', | ||
imageMaxHeight: ' | color: 'white', | ||
border: 'none', | |||
borderRadius: '5px', | |||
padding: '10px 20px', | |||
fontSize: '18px', | |||
cursor: 'pointer', | |||
marginTop: '20px' | |||
} | |||
background: ' | |||
color: ' | |||
borderRadius: ' | |||
fontSize: ' | |||
} | |||
}; | }; | ||
// Функция для создания кастомного overlay (улучшенная версия) | |||
function showCustomOverlay(url) { | |||
// | |||
function | |||
const overlay = document.createElement('div'); | const overlay = document.createElement('div'); | ||
overlay. | overlay.style.position = 'fixed'; | ||
overlay.style. | overlay.style.top = '0'; | ||
overlay.style.left = '0'; | |||
overlay.style.width = '100%'; | |||
overlay.style.height = '100%'; | |||
overlay.style.background = config.overlayBg; | |||
overlay.style.display = 'flex'; | |||
overlay.style.justifyContent = 'center'; | |||
overlay.style.alignItems = 'center'; | |||
overlay.style.flexDirection = 'column'; | |||
overlay.style.zIndex = '10000'; | |||
overlay.style.cursor = 'pointer'; | |||
const img = document.createElement('img'); | |||
const | img.src = url; | ||
img.style.maxWidth = config.imageMaxWidth; | |||
img.style.maxHeight = config.imageMaxHeight; | |||
img.style.objectFit = 'contain'; | |||
img.style.borderRadius = '8px'; | |||
overlay.appendChild(img); | |||
const closeBtn = document.createElement('button'); | const closeBtn = document.createElement('button'); | ||
closeBtn. | closeBtn.innerText = config.closeBtnText; | ||
closeBtn.style.marginTop = config.closeBtnStyle.marginTop; | |||
closeBtn.style. | closeBtn.style.padding = config.closeBtnStyle.padding; | ||
closeBtn.style.fontSize = config.closeBtnStyle.fontSize; | |||
closeBtn.style.cursor = config.closeBtnStyle.cursor; | |||
closeBtn.style.background = config.closeBtnStyle.background; | |||
closeBtn.style.color = config.closeBtnStyle.color; | |||
closeBtn.style.border = config.closeBtnStyle.border; | |||
closeBtn.style.borderRadius = config.closeBtnStyle.borderRadius; | |||
// Закрытие по клику на оверлей или кнопку | |||
const closeOverlay = () => { | |||
document.body.removeChild(overlay); | |||
document.body.style.overflow = 'auto'; | |||
}; | |||
// | |||
overlay.addEventListener('click', (e) => { | |||
if (e.target === overlay) closeOverlay(); | |||
}); | |||
closeBtn.addEventListener('click', closeOverlay); | |||
// Закрытие по ESC | |||
const keyHandler = (e) => { | |||
} | if (e.key === 'Escape') closeOverlay(); | ||
}; | |||
document.addEventListener('keydown', keyHandler); | |||
// Удаляем обработчик после закрытия | |||
overlay.addEventListener('click', function handler() { | |||
document.removeEventListener('keydown', keyHandler); | |||
overlay.removeEventListener('click', handler); | |||
}); | |||
overlay.appendChild(closeBtn); | |||
document.body.appendChild(overlay); | |||
// | // Блокируем прокрутку страницы | ||
document.body.style.overflow = 'hidden'; | |||
} | } | ||
// | // Перехватываем клики на обычные картинки (без MediaViewer) | ||
function | document.body.addEventListener('click', function(e) { | ||
const target = e.target; | |||
if ( | // Если картинка не часть MediaViewer overlay и нет ссылки на /w/images/ | ||
if (target.tagName === 'IMG' && !target.closest('.mediaViewerOverlay')) { | |||
const parentLink = target.closest('a[href*="/w/images/"]'); | |||
if (!parentLink) { | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
showCustomOverlay(target.src); | |||
} | |||
} | } | ||
// | // Ссылки на файлы, где MediaViewer не срабатывает | ||
if ( | if (target.tagName === 'A' && target.href && target.href.includes('/w/images/')) { | ||
// проверка: если кликнули на миниатюру с MediaViewer, не блокируем | |||
if (!target.closest('.thumb')) { | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
showCustomOverlay(target.href); | |||
} | |||
} | } | ||
}, true); | |||
return true; | // Функция добавления кнопки "Закрити" к MediaViewer overlay (улучшенная) | ||
function addCloseButtonToMediaViewer() { | |||
const overlay = document.querySelector('.mediaViewerOverlay, .mwe-popups'); | |||
if (!overlay || overlay.dataset.closeBtnAdded) return; | |||
overlay.dataset.closeBtnAdded = true; | |||
const closeBtn = document.createElement('button'); | |||
closeBtn.innerText = config.closeBtnText; | |||
closeBtn.style.position = 'absolute'; | |||
closeBtn.style.top = '20px'; | |||
closeBtn.style.right = '20px'; | |||
closeBtn.style.padding = config.closeBtnStyle.padding; | |||
closeBtn.style.fontSize = config.closeBtnStyle.fontSize; | |||
closeBtn.style.cursor = config.closeBtnStyle.cursor; | |||
closeBtn.style.background = config.closeBtnStyle.background; | |||
closeBtn.style.color = config.closeBtnStyle.color; | |||
closeBtn.style.border = config.closeBtnStyle.border; | |||
closeBtn.style.borderRadius = config.closeBtnStyle.borderRadius; | |||
closeBtn.style.zIndex = '10001'; | |||
closeBtn.addEventListener('click', () => { | |||
overlay.style.display = 'none'; | |||
}); | |||
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 | ||
const observer = new MutationObserver((mutations) => { | |||
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 }); | |||
// | // Добавляем стили для улучшения внешнего вида | ||
const style = document.createElement('style'); | const style = document.createElement('style'); | ||
style.textContent = ` | style.textContent = ` | ||
.custom- | .custom-overlay-img { | ||
transition: transform 0.2s ease; | |||
} | } | ||
.custom- | .custom-overlay-img:hover { | ||
transform: scale(1. | transform: scale(1.02); | ||
} | } | ||
button:hover { | |||
opacity: 0.9; | |||
transform: scale(1.05); | |||
transition: all 0.2s ease; | |||
. | |||
} | } | ||
`; | `; | ||
document.head.appendChild(style); | document.head.appendChild(style); | ||
})(); | })(); | ||