Reorganizing options.js to be easier to understand

This commit is contained in:
Jean Viscogliosi-Pate 2024-12-22 09:00:53 -08:00
parent df50c8a00c
commit 731825b755
3 changed files with 159 additions and 162 deletions

View File

@ -39,47 +39,47 @@ label {
font-size: 50px; font-size: 50px;
} }
#prn-other { #other {
display: none; /* Modified by options.js */ display: none; /* Modified by options.js */
gap: 6px; gap: 6px;
margin-top: 12px; margin-top: 12px;
margin-left: 18px; margin-left: 18px;
} }
#prn-other li { #other li {
display: grid; display: grid;
grid-template-columns: 1fr 2fr; grid-template-columns: 1fr 2fr;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
} }
#prn-other > li > label { #other > li > label {
font-size: var(--small-text); font-size: var(--small-text);
text-align: right; text-align: right;
text-wrap: nowrap; text-wrap: nowrap;
} }
#prn-other > li > input { #other > li > input {
font-size: var(--small-text); font-size: var(--small-text);
} }
#prn-other > li > select { #other > li > select {
font-size: var(--small-text); font-size: var(--small-text);
width: min-content; width: min-content;
} }
#replace > li { #also > li {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
margin-top: 6px; margin-top: 6px;
} }
.rpl-lhs { .lhs {
text-align: right; text-align: right;
} }
#replace > li > button { #also > li > button {
background-color: transparent; background-color: transparent;
width: fit-content; width: fit-content;
margin: 0; margin: 0;

View File

@ -21,8 +21,8 @@
<h2 class="visually-hidden">Pronouns</h2> <h2 class="visually-hidden">Pronouns</h2>
<div class="primary-prompt"> <div class="primary-prompt">
<label for="prn-preset">My pronouns are</label> <label for="preset">My pronouns are</label>
<select id="prn-preset" name="preset"> <select id="preset" name="preset">
<option value=""></option> <option value=""></option>
<option value="he">he/him</option> <option value="he">he/him</option>
<option value="she">she/her</option> <option value="she">she/her</option>
@ -31,7 +31,7 @@
</select> </select>
</div> </div>
<ul id="prn-other"> <ul id="other">
<li> <li>
<label for="prn-s">Subjective</label> <label for="prn-s">Subjective</label>
<input type="text" id="prn-s" name="subjective" placeholder="e.g. he, they"> <input type="text" id="prn-s" name="subjective" placeholder="e.g. he, they">
@ -100,9 +100,9 @@
<h2 class="visually-hidden">Also replace</h2> <h2 class="visually-hidden">Also replace</h2>
<label class="primary-prompt" for="replace-1">I also want to replace...</label> <label class="primary-prompt" for="lhs-1">I also want to replace...</label>
<ul id="replace"></ul> <ul id="also"></ul>
<div id="button-grid"> <div id="button-grid">
<button type="submit"> <button type="submit">

View File

