33 lines
1.3 KiB
JavaScript
33 lines
1.3 KiB
JavaScript
|
|
// Translate — right-click a selection, get a translation in the sidebar.
|
||
|
|
//
|
||
|
|
// One sidebar panel; the panel HTML does the actual translation (LibreTranslate
|
||
|
|
// or Google unofficial free endpoint, user's pick). When the user picks
|
||
|
|
// "Translate selection" from a page's right-click menu we stash the selection
|
||
|
|
// under storage.__pending and reveal our sidebar; the panel reads __pending on
|
||
|
|
// load / on visibility change and translates immediately.
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
activate(api) {
|
||
|
|
api.registerSidebarPanel({
|
||
|
|
id: "main",
|
||
|
|
title: "Translate",
|
||
|
|
icon: "🌐",
|
||
|
|
page: "panel.html",
|
||
|
|
});
|
||
|
|
|
||
|
|
api.onMessage("context-menu", async (payload) => {
|
||
|
|
const text = String(payload && payload.selectionText || "").trim();
|
||
|
|
if (!text) { api.log("context-menu fired with no selection"); return; }
|
||
|
|
// Cap what we stash to keep storage tiny; the address bar and menu already
|
||
|
|
// truncate visually, but the raw selection can be huge.
|
||
|
|
const clip = text.length > 12_000 ? text.slice(0, 12_000) : text;
|
||
|
|
api.storage.set("__pending", { text: clip, host: payload.host || "", at: Date.now() });
|
||
|
|
api.revealSidebar("main");
|
||
|
|
api.log(`context-menu → translate ${clip.length} chars from ${payload.host || "?"}`);
|
||
|
|
return { ok: true };
|
||
|
|
});
|
||
|
|
|
||
|
|
api.log("registered translate panel + context-menu item");
|
||
|
|
},
|
||
|
|
};
|