Skip to content

Commit 0390798

Browse files
committed
fix(extension): 修复Chrome扩展API调用错误并优化错误处理
refactor(i18n): 更新翻译文本使其更准确和用户友好
1 parent a90f150 commit 0390798

7 files changed

Lines changed: 135 additions & 61 deletions

File tree

content/toolbar/actions.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ class ToolbarActions {
77
this.lastRequest = null;
88
}
99

10+
safeSendMessage(message) {
11+
try {
12+
if (!chrome?.runtime?.id) {
13+
if (this.ui?.showError) this.ui.showError('扩展已重载,请刷新页面后重试');
14+
return;
15+
}
16+
const result = chrome.runtime.sendMessage(message);
17+
if (result && typeof result.catch === 'function') {
18+
result.catch(() => { });
19+
}
20+
} catch (e) { }
21+
}
22+
1023
get t() {
1124
return window.GeminiToolbarStrings;
1225
}
@@ -19,8 +32,9 @@ class ToolbarActions {
1932
* @param {string} model - Model Name
2033
*/
2134
async handleImagePrompt(imgBase64, rect, mode, model = "gemini-2.5-flash") {
22-
const t = this.t;
23-
let title, prompt, loadingMsg, inputVal;
35+
try {
36+
const t = this.t;
37+
let title, prompt, loadingMsg, inputVal;
2438

2539
switch (mode) {
2640
case 'ocr':
@@ -86,10 +100,14 @@ class ToolbarActions {
86100
};
87101

88102
this.lastRequest = msg;
89-
chrome.runtime.sendMessage(msg);
103+
this.safeSendMessage(msg);
104+
} catch (e) {
105+
console.error('[ToolbarActions] handleImagePrompt failed:', e);
106+
}
90107
}
91108

92109
async handleQuickAction(actionType, selection, rect, model = "gemini-2.5-flash", mousePoint = null, gemId = null) {
110+
try {
93111
const t = this.t;
94112
let prompt, title, inputPlaceholder, loadingMsg;
95113

@@ -138,13 +156,16 @@ class ToolbarActions {
138156

139157
// Log the selection content being processed
140158
if (selection) {
141-
chrome.runtime.sendMessage({
159+
this.safeSendMessage({
142160
action: 'DEBUG_LOG',
143161
message: `[ToolbarAction] ${actionType.toUpperCase()} Input Content:\n${selection}`
144162
});
145163
}
146164

147-
chrome.runtime.sendMessage(msg);
165+
this.safeSendMessage(msg);
166+
} catch (e) {
167+
console.error('[ToolbarActions] handleQuickAction failed:', e);
168+
}
148169
}
149170

150171
handleSubmitAsk(question, context, sessionId = null, model = "gemini-2.5-flash", gemId = null) {
@@ -188,7 +209,7 @@ class ToolbarActions {
188209
};
189210

190211
this.lastRequest = msg;
191-
chrome.runtime.sendMessage(msg);
212+
this.safeSendMessage(msg);
192213
}
193214

194215
handleRetry() {
@@ -201,20 +222,20 @@ class ToolbarActions {
201222

202223
const loadingMsg = this.t.loading.regenerate;
203224
this.ui.showLoading(loadingMsg);
204-
chrome.runtime.sendMessage(this.lastRequest);
225+
this.safeSendMessage(this.lastRequest);
205226
}
206227

207228
handleCancel() {
208-
chrome.runtime.sendMessage({ action: "CANCEL_PROMPT" });
229+
this.safeSendMessage({ action: "CANCEL_PROMPT" });
209230
}
210231

211232
handleContinueChat(sessionId) {
212-
chrome.runtime.sendMessage({
233+
this.safeSendMessage({
213234
action: "OPEN_SIDE_PANEL",
214235
sessionId: sessionId
215236
});
216237
}
217238
}
218239

219240
// Export global for Content Script usage
220-
window.GeminiToolbarActions = ToolbarActions;
241+
window.GeminiToolbarActions = ToolbarActions;

content/toolbar/controller.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,30 @@
6565
});
6666

6767
// Restore floating model preference
68-
chrome.storage.local.get(['gemini_floating_model', 'gemini_gem_id'], (result) => {
69-
this.savedModel = result.gemini_floating_model;
70-
if (result.gemini_gem_id) {
71-
this.storedGemId = result.gemini_gem_id;
68+
try {
69+
if (chrome.runtime?.id) {
70+
chrome.storage.local.get(['gemini_floating_model', 'gemini_gem_id'], (result) => {
71+
const err = chrome.runtime?.lastError;
72+
if (err) return;
73+
this.savedModel = result?.gemini_floating_model;
74+
if (result?.gemini_gem_id) {
75+
this.storedGemId = result.gemini_gem_id;
76+
}
77+
});
7278
}
73-
});
79+
} catch (e) { }
7480

7581
// Load models and Gems list
7682
this.loadModelsAndGems();
7783

7884
// Listen for settings changes
79-
chrome.storage.onChanged.addListener((changes, area) => {
80-
if (area === 'local' && changes.gemini_gem_id) {
81-
this.storedGemId = changes.gemini_gem_id.newValue;
82-
}
83-
});
85+
try {
86+
chrome.storage.onChanged.addListener((changes, area) => {
87+
if (area === 'local' && changes.gemini_gem_id) {
88+
this.storedGemId = changes.gemini_gem_id.newValue;
89+
}
90+
});
91+
} catch (e) { }
8492

8593
// Initialize Modules
8694
this.imageDetector.init();
@@ -110,7 +118,12 @@
110118
this.showGlobalInput(true); // 带网页上下文打开
111119
} else {
112120
// 需要截图的操作模式:ocr, snip, screenshot_translate
113-
chrome.runtime.sendMessage({ action: "INITIATE_CAPTURE" });
121+
try {
122+
if (chrome.runtime?.id) {
123+
const res = chrome.runtime.sendMessage({ action: "INITIATE_CAPTURE" });
124+
if (res && typeof res.catch === 'function') res.catch(() => {});
125+
}
126+
} catch (e) { }
114127
}
115128
}
116129

@@ -406,7 +419,13 @@
406419

407420
handleModelChange(model) {
408421
// Save preference specifically for the floating window
409-
chrome.storage.local.set({ 'gemini_floating_model': model });
422+
try {
423+
if (!chrome.runtime?.id) return;
424+
chrome.storage.local.set({ 'gemini_floating_model': model }, () => {
425+
const err = chrome.runtime?.lastError;
426+
if (err) { }
427+
});
428+
} catch (e) { }
410429
}
411430

412431
handleAction(actionType, data) {
@@ -487,4 +506,4 @@
487506

488507
// Export to Window
489508
window.GeminiToolbarController = ToolbarController;
490-
})();
509+
})();

content/toolbar/ui/manager.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,13 @@
125125
}
126126

