mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-27 05:31:53 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
103a40fdf5 | ||
|
|
4a99b773be | ||
|
|
7fe4731b91 | ||
|
|
08af08c9a8 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Yakit Chrome Endpoint",
|
"name": "Yakit Chrome Endpoint",
|
||||||
"version": "0.0.4",
|
"version": "0.0.6",
|
||||||
"description": "A Endpoint for Yakit MITM or more",
|
"description": "A Endpoint for Yakit MITM or more",
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "proxy/options.html",
|
"page": "proxy/options.html",
|
||||||
|
|||||||
+216
-186
@@ -1,19 +1,26 @@
|
|||||||
console.log("Content script starting...");
|
console.log("Content script starting...");
|
||||||
|
|
||||||
// 代理操作类型常量
|
(function () {
|
||||||
const ProxyActionType = {
|
// 检查是否为 HTML 文档
|
||||||
SET_PROXY_CONFIG: 'SET_PROXY_CONFIG',
|
if (document.documentElement?.nodeName.toLowerCase() !== 'html') {
|
||||||
CLEAR_PROXY_CONFIG: 'CLEAR_PROXY_CONFIG',
|
console.log("Not an HTML document, content script will not run");
|
||||||
GET_PROXY_STATUS: 'GET_PROXY_STATUS',
|
return;
|
||||||
GET_PROXY_CONFIGS: 'GET_PROXY_CONFIGS',
|
}
|
||||||
UPDATE_PROXY_CONFIG: 'UPDATE_PROXY_CONFIG'
|
|
||||||
};
|
|
||||||
|
|
||||||
// 在文件顶部添加常量声明
|
// 代理操作类型常量
|
||||||
const YAK_ICON_URL = chrome.runtime.getURL('/images/yak.svg');
|
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",
|
||||||
|
};
|
||||||
|
|
||||||
// 添加一个通用的消息发送函数
|
// 在文件顶部添加常量声明
|
||||||
async function sendMessageWithRetry(message, maxRetries = 3) {
|
const YAK_ICON_URL = chrome.runtime.getURL("/images/yak.svg");
|
||||||
|
|
||||||
|
// 添加一个通用的消息发送函数
|
||||||
|
async function sendMessageWithRetry(message, maxRetries = 3) {
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
try {
|
try {
|
||||||
return await chrome.runtime.sendMessage(message);
|
return await chrome.runtime.sendMessage(message);
|
||||||
@@ -23,123 +30,123 @@ async function sendMessageWithRetry(message, maxRetries = 3) {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
// 等待一小段时间后重试
|
// 等待一小段时间后重试
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前代理状态
|
// 获取当前代理状态
|
||||||
async function getCurrentProxy() {
|
async function getCurrentProxy() {
|
||||||
try {
|
try {
|
||||||
const response = await sendMessageWithRetry({
|
const response = await sendMessageWithRetry({
|
||||||
action: ProxyActionType.GET_PROXY_STATUS
|
action: ProxyActionType.GET_PROXY_STATUS,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response || !response.success) {
|
if (!response || !response.success) {
|
||||||
console.log('No valid response from background script');
|
console.log("No valid response from background script");
|
||||||
return { enable: false, proxy: '', currentMode: 'direct' };
|
return {enable: false, proxy: "", currentMode: "direct"};
|
||||||
}
|
}
|
||||||
|
|
||||||
const status = response.data;
|
const status = response.data;
|
||||||
console.log('Proxy status from background:', status);
|
console.log("Proxy status from background:", status);
|
||||||
|
|
||||||
// 返回当前模式
|
// 返回当前模式
|
||||||
return {
|
return {
|
||||||
enable: status.enabled,
|
enable: status.enabled,
|
||||||
proxy: status.mode === 'system' ? 'system' : '',
|
proxy: status.mode === "system" ? "system" : "",
|
||||||
currentMode: status.mode || 'direct' // 使用 mode 来判断当前激活的代理
|
currentMode: status.mode || "direct", // 使用 mode 来判断当前激活的代理
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting proxy status:', error);
|
console.error("Error getting proxy status:", error);
|
||||||
return { enable: false, proxy: '', currentMode: 'direct' };
|
return {enable: false, proxy: "", currentMode: "direct"};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有代理配置
|
// 获取所有代理配置
|
||||||
async function getProxyConfigs() {
|
async function getProxyConfigs() {
|
||||||
try {
|
try {
|
||||||
const response = await sendMessageWithRetry({
|
const response = await sendMessageWithRetry({
|
||||||
action: ProxyActionType.GET_PROXY_CONFIGS
|
action: ProxyActionType.GET_PROXY_CONFIGS,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
console.log('No response from background script');
|
console.log("No response from background script");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
console.error('Error in response:', response.error);
|
console.error("Error in response:", response.error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return response.data || [];
|
return response.data || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting proxy configs:', error);
|
console.error("Error getting proxy configs:", error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换代理
|
// 切换代理
|
||||||
async function switchProxy(config) {
|
async function switchProxy(config) {
|
||||||
try {
|
try {
|
||||||
console.log('Switching proxy:', config);
|
console.log("Switching proxy:", config);
|
||||||
|
|
||||||
// 根据配置类型构建正确的配置对象
|
// 根据配置类型构建正确的配置对象
|
||||||
let proxyConfig;
|
let proxyConfig;
|
||||||
if (config.proxyType === 'system') {
|
if (config.proxyType === "system") {
|
||||||
proxyConfig = {
|
proxyConfig = {
|
||||||
id: 'system',
|
id: "system",
|
||||||
name: '[系统代理]',
|
name: "[系统代理]",
|
||||||
proxyType: 'system',
|
proxyType: "system",
|
||||||
enabled: true
|
enabled: true,
|
||||||
};
|
};
|
||||||
} else if (config.proxyType === 'direct') {
|
} else if (config.proxyType === "direct") {
|
||||||
proxyConfig = {
|
proxyConfig = {
|
||||||
id: 'direct',
|
id: "direct",
|
||||||
name: '[直接连接]',
|
name: "[直接连接]",
|
||||||
proxyType: 'direct',
|
proxyType: "direct",
|
||||||
enabled: false
|
enabled: false,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
proxyConfig = {
|
proxyConfig = {
|
||||||
...config,
|
...config,
|
||||||
enabled: true
|
enabled: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送配置更改消息
|
// 发送配置更改消息
|
||||||
await sendMessageWithRetry({
|
await sendMessageWithRetry({
|
||||||
action: ProxyActionType.SET_PROXY_CONFIG,
|
action: ProxyActionType.SET_PROXY_CONFIG,
|
||||||
config: proxyConfig
|
config: proxyConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
await PanelManager.updatePanel();
|
await PanelManager.updatePanel();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error switching proxy:', error);
|
console.error("Error switching proxy:", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 清除代理
|
// 清除代理
|
||||||
async function clearProxy() {
|
async function clearProxy() {
|
||||||
try {
|
try {
|
||||||
const response = await sendMessageWithRetry({
|
const response = await sendMessageWithRetry({
|
||||||
action: ProxyActionType.SET_PROXY_CONFIG,
|
action: ProxyActionType.SET_PROXY_CONFIG,
|
||||||
config: {
|
config: {
|
||||||
id: 'direct',
|
id: "direct",
|
||||||
name: '[直接连接]',
|
name: "[直接连接]",
|
||||||
proxyType: 'direct',
|
proxyType: "direct",
|
||||||
enabled: false
|
enabled: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Clear proxy response:', response);
|
console.log("Clear proxy response:", response);
|
||||||
// 使用 PanelManager 的 updatePanel 方法
|
// 使用 PanelManager 的 updatePanel 方法
|
||||||
await PanelManager.updatePanel();
|
await PanelManager.updatePanel();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error clearing proxy:', error);
|
console.error("Error clearing proxy:", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 修改 PanelManager
|
// 修改 PanelManager
|
||||||
const PanelManager = {
|
const PanelManager = {
|
||||||
panel: null,
|
panel: null,
|
||||||
messageListener: null,
|
messageListener: null,
|
||||||
_updating: false,
|
_updating: false,
|
||||||
@@ -155,18 +162,18 @@ const PanelManager = {
|
|||||||
init() {
|
init() {
|
||||||
// 确保 document.body 存在
|
// 确保 document.body 存在
|
||||||
if (!document.body) {
|
if (!document.body) {
|
||||||
console.log('Body not ready, waiting...');
|
console.log("Body not ready, waiting...");
|
||||||
this.waitForBody();
|
this.waitForBody();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.panel) {
|
if (this.panel) {
|
||||||
console.log('Panel already exists, updating...');
|
console.log("Panel already exists, updating...");
|
||||||
this.updatePanel();
|
this.updatePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Creating new panel...');
|
console.log("Creating new panel...");
|
||||||
this.createPanel();
|
this.createPanel();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -177,10 +184,10 @@ const PanelManager = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Setting up MutationObserver for body');
|
console.log("Setting up MutationObserver for body");
|
||||||
const observer = new MutationObserver((mutations, obs) => {
|
const observer = new MutationObserver((mutations, obs) => {
|
||||||
if (document.body) {
|
if (document.body) {
|
||||||
console.log('Body found via observer');
|
console.log("Body found via observer");
|
||||||
obs.disconnect();
|
obs.disconnect();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -188,25 +195,25 @@ const PanelManager = {
|
|||||||
|
|
||||||
observer.observe(document.documentElement, {
|
observer.observe(document.documentElement, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true
|
subtree: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
createPanel() {
|
createPanel() {
|
||||||
if (!document.body) {
|
if (!document.body) {
|
||||||
console.log('Body not available during panel creation');
|
console.log("Body not available during panel creation");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建容器
|
// 创建容器
|
||||||
const container = document.createElement('div');
|
const container = document.createElement("div");
|
||||||
container.id = 'yakit-proxy-panel';
|
container.id = "yakit-proxy-panel";
|
||||||
|
|
||||||
// 创建 shadow DOM
|
// 创建 shadow DOM
|
||||||
const shadow = container.attachShadow({ mode: 'open' });
|
const shadow = container.attachShadow({mode: "open"});
|
||||||
|
|
||||||
// 添加样式
|
// 添加样式
|
||||||
const style = document.createElement('style');
|
const style = document.createElement("style");
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
.floating-panel {
|
.floating-panel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -440,8 +447,8 @@ const PanelManager = {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
// 创建面板内容
|
// 创建面板内容
|
||||||
const panel = document.createElement('div');
|
const panel = document.createElement("div");
|
||||||
panel.className = 'floating-panel';
|
panel.className = "floating-panel";
|
||||||
panel.innerHTML = `
|
panel.innerHTML = `
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
@@ -465,8 +472,8 @@ const PanelManager = {
|
|||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
this.panel = container;
|
this.panel = container;
|
||||||
|
|
||||||
const floatingPanel = shadow.querySelector('.floating-panel');
|
const floatingPanel = shadow.querySelector(".floating-panel");
|
||||||
const header = shadow.querySelector('.panel-header');
|
const header = shadow.querySelector(".panel-header");
|
||||||
|
|
||||||
// 添加拖拽功能
|
// 添加拖拽功能
|
||||||
this._initDragFeature(header, floatingPanel);
|
this._initDragFeature(header, floatingPanel);
|
||||||
@@ -475,9 +482,9 @@ const PanelManager = {
|
|||||||
this._initAutoCollapse(floatingPanel);
|
this._initAutoCollapse(floatingPanel);
|
||||||
|
|
||||||
// 添加点击展开/收起功能
|
// 添加点击展开/收起功能
|
||||||
header.addEventListener('click', (e) => {
|
header.addEventListener("click", (e) => {
|
||||||
if (!this.isDragging) {
|
if (!this.isDragging) {
|
||||||
floatingPanel.classList.toggle('expanded');
|
floatingPanel.classList.toggle("expanded");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -488,7 +495,7 @@ const PanelManager = {
|
|||||||
this.updatePanel();
|
this.updatePanel();
|
||||||
|
|
||||||
// 添加页面卸载时的清理
|
// 添加页面卸载时的清理
|
||||||
window.addEventListener('unload', () => {
|
window.addEventListener("unload", () => {
|
||||||
if (this._pollingInterval) {
|
if (this._pollingInterval) {
|
||||||
clearInterval(this._pollingInterval);
|
clearInterval(this._pollingInterval);
|
||||||
}
|
}
|
||||||
@@ -497,7 +504,7 @@ const PanelManager = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating panel:', error);
|
console.error("Error creating panel:", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -513,9 +520,11 @@ const PanelManager = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理状态更新消息
|
// 处理状态更新消息
|
||||||
if (message.action === 'PROXY_STATUS_CHANGED' ||
|
if (
|
||||||
message.action === 'PROXY_CONFIGS_UPDATED') {
|
message.action === "PROXY_STATUS_CHANGED" ||
|
||||||
console.log('Received update message:', message, 'from:', sender);
|
message.action === "PROXY_CONFIGS_UPDATED"
|
||||||
|
) {
|
||||||
|
console.log("Received update message:", message, "from:", sender);
|
||||||
await this.updatePanel();
|
await this.updatePanel();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -525,18 +534,19 @@ const PanelManager = {
|
|||||||
|
|
||||||
async updatePanel() {
|
async updatePanel() {
|
||||||
if (!this.panel || !document.body.contains(this.panel)) {
|
if (!this.panel || !document.body.contains(this.panel)) {
|
||||||
console.log('Panel not in document, recreating...');
|
console.log("Panel not in document, recreating...");
|
||||||
this.createPanel();
|
this.createPanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const panel = this.panel.shadowRoot?.querySelector('.panel-content');
|
const panel = this.panel.shadowRoot?.querySelector(".panel-content");
|
||||||
if (!panel) return;
|
if (!panel) return;
|
||||||
|
|
||||||
// 使用更新队列确保更新按顺序执行
|
// 使用更新队列确保更新按顺序执行
|
||||||
this._updateQueue = this._updateQueue.then(async () => {
|
this._updateQueue = this._updateQueue
|
||||||
|
.then(async () => {
|
||||||
if (this._updating) {
|
if (this._updating) {
|
||||||
console.log('Update already in progress, skipping...');
|
console.log("Update already in progress, skipping...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,38 +556,39 @@ const PanelManager = {
|
|||||||
// 获取最新状态
|
// 获取最新状态
|
||||||
const [currentProxy, configs] = await Promise.all([
|
const [currentProxy, configs] = await Promise.all([
|
||||||
getCurrentProxy(),
|
getCurrentProxy(),
|
||||||
getProxyConfigs()
|
getProxyConfigs(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 状态没有变化时不更新
|
// 状态没有变化时不更新
|
||||||
const newState = JSON.stringify({ currentProxy, configs });
|
const newState = JSON.stringify({currentProxy, configs});
|
||||||
if (this._currentState === newState) {
|
if (this._currentState === newState) {
|
||||||
console.log('State unchanged, skipping update');
|
console.log("State unchanged, skipping update");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._currentState = newState;
|
this._currentState = newState;
|
||||||
|
|
||||||
// 再次检查面板状态
|
// 再次检查面板状态
|
||||||
if (!this.panel || !document.body.contains(this.panel)) {
|
if (!this.panel || !document.body.contains(this.panel)) {
|
||||||
console.log('Panel was removed during data fetch');
|
console.log("Panel was removed during data fetch");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Updating panel with:', { currentProxy, configs });
|
console.log("Updating panel with:", {currentProxy, configs});
|
||||||
|
|
||||||
if (!Array.isArray(configs)) {
|
if (!Array.isArray(configs)) {
|
||||||
console.error('Invalid configs:', configs);
|
console.error("Invalid configs:", configs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存当前激活的项
|
// 保存当前激活的项
|
||||||
const currentActiveId = panel.querySelector('.proxy-item.active')?.dataset.id;
|
const currentActiveId =
|
||||||
|
panel.querySelector(".proxy-item.active")?.dataset.id;
|
||||||
|
|
||||||
// 构建新的 HTML
|
// 构建新的 HTML
|
||||||
const newHtml = this._buildPanelHtml(currentProxy, configs);
|
const newHtml = this._buildPanelHtml(currentProxy, configs);
|
||||||
|
|
||||||
// 创建一个临时容器来比较内容
|
// 创建一个临时容器来比较内容
|
||||||
const temp = document.createElement('div');
|
const temp = document.createElement("div");
|
||||||
temp.innerHTML = newHtml;
|
temp.innerHTML = newHtml;
|
||||||
|
|
||||||
// 只在内容真正改变时更新
|
// 只在内容真正改变时更新
|
||||||
@@ -587,30 +598,33 @@ const PanelManager = {
|
|||||||
this._bindEventListeners(panel, configs, currentProxy);
|
this._bindEventListeners(panel, configs, currentProxy);
|
||||||
|
|
||||||
// 验证更新后的状态
|
// 验证更新后的状态
|
||||||
const newActiveId = panel.querySelector('.proxy-item.active')?.dataset.id;
|
const newActiveId =
|
||||||
|
panel.querySelector(".proxy-item.active")?.dataset.id;
|
||||||
if (currentActiveId !== newActiveId) {
|
if (currentActiveId !== newActiveId) {
|
||||||
console.log('Active state changed:', {
|
console.log("Active state changed:", {
|
||||||
from: currentActiveId,
|
from: currentActiveId,
|
||||||
to: newActiveId
|
to: newActiveId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新当前代理信息显示
|
// 更新当前代理信息显示
|
||||||
const activeProxyInfo = this.panel.shadowRoot?.querySelector('.active-proxy-info');
|
const activeProxyInfo =
|
||||||
|
this.panel.shadowRoot?.querySelector(".active-proxy-info");
|
||||||
if (activeProxyInfo) {
|
if (activeProxyInfo) {
|
||||||
let proxyIcon = '🟢';
|
let proxyIcon = "🟢";
|
||||||
let proxyName = '直接连接';
|
let proxyName = "直接连接";
|
||||||
|
|
||||||
if (currentProxy.currentMode === 'system') {
|
if (currentProxy.currentMode === "system") {
|
||||||
proxyIcon = '⚙️';
|
proxyIcon = "⚙️";
|
||||||
proxyName = '系统代理';
|
proxyName = "系统代理";
|
||||||
} else if (currentProxy.currentMode === 'fixed_servers') {
|
} else if (currentProxy.currentMode === "fixed_servers") {
|
||||||
const activeConfig = configs.find(c => c.enabled);
|
const activeConfig = configs.find((c) => c.enabled);
|
||||||
if (activeConfig) {
|
if (activeConfig) {
|
||||||
proxyIcon = activeConfig.proxyType === 'pac_script' ? '📜' : '🌐';
|
proxyIcon =
|
||||||
proxyName = activeConfig.name || '未命名代理';
|
activeConfig.proxyType === "pac_script" ? "📜" : "🌐";
|
||||||
|
proxyName = activeConfig.name || "未命名代理";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,12 +634,13 @@ const PanelManager = {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error updating panel:', error);
|
console.error("Error updating panel:", error);
|
||||||
} finally {
|
} finally {
|
||||||
this._updating = false;
|
this._updating = false;
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
})
|
||||||
console.error('Error in update queue:', error);
|
.catch((error) => {
|
||||||
|
console.error("Error in update queue:", error);
|
||||||
this._updating = false;
|
this._updating = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -635,45 +650,60 @@ const PanelManager = {
|
|||||||
// 将 HTML 构建逻辑抽离成单独的方法
|
// 将 HTML 构建逻辑抽离成单独的方法
|
||||||
_buildPanelHtml(currentProxy, configs) {
|
_buildPanelHtml(currentProxy, configs) {
|
||||||
let html = `
|
let html = `
|
||||||
<div class="proxy-item ${currentProxy.currentMode === 'direct' ? 'active' : ''}"
|
<div class="proxy-item ${
|
||||||
|
currentProxy.currentMode === "direct" ? "active" : ""
|
||||||
|
}"
|
||||||
data-id="direct"
|
data-id="direct"
|
||||||
title="直接连接">
|
title="直接连接">
|
||||||
<span>🟢</span>
|
<span>🟢</span>
|
||||||
<span>直接连接</span>
|
<span>直接连接</span>
|
||||||
${currentProxy.currentMode === 'direct' ? '<div class="proxy-status"></div>' : ''}
|
${
|
||||||
|
currentProxy.currentMode === "direct"
|
||||||
|
? '<div class="proxy-status"></div>'
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="proxy-item ${currentProxy.currentMode === 'system' ? 'active' : ''}"
|
<div class="proxy-item ${
|
||||||
|
currentProxy.currentMode === "system" ? "active" : ""
|
||||||
|
}"
|
||||||
data-id="system"
|
data-id="system"
|
||||||
title="系统代理">
|
title="系统代理">
|
||||||
<span>⚙️</span>
|
<span>⚙️</span>
|
||||||
<span>系统代理</span>
|
<span>系统代理</span>
|
||||||
${currentProxy.currentMode === 'system' ? '<div class="proxy-status"></div>' : ''}
|
${
|
||||||
|
currentProxy.currentMode === "system"
|
||||||
|
? '<div class="proxy-status"></div>'
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 添加自定义代理配置
|
// 添加自定义代理配置
|
||||||
configs.forEach(config => {
|
configs.forEach((config) => {
|
||||||
if (config.proxyType !== 'direct' && config.proxyType !== 'system') {
|
if (config.proxyType !== "direct" && config.proxyType !== "system") {
|
||||||
const isActive = currentProxy.currentMode === 'fixed_servers' && config.enabled;
|
const isActive =
|
||||||
const proxyIcon = config.proxyType === 'pac_script' ? '📜' : '🌐';
|
currentProxy.currentMode === "fixed_servers" && config.enabled;
|
||||||
|
const proxyIcon = config.proxyType === "pac_script" ? "📜" : "🌐";
|
||||||
|
|
||||||
// 构建 title 提示信息
|
// 构建 title 提示信息
|
||||||
let tooltipText;
|
let tooltipText;
|
||||||
if (config.proxyType === 'pac_script') {
|
if (config.proxyType === "pac_script") {
|
||||||
tooltipText = 'PAC Script';
|
tooltipText = "PAC Script";
|
||||||
} else {
|
} else {
|
||||||
const scheme = config.scheme ? `${config.scheme.toUpperCase()} ` : '';
|
const scheme = config.scheme
|
||||||
|
? `${config.scheme.toUpperCase()} `
|
||||||
|
: "";
|
||||||
tooltipText = `${scheme}${config.host}:${config.port}`;
|
tooltipText = `${scheme}${config.host}:${config.port}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<div class="proxy-item ${isActive ? 'active' : ''}"
|
<div class="proxy-item ${isActive ? "active" : ""}"
|
||||||
data-id="${config.id}"
|
data-id="${config.id}"
|
||||||
title="${tooltipText}">
|
title="${tooltipText}">
|
||||||
<span>${proxyIcon}</span>
|
<span>${proxyIcon}</span>
|
||||||
<span>${config.name || '未命名代理'}</span>
|
<span>${config.name || "未命名代理"}</span>
|
||||||
${isActive ? '<div class="proxy-status"></div>' : ''}
|
${isActive ? '<div class="proxy-status"></div>' : ""}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -696,7 +726,7 @@ const PanelManager = {
|
|||||||
|
|
||||||
_bindEventListeners(panel, configs, currentProxy) {
|
_bindEventListeners(panel, configs, currentProxy) {
|
||||||
// 代理项点击事件
|
// 代理项点击事件
|
||||||
panel.querySelectorAll('.proxy-item').forEach(item => {
|
panel.querySelectorAll(".proxy-item").forEach((item) => {
|
||||||
const id = item.dataset.id;
|
const id = item.dataset.id;
|
||||||
|
|
||||||
// 使用事件委托来提高性能
|
// 使用事件委托来提高性能
|
||||||
@@ -704,39 +734,39 @@ const PanelManager = {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (this._updating) {
|
if (this._updating) {
|
||||||
console.log('Panel is updating, ignoring click');
|
console.log("Panel is updating, ignoring click");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加点击反馈
|
// 添加点击反馈
|
||||||
const originalOpacity = item.style.opacity;
|
const originalOpacity = item.style.opacity;
|
||||||
item.style.opacity = '0.7';
|
item.style.opacity = "0.7";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 立即更新 UI 状态,不等待响应
|
// 立即更新 UI 状态,不等待响应
|
||||||
panel.querySelectorAll('.proxy-item').forEach(i => {
|
panel.querySelectorAll(".proxy-item").forEach((i) => {
|
||||||
i.classList.remove('active');
|
i.classList.remove("active");
|
||||||
i.querySelector('span').style.color = '#666';
|
i.querySelector("span").style.color = "#666";
|
||||||
});
|
});
|
||||||
item.classList.add('active');
|
item.classList.add("active");
|
||||||
item.querySelector('span').style.color = '#ff6b00';
|
item.querySelector("span").style.color = "#ff6b00";
|
||||||
|
|
||||||
if (id === 'direct') {
|
if (id === "direct") {
|
||||||
await clearProxy();
|
await clearProxy();
|
||||||
} else if (id === 'system') {
|
} else if (id === "system") {
|
||||||
await switchProxy({
|
await switchProxy({
|
||||||
id: 'system',
|
id: "system",
|
||||||
name: '[系统代理]',
|
name: "[系统代理]",
|
||||||
proxyType: 'system'
|
proxyType: "system",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const config = configs.find(c => c.id === id);
|
const config = configs.find((c) => c.id === id);
|
||||||
if (config) {
|
if (config) {
|
||||||
await switchProxy(config);
|
await switchProxy(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error handling proxy item click:', error);
|
console.error("Error handling proxy item click:", error);
|
||||||
// 发生错误时恢复原状
|
// 发生错误时恢复原状
|
||||||
await this.updatePanel();
|
await this.updatePanel();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -745,29 +775,29 @@ const PanelManager = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 使用 { once: true } 确保事件监听器不会重复
|
// 使用 { once: true } 确保事件监听器不会重复
|
||||||
item.addEventListener('click', clickHandler, { once: true });
|
item.addEventListener("click", clickHandler, {once: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加代理按钮
|
// 添加代理按钮
|
||||||
panel.querySelector('.add-proxy')?.addEventListener('click', async () => {
|
panel.querySelector(".add-proxy")?.addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
await sendMessageWithRetry({
|
await sendMessageWithRetry({
|
||||||
action: 'OPEN_OPTIONS_PAGE',
|
action: "OPEN_OPTIONS_PAGE",
|
||||||
triggerAdd: true
|
triggerAdd: true,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error handling add proxy:', error);
|
console.error("Error handling add proxy:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置按钮
|
// 设置按钮
|
||||||
panel.querySelector('.settings')?.addEventListener('click', async () => {
|
panel.querySelector(".settings")?.addEventListener("click", async () => {
|
||||||
try {
|
try {
|
||||||
await sendMessageWithRetry({
|
await sendMessageWithRetry({
|
||||||
action: 'OPEN_OPTIONS_PAGE'
|
action: "OPEN_OPTIONS_PAGE",
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error opening options page:', error);
|
console.error("Error opening options page:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -790,13 +820,13 @@ const PanelManager = {
|
|||||||
|
|
||||||
// 保持水平位置不变,只改变垂直位置
|
// 保持水平位置不变,只改变垂直位置
|
||||||
panel.style.top = `${boundedTop}px`;
|
panel.style.top = `${boundedTop}px`;
|
||||||
panel.style.transform = 'translateY(0)'; // 移除默认的 translateY(-50%)
|
panel.style.transform = "translateY(0)"; // 移除默认的 translateY(-50%)
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseDown = (e) => {
|
const onMouseDown = (e) => {
|
||||||
// 如果点击时是展开状态,则处理展开/收起
|
// 如果点击时是展开状态,则处理展开/收起
|
||||||
if (panel.classList.contains('expanded')) {
|
if (panel.classList.contains("expanded")) {
|
||||||
panel.classList.remove('expanded');
|
panel.classList.remove("expanded");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,11 +841,11 @@ const PanelManager = {
|
|||||||
|
|
||||||
// 开始拖动时固定当前位置
|
// 开始拖动时固定当前位置
|
||||||
panel.style.top = `${startTop}px`;
|
panel.style.top = `${startTop}px`;
|
||||||
panel.style.transform = 'translateY(0)';
|
panel.style.transform = "translateY(0)";
|
||||||
|
|
||||||
// 添加拖动时的视觉反馈
|
// 添加拖动时的视觉反馈
|
||||||
panel.style.transition = 'none';
|
panel.style.transition = "none";
|
||||||
panel.classList.add('dragging');
|
panel.classList.add("dragging");
|
||||||
|
|
||||||
// 防止文本选择
|
// 防止文本选择
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -839,27 +869,27 @@ const PanelManager = {
|
|||||||
rafId = null;
|
rafId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.classList.remove('dragging');
|
panel.classList.remove("dragging");
|
||||||
panel.style.transition = '';
|
panel.style.transition = "";
|
||||||
|
|
||||||
// 保存位置
|
// 保存位置
|
||||||
const top = panel.getBoundingClientRect().top;
|
const top = panel.getBoundingClientRect().top;
|
||||||
const viewportHeight = window.innerHeight;
|
const viewportHeight = window.innerHeight;
|
||||||
const percentage = (top / viewportHeight) * 100;
|
const percentage = (top / viewportHeight) * 100;
|
||||||
localStorage.setItem('yakitProxyPanelPosition', percentage.toString());
|
localStorage.setItem("yakitProxyPanelPosition", percentage.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
// 修改事件监听
|
// 修改事件监听
|
||||||
header.addEventListener('mousedown', onMouseDown);
|
header.addEventListener("mousedown", onMouseDown);
|
||||||
document.addEventListener('mousemove', onMouseMove, { passive: true });
|
document.addEventListener("mousemove", onMouseMove, {passive: true});
|
||||||
document.addEventListener('mouseup', onMouseUp);
|
document.addEventListener("mouseup", onMouseUp);
|
||||||
|
|
||||||
// 恢复保存的位置
|
// 恢复保存的位置
|
||||||
const savedPosition = localStorage.getItem('yakitProxyPanelPosition');
|
const savedPosition = localStorage.getItem("yakitProxyPanelPosition");
|
||||||
if (savedPosition) {
|
if (savedPosition) {
|
||||||
const top = (parseFloat(savedPosition) / 100) * window.innerHeight;
|
const top = (parseFloat(savedPosition) / 100) * window.innerHeight;
|
||||||
panel.style.top = `${top}px`;
|
panel.style.top = `${top}px`;
|
||||||
panel.style.transform = 'translateY(0)';
|
panel.style.transform = "translateY(0)";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -867,9 +897,9 @@ const PanelManager = {
|
|||||||
let leaveTimer = null;
|
let leaveTimer = null;
|
||||||
|
|
||||||
const onMouseLeave = () => {
|
const onMouseLeave = () => {
|
||||||
if (panel.classList.contains('expanded')) {
|
if (panel.classList.contains("expanded")) {
|
||||||
leaveTimer = setTimeout(() => {
|
leaveTimer = setTimeout(() => {
|
||||||
panel.classList.remove('expanded');
|
panel.classList.remove("expanded");
|
||||||
}, 300); // 300ms 延迟,避免意外触发
|
}, 300); // 300ms 延迟,避免意外触发
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -881,36 +911,36 @@ const PanelManager = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
panel.addEventListener('mouseleave', onMouseLeave);
|
panel.addEventListener("mouseleave", onMouseLeave);
|
||||||
panel.addEventListener('mouseenter', onMouseEnter);
|
panel.addEventListener("mouseenter", onMouseEnter);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 修改初始化调用
|
// 修改初始化调用
|
||||||
console.log("Setting up initialization...");
|
console.log("Setting up initialization...");
|
||||||
|
|
||||||
// 根据文档状态决定初始化方式
|
// 根据文档状态决定初始化方式
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === "loading") {
|
||||||
console.log('Document still loading, waiting for DOMContentLoaded');
|
console.log("Document still loading, waiting for DOMContentLoaded");
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
console.log('DOMContentLoaded fired');
|
console.log("DOMContentLoaded fired");
|
||||||
PanelManager.init();
|
PanelManager.init();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('Document already loaded, initializing immediately');
|
console.log("Document already loaded, initializing immediately");
|
||||||
PanelManager.init();
|
PanelManager.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保留 load 事件作为备份
|
// 保留 load 事件作为备份
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener("load", () => {
|
||||||
console.log("Window load triggered");
|
console.log("Window load triggered");
|
||||||
if (!PanelManager.panel) {
|
if (!PanelManager.panel) {
|
||||||
PanelManager.init();
|
PanelManager.init();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加更详细的日志
|
|
||||||
console.log("Document readyState:", document.readyState);
|
|
||||||
console.log("Document body exists:", !!document.body);
|
|
||||||
console.log("Document documentElement exists:", !!document.documentElement);
|
|
||||||
|
|
||||||
|
// 添加更详细的日志
|
||||||
|
console.log("Document readyState:", document.readyState);
|
||||||
|
console.log("Document body exists:", !!document.body);
|
||||||
|
console.log("Document documentElement exists:", !!document.documentElement);
|
||||||
|
})();
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export const ProxySettings: React.FC<ProxySettingsProps> = ({
|
|||||||
// 处理固定代理服务器模式
|
// 处理固定代理服务器模式
|
||||||
const bypassList = values.bypassList
|
const bypassList = values.bypassList
|
||||||
? values.bypassList.split('\n').map(line => line.trim()).filter(line => line.length > 0)
|
? values.bypassList.split('\n').map(line => line.trim()).filter(line => line.length > 0)
|
||||||
: ["localhost", "127.0.0.1"];
|
: [""];
|
||||||
|
|
||||||
updatedConfig = {
|
updatedConfig = {
|
||||||
id: editingConfig.id,
|
id: editingConfig.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user