126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
const statusEl = document.getElementById("status");
|
|
const btnSelection = document.getElementById("translateSelection");
|
|
const btnPage = document.getElementById("translatePage");
|
|
const btnRestore = document.getElementById("restorePage");
|
|
const btnOptions = document.getElementById("openOptions");
|
|
|
|
function setStatus(text, type = "info") {
|
|
statusEl.textContent = text || "";
|
|
statusEl.dataset.type = type;
|
|
}
|
|
|
|
function setButtonBusy(button, busy, busyText) {
|
|
if (!button) {
|
|
return;
|
|
}
|
|
if (!button.dataset.label) {
|
|
button.dataset.label = button.textContent;
|
|
}
|
|
button.disabled = busy;
|
|
button.textContent = busy ? busyText : button.dataset.label;
|
|
}
|
|
|
|
function setAllButtonsDisabled(disabled) {
|
|
btnSelection.disabled = disabled;
|
|
btnPage.disabled = disabled;
|
|
btnRestore.disabled = disabled;
|
|
btnOptions.disabled = disabled;
|
|
}
|
|
|
|
async function getActiveTabId() {
|
|
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
|
if (!tab?.id) {
|
|
throw new Error("未找到当前标签页");
|
|
}
|
|
return tab.id;
|
|
}
|
|
|
|
async function sendAction(action) {
|
|
const tabId = await getActiveTabId();
|
|
return new Promise((resolve, reject) => {
|
|
chrome.tabs.sendMessage(tabId, { action }, (response) => {
|
|
if (chrome.runtime.lastError) {
|
|
reject(new Error("当前页面不支持此操作"));
|
|
return;
|
|
}
|
|
if (response?.ok === false) {
|
|
reject(new Error(response.error || "操作失败"));
|
|
return;
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
async function translateSelectionInTab() {
|
|
const tabId = await getActiveTabId();
|
|
return new Promise((resolve, reject) => {
|
|
chrome.runtime.sendMessage({ action: "translateSelectionInTab", tabId }, (response) => {
|
|
if (chrome.runtime.lastError) {
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
return;
|
|
}
|
|
if (!response?.ok) {
|
|
reject(new Error(response?.error || "翻译失败"));
|
|
return;
|
|
}
|
|
resolve({
|
|
text: response.text || "",
|
|
shown: !!response.shown
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
async function runAction(button, busyText, action) {
|
|
setStatus("");
|
|
setAllButtonsDisabled(true);
|
|
setButtonBusy(button, true, busyText);
|
|
|
|
try {
|
|
const result = await action();
|
|
return result;
|
|
} finally {
|
|
setButtonBusy(button, false, busyText);
|
|
setAllButtonsDisabled(false);
|
|
}
|
|
}
|
|
|
|
btnOptions.addEventListener("click", () => {
|
|
chrome.runtime.openOptionsPage();
|
|
window.close();
|
|
});
|
|
|
|
btnSelection.addEventListener("click", async () => {
|
|
try {
|
|
const result = await runAction(btnSelection, "翻译中...", translateSelectionInTab);
|
|
if (!result.shown && result.text) {
|
|
alert(result.text);
|
|
}
|
|
setStatus("翻译完成", "success");
|
|
setTimeout(() => window.close(), 120);
|
|
} catch (err) {
|
|
setStatus(err.message || "翻译失败", "error");
|
|
}
|
|
});
|
|
|
|
btnPage.addEventListener("click", async () => {
|
|
try {
|
|
await runAction(btnPage, "启动中...", () => sendAction("translatePage"));
|
|
setStatus("已开启随滚动翻译", "success");
|
|
setTimeout(() => window.close(), 120);
|
|
} catch (err) {
|
|
setStatus(err.message || "操作失败", "error");
|
|
}
|
|
});
|
|
|
|
btnRestore.addEventListener("click", async () => {
|
|
try {
|
|
await runAction(btnRestore, "恢复中...", () => sendAction("restorePage"));
|
|
setStatus("已恢复原文", "success");
|
|
setTimeout(() => window.close(), 120);
|
|
} catch (err) {
|
|
setStatus(err.message || "操作失败", "error");
|
|
}
|
|
});
|