Register commands and URL-regexes separately
This allows easy re-use of commands, tying names to URL-regexes rather than command-strings. Much more user-friendly, I reckon! Also, now we use “$URL” instead of “%s” for URL substitution in commands. More shelly that way.
This commit is contained in:
parent
40b5ae16cb
commit
45462ffa98
|
@ -16,18 +16,20 @@ function getUrlCommand(url) {
|
||||||
let matchRegex = "";
|
let matchRegex = "";
|
||||||
try {
|
try {
|
||||||
let savedCommands = JSON.parse(localStorage.getItem("commands"));
|
let savedCommands = JSON.parse(localStorage.getItem("commands"));
|
||||||
|
let savedRegexRules = JSON.parse(localStorage.getItem("urlRules"));
|
||||||
// Find the most-applicable command…
|
// Find the most-applicable command…
|
||||||
for (regexCommandPair of savedCommands) {
|
for (regexCommandIPair of savedRegexRules) {
|
||||||
let regex = regexCommandPair[0];
|
let regex = regexCommandIPair[0];
|
||||||
let match = url.match(regex);
|
let match = url.match(regex);
|
||||||
let compared = compareRegexComplexity(matchRegex, regex);
|
let compared = compareRegexComplexity(matchRegex, regex);
|
||||||
if (match && (compared == 0 || compared == 1)) {
|
if (match && (compared == 0 || compared == 1)) {
|
||||||
matchCommand = regexCommandPair[1];
|
let command_i = regexCommandIPair[1];
|
||||||
|
matchCommand = savedCommands[command_i][1];
|
||||||
matchRegex = regex;
|
matchRegex = regex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// … and replace the substitution-string with the URL.
|
// … and replace the substitution-string with the URL.
|
||||||
matchCommand = matchCommand.replaceAll("%s", url);
|
matchCommand = matchCommand.replaceAll("$URL", url);
|
||||||
} catch {};
|
} catch {};
|
||||||
return matchCommand;
|
return matchCommand;
|
||||||
}
|
}
|
||||||
|
|
44
options.html
44
options.html
|
@ -1,24 +1,34 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf8">
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table id="commandTable">
|
<section>
|
||||||
<tr>
|
<h3>Shell commands</h3>
|
||||||
<th>URL regex</th>
|
<p>Add shell commands, to be executed with a page’s URL as its argument. In a command, $URL will be replaced with the target page’s URL.</p>
|
||||||
<th>Shell command</th>
|
<table id="commandTable">
|
||||||
</tr>
|
<tr>
|
||||||
<!-- <tr class="regexCommandRow">
|
<th>Name</th>
|
||||||
<td>
|
<th>Shell command</th>
|
||||||
<input type="text" class="regex" name="color"
|
</tr>
|
||||||
placeholder="https://example.com/*"/>
|
</table>
|
||||||
</td>
|
<button style="width: 5em;" id="save-cmd">Apply</button>
|
||||||
<td>
|
</section>
|
||||||
<input type="text" class="command" name="color"
|
|
||||||
placeholder="curl %s > /tmp/example" />
|
|
||||||
</td>
|
<section>
|
||||||
</tr> -->
|
<h3>URL/Page rules</h3>
|
||||||
</table>
|
<p>Associate the above commands with URLs, based on regex rules. When a URL is tied to a command, a button will appear in context-menus and the address bar to run said command.</p>
|
||||||
|
<table id="regexTable">
|
||||||
|
<tr>
|
||||||
|
<th>URL regex</th>
|
||||||
|
<th>Shell command</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<button style="width: 5em;" id="save-regex">Apply</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
<button id="save">Apply</button>
|
|
||||||
|
|
||||||
<script src="options.js"></script>
|
<script src="options.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
134
options.js
134
options.js
|
@ -1,25 +1,50 @@
|
||||||
|
// Given the name of an array saved to localStorage, return it (if possible).
|
||||||
|
function savedArray(name) {
|
||||||
|
let saved = [];
|
||||||
|
try {
|
||||||
|
saved = JSON.parse(localStorage.getItem(name));
|
||||||
|
return saved;
|
||||||
|
} catch { };
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Iterate over the commands-table and save each of the user’s valid
|
// Iterate over the commands-table and save each of the user’s valid
|
||||||
// regex+command rows to storage.
|
// name+command rows to storage.
|
||||||
function saveCommands() {
|
function saveCommands() {
|
||||||
let commands = [];
|
let commands = [];
|
||||||
for (commandTr of document.getElementsByClassName("regexCommandRow")) {
|
for (commandTr of document.getElementsByClassName("nameCommandRow")) {
|
||||||
let regex = commandTr.getElementsByClassName("regex")[0].value;
|
let name = commandTr.getElementsByClassName("name")[0].value;
|
||||||
let command = commandTr.getElementsByClassName("command")[0].value;
|
let command = commandTr.getElementsByClassName("command")[0].value;
|
||||||
if (regex && command)
|
if (name && command)
|
||||||
commands.push([regex, command]);
|
commands.push([name, command]);
|
||||||
}
|
}
|
||||||
localStorage.setItem("commands", JSON.stringify(commands));
|
localStorage.setItem("commands", JSON.stringify(commands));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read the user’s saved command-regex pairs from storage, and populate the
|
// Iterate over the regex-table and save each of the user’s valid
|
||||||
|
// regex+command-index rows to storage.
|
||||||
|
function saveRegexRules() {
|
||||||
|
let rules = [];
|
||||||
|
for (regexTr of document.getElementsByClassName("regexCommandRow")) {
|
||||||
|
let regex = regexTr.getElementsByClassName("regex")[0].value;
|
||||||
|
let command_i = regexTr.getElementsByClassName("commandMenu")[0].value;
|
||||||
|
if (regex && command_i)
|
||||||
|
rules.push([regex, command_i]);
|
||||||
|
}
|
||||||
|
localStorage.setItem("urlRules", JSON.stringify(rules));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read the user’s saved name+command pairs from storage, and populate the
|
||||||
// command-table with them.
|
// command-table with them.
|
||||||
function populateCommandTable() {
|
function populateCommandTable() {
|
||||||
let commandTable = document.getElementById("commandTable");
|
let commandTable = document.getElementById("commandTable");
|
||||||
try {
|
try {
|
||||||
let savedCommands = JSON.parse(localStorage.getItem("commands"));
|
let savedCommands = savedArray("commands");
|
||||||
for (cmdRegex of savedCommands) {
|
for (cmdName of savedCommands) {
|
||||||
let commandTr = createCommandTr(cmdRegex[0], cmdRegex[1]);
|
let commandTr = createCommandTr(cmdName[0], cmdName[1]);
|
||||||
commandTable.appendChild(commandTr);
|
commandTable.appendChild(commandTr);
|
||||||
}
|
}
|
||||||
} catch { };
|
} catch { };
|
||||||
|
@ -28,30 +53,57 @@ function populateCommandTable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read the user’s saved regex+command-index pairs from storage, and populate the
|
||||||
|
// command-table with them.
|
||||||
|
function populateRegexTable() {
|
||||||
|
let regexTable = document.getElementById("regexTable");
|
||||||
|
try {
|
||||||
|
let savedRegex = savedArray("urlRules");
|
||||||
|
for (let i = 0; i < savedRegex.length; i++) {
|
||||||
|
let regexTr = createRegexTr(savedRegex[i][0], savedRegex[i][1], createCommandMenu());
|
||||||
|
regexTable.appendChild(regexTr);
|
||||||
|
}
|
||||||
|
} catch { };
|
||||||
|
// Always, again, have a spare tire!!
|
||||||
|
regexTable.appendChild(createRegexTr("", "", createCommandMenu()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a <select> drop-down menu containing all of the user’s commands.
|
||||||
|
function createCommandMenu() {
|
||||||
|
let commandMenu = document.createElement("SELECT");
|
||||||
|
commandMenu.setAttribute("class", "commandMenu");
|
||||||
|
commandMenu.setAttribute("type", "text");
|
||||||
|
|
||||||
|
let savedCommands = savedArray("commands");
|
||||||
|
for (let i = 0; i < savedCommands.length; i++) {
|
||||||
|
let commandOption = document.createElement("OPTION");
|
||||||
|
commandOption.setAttribute("value", i);
|
||||||
|
commandOption.text = savedCommands[i][0];
|
||||||
|
commandMenu.appendChild(commandOption);
|
||||||
|
}
|
||||||
|
return commandMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create a table-row for the command-table, with the command & regex inputs’
|
// Create a table-row for the command-table, with the command & regex inputs’
|
||||||
// values set to the given parameters. If they are undefined, the inputs will
|
// values set to the given parameters. If they are undefined, the inputs will
|
||||||
// have no value.
|
// have no value.
|
||||||
function createCommandTr(regex, command) {
|
function createRegexTr(regex, command_i, commandMenu) {
|
||||||
let regexInput = document.createElement("INPUT");
|
let regexInput = document.createElement("INPUT");
|
||||||
regexInput.setAttribute("class", "regex");
|
regexInput.setAttribute("class", "regex");
|
||||||
regexInput.setAttribute("type", "text");
|
regexInput.setAttribute("type", "text");
|
||||||
regexInput.setAttribute("placeholder", "https://example.com/*");
|
regexInput.setAttribute("placeholder", "https://example.org/.*");
|
||||||
if (regex && command)
|
if (regex && command_i)
|
||||||
regexInput.setAttribute("value", regex);
|
regexInput.setAttribute("value", regex);
|
||||||
|
|
||||||
let regexTd = document.createElement("TD");
|
let regexTd = document.createElement("TD");
|
||||||
regexTd.appendChild(regexInput);
|
regexTd.appendChild(regexInput);
|
||||||
|
|
||||||
let commandInput = document.createElement("INPUT");
|
|
||||||
commandInput.setAttribute("class", "command");
|
|
||||||
commandInput.setAttribute("type", "text");
|
|
||||||
commandInput.setAttribute("placeholder", "curl %s > /tmp/downloaded");
|
|
||||||
if (regex && command)
|
|
||||||
commandInput.setAttribute("value", command);
|
|
||||||
|
|
||||||
let commandTd = document.createElement("TD");
|
let commandTd = document.createElement("TD");
|
||||||
commandTd.appendChild(commandInput);
|
try {
|
||||||
|
commandMenu.childNodes[command_i].setAttribute("selected", true);
|
||||||
|
} catch { };
|
||||||
|
commandTd.appendChild(commandMenu);
|
||||||
let tr = document.createElement("TR");
|
let tr = document.createElement("TR");
|
||||||
tr.setAttribute("class", "regexCommandRow");
|
tr.setAttribute("class", "regexCommandRow");
|
||||||
tr.appendChild(regexTd);
|
tr.appendChild(regexTd);
|
||||||
|
@ -60,12 +112,48 @@ function createCommandTr(regex, command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a table-row for the command-table, with the command & regex inputs’
|
||||||
|
// values set to the given parameters. If they are undefined, the inputs will
|
||||||
|
// have no value.
|
||||||
|
function createCommandTr(name, command) {
|
||||||
|
let nameInput = document.createElement("INPUT");
|
||||||
|
nameInput.setAttribute("class", "name");
|
||||||
|
nameInput.setAttribute("type", "text");
|
||||||
|
nameInput.setAttribute("placeholder", "Curl");
|
||||||
|
if (name && command)
|
||||||
|
nameInput.setAttribute("value", name);
|
||||||
|
|
||||||
|
let nameTd = document.createElement("TD");
|
||||||
|
nameTd.appendChild(nameInput);
|
||||||
|
|
||||||
|
let commandInput = document.createElement("INPUT");
|
||||||
|
commandInput.setAttribute("class", "command");
|
||||||
|
commandInput.setAttribute("type", "text");
|
||||||
|
commandInput.setAttribute("placeholder", "curl $URL > /tmp/downloaded");
|
||||||
|
if (name && command)
|
||||||
|
commandInput.setAttribute("value", command);
|
||||||
|
|
||||||
|
let commandTd = document.createElement("TD");
|
||||||
|
commandTd.appendChild(commandInput);
|
||||||
|
|
||||||
|
let tr = document.createElement("TR");
|
||||||
|
tr.setAttribute("class", "nameCommandRow");
|
||||||
|
tr.appendChild(nameTd);
|
||||||
|
tr.appendChild(commandTd);
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("click", e => {
|
document.addEventListener("click", e => {
|
||||||
if (e.target.id == ("save")) {
|
if (e.target.id == ("save-cmd")) {
|
||||||
saveCommands();
|
saveCommands();
|
||||||
location.reload();
|
location.reload();
|
||||||
|
} else if (e.target.id == ("save-regex")) {
|
||||||
|
saveRegexRules();
|
||||||
|
location.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
populateCommandTable();
|
populateCommandTable();
|
||||||
|
populateRegexTable();
|
||||||
|
|
Ŝarĝante…
Reference in New Issue