286 lines
7.8 KiB
JavaScript
286 lines
7.8 KiB
JavaScript
document.addEventListener("DOMContentLoaded", init);
|
|
|
|
function init() {
|
|
loadDomain();
|
|
document.querySelector("#toggle").addEventListener("click", toggle);
|
|
|
|
restore();
|
|
document.querySelector("#preset").addEventListener("change", showOther);
|
|
document.querySelector("#options").addEventListener("submit", save);
|
|
document.querySelector("#restore").addEventListener("click", restore);
|
|
}
|
|
|
|
/*TODO except browser like about*/
|
|
/* Loads and displays information about the current domain */
|
|
function loadDomain() {
|
|
let tabs = browser.tabs.query({ active: true, currentWindow: true });
|
|
tabs.then((tabs) => {
|
|
const hostname = new URL(tabs[0].url).hostname;
|
|
document.querySelector("#domain").innerHTML = hostname;
|
|
|
|
let storage = browser.storage.local.get("domains");
|
|
storage.then((storage) => {
|
|
const hostname = document.querySelector("#domain").innerHTML;
|
|
const domains = storage.domains;
|
|
if (domains === undefined) {
|
|
browser.storage.local.set({"domains": []});
|
|
}
|
|
else if (domains.includes(hostname)) {
|
|
toggleButton();
|
|
}
|
|
}, logError);
|
|
}, logError);
|
|
}
|
|
|
|
/* Adds or removes the current domain from storage */
|
|
function toggle() {
|
|
let storage = browser.storage.local.get("domains");
|
|
storage.then((storage) => {
|
|
const hostname = document.querySelector("#domain").innerHTML;
|
|
let domains = storage.domains;
|
|
const index = domains.indexOf(hostname);
|
|
if (index > -1) {
|
|
domains.splice(index, 1);
|
|
} else {
|
|
domains.push(hostname);
|
|
}
|
|
browser.storage.local.set({"domains": domains});
|
|
}, logError);
|
|
toggleButton();
|
|
browser.tabs.reload();
|
|
}
|
|
|
|
/* Toggles the displayed button state */
|
|
function toggleButton() {
|
|
document.querySelector("#toggle").classList.toggle("is-on");
|
|
let state = document.querySelector("#state");
|
|
let button = document.querySelector("#toggle");
|
|
state.classList.toggle("is-on");
|
|
if (state.innerHTML == "disabled") {
|
|
state.innerHTML = "enabled"
|
|
button.title = "Toggle to disable";
|
|
} else {
|
|
state.innerHTML = "disabled";
|
|
button.title = "Toggle to enable";
|
|
}
|
|
}
|
|
|
|
/* Gets saved options and loads them */
|
|
function restore() {
|
|
let options = browser.storage.local.get();
|
|
options.then(load, logError);
|
|
}
|
|
|
|
/* Fills form fields with stored options */
|
|
function load(options) {
|
|
if (options.name === undefined) {
|
|
options.name = "";
|
|
options.preset = "";
|
|
options.other = {};
|
|
options.pov = "";
|
|
options.also = {};
|
|
}
|
|
|
|
document.querySelector("#name").value = options.name;
|
|
document.querySelector("#preset").value = options.preset;
|
|
loadOther(options);
|
|
document.querySelector("#pov").value = options.pov;
|
|
loadAlso(options);
|
|
}
|
|
|
|
/* Helper for load, sets contents of other in HTML */
|
|
function loadOther(options) {
|
|
if (Object.keys(options.other).length === 0) {
|
|
return;
|
|
}
|
|
|
|
document.querySelector("#other").querySelectorAll("input, select").forEach((pronoun) => {
|
|
pronoun.value = options.other[pronoun.id];
|
|
});
|
|
|
|
showOther();
|
|
}
|
|
|
|
/* Helper for load, sets contents of also in HTML */
|
|
function loadAlso(options) {
|
|
const also = document.querySelector("#also");
|
|
also.innerHTML = "";
|
|
|
|
if (Object.keys(options.also).length === 0) {
|
|
addFinal(also, 0);
|
|
return;
|
|
}
|
|
|
|
let li;
|
|
let i = 0;
|
|
Object.entries(options.also).forEach(([key, value]) => {
|
|
li = createLi(i);
|
|
li.querySelector("#lhs-" + i).value = key;
|
|
li.querySelector("#rhs-" + i).value = value;
|
|
also.append(li);
|
|
i++;
|
|
});
|
|
|
|
addFinal(also, i);
|
|
}
|
|
|
|
/* Saves options */
|
|
function save() {
|
|
browser.storage.local.set({
|
|
"name": document.querySelector("#name").value,
|
|
"preset": document.querySelector("#preset").value,
|
|
"other": saveOther(),
|
|
"pov": document.querySelector("#pov").value,
|
|
"also": saveAlso()
|
|
});
|
|
browser.tabs.reload();
|
|
}
|
|
|
|
/* Helper for save, gets contents of other */
|
|
function saveOther() {
|
|
const other = {};
|
|
document.querySelector("#other").querySelectorAll("input, select").forEach((pronoun) => {
|
|
other[pronoun.id] = pronoun.value;
|
|
});
|
|
return other;
|
|
}
|
|
|
|
/* Helper for save, gets contents of also */
|
|
function saveAlso() {
|
|
const also = {};
|
|
const lhs = document.querySelectorAll(".lhs");
|
|
const rhs = document.querySelectorAll(".rhs");
|
|
for (let i = 0; i < lhs.length; i++) {
|
|
if (lhs[i].value == "") { continue; }
|
|
also[lhs[i].value] = rhs[i].value;
|
|
}
|
|
return also;
|
|
}
|
|
|
|
/* Creates the HTML for a new also replacement */
|
|
function createLi(index) {
|
|
const li = document.createElement("li");
|
|
li.classList.add("unhide");
|
|
|
|
const lhs = document.createElement("input");
|
|
lhs.type = "text";
|
|
lhs.className = "lhs";
|
|
lhs.id = "lhs-" + index;
|
|
lhs.name = lhs.id;
|
|
|
|
const rhs = document.createElement("input");
|
|
rhs.type = "text";
|
|
rhs.className = "rhs";
|
|
rhs.id = "rhs-" + index;
|
|
rhs.name = rhs.id;
|
|
|
|
const rhsLabel = document.createElement("label");
|
|
rhsLabel.for = rhs.id;
|
|
rhsLabel.innerHTML = "with";
|
|
|
|
const button = document.createElement("button");
|
|
button.type = "button";
|
|
button.id = "delete-" + index;
|
|
button.className = "delete"
|
|
button.innerHTML = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z\"/><path d=\"m12 9 6 6\"/><path d=\"m18 9-6 6\"/></svg>";
|
|
button.addEventListener("click", removeLi);
|
|
|
|
li.append(lhs);
|
|
li.append(rhsLabel);
|
|
li.append(rhs);
|
|
li.append(button);
|
|
|
|
return li;
|
|
}
|
|
|
|
/* Adds a new also replacement when the last lhs is filled */
|
|
function addLi() {
|
|
if (this.value == "") {
|
|
return;
|
|
}
|
|
|
|
const index = document.querySelectorAll(".lhs").length;
|
|
const li = createLi(index);
|
|
setFinal(this.parentNode, false);
|
|
setFinal(li, true);
|
|
document.querySelector("#also").append(li);
|
|
|
|
li.classList.add("hide");
|
|
requestAnimationFrame(() => {
|
|
li.classList.remove("hide")
|
|
})
|
|
}
|
|
|
|
/* Removes an item from the list of also replacements */
|
|
async function removeLi() {
|
|
this.parentNode.classList.add("hide");
|
|
let fields = this.parentNode.querySelectorAll("input, button");
|
|
fields.forEach((field) => {
|
|
field.disabled = true;
|
|
});
|
|
|
|
await sleep(200); /* TODO make 300 different if reduced motion */
|
|
|
|
let also = document.querySelector("#also");
|
|
also.removeChild(this.parentNode);
|
|
let list = also.querySelectorAll("li");
|
|
list.forEach((li, index) => {
|
|
lhs = li.querySelector(".lhs");
|
|
lhs.id = "lhs-" + index;
|
|
lhs.name = lhs.id;
|
|
|
|
rhs = li.querySelector(".rhs");
|
|
rhs.id = "rhs-" + index;
|
|
rhs.name = rhs.id;
|
|
|
|
rhsLabel = li.querySelector("label");
|
|
rhsLabel.for = rhs.id;
|
|
});
|
|
}
|
|
|
|
/* Adds a final, empty field to the list of also replacements */
|
|
function addFinal(also, index) {
|
|
const li = createLi(index);
|
|
setFinal(li, true);
|
|
also.append(li);
|
|
return;
|
|
}
|
|
|
|
/* Shows the button to clear the field if isFinal is true */
|
|
function setFinal(li, isFinal) {
|
|
if (isFinal) {
|
|
li.querySelector(".lhs").addEventListener("change", addLi);
|
|
li.classList.add("hide-button");
|
|
} else {
|
|
li.querySelector(".lhs").removeEventListener("change", addLi);
|
|
li.classList.remove("hide-button");
|
|
}
|
|
}
|
|
|
|
/* Displays more options for pronouns if "other" is selected */
|
|
function showOther() {
|
|
let other = document.querySelector("#other");
|
|
let fields = other.querySelectorAll("input, select");
|
|
if (document.querySelector("#preset").value == "other") {
|
|
other.classList.remove("hide");
|
|
fields.forEach((field) => {
|
|
field.disabled = false;
|
|
});
|
|
} else {
|
|
other.classList.add("hide");
|
|
fields.forEach((field) => {
|
|
field.disabled = true;
|
|
});
|
|
}
|
|
}
|
|
|
|
/* Sleep */
|
|
function sleep(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
/* Required by then */
|
|
function logError(error) {
|
|
console.log(`Error: ${error}`);
|
|
}
|