135 lines
No EOL
4.6 KiB
JavaScript
135 lines
No EOL
4.6 KiB
JavaScript
// ==================== МОДУЛЬ ВИДЕО ОКОН ====================
|
||
|
||
(function() {
|
||
const core = window.VideoIPRedirect;
|
||
if (!core) {
|
||
console.error('[CAPS_Enhancer] CORE не загружен!');
|
||
return;
|
||
}
|
||
|
||
const debugLog = (msg, ...args) => core.debugLog('video', msg, ...args);
|
||
const isElementVisible = core.isElementVisible;
|
||
|
||
debugLog('🎬 Загрузка модуля...');
|
||
|
||
// Функция для поиска АКТИВНОГО окна с видео
|
||
function findActiveVideoWindow() {
|
||
debugLog('Поиск активного окна с видео');
|
||
const videos = document.querySelectorAll('img[src*=":8888/screen"][src*="/getVideo/"]');
|
||
debugLog(`Найдено видео: ${videos.length}`);
|
||
|
||
if (videos.length === 0) {
|
||
debugLog('Видео не найдены');
|
||
return null;
|
||
}
|
||
|
||
const video = videos[0];
|
||
|
||
let parent = video.parentElement;
|
||
let depth = 0;
|
||
let windowElement = null;
|
||
let header = null;
|
||
|
||
while (parent && depth < 15) {
|
||
const potentialHeader = parent.querySelector('div[class*="header"], div.header');
|
||
if (potentialHeader && potentialHeader.querySelector('p')) {
|
||
header = potentialHeader;
|
||
windowElement = parent;
|
||
debugLog(`Найден заголовок на глубине ${depth}`);
|
||
break;
|
||
}
|
||
parent = parent.parentElement;
|
||
depth++;
|
||
}
|
||
|
||
if (!header) {
|
||
const headers = document.querySelectorAll('div[class*="header"], div.header');
|
||
|
||
for (let h of headers) {
|
||
const parentWindow = h.closest('div[style*="fixed"], div[style*="absolute"]');
|
||
if (parentWindow && isElementVisible(parentWindow)) {
|
||
header = h;
|
||
windowElement = parentWindow;
|
||
debugLog('Найден заголовок через родительское окно');
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (header && windowElement) {
|
||
const title = header.querySelector('p')?.textContent?.trim() || '';
|
||
debugLog('✅ Активное окно найдено');
|
||
return { window: windowElement, header, title, video };
|
||
}
|
||
|
||
debugLog('❌ Активное окно не найдено');
|
||
return null;
|
||
}
|
||
|
||
// Функция для добавления кнопки в заголовок
|
||
function addButtonToHeader(header, ip) {
|
||
if (header.querySelector('.video-redirect-btn')) {
|
||
return null;
|
||
}
|
||
|
||
const button = core.createStyledButton(
|
||
`🔗 ${ip}:${core.TARGET_PORT_VIDEO}`,
|
||
(e) => {
|
||
e.stopPropagation();
|
||
window.open(`http://${ip}:${core.TARGET_PORT_VIDEO}`, '_blank');
|
||
},
|
||
'video-redirect-btn'
|
||
);
|
||
|
||
const p = header.querySelector('p');
|
||
if (p) {
|
||
p.style.display = 'inline-block';
|
||
p.style.marginRight = '8px';
|
||
p.insertAdjacentElement('afterend', button);
|
||
} else {
|
||
header.appendChild(button);
|
||
}
|
||
|
||
return button;
|
||
}
|
||
|
||
// Главная функция
|
||
function addButtonToActiveWindow() {
|
||
debugLog('========== НАЧАЛО ==========');
|
||
|
||
const pageType = core.checkPageType();
|
||
if (!pageType.isVideoPage) {
|
||
return false;
|
||
}
|
||
|
||
const activeWindow = findActiveVideoWindow();
|
||
if (!activeWindow) {
|
||
return false;
|
||
}
|
||
|
||
const src = activeWindow.video.src || activeWindow.video.getAttribute('src');
|
||
const ipData = core.extractIpAndPort(src);
|
||
|
||
if (!ipData) {
|
||
debugLog('Не удалось извлечь IP');
|
||
return false;
|
||
}
|
||
|
||
addButtonToHeader(activeWindow.header, ipData.ip);
|
||
debugLog('✅ Кнопка добавлена');
|
||
debugLog('========== КОНЕЦ ==========');
|
||
|
||
return true;
|
||
}
|
||
|
||
// Публичный API
|
||
window.VideoIPRedirect.VideoWindow = {
|
||
addButtonToVideoWindow: addButtonToActiveWindow,
|
||
removeButtonsFromWindow: function() {
|
||
const btns = document.querySelectorAll('.video-redirect-btn');
|
||
btns.forEach(btn => btn.remove());
|
||
}
|
||
};
|
||
|
||
debugLog('✅ Модуль загружен');
|
||
})(); |