Skip to content

Commit e7e1c1f

Browse files
committed
refactor: 简化 i18n 数据逻辑和协议处理
- toggle.js: 从 localStorage (app-lang) 读取语言状态,与 BaseI18n 共享数据源 - shared-actions.js: 移除过时的 status/success 协议兼容层,改为警告日志 - shared-i18n-base.js: ready() 方法改为纯 Promise 风格,移除回调参数支持 - popup.js: 简化 i18n ready 调用逻辑
1 parent e834387 commit e7e1c1f

7 files changed

Lines changed: 48 additions & 44 deletions

File tree

background.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ const updateHeaderRulesInternal = async (
319319
? backgroundI18n.t("auto_switch_skip_duplicate", { language })
320320
: backgroundI18n.t("language_already_set", { language });
321321
sendBackgroundLog(logMessage, "info");
322-
return { status: "unchanged", language };
322+
return { changed: false, language };
323323
}
324324

325325
sendBackgroundLog(
@@ -375,7 +375,7 @@ const updateHeaderRulesInternal = async (
375375
`${backgroundI18n.t("rules_updated_successfully", { language })}${isAutoSwitch ? ` (${backgroundI18n.t("auto_switch")})` : ""} (${duration}ms)`,
376376
"success",
377377
);
378-
return { status: "success", language };
378+
return { changed: true, language };
379379
} catch (error) {
380380
sendBackgroundLog(
381381
`${backgroundI18n.t("update_rules_failed")}: ${error.message}`,
@@ -591,17 +591,17 @@ const handleUpdateRulesRequest = async (request) => {
591591

592592
const result = await updateHeaderRules(language);
593593
sendBackgroundLog(
594-
`${backgroundI18n.t("rules_update_completed")}: ${result.status}`,
594+
`${backgroundI18n.t("rules_update_completed")}: ${result.changed ? "changed" : "unchanged"}`,
595595
"info",
596596
);
597597

598598
await chrome.storage.local.set({ currentLanguage: language });
599599

600600
// 只在状态发生变化时才通知UI更新
601-
if (result.status === "success") {
601+
if (result.changed) {
602602
notifyPopupUIUpdate(autoSwitchEnabled, result.language);
603603
}
604-
return { status: result.status, language: result.language };
604+
return { changed: result.changed, language: result.language };
605605
} catch (error) {
606606
// 记录错误日志并重新抛出,让上层统一处理
607607
const errorMessage = error?.message || String(error);
@@ -1079,7 +1079,7 @@ chrome.tabs.onUpdated.addListener(async (_tabId, changeInfo, tab) => {
10791079
"info",
10801080
);
10811081
const result = await updateHeaderRules(targetLanguage, 0, true);
1082-
if (result.status === "success") {
1082+
if (result.changed) {
10831083
notifyPopupUIUpdate(true, targetLanguage);
10841084
}
10851085
} else {
@@ -1100,7 +1100,7 @@ chrome.tabs.onUpdated.addListener(async (_tabId, changeInfo, tab) => {
11001100
"info",
11011101
);
11021102
const result = await updateHeaderRules(fallbackLanguage, 0, true);
1103-
if (result.status === "success") {
1103+
if (result.changed) {
11041104
notifyPopupUIUpdate(true, fallbackLanguage);
11051105
}
11061106
}

docs/TODO.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## 🔧 TODO
22

3-
#### 性能优化
3+
### 性能优化
44

5-
## 1. 全局变量耦合严重
5+
## [] 1. 全局变量耦合严重
66
**文件**: `shared-i18n-base.js`, `domain-rules-manager.js`, `popup.js`
77

88
组件通过全局变量通信(如 `domainManagerI18n`, `popupI18n`, `sendDebugLog`),而不是通过依赖注入或参数传递:
@@ -16,14 +16,18 @@ ensureI18n() {
1616
}
1717
```
1818

19-
## 2. 重复的语言状态管理
19+
**验证结果**: ✅ 问题存在于 [`domain-rules-manager.js:22`](domain-rules-manager.js:22),使用全局变量 `domainManagerI18n`
20+
21+
## [x] 2. 重复的语言状态管理
2022
**文件**: `toggle.js``shared-i18n-base.js`
2123

2224
两个独立的语言管理逻辑:
2325
- `LanguageToggle` 类自己管理 `currentLang` 和 localStorage
2426
- `BaseI18n` 也管理 `currentLang` 和 localStorage
2527

26-
## 3. 环境判断方式过时
28+
**验证结果**: ✅ 问题存在于 [`toggle.js:7`](toggle.js:7)[`shared-i18n-base.js:23`](shared/shared-i18n-base.js:23),两者都管理 `currentLang`
29+
30+
## [] 3. 环境判断方式过时
2731
**文件**: `shared-i18n-base.js`
2832

2933
```73:91:shared-i18n-base.js
@@ -36,7 +40,9 @@ _detectLanguage() {
3640

3741
现代做法应该分离 Service Worker 和浏览器环境的代码,而不是用标志位判断。
3842

39-
## 4. 动态脚本加载方式过时
43+
**验证结果**: ✅ 问题存在于 [`shared-i18n-base.js:75`](shared/shared-i18n-base.js:75)
44+
45+
## [] 4. 动态脚本加载方式过时
4046
**文件**: `shared-i18n-base.js`
4147

4248
```138:160:shared-i18n-base.js
@@ -52,7 +58,9 @@ _loadScriptForBrowser(src) {
5258

5359
应该使用 ES Module 动态导入 `import()` 替代创建 script 标签。
5460

55-
## 5. 协议兼容层说明历史债务
61+
**验证结果**: ✅ 问题存在于 [`shared-i18n-base.js:138-160`](shared/shared-i18n-base.js:138)
62+
63+
## [x] 5. 协议兼容层说明历史债务
5664
**文件**: `shared-actions.js`
5765

5866
```27:51:shared-actions.js
@@ -65,7 +73,9 @@ if (response?.status === "success") return response;
6573
if (response?.success === true) return response;
6674
```
6775
68-
## 6. i18n 回调风格设计过时
76+
**验证结果**: ✅ 问题存在于 [`shared-actions.js:27-51`](shared/shared-actions.js:27)
77+
78+
## [x] 6. i18n 回调风格设计过时
6979
**文件**: `shared-i18n-base.js`
7080
7181
```207:213:shared-i18n-base.js
@@ -80,7 +90,9 @@ ready(callback) {
8090
8191
现代 JS 直接使用 Promise,不需要回调风格。
8292
83-
## 7. 单例模式过度使用
93+
**验证结果**: ✅ 问题存在于 [`shared-i18n-base.js:207-213`](shared/shared-i18n-base.js:207)
94+
95+
## [] 7. 单例模式过度使用
8496
**文件**: `domain-rules-manager.js`, `background.js`
8597
8698
```279:281:domain-rules-manager.js
@@ -89,15 +101,22 @@ const domainRulesManager = new DomainRulesManager();
89101
90102
单例难以测试,且导出的是实例而非类,限制了灵活性。
91103
92-
## 8. 状态分散管理
104+
**验证结果**: ✅ 问题存在于 [`domain-rules-manager.js:281`](domain-rules-manager.js:281)
105+
106+
## [] 8. 状态分散管理
93107
全局状态分散在各处:
94108
- `background.js`: `autoSwitchEnabled`, `isInitialized`
95109
- `popup.js`: `updateCheckInProgress`, `updateCheckController`
96110
- `domain-rules-manager.js`: `domainCache`
97111
98112
没有统一的状态管理方案。
99113
100-
#### i18n 系统重构(待完成)
114+
**验证结果**: ✅ 问题存在于:
115+
- [`background.js:69-70`](background.js:69) - `autoSwitchEnabled`, `isInitialized`
116+
- [`popup.js:9-10`](popup.js:9) - `updateCheckInProgress`, `updateCheckController`
117+
- [`domain-rules-manager.js:10`](domain-rules-manager.js:10) - `domainCache`
118+
119+
### i18n 系统重构(待完成)
101120
- [ ] **统一 i18n 实例命名**:将 `debugI18n`/`popupI18n`/`detectI18n`/`backgroundI18n` 统一为 `appI18n`
102121
- **原因**:简化 `getFallbackTranslation` 中的实例检测逻辑,去除多层 typeof 判断
103122
- **涉及文件**:

popup.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -964,13 +964,9 @@ const debouncedUIUpdate = (updateFn, delay = 16) => {
964964
// --- 扩展初始化 ---
965965
document.addEventListener("DOMContentLoaded", async () => {
966966
// 等待翻译系统加载完成
967-
await new Promise((resolve) => {
968-
if (popupI18n.isReady) {
969-
resolve();
970-
} else {
971-
popupI18n.ready(resolve);
972-
}
973-
});
967+
if (!popupI18n.isReady) {
968+
await popupI18n.ready();
969+
}
974970

975971
// 获取DOM元素
976972
const languageSelect = getEl("languageSelect");

shared/md5.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function md5(string) {
184184
}
185185

186186
function str2rstrUTF8(input) {
187-
// 使用 decodeURIComponent 替代已弃用的 unescape
187+
// 使用 decodeURIComponent 替代已弃用的 unescape
188188
return decodeURIComponent(encodeURIComponent(input));
189189
}
190190

shared/shared-actions.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,8 @@ const requestBackground = async (type, payload = {}) => {
3838
throw err;
3939
}
4040

41-
// 兼容旧协议:status/success 字段混用,统一转换为返回或抛错
42-
if (response?.status === "success") return response;
43-
if (response?.status === "error") {
44-
throw new Error(response?.message || "Background error");
45-
}
46-
if (response?.success === true) return response;
47-
if (response?.success === false) {
48-
throw new Error(response?.error || "Background error");
49-
}
50-
41+
// 协议格式不符:返回原始响应但记警告
42+
console.warn("requestBackground: unexpected response format", response);
5143
return response;
5244
};
5345

shared/shared-i18n-base.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,10 @@ class BaseI18n {
201201

202202
/**
203203
* 允许外部代码等待翻译系统准备就绪。
204-
* @param {Function} [callback] - (可选) 准备就绪后执行的回调函数。
205204
* @returns {Promise<void>}
206205
*/
207-
ready(callback) {
208-
const promise = this._initPromise || this.init();
209-
if (typeof callback === "function") {
210-
promise.then(callback);
211-
}
212-
return promise;
206+
ready() {
207+
return this._initPromise || this.init();
213208
}
214209

215210
/**

toggle.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// 语言切换功能(复用共享工具函数)
44
class LanguageToggle {
55
constructor() {
6-
// 通过 window 对象访问全局函数(因为 toggle.js 是 module)
7-
this.currentLang = window.detectCurrentLanguage();
6+
// 语言状态从 localStorage (app-lang) 读取,与 BaseI18n 共享同一数据源
7+
this.currentLang =
8+
localStorage.getItem("app-lang") ||
9+
(navigator.language.startsWith("zh") ? "zh" : "en");
810
}
911

1012
/**

0 commit comments

Comments
 (0)