Two follow-ups from the screenshot editor rework (task_b9608dc6): 1) toolbar-menu popup goes native. The DOM popover in chrome.html was getting clipped by chrome.html's own WebContentsView height and then covered by the tab view below it. Route through main.js's Menu.popup() so the menu escapes the chrome-view layering entirely. Preload exposes toolbarMenuPopup(addonId, rect) + subscribes to toolbar-menu-closed so chrome can drop the button's "active" tint. 2) capturePage() intermittently returns a 0x0 image on Windows right after a navigation (view hasn't painted a frame yet). Retry up to six times with 150 ms between attempts; throw a specific error if still empty so the addon can surface a real message instead of silently producing a blank PNG. Also lands an [addons] openAddonTab log line so the editor tab opening is easy to trace in main's log.
84 lines
5.5 KiB
JavaScript
84 lines
5.5 KiB
JavaScript
const { contextBridge, ipcRenderer } = require("electron");
|
|
contextBridge.exposeInMainWorld("theseus", {
|
|
navigate: (input) => ipcRenderer.invoke("navigate", input),
|
|
search: (q) => ipcRenderer.invoke("search", q),
|
|
newTab: () => ipcRenderer.invoke("new-tab"),
|
|
closeTab: (id) => ipcRenderer.invoke("close-tab", id),
|
|
switchTab: (id) => ipcRenderer.invoke("switch-tab", id),
|
|
moveTab: (id, targetId, place) => ipcRenderer.invoke("move-tab", id, targetId, place),
|
|
suggestAddress: (query, rect) => ipcRenderer.invoke("suggest-address", query, rect),
|
|
closeAddressPicker: () => ipcRenderer.invoke("close-address-picker"),
|
|
addressCursor: (dir) => ipcRenderer.invoke("address-cursor", dir),
|
|
togglePwFill: (rect) => ipcRenderer.invoke("toggle-pw-fill", rect),
|
|
onPwAvailability: (cb) => ipcRenderer.on("pw-availability", (_e, d) => cb(d)),
|
|
// Update chip: chrome subscribes to update-available; clicking the chip's
|
|
// download button opens the URL in the system browser; ✕ dismisses for
|
|
// the current session.
|
|
onUpdateAvailable: (cb) => ipcRenderer.on("update-available", (_e, d) => cb(d)),
|
|
openUpdateDownload: (url) => ipcRenderer.invoke("open-update-download", url),
|
|
installUpdateNow: () => ipcRenderer.invoke("install-update-now"),
|
|
dismissUpdate: () => ipcRenderer.invoke("dismiss-update"),
|
|
goHome: () => ipcRenderer.invoke("go-home"),
|
|
back: () => ipcRenderer.invoke("go-back"),
|
|
forward: () => ipcRenderer.invoke("go-forward"),
|
|
reload: (hard) => ipcRenderer.invoke("reload", !!hard),
|
|
stop: () => ipcRenderer.invoke("stop"),
|
|
toggleTor: () => ipcRenderer.invoke("toggle-tor"),
|
|
openSettings: () => ipcRenderer.invoke("open-settings"),
|
|
getSettings: () => ipcRenderer.invoke("settings-get"),
|
|
setSetting: (key, val) => ipcRenderer.invoke("settings-set", key, val),
|
|
onSettingsUpdate: (cb) => ipcRenderer.on("settings-update", (_e, d) => cb(d)),
|
|
toggleSiteInfo: (rect) => ipcRenderer.invoke("toggle-site-info", rect),
|
|
switchToBcnr: () => ipcRenderer.invoke("switch-to-bcnr"),
|
|
setChromeHeight: (h) => ipcRenderer.invoke("set-chrome-height", h),
|
|
getSearchEngines: () => ipcRenderer.invoke("search-engines"),
|
|
setSearchEngine: (id) => ipcRenderer.invoke("set-search-engine", id),
|
|
addEngine: (eng) => ipcRenderer.invoke("add-engine", eng),
|
|
removeEngine: (id) => ipcRenderer.invoke("remove-engine", id),
|
|
toggleEnginePicker: (rect) => ipcRenderer.invoke("toggle-engine-picker", rect),
|
|
onEngines: (cb) => ipcRenderer.on("engines", (_e, d) => cb(d)),
|
|
getBookmarks: () => ipcRenderer.invoke("bookmarks-get"),
|
|
addBookmark: (bm) => ipcRenderer.invoke("bookmark-add", bm),
|
|
updateBookmark: (url, patch) => ipcRenderer.invoke("bookmark-update", url, patch),
|
|
removeBookmark: (url) => ipcRenderer.invoke("bookmark-remove", url),
|
|
onBookmarks: (cb) => ipcRenderer.on("bookmarks", (_e, d) => cb(d)),
|
|
onNav: (cb) => ipcRenderer.on("nav", (_e, d) => cb(d)),
|
|
onTor: (cb) => ipcRenderer.on("tor", (_e, d) => cb(d)),
|
|
onTabs: (cb) => ipcRenderer.on("tabs", (_e, d) => cb(d)),
|
|
tabReload: (id) => ipcRenderer.invoke("tab-reload", id),
|
|
tabDuplicate: (id) => ipcRenderer.invoke("tab-duplicate", id),
|
|
tabMute: (id, on) => ipcRenderer.invoke("tab-mute", id, on),
|
|
tabGroup: (id, color) => ipcRenderer.invoke("tab-group", id, color),
|
|
tabGroupToggle: (color) => ipcRenderer.invoke("tab-group-toggle", color),
|
|
tabBookmark: (id) => ipcRenderer.invoke("tab-bookmark", id),
|
|
onAddressPicked: (cb) => ipcRenderer.on("address-picked", (_e, url) => cb(url)),
|
|
onBcnrOffer: (cb) => ipcRenderer.on("bcnr-offer", (_e, d) => cb(d)),
|
|
// Collision-mode (BCNR ↔ ICANN) live switcher for the active tab
|
|
collisionSwitch: (arg) => ipcRenderer.invoke("collision-switch", arg),
|
|
collisionState: () => ipcRenderer.invoke("collision-state"),
|
|
// Downloads — the toolbar button subscribes to `downloads` to update its
|
|
// badge, and toggleDownloads opens/closes the floating panel.
|
|
getDownloads: () => ipcRenderer.invoke("downloads-get"),
|
|
toggleDownloads: (rect) => ipcRenderer.invoke("toggle-downloads", rect),
|
|
onDownloads: (cb) => ipcRenderer.on("downloads", (_e, d) => cb(d)),
|
|
// Add-on sidebar: toggle, open on a specific panel, close, or subscribe
|
|
// to state (visibility + which panel is active + the panel list). The
|
|
// extension dock in chrome.html renders one button per panel and calls
|
|
// openSidebar / closeSidebar accordingly.
|
|
toggleSidebar: () => ipcRenderer.invoke("sidebar-toggle"),
|
|
openSidebar: (panelId) => ipcRenderer.invoke("sidebar-open", panelId),
|
|
closeSidebar: () => ipcRenderer.invoke("sidebar-close"),
|
|
sidebarState: () => ipcRenderer.invoke("sidebar-state"),
|
|
onSidebarState: (cb) => ipcRenderer.on("sidebar-state", (_e, d) => cb(d)),
|
|
// Toolbar-menu (dropdown from an add-on's dock icon): dispatch the picked
|
|
// item id to the add-on's "menu-select" handler.
|
|
addonMenuSelect: (addonId, itemId) => ipcRenderer.invoke("addon-menu-select", addonId, itemId),
|
|
// Pop the dock-icon dropdown as a NATIVE menu. Renderer-side DOM popovers
|
|
// get clipped by chrome.html's own WebContentsView height (CHROME_H) and
|
|
// then covered by the tab view below it — a native Menu.popup escapes that
|
|
// layering entirely. Pass the button's viewport-rect so main can anchor.
|
|
toolbarMenuPopup: (addonId, rect) => ipcRenderer.invoke("toolbar-menu-popup", addonId, rect),
|
|
// Chrome listens so it can drop the "active" tint when the native menu
|
|
// dismisses (Esc, outside click, item picked — main fires all three).
|
|
onToolbarMenuClosed: (cb) => ipcRenderer.on("toolbar-menu-closed", () => cb()),
|
|
});
|