Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 52 additions & 6 deletions brotab/extension/chrome/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,26 @@ class ChromeTabs extends BrowserTabs {
}

runScript(tab_id, script, payload, onSuccess, onError) {
this._browser.tabs.executeScript(
tab_id, {code: script},
(result) => {
// https://stackoverflow.com/a/45603880/258421
let lastError = chrome.runtime.lastError;
// Manifest V3: use chrome.scripting.executeScript instead of tabs.executeScript
this._browser.scripting.executeScript(
{
target: { tabId: tab_id },
func: (code) => {
// Execute provided code string in the page context
// and return its result. This mirrors MV2 behavior where
// executeScript returned an array with a single result.
// eslint-disable-next-line no-eval
return eval(code);
},
args: [script]
},
(injectionResults) => {
const lastError = chrome.runtime.lastError;
if (lastError) {
onError(lastError, payload);
} else {
onSuccess(result, payload);
const results = (injectionResults || []).map(r => r.result);
onSuccess(results, payload);
}
}
);
Expand All @@ -297,6 +308,41 @@ var browserTabs = undefined;
const NATIVE_APP_NAME = 'brotab_mediator';
reconnect();

// In MV3, the service worker can be suspended when idle.
// Use an alarm to periodically wake it and re-establish the native connection
// without sending unsolicited messages to the native app.
try {
if (typeof chrome !== 'undefined' && chrome.alarms) {
const KEEPALIVE_ALARM = 'bt-keepalive';

function scheduleKeepAlive() {
// Minimum is 1 minute; keep it modest to avoid excessive wakeups
chrome.alarms.create(KEEPALIVE_ALARM, { periodInMinutes: 1 });
}

chrome.runtime.onInstalled.addListener(() => {
scheduleKeepAlive();
// Ensure we have a connection on install/refresh
if (!port) reconnect();
});

chrome.runtime.onStartup.addListener(() => {
scheduleKeepAlive();
// Ensure we have a connection on browser startup
if (!port) reconnect();
});

chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm && alarm.name === KEEPALIVE_ALARM) {
// If there is no active port, re-connect; do not send messages
if (!port) reconnect();
}
});
}
} catch (e) {
console.warn('Keepalive scheduling failed:', e);
}

function reconnect() {
console.log("Connecting to native app");
if (typeof browser !== 'undefined') {
Expand Down
9 changes: 6 additions & 3 deletions brotab/extension/chrome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
// Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"description": "Control your browser's tabs from command line",
"manifest_version": 2,
"manifest_version": 3,
"name": "BroTab",
"version": "1.4.0",
"background": {
"scripts": ["background.js"]
"service_worker": "background.js"
},
"icons": {
"128": "brotab-icon-128x128.png"
},
"permissions": ["nativeMessaging", "tabs", "activeTab", "<all_urls>"],
"permissions": ["nativeMessaging", "tabs", "activeTab", "scripting", "alarms"],
"host_permissions": [
"<all_urls>"
],
"short_name": "BroTab"
}