@ -2,193 +2,190 @@ document.addEventListener("DOMContentLoaded", init);
function init() { function init() {
restore(); restore();
document.querySelector("#preset").addEventListener("change", showOther);
/* Shows more pronoun options when "other" is selected */ document.querySelector("#options").addEventListener("submit", save);
document.getElementById("prn-preset").addEventListener("change", showOther); document.querySelector("#restore").addEventListener("click", restore);
/* Save changes or restore previous version */
document.getElementById("options").addEventListener("submit", save);
document.getElementById("restore").addEventListener("click", restore);
} }
/* Gets saved options and loads them */
function restore() { function restore() {
let options = browser.storage.local.get(); let options = browser.storage.local.get();
options.then(load, logError); options.then(load, logError);
} }
/* Fills form fields with stored options */
function load(options) { function load(options) {
if (options.name === undefined) { if (options.name === undefined) {
options.name = ""; options.name = "";
options.prnPreset = ""; options.preset = "";
options.pov = ""; options.pov = "";
} }
document.querySelector("#name").value = options.name; document.querySelector("#name").value = options.name;
document.querySelector("#prn-preset").value = options.prnPreset; document.querySelector("#preset").value = options.preset;
setPronouns(options);
document.querySelector("#pov").value = options.pov; document.querySelector("#pov").value = options.pov;
const isEmpty = retrieveAlso(options); loadOther(options);
loadAlso(options);
/* Create empty replacement */
also = document.getElementById("replace");
if (isEmpty)
{
const rplc = createReplacement(0);
setAlsoFinal(rplc, true);
also.append(rplc);
}
showOther(); showOther();
} }
function logError(error) { /* Helper for load, sets contents of other */
console.log(`Error: ${error}`); function loadOther(options) {
} if (options.other === undefined) {
function setPronouns(options) {
if (options.prns === undefined) {
return; return;
} }
document.getElementById("prn-other").querySelectorAll("input, select").forEach((prn) => { document.querySelector("#other").querySelectorAll("input, select").forEach((pronoun) => {
prn.value = options.prns[prn.id]; pronoun.value = options.other[pronoun.id];
}); });
} }
function retrieveAlso(options) { /* Helper for load, sets contents of also */
if (options.rplc === undefined) { function loadAlso(options) {
return true; const also = document.querySelector("#also");
}
also = document.getElementById("replace");
also.innerHTML = ""; also.innerHTML = "";
let rplc; if (options.also === undefined) {
const li = createLi(0);
setFinal(li, true);
also.append(li);
return;
}
let li;
let i = 0; let i = 0;
Object.entries(options.rplc).forEach(([id, value]) => { Object.entries(options.also).forEach(([id, value]) => {
rplc = createReplacement(i); li = createLi(i);
rplc.querySelector("#rpl-lhs-" + i).value = id; li.querySelector("#lhs-" + i).value = id;
rplc.querySelector("#rpl-rhs-" + i).value = value; li.querySelector("#rhs-" + i).value = value;
also.append(rplc); also.append(li);
i++; i++;
}); });
setAlsoFinal(rplc, true); setFinal(li, true);
return false;
} }
/* 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()
});
}
/* 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++) {
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");
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";
const buttonImg = document.createElement("img");
buttonImg.src = "../img/delete.svg";
buttonImg.alt="Clear fields";
button.append(buttonImg);
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);
}
/* Removes an item from the list of also replacements */
function removeLi() {
document.querySelector("#also").removeChild(this.parentNode);
const also = document.querySelector("#also").querySelectorAll("li");
also.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;
});
}
/* 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() { function showOther() {
let other = document.getElementById("prn-other"); let other = document.querySelector("#other");
if (document.querySelector("#prn-preset").value == "other") { if (document.querySelector("#preset").value == "other") {
other.style.display = "grid"; other.style.display = "grid";
} else { } else {
other.style.display = "none"; other.style.display = "none";
} }
} }
function addReplacement() { /* Required by then */
if (this.value == "") { function logError(error) {
return; console.log(`Error: ${error}`);
}
const index = document.getElementsByClassName("rpl-lhs").length;
const rplc = createReplacement(index);
this.removeEventListener("change", addReplacement);
this.parentNode.classList.remove("hide-button");
rplc.querySelector("#rpl-lhs-" + index).addEventListener("change", addReplacement);
rplc.classList.add("hide-button");
document.getElementById("replace").append(rplc);
}
function createReplacement(index) {
const rplc = document.createElement("li");
const lhsInput = document.createElement("input");
lhsInput.type = "text";
lhsInput.className = "rpl-lhs";
lhsInput.id = "rpl-lhs-" + index;
lhsInput.name = lhsInput.id;
const rhsInput = document.createElement("input");
rhsInput.type = "text";
rhsInput.className = "rpl-rhs";
rhsInput.id = "rpl-rhs-" + index;
rhsInput.name = rhsInput.id;
const rhsLabel = document.createElement("label");
rhsLabel.for = rhsInput.id;
rhsLabel.innerHTML = "with";
const clearButton = document.createElement("button");
clearButton.type = "button";
const buttonImg = document.createElement("img");
buttonImg.src = "../img/delete.svg";
buttonImg.alt="Clear fields";
clearButton.append(buttonImg);
clearButton.addEventListener("click", removeReplacement);
rplc.append(lhsInput);
rplc.append(rhsLabel);
rplc.append(rhsInput);
rplc.append(clearButton);
return rplc;
}
function removeReplacement() {
document.getElementById("replace").removeChild(this.parentNode);
const replacements = document.getElementById("replace").querySelectorAll("li");
replacements.forEach((item, index) => {
lhs = item.querySelector(".rpl-lhs");
rhsLabel = item.querySelector("label");
rhs = item.querySelector(".rpl-rhs");
lhs.id = "rpl-lhs-" + index;
lhs.name = lhs.id;
rhs.id = "rpl-rhs-" + index;
rhs.name = rhs.id;
rhsLabel.for = rhs.id;
});
}
function save() {
browser.storage.local.set({
"name": document.querySelector("#name").value,
"prnPreset": document.querySelector("#prn-preset").value,
"prns": getPronouns(),
"pov": document.querySelector("#pov").value,
"rplc": getReplacements()
});
}
function getPronouns() {
const prns = {};
document.getElementById("prn-other").querySelectorAll("input, select").forEach((prn) => {
prns[prn.id] = prn.value;
});
return prns;
}
function getReplacements() {
const rplc = {};
const lhs = document.getElementsByClassName("rpl-lhs");
const rhs = document.getElementsByClassName("rpl-rhs");
for (let i = 0; i < lhs.length; i++) {
rplc[lhs[i].value] = rhs[i].value;
}
return rplc;
}
function setAlsoFinal(li, isFinal) {
if (isFinal) {
li.querySelector(".rpl-lhs").addEventListener("change", addReplacement);
li.classList.add("hide-button");
} else {
li.querySelector(".rpl-lhs").removeEventListener("change", addReplacement);
li.classList.remove("hide-button");
}
} }