Implemented verb functionality for the content script

This commit is contained in:
Jean Viscogliosi-Pate 2024-12-23 15:34:49 -08:00
parent e94e5f2e07
commit 2e911575dc
12 changed files with 1066 additions and 487 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
*-update/*
*.DS_Store
metamorpov.zip
node_modules
src/replace-words-and-verbs.js

View File

@ -1,5 +0,0 @@
zip-ff:
zip ff-update manifest.json LICENSE *.png *.css *.js *.html
zip-chrome:
zip chrome-update manifest.json *.png *.css *.js *.html

View File

@ -1,5 +1,13 @@
# MetamorPOV
Enables customization of reader-insert stories by replacing author-provided hooks such as Y/n, pov/s, and vrb/do/present/.
## Development
- Uh npm, flake bla bla web-ext, nix is bad so installing pkg rollup globally fails, but that's okay because to install locally run `npm install --save-dev rollup` and then `npx rollup` to execute it.
- to-do credit englishverbshelper, apache 2
- to-do retheme to and credit primary
## Copyright and License
Portions of MetamorPOV are derived from InteractiveFics, licensed under [MIT](third-party-licenses/LICENSE-InteractiveFics), copyrighted 2015-2023 by Mariam Maarouf. Icons, excepting the butterfly, are redistributed from Luicide, licensed under [ISC](third-party-licenses/LICENSE-Luicide), copyrighted 2022 by Lucide Contributors. Luicide contains portions of Feather, licensed under [MIT](third-party-licenses/LICENSE-Feather), copyrighted 2013-2022 by Cole Bemis. All other portions of MetamorPOV are licensed under [GPL-3.0-or-later](LICENSE), copyrighted 2024 by Jean Viscogliosi-Pate.

View File

@ -13,8 +13,8 @@
devShells = eachSystem (pkgs: {
default = pkgs.mkShell {
buildInputs = [
pkgs.gnumake
pkgs.zip
pkgs.nodejs_22
pkgs.web-ext
];
};
});

621
package-lock.json generated Normal file
View File

@ -0,0 +1,621 @@
{
"name": "metamorpov",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "metamorpov",
"version": "0.1.0",
"license": "GPL-3.0-or-later",
"devDependencies": {
"@rollup/plugin-commonjs": "28.0.2",
"@rollup/plugin-node-resolve": "15.3.0",
"english-verbs-gerunds": "3.3.1",
"english-verbs-helper": "3.3.1",
"english-verbs-irregular": "3.3.1",
"rollup": "^4.27.3"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@rollup/plugin-commonjs": {
"version": "28.0.2",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz",
"integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
"estree-walker": "^2.0.2",
"fdir": "^6.2.0",
"is-reference": "1.2.1",
"magic-string": "^0.30.3",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=16.0.0 || 14 >= 14.17"
},
"peerDependencies": {
"rollup": "^2.68.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-node-resolve": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
"integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
"deepmerge": "^4.2.2",
"is-module": "^1.0.0",
"resolve": "^1.22.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.78.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
"integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz",
"integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz",
"integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz",
"integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz",
"integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz",
"integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz",
"integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz",
"integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz",
"integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz",
"integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz",
"integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz",
"integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz",
"integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz",
"integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz",
"integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz",
"integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz",
"integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz",
"integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz",
"integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
"dev": true,
"license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/english-verbs-gerunds": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/english-verbs-gerunds/-/english-verbs-gerunds-3.3.1.tgz",
"integrity": "sha512-j1lltTeuvPwgwa/ROAjT/1B1RBA8724uJ2tCjGyRqn87VGAU/YKtYO/camMB1G/WaHT3j5iI3cmdVoPj5H3K2w==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/english-verbs-helper": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/english-verbs-helper/-/english-verbs-helper-3.3.1.tgz",
"integrity": "sha512-8mFnB6Z5W44aX20MTA9Wu7Fqad3KkykFcpLAcD3I930J1mIlqmsJhS81Qs8b23QCg2Aq1QfN9t0Xa2hsENFWgQ==",
"dev": true,
"license": "Apache-2.0",
"funding": {
"type": "patreon",
"url": "https://www.patreon.com/ludan"
}
},
"node_modules/english-verbs-irregular": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/english-verbs-irregular/-/english-verbs-irregular-3.3.1.tgz",
"integrity": "sha512-Ji6a/4QbXKryxLD/yw+tp6xz7kCOcHOdaDcesEyFYHQxUNRnWbLWybXAYnoLn3VHC0AxXbQonZwO6Bw7JvoaVA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true,
"license": "MIT"
},
"node_modules/fdir": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz",
"integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
"dev": true,
"license": "MIT"
},
"node_modules/is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "*"
}
},
"node_modules/magic-string": {
"version": "0.30.17",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
"integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true,
"license": "MIT"
},
"node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/rollup": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz",
"integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.6"
},
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.29.1",
"@rollup/rollup-android-arm64": "4.29.1",
"@rollup/rollup-darwin-arm64": "4.29.1",
"@rollup/rollup-darwin-x64": "4.29.1",
"@rollup/rollup-freebsd-arm64": "4.29.1",
"@rollup/rollup-freebsd-x64": "4.29.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
"@rollup/rollup-linux-arm-musleabihf": "4.29.1",
"@rollup/rollup-linux-arm64-gnu": "4.29.1",
"@rollup/rollup-linux-arm64-musl": "4.29.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
"@rollup/rollup-linux-riscv64-gnu": "4.29.1",
"@rollup/rollup-linux-s390x-gnu": "4.29.1",
"@rollup/rollup-linux-x64-gnu": "4.29.1",
"@rollup/rollup-linux-x64-musl": "4.29.1",
"@rollup/rollup-win32-arm64-msvc": "4.29.1",
"@rollup/rollup-win32-ia32-msvc": "4.29.1",
"@rollup/rollup-win32-x64-msvc": "4.29.1",
"fsevents": "~2.3.2"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}
}
}

23
package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "metamorpov",
"title": "MetamorPOV",
"version": "0.1.0",
"description": "Enables customization of reader-insert stories by replacing author-provided hooks such as Y/n, pov/s, and vrb/do/present/.",
"repository": {
"type": "git",
"url": "git+https://git.viscogliosi-pate.com/jean/metamorpov.git"
},
"author": "Jean Viscogliosi-Pate",
"license": "GPL-3.0-or-later",
"scripts": {
"build": "npx rollup -c"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "15.3.0",
"@rollup/plugin-commonjs": "28.0.2",
"english-verbs-helper": "3.3.1",
"english-verbs-gerunds": "3.3.1",
"english-verbs-irregular": "3.3.1",
"rollup": "^4.27.3"
}
}

11
rollup.config.js Normal file
View File

@ -0,0 +1,11 @@
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/replace-words.js',
output: {
file: 'src/replace-words-and-verbs.js',
format: 'cjs',
},
plugins: [nodeResolve(), commonjs()]
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -10,7 +10,7 @@
"gecko": {
"id": "metamorpov@viscogliosi-pate.com"
},
"gecko": {}
"gecko_android": {}
},
"browser_action": {
@ -43,7 +43,7 @@
"content_scripts": [
{
"js": [
"content_script.js"
"replace-words-and-verbs.js"
],
"run_at": "document_idle",
"matches": [

View File

@ -1,214 +1,113 @@
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)
document.getElementById('replace-other-words-form').addEventListener('submit', replaceOther)
document.getElementById('show-saved').addEventListener('click', loadSaved)
document.getElementById('refresh-replacements').addEventListener('click', refreshReplacements)
document.getElementById('enable-observer').addEventListener('click', toggleMutationObserver)
document.getElementById('toggle').addEventListener('click', togglePauseDomain)
// set settings buttons
setMutationObserverKey()
setPauseDomainKey()
});
const changeName = () => {
const person = document.getElementById('change-name-form-text').value
if (person) {
chrome.storage.sync.set({'person': person}, chrome.tabs.reload())
}
}
const replaceOther = () => {
const input_word = document.getElementById('replace-word').value
const replacement = document.getElementById('replace-with').value
const is_case_sensitive = document.getElementById('is-case-sensitive').checked
if (input_word && replacement) {
if (document.getElementById('is-perm').checked) {
const obj = {}
obj[input_word] = replacement
obj[`${input_word}_case_sensitive`] = is_case_sensitive
chrome.storage.sync.set(obj)
}
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{
input_word: input_word,
replace_value: replacement,
case_sensitive: is_case_sensitive
})
})
}
}
const refreshReplacements = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{
refresh: true
})
})
}
const loadSaved = () => {
const list = document.getElementById('saved-items-list')
list.innerHTML = ''
chrome.storage.sync.get(null, loadSavedItemsWrapper(false))
chrome.storage.local.get(null, loadSavedItemsWrapper(true))
}
const loadSavedItemsWrapper = isLocal => items => loadSavedItems(items, isLocal)
const loadSavedItems = (items, isLocal) => {
const list = document.getElementById('saved-items-list')
for (var key in items) {
if (key !== DEACTIVATE_KEY && key !== MUTATION_OBSERVER_KEY && key !== PAUSED_KEY && !key.endsWith('_case_sensitive')) {
const label = key === 'person' ? 'Y/N' : key
const case_sensitive = !!items[`${key}_case_sensitive`]
const case_sensitive_string = case_sensitive ? 'case sensitive' : 'not case sensitive'
const representative = `${label} -> ${items[key]} (${case_sensitive_string})`
const list_item = createListItem(key, representative, 'one-saved-item', isLocal)
list.appendChild(list_item)
}
}
}
const createListItem = (id, text, className, isLocal) => {
const text_node = document.createTextNode(text)
const list_node = document.createElement('LI')
list_node.appendChild(text_node)
list_node.className = className
list_node.id = id
list_node.addEventListener('click', () => {
if (isLocal) {
chrome.storage.local.remove(id)
} else {
chrome.storage.sync.remove(id)
}
list_node.className += ' strikethrough'
})
return list_node
}
const setDeactivateKey = () => {
chrome.storage.sync.get(DEACTIVATE_KEY, obj => {
const is_deactivated = obj[DEACTIVATE_KEY]
toggleDeactivateLabel(is_deactivated)
if (is_deactivated) {
const other_elements = document.getElementsByClassName('fade-when-deactivate')
const deactivate_only_elements = document.getElementsByClassName('fade-when-deactivate-only')
Array.from([...other_elements, ...deactivate_only_elements]).forEach(element => {
element.style.opacity = '0.5'
})
const input_elements = document.getElementsByTagName('INPUT')
Array.from(input_elements).forEach(input => {
if (input.id !== 'deactivate') {
input.disabled = 'disabled'
}
})
}
})
}
const setMutationObserverKey = () => {
chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
const is_enabled = obj[MUTATION_OBSERVER_KEY]
toggleMutationObserverLabel(is_enabled)
})
}
const setPauseDomainKey = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
const hostname = new URL(tabs[0].url).hostname
document.getElementById('this-url').innerHTML = hostname
const storage_key = {}
storage_key[PAUSED_KEY] = []
chrome.storage.sync.get(storage_key, obj => {
const hostnames = obj[PAUSED_KEY]
const is_paused = hostnames.indexOf(hostname) !== -1
togglePauseDomainLabel(is_paused)
if (is_paused) {
const other_elements = document.getElementsByClassName('fade-when-deactivate')
const pause_only_other_elements = document.getElementsByClassName('fade-when-pause')
Array.from([...other_elements, ...pause_only_other_elements]).forEach(element => {
element.style.opacity = '0.5'
})
const input_elements = document.getElementsByTagName('INPUT')
Array.from(input_elements).forEach(input => {
if (input.id !== 'pause' && input.id !== 'deactivate') {
input.disabled = 'disabled'
}
})
}
})
})
}
const toggleDeactivateLabel = (isDeactivated) => {
document.getElementById('deactivate').checked = isDeactivated;
}
const toggleMutationObserverLabel = (isEnabled) => {
document.getElementById('enable-observer').checked = isEnabled;
}
const togglePauseDomainLabel = (isPaused) => {
document.getElementById('pause').checked = isPaused;
}
const toggleMutationObserver = () => {
chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
const was_enabled = obj[MUTATION_OBSERVER_KEY]
if (was_enabled) {
chrome.storage.sync.remove(MUTATION_OBSERVER_KEY)
} else {
const new_object = {}
new_object[MUTATION_OBSERVER_KEY] = true
chrome.storage.sync.set(new_object)
}
chrome.tabs.reload()
})
}
const togglePauseDomain = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
const hostname = new URL(tabs[0].url).hostname
const storage_key = {}
storage_key[PAUSED_KEY] = []
chrome.storage.sync.get(storage_key, obj => {
const hostnames = obj[PAUSED_KEY]
const was_paused = hostnames.indexOf(hostname) !== -1
var new_hostnames;
if (was_paused) {
new_hostnames = hostnames.filter(h => h !== hostname)
} else {
new_hostnames = hostnames
new_hostnames.push(hostname)
}
const new_obj = {}
new_obj[PAUSED_KEY] = new_hostnames
chrome.storage.sync.set(new_obj)
chrome.tabs.reload()
window.close()
})
})
}
// DEACTIVATE_KEY = 'deactivate-this-extension-pls-interactive-fics-yalla-bina';
//
// document.addEventListener('DOMContentLoaded', function () {
// // event listeners
// document.getElementById('change-name-form').addEventListener('submit', changeName)
// document.getElementById('replace-other-words-form').addEventListener('submit', replaceOther)
// document.getElementById('show-saved').addEventListener('click', loadSaved)
// document.getElementById('refresh-replacements').addEventListener('click', refreshReplacements)
// document.getElementById('enable-observer').addEventListener('click', toggleMutationObserver)
// document.getElementById('toggle').addEventListener('click', togglePauseDomain)
//
// // set settings buttons
// setMutationObserverKey()
// setPauseDomainKey()
// });
//
//
// const changeName = () => {
// const person = document.getElementById('change-name-form-text').value
// if (person) {
// chrome.storage.sync.set({'person': person}, chrome.tabs.reload())
// }
// }
//
// const refreshReplacements = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// chrome.tabs.sendMessage(
// tabs[0].id,
// {
// refresh: true
// })
// })
// }
//
// const loadSaved = () => {
// const list = document.getElementById('saved-items-list')
// list.innerHTML = ''
// chrome.storage.sync.get(null, loadSavedItemsWrapper(false))
// chrome.storage.local.get(null, loadSavedItemsWrapper(true))
// }
//
// const loadSavedItemsWrapper = isLocal => items => loadSavedItems(items, isLocal)
//
// const loadSavedItems = (items, isLocal) => {
// const list = document.getElementById('saved-items-list')
// for (var key in items) {
// if (key !== DEACTIVATE_KEY && key !== MUTATION_OBSERVER_KEY && key !== PAUSED_KEY && !key.endsWith('_case_sensitive')) {
// const label = key === 'person' ? 'Y/N' : key
// const case_sensitive = !!items[`${key}_case_sensitive`]
// const case_sensitive_string = case_sensitive ? 'case sensitive' : 'not case sensitive'
// const representative = `${label} -> ${items[key]} (${case_sensitive_string})`
// const list_item = createListItem(key, representative, 'one-saved-item', isLocal)
// list.appendChild(list_item)
// }
// }
// }
//
// const setPauseDomainKey = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// const hostname = new URL(tabs[0].url).hostname
// document.getElementById('this-url').innerHTML = hostname
//
// const storage_key = {}
// storage_key[PAUSED_KEY] = []
// chrome.storage.sync.get(storage_key, obj => {
// const hostnames = obj[PAUSED_KEY]
// const is_paused = hostnames.indexOf(hostname) !== -1
// togglePauseDomainLabel(is_paused)
//
// if (is_paused) {
// const other_elements = document.getElementsByClassName('fade-when-deactivate')
// const pause_only_other_elements = document.getElementsByClassName('fade-when-pause')
// Array.from([...other_elements, ...pause_only_other_elements]).forEach(element => {
// element.style.opacity = '0.5'
// })
// const input_elements = document.getElementsByTagName('INPUT')
// Array.from(input_elements).forEach(input => {
// if (input.id !== 'pause' && input.id !== 'deactivate') {
// input.disabled = 'disabled'
// }
// })
// }
// })
// })
// }
//
// const togglePauseDomain = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// const hostname = new URL(tabs[0].url).hostname
//
// const storage_key = {}
// storage_key[PAUSED_KEY] = []
// chrome.storage.sync.get(storage_key, obj => {
// const hostnames = obj[PAUSED_KEY]
// const was_paused = hostnames.indexOf(hostname) !== -1
// var new_hostnames;
//
// if (was_paused) {
// new_hostnames = hostnames.filter(h => h !== hostname)
// } else {
// new_hostnames = hostnames
// new_hostnames.push(hostname)
// }
//
// const new_obj = {}
// new_obj[PAUSED_KEY] = new_hostnames
// chrome.storage.sync.set(new_obj)
//
// chrome.tabs.reload()
// window.close()
// })
// })
// }

View File

@ -1,214 +1,214 @@
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)
document.getElementById('replace-other-words-form').addEventListener('submit', replaceOther)
document.getElementById('show-saved').addEventListener('click', loadSaved)
document.getElementById('refresh-replacements').addEventListener('click', refreshReplacements)
document.getElementById('enable-observer').addEventListener('click', toggleMutationObserver)
document.getElementById('toggle').addEventListener('click', togglePauseDomain)
// set settings buttons
setMutationObserverKey()
setPauseDomainKey()
});
const changeName = () => {
const person = document.getElementById('change-name-form-text').value
if (person) {
chrome.storage.sync.set({'person': person}, chrome.tabs.reload())
}
}
const replaceOther = () => {
const input_word = document.getElementById('replace-word').value
const replacement = document.getElementById('replace-with').value
const is_case_sensitive = document.getElementById('is-case-sensitive').checked
if (input_word && replacement) {
if (document.getElementById('is-perm').checked) {
const obj = {}
obj[input_word] = replacement
obj[`${input_word}_case_sensitive`] = is_case_sensitive
chrome.storage.sync.set(obj)
}
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{
input_word: input_word,
replace_value: replacement,
case_sensitive: is_case_sensitive
})
})
}
}
const refreshReplacements = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{
refresh: true
})
})
}
const loadSaved = () => {
const list = document.getElementById('saved-items-list')
list.innerHTML = ''
chrome.storage.sync.get(null, loadSavedItemsWrapper(false))
chrome.storage.local.get(null, loadSavedItemsWrapper(true))
}
const loadSavedItemsWrapper = isLocal => items => loadSavedItems(items, isLocal)
const loadSavedItems = (items, isLocal) => {
const list = document.getElementById('saved-items-list')
for (var key in items) {
if (key !== DEACTIVATE_KEY && key !== MUTATION_OBSERVER_KEY && key !== PAUSED_KEY && !key.endsWith('_case_sensitive')) {
const label = key === 'person' ? 'Y/N' : key
const case_sensitive = !!items[`${key}_case_sensitive`]
const case_sensitive_string = case_sensitive ? 'case sensitive' : 'not case sensitive'
const representative = `${label} -> ${items[key]} (${case_sensitive_string})`
const list_item = createListItem(key, representative, 'one-saved-item', isLocal)
list.appendChild(list_item)
}
}
}
const createListItem = (id, text, className, isLocal) => {
const text_node = document.createTextNode(text)
const list_node = document.createElement('LI')
list_node.appendChild(text_node)
list_node.className = className
list_node.id = id
list_node.addEventListener('click', () => {
if (isLocal) {
chrome.storage.local.remove(id)
} else {
chrome.storage.sync.remove(id)
}
list_node.className += ' strikethrough'
})
return list_node
}
const setDeactivateKey = () => {
chrome.storage.sync.get(DEACTIVATE_KEY, obj => {
const is_deactivated = obj[DEACTIVATE_KEY]
toggleDeactivateLabel(is_deactivated)
if (is_deactivated) {
const other_elements = document.getElementsByClassName('fade-when-deactivate')
const deactivate_only_elements = document.getElementsByClassName('fade-when-deactivate-only')
Array.from([...other_elements, ...deactivate_only_elements]).forEach(element => {
element.style.opacity = '0.5'
})
const input_elements = document.getElementsByTagName('INPUT')
Array.from(input_elements).forEach(input => {
if (input.id !== 'deactivate') {
input.disabled = 'disabled'
}
})
}
})
}
const setMutationObserverKey = () => {
chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
const is_enabled = obj[MUTATION_OBSERVER_KEY]
toggleMutationObserverLabel(is_enabled)
})
}
const setPauseDomainKey = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
const hostname = new URL(tabs[0].url).hostname
document.getElementById('this-url').innerHTML = hostname
const storage_key = {}
storage_key[PAUSED_KEY] = []
chrome.storage.sync.get(storage_key, obj => {
const hostnames = obj[PAUSED_KEY]
const is_paused = hostnames.indexOf(hostname) !== -1
togglePauseDomainLabel(is_paused)
if (is_paused) {
const other_elements = document.getElementsByClassName('fade-when-deactivate')
const pause_only_other_elements = document.getElementsByClassName('fade-when-pause')
Array.from([...other_elements, ...pause_only_other_elements]).forEach(element => {
element.style.opacity = '0.5'
})
const input_elements = document.getElementsByTagName('INPUT')
Array.from(input_elements).forEach(input => {
if (input.id !== 'pause' && input.id !== 'deactivate') {
input.disabled = 'disabled'
}
})
}
})
})
}
const toggleDeactivateLabel = (isDeactivated) => {
document.getElementById('deactivate').checked = isDeactivated;
}
const toggleMutationObserverLabel = (isEnabled) => {
document.getElementById('enable-observer').checked = isEnabled;
}
const togglePauseDomainLabel = (isPaused) => {
document.getElementById('pause').checked = isPaused;
}
const toggleMutationObserver = () => {
chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
const was_enabled = obj[MUTATION_OBSERVER_KEY]
if (was_enabled) {
chrome.storage.sync.remove(MUTATION_OBSERVER_KEY)
} else {
const new_object = {}
new_object[MUTATION_OBSERVER_KEY] = true
chrome.storage.sync.set(new_object)
}
chrome.tabs.reload()
})
}
const togglePauseDomain = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
const hostname = new URL(tabs[0].url).hostname
const storage_key = {}
storage_key[PAUSED_KEY] = []
chrome.storage.sync.get(storage_key, obj => {
const hostnames = obj[PAUSED_KEY]
const was_paused = hostnames.indexOf(hostname) !== -1
var new_hostnames;
if (was_paused) {
new_hostnames = hostnames.filter(h => h !== hostname)
} else {
new_hostnames = hostnames
new_hostnames.push(hostname)
}
const new_obj = {}
new_obj[PAUSED_KEY] = new_hostnames
chrome.storage.sync.set(new_obj)
chrome.tabs.reload()
window.close()
})
})
}
// 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)
// document.getElementById('replace-other-words-form').addEventListener('submit', replaceOther)
// document.getElementById('show-saved').addEventListener('click', loadSaved)
// document.getElementById('refresh-replacements').addEventListener('click', refreshReplacements)
// document.getElementById('enable-observer').addEventListener('click', toggleMutationObserver)
// document.getElementById('toggle').addEventListener('click', togglePauseDomain)
//
// // set settings buttons
// setMutationObserverKey()
// setPauseDomainKey()
// });
//
//
// const changeName = () => {
// const person = document.getElementById('change-name-form-text').value
// if (person) {
// chrome.storage.sync.set({'person': person}, chrome.tabs.reload())
// }
// }
//
// const replaceOther = () => {
// const input_word = document.getElementById('replace-word').value
// const replacement = document.getElementById('replace-with').value
// const is_case_sensitive = document.getElementById('is-case-sensitive').checked
// if (input_word && replacement) {
// if (document.getElementById('is-perm').checked) {
// const obj = {}
// obj[input_word] = replacement
// obj[`${input_word}_case_sensitive`] = is_case_sensitive
// chrome.storage.sync.set(obj)
// }
//
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// chrome.tabs.sendMessage(
// tabs[0].id,
// {
// input_word: input_word,
// replace_value: replacement,
// case_sensitive: is_case_sensitive
// })
// })
// }
// }
//
// const refreshReplacements = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// chrome.tabs.sendMessage(
// tabs[0].id,
// {
// refresh: true
// })
// })
// }
//
// const loadSaved = () => {
// const list = document.getElementById('saved-items-list')
// list.innerHTML = ''
// chrome.storage.sync.get(null, loadSavedItemsWrapper(false))
// chrome.storage.local.get(null, loadSavedItemsWrapper(true))
// }
//
// const loadSavedItemsWrapper = isLocal => items => loadSavedItems(items, isLocal)
//
// const loadSavedItems = (items, isLocal) => {
// const list = document.getElementById('saved-items-list')
// for (var key in items) {
// if (key !== DEACTIVATE_KEY && key !== MUTATION_OBSERVER_KEY && key !== PAUSED_KEY && !key.endsWith('_case_sensitive')) {
// const label = key === 'person' ? 'Y/N' : key
// const case_sensitive = !!items[`${key}_case_sensitive`]
// const case_sensitive_string = case_sensitive ? 'case sensitive' : 'not case sensitive'
// const representative = `${label} -> ${items[key]} (${case_sensitive_string})`
// const list_item = createListItem(key, representative, 'one-saved-item', isLocal)
// list.appendChild(list_item)
// }
// }
// }
//
// const createListItem = (id, text, className, isLocal) => {
// const text_node = document.createTextNode(text)
// const list_node = document.createElement('LI')
// list_node.appendChild(text_node)
// list_node.className = className
// list_node.id = id
// list_node.addEventListener('click', () => {
// if (isLocal) {
// chrome.storage.local.remove(id)
// } else {
// chrome.storage.sync.remove(id)
// }
// list_node.className += ' strikethrough'
// })
// return list_node
// }
//
//
// const setDeactivateKey = () => {
// chrome.storage.sync.get(DEACTIVATE_KEY, obj => {
// const is_deactivated = obj[DEACTIVATE_KEY]
// toggleDeactivateLabel(is_deactivated)
//
// if (is_deactivated) {
// const other_elements = document.getElementsByClassName('fade-when-deactivate')
// const deactivate_only_elements = document.getElementsByClassName('fade-when-deactivate-only')
// Array.from([...other_elements, ...deactivate_only_elements]).forEach(element => {
// element.style.opacity = '0.5'
// })
// const input_elements = document.getElementsByTagName('INPUT')
// Array.from(input_elements).forEach(input => {
// if (input.id !== 'deactivate') {
// input.disabled = 'disabled'
// }
// })
// }
// })
// }
//
// const setMutationObserverKey = () => {
// chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
// const is_enabled = obj[MUTATION_OBSERVER_KEY]
// toggleMutationObserverLabel(is_enabled)
// })
// }
//
// const setPauseDomainKey = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// const hostname = new URL(tabs[0].url).hostname
// document.getElementById('this-url').innerHTML = hostname
//
// const storage_key = {}
// storage_key[PAUSED_KEY] = []
// chrome.storage.sync.get(storage_key, obj => {
// const hostnames = obj[PAUSED_KEY]
// const is_paused = hostnames.indexOf(hostname) !== -1
// togglePauseDomainLabel(is_paused)
//
// if (is_paused) {
// const other_elements = document.getElementsByClassName('fade-when-deactivate')
// const pause_only_other_elements = document.getElementsByClassName('fade-when-pause')
// Array.from([...other_elements, ...pause_only_other_elements]).forEach(element => {
// element.style.opacity = '0.5'
// })
// const input_elements = document.getElementsByTagName('INPUT')
// Array.from(input_elements).forEach(input => {
// if (input.id !== 'pause' && input.id !== 'deactivate') {
// input.disabled = 'disabled'
// }
// })
// }
// })
// })
// }
//
// const toggleDeactivateLabel = (isDeactivated) => {
// document.getElementById('deactivate').checked = isDeactivated;
//
// }
//
// const toggleMutationObserverLabel = (isEnabled) => {
// document.getElementById('enable-observer').checked = isEnabled;
// }
//
// const togglePauseDomainLabel = (isPaused) => {
// document.getElementById('pause').checked = isPaused;
// }
//
// const toggleMutationObserver = () => {
// chrome.storage.sync.get(MUTATION_OBSERVER_KEY, obj => {
// const was_enabled = obj[MUTATION_OBSERVER_KEY]
//
// if (was_enabled) {
// chrome.storage.sync.remove(MUTATION_OBSERVER_KEY)
// } else {
// const new_object = {}
// new_object[MUTATION_OBSERVER_KEY] = true
// chrome.storage.sync.set(new_object)
// }
//
// chrome.tabs.reload()
// })
// }
//
// const togglePauseDomain = () => {
// chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
// const hostname = new URL(tabs[0].url).hostname
//
// const storage_key = {}
// storage_key[PAUSED_KEY] = []
// chrome.storage.sync.get(storage_key, obj => {
// const hostnames = obj[PAUSED_KEY]
// const was_paused = hostnames.indexOf(hostname) !== -1
// var new_hostnames;
//
// if (was_paused) {
// new_hostnames = hostnames.filter(h => h !== hostname)
// } else {
// new_hostnames = hostnames
// new_hostnames.push(hostname)
// }
//
// const new_obj = {}
// new_obj[PAUSED_KEY] = new_hostnames
// chrome.storage.sync.set(new_obj)
//
// chrome.tabs.reload()
// window.close()
// })
// })
// }

View File

@ -1,32 +1,40 @@
PAUSED_KEY = 'pause-this-domain-pls-interactive-fics-yalla-bina';
//PAUSED_KEY = 'pause-this-domain-pls-interactive-fics-yalla-bina';
const verbsHelper = require('english-verbs-helper');
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
if ('input_word' in message){
escapeAndReplace(message.input_word, message.replace_value, message.case_sensitive)
escapeAndReplace(message.input_word, message.replace_value, message.case_sensitive);
} else {
replaceAll()
replaceAll();
}
});
const replaceAll = () => {
browser.storage.local.get(null, replaceAllInStorage)
function replaceAll() {
browser.storage.local.get(null, replaceAllInStorage); // TODO this is bad
}
const replaceAllInStorage = (options) => {
const hostname = window.location.hostname
const is_paused = options[PAUSED_KEY] && options[PAUSED_KEY].indexOf(hostname) !== -1
function replaceAllInStorage(options) {
//const hostname = window.location.hostname
//const is_paused = options[PAUSED_KEY] && options[PAUSED_KEY].indexOf(hostname) !== -1
if (true) { // change paused later to only care about hostname
replaceName(options);
replacePronouns(options);
replacePov(options);
replacePlv(options);
replaceAlso(options);
replaceVerbs(options);
}
}
function replaceName(options) {
const regexp = /\by\/n\b|\(y\/n\)|\[y\/n\]/ig;
replace(regexp, options["name"]);
walk(document.body, regexp, options["name"], directMethod);
}
function replaceVerbs(options) {
const regexp = /vrb\/([\w\s]+)\/([\w\s]+)\//;
walk(document.body, regexp, options, verbMethod);
}
// TODO case sensitivity, premade regexp
@ -182,7 +190,7 @@ function replaceAlso(options) {
}
function escapeAndReplace(input_word, replace_value, case_sensitive) {
let input_word_escaped = escapeRegExp(input_word.trim())
let input_word_escaped = input_word.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
const flags = case_sensitive ? "g" : "ig"
if (input_word_escaped[0].match(/[a-z]/i)) {
input_word_escaped = `\\b${input_word_escaped}`
@ -191,51 +199,64 @@ function escapeAndReplace(input_word, replace_value, case_sensitive) {
input_word_escaped = `${input_word_escaped}\\b`
}
const regexp_input_word = new RegExp(input_word_escaped, flags)
replace(regexp_input_word, replace_value)
walk(document.body, regexp_input_word, replace_value, directMethod);
}
const escapeRegExp = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
const replace = (input_word, replace_value) => {
browser.storage.local.get(obj => {
if (replace_value) {
walk(document.body, input_word, replace_value)
}
})
}
const replaceText = (textNode, input_word, replace_value) => {
let node_value = textNode.nodeValue
node_value = node_value.replace(input_word, replace_value)
textNode.nodeValue = node_value
}
function walk(node, v, p){
// I stole the base to this function from here:
// https://stackoverflow.com/questions/5904914/javascript-regex-to-replace-text-not-in-html-attributes/5904945
if (node.contentEditable != 'true' && node.type != 'textarea' && node.type != 'input') {
function walk(node, input_word, replace_value, replaceMethod) {
if (node.contentEditable == "true" || node.type == "textarea" || node.type == "input") { return; }
var child, next;
switch (node.nodeType) {
case 1: // Element
case 9: // Document
case 11: // Document fragment
case 1: /* ELEMENT_NODE */
case 9: /* DOCUMENT_NODE */
case 11: /* DOCUMENT_FRAGMENT_NODE */
child = node.firstChild;
while (child) {
next = child.nextSibling;
walk(child, v, p);
walk(child, input_word, replace_value, replaceMethod);
child = next;
}
break;
case 3: // Text node
replaceText(node, v, p);
break;
case 3: /* TEXT_NODE */
replaceMethod(node, input_word, replace_value);
}
}
function directMethod(node, input_word, replace_value) {
node.nodeValue = node.nodeValue.replace(input_word, replace_value); // TODO might replaceall work better here?;
}
// TODO do something about options being not input_word
function verbMethod(node, regexp, options) {
var match = node.nodeValue.match(regexp);
if (match == null) { return; }
var verb = match[1];
var tense = match[2];
const replace_value = verbsHelper.getConjugation(null, verb, tense, getPovIndex(options));
node.nodeValue = node.nodeValue.replace(regexp, replace_value);
}
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}
replaceAll()
// TODO figure out plv for this
function getPovIndex(options) {
switch (options.pov) {
case "first":
return 0;
case "second":
return 1;
case "third":
if (options.preset == "he" || options.preset == "she") {
return 2;
} else if (options.preset == "they") {
return 5;
} else if (options.other.plurality == "singular") {
return 2;
} else {
return 5;
}
}
}
replaceAll();