Sorry it's sloppy, making options functional

This commit is contained in:
Jean Viscogliosi-Pate 2024-12-22 01:39:01 -08:00
parent 438f015f62
commit df50c8a00c
8 changed files with 265 additions and 54 deletions

View File

@ -8,13 +8,17 @@
body {
background-color: var(--background-color);
color: var(--text-color);
width: 350px;
width: 350px; /* Same as width of add-on viewer on my system */
padding-left: 10px;
padding-right: 10px;
font-family: 'Inter', sans-serif;
font-size: var(--small-text);
margin: auto;
overflow-y: scroll;
}
ul {
list-style: none;
padding-left: 0;
}
button {

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

@ -6,6 +6,13 @@
"description": "Enables customization of reader-insert stories by replacing author-provided hooks such as Y/n, pov/s, and vrb/do/present/.",
"browser_specific_settings": {
"gecko": {
"id": "metamorpov@viscogliosi-pate.com"
},
"gecko": {}
},
"browser_action": {
"default_title": "MetamorPOV",
"default_icon": {

View File

@ -1,3 +1,7 @@
DEACTIVATE_KEY = 'deactivate-this-extension-pls-interactive-fics-yalla-bina';
MUTATION_OBSERVER_KEY = 'observe-this-dom-pls-interactive-fics-yalla-bina';
document.addEventListener('DOMContentLoaded', function () {
// event listeners
document.getElementById('change-name-form').addEventListener('submit', changeName)

View File

@ -1,5 +1,9 @@
@import url("../global.css");
body {
height: 356px; /* Height of popup */
}
input {
border: 0;
border-radius: 30px;
@ -36,53 +40,60 @@ label {
}
#prn-other {
display: grid;
display: none; /* Modified by options.js */
gap: 6px;
margin-top: 12px;
margin-left: 18px;
}
.prn {
#prn-other li {
display: grid;
grid-template-columns: 1fr 2fr;
align-items: center;
gap: 6px;
}
.prn label {
#prn-other > li > label {
font-size: var(--small-text);
text-align: right;
text-wrap: nowrap;
}
.prn input {
#prn-other > li > input {
font-size: var(--small-text);
}
.prn select {
#prn-other > li > select {
font-size: var(--small-text);
width: min-content;
}
.replace {
#replace > li {
display: flex;
align-items: center;
gap: 6px;
margin-top: 6px;
}
.replace img {
cursor: pointer;
visibility: hidden;
}
#replace-1 {
.rpl-lhs {
text-align: right;
}
#replace > li > button {
background-color: transparent;
width: fit-content;
margin: 0;
padding: 0;
}
.hide-button > button {
visibility: hidden;
}
#button-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-columns: 2fr 1fr;
gap: 8px;
margin-top: 20px;
margin-bottom: 20px;

View File

@ -10,12 +10,12 @@
<main>
<h1 class="visually-hidden">Options</h1>
<form>
<form id="options">
<h2 class="visually-hidden">Name</h2>
<div class="primary-prompt">
<label for="y-n">My name is</label>
<input type="text" id="y-n" name="name">
<label for="name">My name is</label>
<input type="text" id="name" name="name">
</div>
<h2 class="visually-hidden">Pronouns</h2>
@ -31,60 +31,60 @@
</select>
</div>
<div id="prn-other">
<div class="prn">
<ul id="prn-other">
<li>
<label for="prn-s">Subjective</label>
<input type="text" id="prn-s" name="subjective" placeholder="e.g. he, they">
</div>
</li>
<div class="prn">
<li>
<label for="prn-o">Objective</label>
<input type="text" id="prn-o" name="objective" placeholder="e.g. her, them">
</div>
</li>
<div class="prn">
<li>
<label for="prn-p">Possessive</label>
<input type="text" id="prn-p" name="possessive" placeholder="e.g. his, their">
</div>
</li>
<div class="prn">
<li>
<label for="prn-a">Adjective</label>
<input type="text" id="prn-a" name="adjective" placeholder="e.g. hers, theirs">
</div>
</li>
<div class="prn">
<li>
<label for="prn-r">Reflexive</label>
<input type="text" id="prn-r" name="reflexive" placeholder="e.g. himself, themself">
</div>
</li>
<div class="prn">
<li>
<label for="prn-h-abbr">Honorific abbr.</label>
<input type="text" id="prn-h-abbr" name="honorific-abbr" placeholder="e.g. Ms., Mx.">
</div>
</li>
<div class="prn">
<li>
<label for="prn-h">Honorific</label>
<input type="text" id="prn-h" name="honorific" placeholder="e.g. mister, mix">
</div>
</li>
<div class="prn">
<li>
<label for="prn-n-adult">Adult noun</label>
<input type="text" id="prn-n-adult" name="adult-noun" placeholder="e.g. woman, person">
</div>
</li>
<div class="prn">
<li>
<label for="prn-n-child">Child noun</label>
<input type="text" id="prn-n-child" name="child-noun" placeholder="e.g. boy, kid">
</div>
</li>
<div class="prn">
<li>
<label for="prn-plural">Conjugates</label>
<select id="prn-plural" name="conjugates">
<option value="singular">singular</option>
<option value="plural">plural</option>
</select>
</div>
</div>
</li>
</ul>
<h2 class="visually-hidden">Perspective</h2>
@ -102,22 +102,17 @@
<label class="primary-prompt" for="replace-1">I also want to replace...</label>
<div class="replace">
<input type="text" id="replace-1" name="replace-1">
<label for="replace-with-1">with</label>
<input type="text" id="replace-with-1" name="replace-with-1">
<img src="../img/delete.svg" alt="Clear fields">
</div>
<ul id="replace"></ul>
<div id="button-grid">
<button>
<button type="submit">
<img src="../img/save.svg" alt="">
Save
</button>
<button>
<img src="../img/revert.svg" alt="">
Revert
<button type="button" id="restore">
<img src="../img/restore.svg" alt="">
Restore
</button>
</div>
</form>

View File

@ -1,3 +1,194 @@
// Event listeners
document.addEventListener("DOMContentLoaded", init);
document.getElementById("y-n").addEventListener("submit", changeName)
function init() {
restore();
/* Shows more pronoun options when "other" is selected */
document.getElementById("prn-preset").addEventListener("change", showOther);
/* Save changes or restore previous version */
document.getElementById("options").addEventListener("submit", save);
document.getElementById("restore").addEventListener("click", restore);
}
function restore() {
let options = browser.storage.local.get();
options.then(load, logError);
}
function load(options) {
if (options.name === undefined) {
options.name = "";
options.prnPreset = "";
options.pov = "";
}
document.querySelector("#name").value = options.name;
document.querySelector("#prn-preset").value = options.prnPreset;
setPronouns(options);
document.querySelector("#pov").value = options.pov;
const isEmpty = retrieveAlso(options);
/* Create empty replacement */
also = document.getElementById("replace");
if (isEmpty)
{
const rplc = createReplacement(0);
setAlsoFinal(rplc, true);
also.append(rplc);
}
showOther();
}
function logError(error) {
console.log(`Error: ${error}`);
}
function setPronouns(options) {
if (options.prns === undefined) {
return;
}
document.getElementById("prn-other").querySelectorAll("input, select").forEach((prn) => {
prn.value = options.prns[prn.id];
});
}
function retrieveAlso(options) {
if (options.rplc === undefined) {
return true;
}
also = document.getElementById("replace");
also.innerHTML = "";
let rplc;
let i = 0;
Object.entries(options.rplc).forEach(([id, value]) => {
rplc = createReplacement(i);
rplc.querySelector("#rpl-lhs-" + i).value = id;
rplc.querySelector("#rpl-rhs-" + i).value = value;
also.append(rplc);
i++;
});
setAlsoFinal(rplc, true);
return false;
}
function showOther() {
let other = document.getElementById("prn-other");
if (document.querySelector("#prn-preset").value == "other") {
other.style.display = "grid";
} else {
other.style.display = "none";
}
}
function addReplacement() {
if (this.value == "") {
return;
}
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");
}
}

View File

@ -41,7 +41,6 @@
ul {
text-align: right;
list-style: none;
}
a{