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

175 lines
6.5 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.

// ==================== POPUP РАСШИРЕНИЯ ====================
const DEFAULT_CONFIG = {
debug: { enabled: true },
disabledSites: [],
uiVisible: true,
autologin: { profiles: [], profilePage1: 0 }
};
const el = {
disableOnSite: document.getElementById('disable-on-site'),
disableOnSiteLabel: document.getElementById('disable-on-site-label'),
debug: document.getElementById('debug'),
uiVisible: document.getElementById('ui-visible'),
btnLogin: document.getElementById('btn-login'),
loginStatus: document.getElementById('login-status'),
reloadRow: document.getElementById('reload-row'),
btnReload: document.getElementById('btn-reload')
};
function getStr(path) {
const o = window.CAPS_STRINGS || {};
const val = path.split('.').reduce((acc, k) => acc && acc[k], o);
return (val !== undefined && val !== null) ? val : path;
}
function applyPopupStrings() {
document.querySelectorAll('[data-i18n]').forEach((node) => {
const key = node.getAttribute('data-i18n');
const text = getStr(key);
if (text === '') {
node.style.display = 'none';
} else if (text && node.tagName !== 'OPTION') {
node.textContent = text;
}
});
}
function updateDisableOnSiteLabel() {
if (!el.disableOnSiteLabel) return;
el.disableOnSiteLabel.textContent = el.disableOnSite.checked ? getStr('popup.siteWorking') : getStr('popup.siteDisabled');
}
let currentHostname = '';
function showLoginStatus(text, type) {
el.loginStatus.textContent = text;
el.loginStatus.className = 'status-text ' + (type || '');
}
function loadConfig() {
return new Promise((resolve) => {
chrome.storage.sync.get(['config'], (result) => {
const config = result.config || {};
resolve(config);
});
});
}
function saveConfig(updates) {
return new Promise((resolve) => {
chrome.storage.sync.get(['config'], (result) => {
const config = { ...(result.config || {}), ...updates };
if (!Array.isArray(config.disabledSites)) config.disabledSites = [];
chrome.storage.sync.set({ config }, () => {
// Уведомить вкладки об обновлении конфига
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, { type: 'CONFIG_UPDATED', config }).catch(() => {});
});
});
resolve();
});
});
});
}
function getActiveTab() {
return new Promise((resolve) => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
resolve(tabs[0] || null);
});
});
}
async function init() {
applyPopupStrings();
const [config, tab] = await Promise.all([loadConfig(), getActiveTab()]);
currentHostname = tab ? new URL(tab.url || 'http://a').hostname : '';
/* Слайд вкл = расширение работает (сайт НЕ в списке отключённых) */
const disabledSites = config.disabledSites || [];
el.disableOnSite.checked = currentHostname ? !disabledSites.includes(currentHostname) : false;
el.disableOnSite.disabled = !currentHostname;
updateDisableOnSiteLabel();
const debug = config.debug || DEFAULT_CONFIG.debug;
el.debug.checked = debug.enabled !== false;
el.uiVisible.checked = config.uiVisible !== false;
function showReloadButton() {
if (el.reloadRow) el.reloadRow.classList.remove('hidden');
}
el.disableOnSite.addEventListener('change', async () => {
updateDisableOnSiteLabel();
let list = (await loadConfig()).disabledSites || [];
if (!Array.isArray(list)) list = [];
if (el.disableOnSite.checked) {
list = list.filter((h) => h !== currentHostname);
} else {
if (currentHostname && !list.includes(currentHostname)) list.push(currentHostname);
}
await saveConfig({ disabledSites: list });
showReloadButton();
});
el.debug.addEventListener('change', async () => {
const config = await loadConfig();
const debug = config.debug || { modules: {} };
await saveConfig({ debug: { ...debug, enabled: el.debug.checked } });
showReloadButton();
});
el.uiVisible.addEventListener('change', async () => {
await saveConfig({ uiVisible: el.uiVisible.checked });
// Немедленно применяем на активной вкладке через сообщение
const tab = await getActiveTab();
if (tab && tab.id) {
chrome.tabs.sendMessage(tab.id, { type: 'TOGGLE_UI_VISIBILITY' }).catch(() => {});
}
});
el.btnReload.addEventListener('click', async () => {
const tab = await getActiveTab();
if (tab && tab.id) {
chrome.tabs.reload(tab.id);
window.close();
}
});
el.btnLogin.addEventListener('click', async () => {
const tab = await getActiveTab();
if (!tab || !tab.id) {
showLoginStatus(getStr('popup.statusNoTab'), 'error');
return;
}
const config = await loadConfig();
const al = config.autologin || {};
const profiles = Array.isArray(al.profiles) ? al.profiles : [];
const profileIdx = al.profilePage1 || 0;
const profile = profiles[profileIdx] || profiles[0];
if (!profile || !profile.username || !profile.password) {
showLoginStatus(getStr('popup.statusNoCredentials'), 'error');
return;
}
el.btnLogin.disabled = true;
showLoginStatus('…', '');
try {
const response = await chrome.tabs.sendMessage(tab.id, { type: 'PERFORM_LOGIN' });
if (response && response.ok) {
const profileName = response.profileName ? ` (${response.profileName})` : '';
showLoginStatus(getStr('popup.statusLoginOk') + profileName, 'success');
} else {
const err = (response && response.error) || 'error';
const msg = err === 'not_login_page' ? getStr('popup.statusNotLoginPage') : err === 'no_credentials' ? getStr('popup.statusNoCredentialsShort') : getStr('popup.statusLoginError');
showLoginStatus(msg, 'error');
}
} catch (e) {
showLoginStatus(getStr('popup.statusOpenLoginPage'), 'error');
}
el.btnLogin.disabled = false;
});
}
init();