caps_enhancer/js/content.js
2026-03-23 17:17:08 +03:00

251 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==================== ГЛАВНЫЙ ФАЙЛ ====================
(function() {
let capsLogoUrl = null; // URL caps.svg, сохраняется при первой замене логотипа
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', waitForConfigAndInit);
} else {
waitForConfigAndInit();
}
// Ожидание загрузки конфигурации перед инициализацией
function waitForConfigAndInit() {
const core = window.VideoIPRedirect;
if (!core) {
console.error('[CAPS_Enhancer] ❌ CORE не загружен!');
return;
}
const debugLog = (msg, ...args) => core.debugLog('content', msg, ...args);
if (core.configReady) {
debugLog('⚙️ Конфигурация готова, запуск инициализации...');
init();
} else {
debugLog('⏳ Ожидание загрузки конфигурации...');
document.addEventListener('VideoIPRedirect:ConfigReady', () => {
debugLog('⚙️ Конфигурация загружена, запуск инициализации...');
init();
}, { once: true });
setTimeout(() => {
if (!core.configReady) {
debugLog('⚠️ Таймаут ожидания конфигурации, запуск с настройками по умолчанию...');
init();
}
}, 2000);
}
}
function init() {
const core = window.VideoIPRedirect;
const debugLog = (msg, ...args) => core.debugLog('content', msg, ...args);
const disabledSites = core.CONFIG.disabledSites || [];
const hostname = window.location.hostname || '';
if (disabledSites.length && disabledSites.includes(hostname)) {
debugLog('⏹ Расширение отключено на этом сайте:', hostname);
return;
}
debugLog('========== ЗАПУСК ==========');
debugLog('DOM загружен, инициализация...');
debugLog('📋 Текущая конфигурация:', core.CONFIG);
const pageType = core.checkPageType();
// Замена логотипа CleverPark на caps.svg (если включено)
const LOGO_SELECTOR = 'img[src*="cleverpark.svg"], img[src*="cleverpark"], img[alt*="CLEVER PARK"], img[alt*="CLEVER"]';
const replaceLogoEnabled = core.CONFIG.replaceLogo !== false;
const hasGetURL = typeof chrome !== 'undefined' && chrome.runtime && typeof chrome.runtime.getURL === 'function';
function tryReplaceLogo(from) {
if (!replaceLogoEnabled || !hasGetURL) return false;
const logo = document.querySelector(LOGO_SELECTOR);
if (logo && !logo.dataset.capsReplaced) {
logo.dataset.capsOriginalSrc = logo.src;
logo.dataset.capsReplaced = '1';
logo.setAttribute('data-caps-logo', 'true');
capsLogoUrl = chrome.runtime.getURL('icons/caps.svg');
logo.src = capsLogoUrl;
debugLog('🖼️ [LOGO] Заменён на caps.svg', from ? '(' + from + ')' : '');
applyVisibilityToElement(logo);
return true;
}
return false;
}
if (replaceLogoEnabled && hasGetURL) {
debugLog('🖼️ [LOGO] Включена замена, селектор:', LOGO_SELECTOR);
tryReplaceLogo('init');
[400, 1000, 2500].forEach((ms, i) => {
setTimeout(() => { tryReplaceLogo('retry-' + (i + 1)); }, ms);
});
const logoObserver = new MutationObserver(() => {
if (tryReplaceLogo('observer')) logoObserver.disconnect();
});
if (document.body) {
logoObserver.observe(document.body, { childList: true, subtree: true });
setTimeout(() => logoObserver.disconnect(), 10000);
}
}
// ПРИОРИТЕТ 1: Обработка страниц noVNC
if (pageType.isNoVNCPage && core.NoVNCRedirect) {
const mode = core.CONFIG.novnc.mode;
debugLog(`🖥️ Обнаружена страница noVNC, режим: ${mode}`);
const handled = core.NoVNCRedirect.handleNoVNCPage();
if (mode === 'redirect' && handled) {
return;
}
}
// ПРИОРИТЕТ 2: Автологин на странице входа
if (core.AutoLogin) {
if (core.AutoLogin.isLoginPage1()) {
debugLog('🔐 Обнаружена страница логина типа 1');
core.AutoLogin.tryAutoLogin();
} else if (core.AutoLogin.isLoginPage2()) {
debugLog('🔐 Обнаружена страница логина типа 2');
core.AutoLogin.performAutoLoginPage2();
}
}
if (!pageType.hasAppMarker) {
debugLog('⏹ Не CLEVER PARK, отключаемся');
return;
}
// Настраиваем Escape
if (core.CloseHandler) {
core.CloseHandler.setupEscapeHandler();
}
// Видео страница
if (pageType.isVideoPage && core.VideoWindow) {
debugLog('🎬 ВИДЕО СТРАНИЦА');
core.retryWithBackoff(() => core.VideoWindow.addButtonToVideoWindow());
const videoObserver = new MutationObserver(() => {
core.VideoWindow.addButtonToVideoWindow();
});
videoObserver.observe(document.body, { childList: true, subtree: true });
}
// Главная страница
if (core.Mnemoschema) {
debugLog('🏠 ГЛАВНАЯ СТРАНИЦА');
const addMnemoButton = () => {
if (!core.activeSchemeButton) {
core.Mnemoschema.addSchemeButton();
}
};
core.retryWithBackoff(addMnemoButton);
}
// Применяем текущий uiVisible после добавления всех элементов
setTimeout(() => applyVisibility(core.CONFIG.uiVisible !== false), 200);
// Слушаем обновления конфигурации для мгновенного применения видимости
document.addEventListener('VideoIPRedirect:ConfigUpdated', () => {
applyVisibility(core.CONFIG.uiVisible !== false);
});
// Горячая клавиша Shift+F1 — переключение видимости улучшений
document.addEventListener('keydown', (e) => {
if (e.shiftKey && e.key === 'F1') {
e.preventDefault();
toggleVisibility();
}
});
debugLog('========== ГОТОВО ==========');
}
// ---- Управление видимостью UI-улучшений ----
function applyVisibilityToElement(el) {
if (!el) return;
const core = window.VideoIPRedirect;
const visible = core && core.CONFIG.uiVisible !== false;
if (el.hasAttribute('data-caps-logo')) {
if (visible && capsLogoUrl) {
el.src = capsLogoUrl;
} else if (!visible && el.dataset.capsOriginalSrc) {
el.src = el.dataset.capsOriginalSrc;
}
} else {
el.style.display = visible ? '' : 'none';
}
}
function applyVisibility(visible) {
// Скрываем/показываем UI-элементы расширения
document.querySelectorAll('[data-caps-ui="true"]').forEach(el => {
el.style.display = visible ? (el.dataset.capsUiDisplay || '') : 'none';
});
// Показываем/скрываем оригинальные элементы (обратная логика)
document.querySelectorAll('[data-caps-original="true"]').forEach(el => {
el.style.display = visible ? 'none' : '';
});
// Для логотипа меняем src вместо скрытия
document.querySelectorAll('[data-caps-logo="true"]').forEach(el => {
if (visible && capsLogoUrl) {
el.src = capsLogoUrl;
} else if (!visible && el.dataset.capsOriginalSrc) {
el.src = el.dataset.capsOriginalSrc;
}
});
}
function toggleVisibility() {
const core = window.VideoIPRedirect;
if (!core) return;
const newVisible = !(core.CONFIG.uiVisible !== false);
core.CONFIG.uiVisible = newVisible;
applyVisibility(newVisible);
// Сохраняем в storage и рассылаем другим вкладкам
if (typeof chrome !== 'undefined' && chrome.storage) {
chrome.storage.sync.get(['config'], (result) => {
const cfg = result.config || {};
cfg.uiVisible = newVisible;
chrome.storage.sync.set({ config: cfg });
});
}
if (typeof chrome !== 'undefined' && chrome.runtime) {
chrome.runtime.sendMessage({
type: 'CONFIG_UPDATED',
config: { uiVisible: newVisible }
}).catch(() => {});
}
}
// ---- Обработка запросов из popup ----
if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onMessage) {
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'PERFORM_LOGIN') {
const core = window.VideoIPRedirect;
if (!core || !core.AutoLogin) {
sendResponse({ ok: false, error: 'not_ready' });
return true;
}
const result = core.AutoLogin.performLoginOnce();
sendResponse(result);
return true;
}
if (message.type === 'TOGGLE_UI_VISIBILITY') {
toggleVisibility();
sendResponse({ ok: true });
return true;
}
});
}
})();