127127
saveWindowDimensions(w, h) {
128-
chrome.storage.local.set({ 'gemini_nexus_window_size': { w, h } });
128+
try {
129+
if (!chrome?.runtime?.id) return;
130+
chrome.storage.local.set({ 'gemini_nexus_window_size': { w, h } }, () => {
131+
const err = chrome.runtime?.lastError;
132+
if (err) { }
133+
});
134+
} catch (e) { }
129135
}
130136

131137
fireCallback(type, ...args) {
@@ -179,7 +185,7 @@
179185

180186
if (this.view && this.view.windowView) {
181187
const self = this;
182-
this.view.windowView.show(rect, contextText, title, function() { self.resetWindowDrag(); }, mousePoint, gemId);
188+
await this.view.windowView.show(rect, contextText, title, function() { self.resetWindowDrag(); }, mousePoint, gemId);
183189
}
184190
}
185191

content/toolbar/ui/renderer.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,16 @@
102102
const img = container.querySelector(`img[data-req-id="${task.reqId}"]`);
103103
if(img) {
104104
// Send message to background to fetch actual image
105-
chrome.runtime.sendMessage({
106-
action: "FETCH_GENERATED_IMAGE",
107-
url: task.url,
108-
reqId: task.reqId
109-
});
105+
try {
106+
if (chrome?.runtime?.id) {
107+
const res = chrome.runtime.sendMessage({
108+
action: "FETCH_GENERATED_IMAGE",
109+
url: task.url,
110+
reqId: task.reqId
111+
});
112+
if (res && typeof res.catch === 'function') res.catch(() => {});
113+
}
114+
} catch (e) { }
110115
}
111116
});
112117
}

content/toolbar/view/window.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,31 @@
2626
if (!this.elements.askWindow) return;
2727

