309 lines
11 KiB
JavaScript
309 lines
11 KiB
JavaScript
class PopupManager {
|
|
constructor() {
|
|
this.currentTab = null;
|
|
this.currentDomain = null;
|
|
this.currentConfig = null;
|
|
this.init();
|
|
}
|
|
|
|
async init() {
|
|
await this.loadCurrentTab();
|
|
await this.loadConfig();
|
|
await this.loadProfiles();
|
|
this.setupUI();
|
|
this.setupEventListeners();
|
|
}
|
|
|
|
async loadCurrentTab() {
|
|
try {
|
|
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
|
this.currentTab = tabs[0];
|
|
|
|
if (this.currentTab.url) {
|
|
this.currentDomain = this.extractDomain(this.currentTab.url);
|
|
document.getElementById('current-domain').textContent = this.currentDomain;
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load current tab:', error);
|
|
document.getElementById('current-domain').textContent = 'Unknown domain';
|
|
}
|
|
}
|
|
|
|
extractDomain(url) {
|
|
try {
|
|
const urlObj = new URL(url);
|
|
return urlObj.hostname.replace(/^www\./, '');
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async loadConfig() {
|
|
try {
|
|
const response = await browser.runtime.sendMessage({ action: 'getConfig' });
|
|
const config = response.config || { domains: {} };
|
|
this.applyTheme(config.settings && config.settings.theme);
|
|
this.currentConfig = this.currentDomain && config.domains
|
|
? config.domains[this.currentDomain] || null
|
|
: null;
|
|
} catch (error) {
|
|
console.error('Failed to load config:', error);
|
|
this.currentConfig = null;
|
|
}
|
|
}
|
|
|
|
applyTheme(theme) {
|
|
document.documentElement.dataset.theme = ['light', 'dark', 'system'].includes(theme) ? theme : 'system';
|
|
}
|
|
|
|
async loadProfiles() {
|
|
try {
|
|
const response = await browser.runtime.sendMessage({ action: 'getProfiles' });
|
|
const profiles = response.profiles || {};
|
|
this.updateProfileSelect(profiles);
|
|
} catch (error) {
|
|
console.error('Failed to load profiles:', error);
|
|
}
|
|
}
|
|
|
|
updateProfileSelect(profiles) {
|
|
const select = document.getElementById('popup-profile-select');
|
|
|
|
// Clear select, keeping only default option
|
|
select.innerHTML = '<option value="">-- Select Profile --</option>';
|
|
|
|
// Add profiles
|
|
Object.keys(profiles).sort().forEach(profileName => {
|
|
const option = document.createElement('option');
|
|
option.value = profileName;
|
|
option.textContent = profileName;
|
|
select.appendChild(option);
|
|
});
|
|
}
|
|
|
|
// Fill form with profile data
|
|
fillFormFromProfile(profileName) {
|
|
if (!profileName) {
|
|
// If empty profile selected, do nothing
|
|
return;
|
|
}
|
|
|
|
// Get profile data
|
|
browser.runtime.sendMessage({ action: 'getProfile', profileName })
|
|
.then(response => {
|
|
const profile = response.profile;
|
|
if (profile) {
|
|
// Fill form fields
|
|
document.getElementById('popup-proxy-type').value = profile.type || 'http';
|
|
document.getElementById('popup-proxy-host').value = profile.host || '';
|
|
document.getElementById('popup-proxy-port').value = profile.port || '';
|
|
document.getElementById('popup-proxy-username').value = profile.username || '';
|
|
document.getElementById('popup-proxy-password').value = profile.password || '';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Failed to load profile for form:', error);
|
|
});
|
|
}
|
|
|
|
setupUI() {
|
|
const enableCheckbox = document.getElementById('enable-proxy');
|
|
const proxyForm = document.getElementById('proxy-form');
|
|
const noProxyInfo = document.getElementById('no-proxy-info');
|
|
|
|
if (this.currentConfig) {
|
|
// Proxy configured for this domain
|
|
enableCheckbox.checked = Boolean(this.currentConfig.enabled);
|
|
enableCheckbox.disabled = false;
|
|
// Show/hide form based on checkbox state
|
|
this.updateFormVisibility(enableCheckbox.checked);
|
|
noProxyInfo.classList.add('hidden');
|
|
|
|
// Populate form
|
|
this.populateForm();
|
|
} else {
|
|
// Proxy not configured
|
|
enableCheckbox.checked = false;
|
|
enableCheckbox.disabled = !this.currentDomain;
|
|
proxyForm.classList.add('hidden');
|
|
noProxyInfo.classList.remove('hidden');
|
|
}
|
|
}
|
|
|
|
updateFormVisibility(showForm) {
|
|
const proxyForm = document.getElementById('proxy-form');
|
|
proxyForm.classList.toggle('hidden', !showForm);
|
|
}
|
|
|
|
populateForm() {
|
|
if (!this.currentConfig) return;
|
|
|
|
document.getElementById('popup-proxy-type').value = this.currentConfig.type || 'http';
|
|
document.getElementById('popup-proxy-host').value = this.currentConfig.host || '';
|
|
document.getElementById('popup-proxy-port').value = this.currentConfig.port || '';
|
|
document.getElementById('popup-proxy-username').value = this.currentConfig.username || '';
|
|
document.getElementById('popup-proxy-password').value = this.currentConfig.password || '';
|
|
}
|
|
|
|
async saveConfig() {
|
|
if (!this.currentDomain) return;
|
|
|
|
// Collect form data
|
|
const domainConfig = {
|
|
type: document.getElementById('popup-proxy-type').value,
|
|
host: document.getElementById('popup-proxy-host').value.trim(),
|
|
port: parseInt(document.getElementById('popup-proxy-port').value, 10),
|
|
username: document.getElementById('popup-proxy-username').value.trim() || null,
|
|
password: document.getElementById('popup-proxy-password').value || null,
|
|
enabled: document.getElementById('enable-proxy').checked
|
|
};
|
|
|
|
// Validation
|
|
if (!domainConfig.host || !domainConfig.port) {
|
|
this.showError('Host and port are required');
|
|
return false;
|
|
}
|
|
|
|
if (domainConfig.port < 1 || domainConfig.port > 65535) {
|
|
this.showError('Port must be between 1 and 65535');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
// Use centralized API for domain update
|
|
const response = await browser.runtime.sendMessage({
|
|
action: 'updateDomain',
|
|
domain: this.currentDomain,
|
|
domainConfig: domainConfig
|
|
});
|
|
|
|
return response.success;
|
|
} catch (error) {
|
|
console.error('Failed to save config:', error);
|
|
this.showError('Failed to save configuration');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async removeDomainConfig() {
|
|
try {
|
|
// Use centralized API for domain removal
|
|
const response = await browser.runtime.sendMessage({
|
|
action: 'removeDomain',
|
|
domain: this.currentDomain
|
|
});
|
|
|
|
return response.success;
|
|
} catch (error) {
|
|
console.error('Failed to remove config:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async toggleProxy(enabled) {
|
|
if (!this.currentDomain) return;
|
|
|
|
try {
|
|
const response = await browser.runtime.sendMessage({
|
|
action: 'toggleProxy',
|
|
domain: this.currentDomain,
|
|
enabled: enabled
|
|
});
|
|
|
|
if (!response.success) {
|
|
// If domain not configured, show message
|
|
this.showError('Domain not configured. Use "Apply & Reload" to configure proxy first.');
|
|
// Return checkbox to previous state
|
|
document.getElementById('enable-proxy').checked = !enabled;
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to toggle proxy:', error);
|
|
this.showError('Failed to toggle proxy');
|
|
// Return checkbox to previous state
|
|
document.getElementById('enable-proxy').checked = !enabled;
|
|
}
|
|
}
|
|
|
|
async applyAndReload() {
|
|
const success = await this.saveConfig();
|
|
|
|
if (success && this.currentTab) {
|
|
// Reload tab
|
|
await browser.tabs.reload(this.currentTab.id);
|
|
|
|
// Close popup
|
|
window.close();
|
|
}
|
|
}
|
|
|
|
showError(message) {
|
|
// Simple error display implementation
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.className = 'error-message';
|
|
errorDiv.textContent = message;
|
|
errorDiv.style.cssText = `
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border-radius: 4px;
|
|
border: 1px solid #f5c6cb;
|
|
`;
|
|
|
|
const main = document.querySelector('.popup-main');
|
|
main.insertBefore(errorDiv, main.firstChild);
|
|
|
|
setTimeout(() => errorDiv.remove(), 3000);
|
|
}
|
|
|
|
setupEventListeners() {
|
|
// Proxy toggle (quick enable/disable)
|
|
document.getElementById('enable-proxy').addEventListener('change', async (e) => {
|
|
const enabled = e.target.checked;
|
|
this.updateFormVisibility(enabled); // Show/hide form
|
|
// A new domain has no stored configuration yet; Apply & Reload saves it.
|
|
if (this.currentConfig) {
|
|
await this.toggleProxy(enabled);
|
|
}
|
|
});
|
|
|
|
// Apply settings
|
|
document.getElementById('apply-proxy').addEventListener('click', () => {
|
|
this.applyAndReload();
|
|
});
|
|
|
|
// Open settings
|
|
document.getElementById('open-options').addEventListener('click', () => {
|
|
browser.runtime.openOptionsPage();
|
|
window.close();
|
|
});
|
|
|
|
// Show/hide password
|
|
document.querySelector('.toggle-password').addEventListener('click', (e) => {
|
|
const input = document.getElementById('popup-proxy-password');
|
|
const type = input.type === 'password' ? 'text' : 'password';
|
|
input.type = type;
|
|
e.target.textContent = type === 'password' ? '👁' : '👁️🗨️';
|
|
});
|
|
|
|
// Handle Enter in form
|
|
document.querySelectorAll('input').forEach(input => {
|
|
input.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') {
|
|
this.applyAndReload();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Fill form from profile
|
|
document.getElementById('popup-profile-select').addEventListener('change', (e) => {
|
|
this.fillFormFromProfile(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Initialization
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
new PopupManager();
|
|
});
|