2024-02-28 22:30:32 -06:00
|
|
|
|
let port = undefined;
|
|
|
|
|
|
|
|
|
|
// Run the shellfox helper program.
|
2024-02-28 23:23:08 -06:00
|
|
|
|
function initShellfoxProgram() {
|
2024-02-28 22:30:32 -06:00
|
|
|
|
port = browser.runtime.connectNative("shellfox");
|
|
|
|
|
port.onDisconnect.addListener((port) => {
|
|
|
|
|
console.log(port.error);
|
|
|
|
|
port = undefined;
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-02-27 23:53:53 -06:00
|
|
|
|
|
|
|
|
|
|
2024-02-28 18:37:13 -06:00
|
|
|
|
// Return the command-string associated with a URL, if any.
|
|
|
|
|
function getUrlCommand(url) {
|
|
|
|
|
let matchCommand = undefined;
|
|
|
|
|
let matchRegex = "";
|
|
|
|
|
try {
|
|
|
|
|
let savedCommands = JSON.parse(localStorage.getItem("commands"));
|
2024-02-28 18:52:02 -06:00
|
|
|
|
// Find the most-applicable command…
|
2024-02-28 18:37:13 -06:00
|
|
|
|
for (regexCommandPair of savedCommands) {
|
|
|
|
|
let regex = regexCommandPair[0];
|
|
|
|
|
let match = url.match(regex);
|
|
|
|
|
let compared = compareRegexComplexity(matchRegex, regex);
|
|
|
|
|
if (match && (compared == 0 || compared == 1)) {
|
|
|
|
|
matchCommand = regexCommandPair[1];
|
|
|
|
|
matchRegex = regex;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-28 18:52:02 -06:00
|
|
|
|
// … and replace the substitution-string with the URL.
|
|
|
|
|
matchCommand = matchCommand.replaceAll("%s", url);
|
2024-02-28 18:37:13 -06:00
|
|
|
|
} catch {};
|
|
|
|
|
return matchCommand;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Execute the shell command associated with the given URL, if any.
|
|
|
|
|
function runUrlCommand(url) {
|
|
|
|
|
let command = getUrlCommand(url);
|
2024-02-28 22:30:32 -06:00
|
|
|
|
if (!port)
|
2024-02-28 23:23:08 -06:00
|
|
|
|
initShellfoxProgram();
|
2024-02-28 18:37:13 -06:00
|
|
|
|
if (command && port) {
|
|
|
|
|
port.postMessage(command);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Compare two regular expressions, returning which one is more specific.
|
|
|
|
|
// Returns -1 if a is more specific, 1 if b is, and 0 if they are equal.
|
|
|
|
|
// It’s a simple (and unreliable) algorithm, for now — purely based on length.
|
|
|
|
|
function compareRegexComplexity(a, b) {
|
|
|
|
|
if (a && ((a && !b) || (a.length > b.length)))
|
|
|
|
|
return -1;
|
|
|
|
|
else if (b && ((b && !a) || (a.length < b.length)))
|
|
|
|
|
return 1
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-02-28 23:23:08 -06:00
|
|
|
|
// Add a context-menu item for running the current page’s associated command.
|
|
|
|
|
function createContextMenuItem() {
|
|
|
|
|
browser.menus.create(
|
|
|
|
|
{
|
|
|
|
|
id: "run-page-command",
|
|
|
|
|
title: "Run shell command",
|
|
|
|
|
contexts: ["page"]
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Simply remove the context-menu item.
|
|
|
|
|
function removeContextMenuItem() {
|
|
|
|
|
browser.menus.remove("run-page-command");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-02-28 22:30:32 -06:00
|
|
|
|
// When the address-bar button is clicked, run the according command (if any).
|
2024-02-28 18:37:13 -06:00
|
|
|
|
browser.pageAction.onClicked.addListener((tab) => {
|
|
|
|
|
runUrlCommand(tab.url);
|
2024-02-27 23:53:53 -06:00
|
|
|
|
});
|
2024-02-28 18:37:13 -06:00
|
|
|
|
|
|
|
|
|
|
2024-02-28 22:30:32 -06:00
|
|
|
|
// When a tab’s URL has been changed, enable/disable the address-bar button
|
|
|
|
|
// based on whether or not there is an according command.
|
2024-02-28 18:37:13 -06:00
|
|
|
|
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
2024-02-28 23:23:08 -06:00
|
|
|
|
let command = getUrlCommand(tab.url);
|
|
|
|
|
if (command) {
|
2024-02-28 18:37:13 -06:00
|
|
|
|
browser.pageAction.show(tabId);
|
2024-02-28 23:23:08 -06:00
|
|
|
|
if (tab.active)
|
|
|
|
|
createContextMenuItem();
|
|
|
|
|
} else {
|
2024-02-28 18:37:13 -06:00
|
|
|
|
browser.pageAction.hide(tabId);
|
2024-02-28 23:23:08 -06:00
|
|
|
|
if (tab.active)
|
|
|
|
|
removeContextMenuItem();
|
|
|
|
|
}
|
2024-02-28 18:37:13 -06:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2024-02-28 22:30:32 -06:00
|
|
|
|
// When the active tab has changed, enable/disable the address-bar button based
|
|
|
|
|
// on whether or not there is an according command for it.
|
2024-02-28 18:37:13 -06:00
|
|
|
|
browser.tabs.onActivated.addListener((activeInfo) => {
|
2024-02-28 22:30:32 -06:00
|
|
|
|
browser.tabs.get(activeInfo.tabId).then((tab) => {
|
2024-02-28 23:23:08 -06:00
|
|
|
|
if (getUrlCommand(tab.url)) {
|
2024-02-28 22:30:32 -06:00
|
|
|
|
browser.pageAction.show(tab.id);
|
2024-02-28 23:23:08 -06:00
|
|
|
|
createContextMenuItem();
|
|
|
|
|
} else {
|
|
|
|
|
browser.pageAction.hide(tab.id);
|
|
|
|
|
removeContextMenuItem();
|
|
|
|
|
}
|
2024-02-28 22:30:32 -06:00
|
|
|
|
});
|
2024-02-28 18:37:13 -06:00
|
|
|
|
});
|
2024-02-28 23:23:08 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
browser.menus.onClicked.addListener((info, tab) => {
|
|
|
|
|
if (info.menuItemId == "run-page-command")
|
|
|
|
|
runUrlCommand(tab.url);
|
|
|
|
|
});
|