Skip to content

Commit 6658212

Browse files
committed
[Refactor] Improved theme detection mechanism switching for better performance and reliability.
1 parent bfd6db5 commit 6658212

File tree

8 files changed

+155
-39
lines changed

8 files changed

+155
-39
lines changed

.DS_Store

0 Bytes
Binary file not shown.

extension.zip

8.1 KB
Binary file not shown.

src/background.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
1414
} else if (request.action === "getModel") {
1515
chrome.storage.sync.get(["model"], function (data) {
1616
sendResponse({
17-
model: data.model || "r1", // 默认使用 R1 模型
17+
model: data.model || "V3", // 默认使用 R1 模型
1818
});
1919
});
2020
return true;
2121
} else if (request.action === "openPopup") {
22-
chrome.runtime.openOptionsPage();
22+
chrome.action.openPopup();
2323
return true;
2424
}
2525
});

src/content/content.js

+28
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,34 @@ function debounce(func, wait) {
194194
};
195195
}
196196

197+
// 添加 ResizeObserver 设置函数
198+
function setupResizeObserver(popup) {
199+
if (!popup) return;
200+
201+
// 如果已存在观察者,先断开连接
202+
if (popup._resizeObserver) {
203+
popup._resizeObserver.disconnect();
204+
}
205+
206+
// 创建防抖的保存尺寸函数
207+
const debouncedSaveSize = debounce((width, height) => {
208+
if (width >= 300 && height >= 200) {
209+
chrome.storage.sync.set({ windowSize: { width, height } });
210+
}
211+
}, 500);
212+
213+
// 创建新的 ResizeObserver
214+
popup._resizeObserver = new ResizeObserver(entries => {
215+
for (const entry of entries) {
216+
const { width, height } = entry.contentRect;
217+
debouncedSaveSize(width, height);
218+
}
219+
});
220+
221+
// 开始观察
222+
popup._resizeObserver.observe(popup);
223+
}
224+
197225
function handleIconClick(e, selectedText, rect, selection) {
198226
e.stopPropagation();
199227
e.preventDefault();

src/content/services/apiService.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,15 @@ export async function getAIResponse(
140140
linkElement.style.color = "#0066cc";
141141
linkElement.style.textDecoration = "underline";
142142
linkElement.style.cursor = "pointer";
143-
linkElement.addEventListener("click", (e) => {
143+
linkElement.addEventListener("click", async (e) => {
144144
e.preventDefault();
145-
chrome.runtime.sendMessage({ action: "openPopup" });
145+
try {
146+
await chrome.runtime.sendMessage({ action: "openPopup" });
147+
} catch (error) {
148+
console.error('Failed to open popup:', error);
149+
// 如果发送消息失败,尝试使用备用方法
150+
chrome.runtime.sendMessage({ action: "getSelectedText" });
151+
}
146152
});
147153

148154
responseElement.textContent = "";

src/content/styles/style.css

+35-7
Original file line numberDiff line numberDiff line change
@@ -1258,17 +1258,45 @@
12581258
}
12591259
}
12601260

1261-
/* 添加主题切换时的过渡效果 */
1261+
/* 优化主题切换过渡效果 */
12621262
.theme-adaptive,
1263-
.theme-adaptive * {
1264-
transition: background-color 0.3s ease, color 0.3s ease,
1265-
border-color 0.3s ease, box-shadow 0.3s ease;
1263+
.theme-adaptive *:not(script):not(style) {
1264+
transition-property: background-color, color, border-color, box-shadow, opacity, transform;
1265+
transition-duration: 200ms;
1266+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1267+
will-change: auto;
12661268
}
12671269

1268-
/* 确保滚动条样式也随主题切换 */
1270+
/* 确保滚动条和其他UI元素的过渡效果 */
12691271
.theme-adaptive .ps__rail-y,
1270-
.theme-adaptive .ps__thumb-y {
1271-
transition: background-color 0.3s ease;
1272+
.theme-adaptive .ps__thumb-y,
1273+
.theme-adaptive .icon-container,
1274+
.theme-adaptive .code-block-wrapper,
1275+
.theme-adaptive pre.hljs,
1276+
.theme-adaptive .copy-button,
1277+
.theme-adaptive .input-container-wrapper {
1278+
transition-property: background-color, color, border-color, box-shadow, opacity, transform;
1279+
transition-duration: 200ms;
1280+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1281+
will-change: auto;
1282+
}
1283+
1284+
/* 优化代码高亮过渡效果 */
1285+
.theme-adaptive .hljs,
1286+
.theme-adaptive .hljs *,
1287+
.theme-adaptive pre.hljs * {
1288+
transition-property: color, background-color;
1289+
transition-duration: 200ms;
1290+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1291+
}
1292+
1293+
/* 优化数学公式过渡效果 */
1294+
.theme-adaptive mjx-container,
1295+
.theme-adaptive .math-inline,
1296+
.theme-adaptive .math-block {
1297+
transition-property: filter;
1298+
transition-duration: 200ms;
1299+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
12721300
}
12731301

12741302
/* 数学公式样式 */

src/content/utils/themeManager.js

+79-25
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { THEME_CLASSES } from './constants';
33
export function isDarkMode() {
44
const bodyBg = window.getComputedStyle(document.body).backgroundColor;
55
const htmlBg = window.getComputedStyle(document.documentElement).backgroundColor;
6+
const bodyColor = window.getComputedStyle(document.body).color;
7+
const htmlColor = window.getComputedStyle(document.documentElement).color;
68

79
function parseColor(color) {
810
const match = color.match(/\d+/g);
@@ -18,50 +20,102 @@ export function isDarkMode() {
1820
};
1921
}
2022

21-
const bodyColor = parseColor(bodyBg);
22-
const htmlColor = parseColor(htmlBg);
23+
const bodyBgColor = parseColor(bodyBg);
24+
const htmlBgColor = parseColor(htmlBg);
25+
const bodyTextColor = parseColor(bodyColor);
26+
const htmlTextColor = parseColor(htmlColor);
2327

24-
const effectiveColor = bodyColor?.isTransparent ? htmlColor : bodyColor;
28+
// 优先使用背景色判断
29+
const effectiveBgColor = bodyBgColor?.isTransparent ? htmlBgColor : bodyBgColor;
30+
// 如果背景色无法判断,使用文字颜色
31+
const effectiveTextColor = bodyTextColor?.isTransparent ? htmlTextColor : bodyTextColor;
2532

26-
if (!effectiveColor || effectiveColor.isTransparent) {
27-
return false;
33+
if (effectiveBgColor && !effectiveBgColor.isTransparent) {
34+
return effectiveBgColor.brightness < 128;
2835
}
2936

30-
const isDark = effectiveColor.brightness < 128;
37+
// 如果背景色无法判断,通过文字颜色反推
38+
if (effectiveTextColor && !effectiveTextColor.isTransparent) {
39+
return effectiveTextColor.brightness > 128;
40+
}
3141

32-
return isDark;
42+
// 如果都无法判断,使用系统主题
43+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
3344
}
3445

3546
export function watchThemeChanges(callback) {
47+
let currentTheme = isDarkMode();
48+
49+
// 创建性能优化的防抖函数
50+
const debouncedCallback = debounce((isDark) => {
51+
if (currentTheme !== isDark) {
52+
currentTheme = isDark;
53+
callback(isDark);
54+
}
55+
}, 50);
56+
57+
// 监听 DOM 变化
3658
const observer = new MutationObserver(() => {
37-
const isDark = isDarkMode();
38-
callback(isDark);
59+
requestAnimationFrame(() => {
60+
debouncedCallback(isDarkMode());
61+
});
3962
});
4063

41-
observer.observe(document.documentElement, {
64+
// 监听更多的属性变化
65+
const observerConfig = {
4266
attributes: true,
43-
attributeFilter: ['style', 'class'],
67+
attributeFilter: ['style', 'class', 'data-theme', 'data-color-mode'],
4468
childList: false,
45-
subtree: false
46-
});
69+
subtree: false,
70+
characterData: false
71+
};
4772

48-
observer.observe(document.body, {
49-
attributes: true,
50-
attributeFilter: ['style', 'class'],
51-
childList: false,
52-
subtree: false
53-
});
73+
// 监听 HTML 和 BODY 元素
74+
observer.observe(document.documentElement, observerConfig);
75+
observer.observe(document.body, observerConfig);
5476

77+
// 监听系统主题变化
78+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
79+
const mediaQueryHandler = (e) => {
80+
requestAnimationFrame(() => {
81+
debouncedCallback(isDarkMode());
82+
});
83+
};
84+
85+
mediaQuery.addEventListener('change', mediaQueryHandler);
86+
87+
// 初始化主题
5588
const initialTheme = isDarkMode();
5689
callback(initialTheme);
5790

58-
return () => observer.disconnect();
91+
// 返回清理函数
92+
return () => {
93+
observer.disconnect();
94+
mediaQuery.removeEventListener('change', mediaQueryHandler);
95+
};
96+
}
97+
98+
// 添加防抖函数
99+
function debounce(func, wait) {
100+
let timeout;
101+
return function executedFunction(...args) {
102+
const later = () => {
103+
clearTimeout(timeout);
104+
func(...args);
105+
};
106+
clearTimeout(timeout);
107+
timeout = setTimeout(later, wait);
108+
};
59109
}
60110

61111
export function applyTheme(popup, isDark) {
62-
if (isDark) {
63-
popup.classList.add('dark-mode');
64-
} else {
65-
popup.classList.remove('dark-mode');
66-
}
112+
requestAnimationFrame(() => {
113+
if (isDark) {
114+
popup.classList.add('dark-mode');
115+
popup.classList.remove('light-mode');
116+
} else {
117+
popup.classList.remove('dark-mode');
118+
popup.classList.add('light-mode');
119+
}
120+
});
67121
}

src/manifest.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"manifest_version": 3,
33
"name": "DeepSeek AI",
4-
"description": "DeepSeek AI助手是一个免费开源的浏览器扩展工具(与DeepSeek官方无关),旨在为用户提供即时、智能的网页内容分析与回答服务。本扩展需要用户自行提供DeepSeek API Key才能使用,API使用费用由DeepSeek平台直接收取。通过集成先进的人工智能大模型,用户可以轻松选择网页上的任何文本内容,并立即获得深度、准确的AI回答。",
5-
"version": "1.8.4",
4+
"description": "DeepSeek AI助手是一个免费开源的浏览器扩展工具(与DeepSeek官方无关),本扩展需要用户自行提供DeepSeek API Key才能使用,通过集成先进的人工智能大模型,用户可以轻松选择网页上的任何文本内容,并立即获得深度、准确的AI回答。",
5+
"version": "1.8.5",
66
"permissions": ["storage", "contextMenus", "scripting", "commands", "tabs"],
77
"content_scripts": [
88
{
@@ -64,7 +64,7 @@
6464
"mac": "Command+Shift+D",
6565
"windows": "Ctrl+Shift+D"
6666
},
67-
"description": "Toggle the DeepSeek chat window."
67+
"description": "Toggle the chat window."
6868
}
6969
},
7070
"host_permissions": [

0 commit comments

Comments
 (0)