caps_enhancer/js/content.js
2026-03-23 16:47:34 +03:00

276 lines
11 KiB
JavaScript
Raw 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() {
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.capsReplaced = '1';
logo.setAttribute('data-caps-ui', 'true');
logo.src = chrome.runtime.getURL('icons/caps.svg');
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;
}
// Кнопка переключения видимости UI (показывается на всех CAPS-страницах)
addToggleButton();
// Настраиваем 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;
el.style.display = visible ? '' : 'none';
}
function applyVisibility(visible) {
document.querySelectorAll('[data-caps-ui="true"]').forEach(el => {
// Кнопка-переключатель не скрывается — иначе не выйти из режима скрытия
if (el.classList.contains('caps-ui-toggle-btn')) return;
el.style.display = visible ? '' : 'none';
});
// Обновляем иконку кнопки переключателя
const toggleBtn = document.querySelector('.caps-ui-toggle-btn');
if (toggleBtn) {
toggleBtn.title = visible ? 'Скрыть улучшения CAPS (Shift+F1)' : 'Показать улучшения CAPS (Shift+F1)';
toggleBtn.textContent = visible ? '👁' : '🙈';
}
}
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(() => {});
}
}
function addToggleButton() {
if (document.querySelector('.caps-ui-toggle-btn')) return;
const core = window.VideoIPRedirect;
const visible = core && core.CONFIG.uiVisible !== false;
const btn = document.createElement('button');
btn.className = 'caps-ui-toggle-btn';
btn.setAttribute('data-caps-ui', 'true');
btn.textContent = visible ? '👁' : '🙈';
btn.title = visible ? 'Скрыть улучшения CAPS (Shift+F1)' : 'Показать улучшения CAPS (Shift+F1)';
btn.style.cssText = `
position: fixed;
bottom: 16px;
right: 16px;
z-index: 999999;
width: 36px;
height: 36px;
border-radius: 50%;
border: none;
background: rgba(102, 126, 234, 0.85);
color: white;
font-size: 18px;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
display: flex;
align-items: center;
justify-content: center;
padding: 0;
line-height: 1;
transition: opacity 0.2s;
`;
btn.onmouseover = () => { btn.style.opacity = '1'; };
btn.onmouseout = () => { btn.style.opacity = '0.7'; };
btn.style.opacity = '0.7';
btn.onclick = () => toggleVisibility();
document.body.appendChild(btn);
}
// ---- Обработка запросов из 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;
}
});
}
})();