2828
// Load and apply saved dimensions
29-
const stored = await chrome.storage.local.get('gemini_nexus_window_size');
30-
if (stored.gemini_nexus_window_size) {
29+
let stored = null;
30+
try {
31+
if (chrome?.runtime?.id) {
32+
stored = await new Promise((resolve) => {
33+
try {
34+
if (!chrome.runtime?.id) {
35+
resolve(null);
36+
return;
37+
}
38+
chrome.storage.local.get(['gemini_nexus_window_size'], (result) => {
39+
if (chrome.runtime?.lastError) {
40+
resolve(null);
41+
return;
42+
}
43+
resolve(result || null);
44+
});
45+
} catch (e) {
46+
resolve(null);
47+
}
48+
});
49+
}
50+
} catch (e) {
51+
stored = null;
52+
}
53+
if (stored && stored.gemini_nexus_window_size) {
3154
let { w, h } = stored.gemini_nexus_window_size;
3255
const maxW = window.innerWidth * 0.95;
3356
const maxH = window.innerHeight * 0.95;

sandbox/core/i18n.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ export const translations = {
99
"settings": "Settings",
1010
"chatHistory": "Chat History",
1111
"newChat": "New Chat",
12-
"pageContext": "Page",
13-
"browserControl": "Browser Control",
12+
"pageContext": "Page Context",
13+
"browserControl": "Control",
1414
"quote": "Quote",
1515
"ocr": "OCR",
16-
"snip": "Snip",
16+
"snip": "Capture",
1717
"screenshotTranslate": "Translate",
1818
"summarize": "Summarize",
19-
"videoSummary": "Video",
19+
"videoSummary": "Video Summary",
2020
"uploadImage": "Upload Image",
2121
"askPlaceholder": "Ask Anywhere...",
2222
"sendMessage": "Send message",
@@ -74,13 +74,13 @@ export const translations = {
7474
// Tooltips
7575
"toggleHistory": "Chat History",
7676
"newChatTooltip": "New Chat",
77-
"pageContextTooltip": "Toggle chat with page content",
78-
"browserControlTooltip": "Allow model to control the browser",
77+
"pageContextTooltip": "Include page content in chat",
78+
"browserControlTooltip": "Let the model control the browser",
7979
"quoteTooltip": "Quote selected text from page",
80-
"ocrTooltip": "Capture area and extract text",
80+
"ocrTooltip": "Capture area and extract text (OCR)",
8181
"screenshotTranslateTooltip": "Capture area and translate text",
82-
"summarizeTooltip": "Summarize current page",
83-
"videoSummaryTooltip": "Summarize video content",
82+
"summarizeTooltip": "Summarize this page",
83+
"videoSummaryTooltip": "Summarize this video",
8484
"mindMap": "MindMap",
8585
"mindMapTooltip": "Generate MindMap Summary (Mermaid)",
8686
"mindMapPrompt": "Please summarize the core content of this page and organize it into a [Mermaid MindMap].\nRequirements:\n1. Use the same language as the page content.\n2. Root node is the page title.\n3. Output directly a mermaid code block:\n```mermaid\nmindmap\n root((Page Title))\n Concept 1\n Detail A\n Detail B\n```",
@@ -126,14 +126,14 @@ export const translations = {
126126
"settings": "设置",
127127
"chatHistory": "历史记录",
128128
"newChat": "新对话",
129-
"pageContext": "网页",
130-
"browserControl": "浏览器控制",
129+
"pageContext": "Tab",
130+
"browserControl": "AI接管",
131131
"quote": "引用",
132-
"ocr": "OCR",
132+
"ocr": "识字",
133133
"snip": "截图",
134-
"screenshotTranslate": "截图翻译",
134+
"screenshotTranslate": "翻译",
135135
"summarize": "总结",
136-
"videoSummary": "总结视频",
136+
"videoSummary": "视频",
137137
"mindMap": "脑图",
138138
"mindMapTooltip": "生成思维导图 (Mermaid)",
139139
"mindMapPrompt": "请总结当前网页的核心内容,并将其整理为一个【Mermaid思维导图】(MindMap)。\n要求:\n1. 使用中文。\n2. 根节点是网页标题,子节点是关键章节或概念。\n3. 直接输出 mermaid 代码块,格式如下:\n```mermaid\nmindmap\n root((网页标题))\n 关键概念1\n 细节A\n 细节B\n 关键概念2\n 细节C\n```",
@@ -193,13 +193,13 @@ export const translations = {
193193
// Tooltips
194194
"toggleHistory": "历史记录",
195195
"newChatTooltip": "新对话",
196-
"pageContextTooltip": "切换网页上下文对话",
197-
"browserControlTooltip": "允许模型控制浏览器",
196+
"pageContextTooltip": "让对话包含网页内容",
197+
"browserControlTooltip": "允许模型接管并操作网页",
198198
"quoteTooltip": "引用网页选中内容",
199-
"ocrTooltip": "区域截图 (OCR文字提取)",
200-
"screenshotTranslateTooltip": "截取区域并翻译文字",
201-
"summarizeTooltip": "总结当前网页内容",
202-
"videoSummaryTooltip": "总结视频内容",
199+
"ocrTooltip": "区域截图并识别文字",
200+
"screenshotTranslateTooltip": "区域截图并翻译文字",
201+
"summarizeTooltip": "总结当前网页",
202+
"videoSummaryTooltip": "总结当前视频",
203203
"snipTooltip": "区域截图 (作为图片输入)",
204204
"removeImage": "移除图片",
205205
"uploadImageTooltip": "上传图片",

0 commit comments

Comments
 (0)