console.log("Content script starting..."); // 代理操作类型常量 const ProxyActionType = { SET_PROXY_CONFIG: 'SET_PROXY_CONFIG', CLEAR_PROXY_CONFIG: 'CLEAR_PROXY_CONFIG', GET_PROXY_STATUS: 'GET_PROXY_STATUS', GET_PROXY_CONFIGS: 'GET_PROXY_CONFIGS', UPDATE_PROXY_CONFIG: 'UPDATE_PROXY_CONFIG' }; // 在文件顶部添加常量声明 const YAK_ICON_URL = chrome.runtime.getURL('/images/yak.svg'); // 添加一个通用的消息发送函数 async function sendMessageWithRetry(message, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await chrome.runtime.sendMessage(message); return response; } catch (error) { console.warn(`Attempt ${i + 1} failed:`, error); if (i === maxRetries - 1) { throw error; } // 等待一小段时间后重试 await new Promise(resolve => setTimeout(resolve, 500)); } } } // 获取当前代理状态 async function getCurrentProxy() { try { const response = await sendMessageWithRetry({ action: ProxyActionType.GET_PROXY_STATUS }); if (!response) { console.log('No response from background script'); return { enable: false, proxy: '' }; } // 检查响应格式 if (!response.success) { console.error('Error in proxy status response:', response.error); return { enable: false, proxy: '' }; } const status = response.data; console.log('Proxy status from background:', status); // 根据状态返回正确的格式 if (status.mode === 'fixed_servers' && status.enabled && status.config) { const config = status.config; // 只在确实有配置时才返回代理信息 if (config.scheme && config.host && config.port) { return { enable: true, proxy: `${config.scheme}://${config.host}:${config.port}` }; } } // 对于直连或系统代理,返回相应状态 return { enable: false, proxy: status.mode === 'system' ? 'system' : '' }; } catch (error) { console.error('Error getting proxy status:', error); return { enable: false, proxy: '' }; } } // 获取所有代理配置 async function getProxyConfigs() { try { const response = await sendMessageWithRetry({ action: ProxyActionType.GET_PROXY_CONFIGS }); if (!response) { console.log('No response from background script'); return []; } if (!response.success) { console.error('Error in response:', response.error); return []; } return response.data || []; } catch (error) { console.error('Error getting proxy configs:', error); return []; } } // 切换代理 async function switchProxy(config) { try { console.log('Switching proxy:', config); await sendMessageWithRetry({ action: ProxyActionType.SET_PROXY_CONFIG, config: config }); await updatePanel(); } catch (error) { console.error('Error switching proxy:', error); } } // 清除代理 async function clearProxy() { try { const response = await sendMessageWithRetry({ action: ProxyActionType.SET_PROXY_CONFIG, config: { id: 'direct', name: '[直接连接]', proxyType: 'direct', enabled: false } }); console.log('Clear proxy response:', response); await updatePanel(); } catch (error) { console.error('Error clearing proxy:', error); } } // 更新面板显示 async function updatePanel() { const panel = document.getElementById('yakit-proxy-panel')?.shadowRoot?.querySelector('.panel-content'); if (!panel) return; const currentProxy = await getCurrentProxy(); const configs = await getProxyConfigs(); console.log('Current proxy status:', currentProxy); // 修改这里的判断逻辑 let html = `
🟢 [直接连接]
⚙️ [系统代理]
`; // 修改自定义代理配置的判断逻辑 configs.forEach(config => { if (config.id !== 'direct' && config.id !== 'system') { const proxyUrl = `${config.scheme}://${config.host}:${config.port}`; const isActive = currentProxy.enable && currentProxy.proxy === proxyUrl && config.enabled; // 添加 title 属性显示详细信息 const tooltipText = `${config.scheme.toUpperCase()} ${config.host}:${config.port}`; html += `
🌐 ${config.name}
`; } }); // 修改添加操作按钮部分 html += `
➕ 添加代理...
👨‍💻 选项
`; panel.innerHTML = html; // 添加事件监听 panel.querySelectorAll('.proxy-item').forEach(item => { item.addEventListener('click', async () => { const id = item.dataset.id; if (id === 'direct') { await clearProxy(); } else if (id === 'system') { await switchProxy({ id: 'system', name: '[系统代理]', proxyType: 'system' }); } else { const config = configs.find(c => c.id === id); if (config) { await switchProxy(config); } } }); }); // 修改添加代理和选项按钮的事件处理 panel.querySelector('.add-proxy')?.addEventListener('click', async () => { try { // 通过发送消息给 background script 来处理添加代理 await sendMessageWithRetry({ action: 'OPEN_OPTIONS_PAGE', triggerAdd: true // 标记需要触发添加代理 }); } catch (error) { console.error('Error handling add proxy:', error); } }); panel.querySelector('.settings')?.addEventListener('click', async () => { try { // 通过发送消息给 background script 来打开选项页 await sendMessageWithRetry({ action: 'OPEN_OPTIONS_PAGE' }); } catch (error) { console.error('Error opening options page:', error); } }); } // 创建并注入悬浮框 function createFloatingPanel() { console.log("Creating floating panel..."); // 检查是否已存在面板 if (document.getElementById('yakit-proxy-panel')) { return; } // 创建容器 const container = document.createElement('div'); container.id = 'yakit-proxy-panel'; // 创建 shadow DOM const shadow = container.attachShadow({ mode: 'open' }); // 添加样式 const style = document.createElement('style'); style.textContent = ` .floating-panel { position: fixed; top: 20px; right: 0; width: 180px; background: white; border-radius: 8px 0 0 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 2147483647; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; transition: transform 0.3s ease; } .floating-panel.collapsed { transform: translateX(100%); } .panel-header { padding: 4px; border-bottom: 1px solid #eee; border-radius: 8px 0 0 0; background: #f8f9fa; display: flex; justify-content: space-between; align-items: center; } .collapse-trigger { position: absolute; left: -20px; top: 0; width: 20px; height: 100%; background: #f8f9fa; border-radius: 8px 0 0 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: -2px 0 5px rgba(0,0,0,0.1); } .collapse-trigger:hover { background: #e9ecef; } .collapse-trigger::after { content: '◀'; transition: transform 0.3s ease; } .floating-panel.collapsed .collapse-trigger::after { transform: rotate(180deg); } .panel-content { padding: 4px; } .proxy-item { position: relative; display: flex; align-items: center; padding: 4px 10px; cursor: pointer; transition: all 0.2s; color: #666; border-left: 3px solid transparent; overflow: hidden; } .proxy-item > span { position: relative; z-index: 1; } .watermark-icon { position: absolute; right: 0; width: 100%; height: 100%; opacity: 0.3; pointer-events: none; display: none; object-fit: contain; object-position: right center; padding: 4px; } .proxy-item.active .watermark-icon { display: block; } .proxy-item.active { color: #ff6b00 !important; background: #fff7e6; border-left: 3px solid #ff6b00; } .proxy-item.active span:first-child { color: #ff6b00 !important; } .proxy-item span:first-child { margin-right: 8px; font-size: 16px; color: #666; transition: color 0.2s; } .proxy-item:hover { background: #f5f5f5; } .proxy-item:hover span:first-child { color: #ff6b00; } .add-proxy { display: flex; align-items: center; padding: 4px 10px; color: #1890ff; cursor: pointer; border-top: 1px solid #eee; transition: all 0.2s; } .add-proxy:hover { background: #f5f5f5; } .settings { padding: 4px 10px; color: #666; cursor: pointer; border-top: 1px solid #eee; transition: all 0.2s; } .settings:hover { background: #f5f5f5; } .panel-header .header-content { display: flex; align-items: center; gap: 8px; padding: 0 4px; } .yak-icon { width: 24px; height: 24px; object-fit: contain; } .divider { height: 1px; background-color: #eee; margin: 4px 0; } `; // 创建面板内容 const panel = document.createElement('div'); panel.className = 'floating-panel'; panel.innerHTML = `
Yak 代理设置
🟢 [直接连接]
⚙️ [系统代理]
➕ [添加代理...]
👨‍💻 选项
`; // 将样式和面板添加到 shadow DOM shadow.appendChild(style); shadow.appendChild(panel); // 将容器添加到页面 document.body.appendChild(container); // 添加事件监听器 const addEventListeners = () => { // 收起/展开功能 panel.querySelector('.collapse-trigger')?.addEventListener('click', (e) => { e.stopPropagation(); panel.classList.toggle('collapsed'); }); // 添加代理按钮 panel.querySelector('.add-proxy')?.addEventListener('click', () => { chrome.runtime.sendMessage({ action: 'OPEN_OPTIONS_PAGE' }); }); // 设置按钮 panel.querySelector('.settings')?.addEventListener('click', () => { chrome.runtime.sendMessage({ action: 'OPEN_OPTIONS_PAGE' }); }); }; // 初始化事件监听器 addEventListeners(); // 初始更新面板 updatePanel(); // 添加代理变化监听 let messageListener = (message) => { if (message.action === 'PROXY_STATUS_CHANGED') { updatePanel(); } }; // 确保只添加一次监听器 chrome.runtime.onMessage.removeListener(messageListener); chrome.runtime.onMessage.addListener(messageListener); // 验证面板是否成功创建 console.log("Panel created:", { containerExists: !!document.getElementById('yakit-proxy-panel'), containerVisible: window.getComputedStyle(container).display !== 'none', shadowRoot: !!container.shadowRoot, panelElement: !!container.shadowRoot?.querySelector('.floating-panel') }); } // 使用 MutationObserver 确保在 DOM 准备好时创建面板 function initPanel() { if (document.body) { console.log("Body found, creating panel"); // 确保background script已经准备好 sendMessageWithRetry({ action: 'PING' }) .then(() => { createFloatingPanel(); }) .catch(error => { console.error('Failed to initialize panel:', error); // 可以在这里添加重试逻辑 setTimeout(initPanel, 1000); }); } else { console.log("Body not found, waiting..."); const observer = new MutationObserver((mutations, obs) => { if (document.body) { console.log("Body found via observer"); obs.disconnect(); initPanel(); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); } } // 尝试多种方式来确保面板被创建 console.log("Setting up initialization..."); window.addEventListener('load', () => { console.log("Window load triggered"); initPanel(); }); // 在关键位置添加更多日志 console.log("Document readyState:", document.readyState); console.log("Document body exists:", !!document.body); console.log("Document documentElement exists:", !!document.documentElement);