This commit is contained in:
Mariam Maarouf 2019-10-19 11:27:27 +02:00
parent ee4b5ed5e8
commit 7dba8578ca
5 changed files with 316 additions and 279 deletions

View File

@ -1,49 +1,44 @@
DISABLE_KEY = 'deactivate-this-extension-pls-interactive-fics-yalla-bina';
DEACTIVATE_KEY = 'deactivate-this-extension-pls-interactive-fics-yalla-bina';
var valChange = /\by\/n\b|\(y\/n\)|\[y\/n\]/ig;
var person;
var replaceAll = function (){
chrome.storage.local.get(null, function(items){
if(items[DISABLE_KEY] !== true){
for(var key in items){
if(items[key]){
if(key=="person")
loadReplace(valChange, items[key]);
else if(key !== DISABLE_KEY){
var s = escapeRegExp(key);
var temp = new RegExp(s, "ig");
loadReplace(temp, items[key]);
}
}
}
}
});
}
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
var s = escapeRegExp(message.stuff);
var val = new RegExp(s, "ig");
if(message.isYN)
loadReplace(val, person);
else
if(message.replaceVal){
loadReplace(val, message.replaceVal);
}
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
escapeAndReplace(message.input_word, message.replace_value)
});
function loadReplace(rep, p){
chrome.storage.local.get(DISABLE_KEY, function(obj){
var enabled = obj[DISABLE_KEY] !== true;
if(p!=null && enabled){
walk(document.body, rep, p);
const replaceAll = () => {
chrome.storage.local.get(null, items => {
if (!items[DEACTIVATE_KEY]) {
for (var key in itmes) {
if (key == 'person') {
const regexp_y_n = /\by\/n\b|\(y\/n\)|\[y\/n\]/ig
replace(regexp_y_n, items[key])
} else if (key !== DEACTIVATE_KEY) {
escapeAndReplace(key, items[key])
}
});
}
}
})
}
const escapeAndReplace = (input_word, replace_value) => {
const input_word_escaped = escapeRegExp(input_word)
const regexp_input_word = new RegExp(input_word_escaped, "ig")
replace(regexp_input_word, replace_value)
}
const escapeRegExp = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
const replace = (input_word, replace_value) => {
chrome.storage.local.get(DEACTIVATE_KEY, obj => {
if (replace_value && !obj[DEACTIVATE_KEY]) {
walk(document.body, input_word, replace_value)
}
})
}
const replaceText = (textNode, input_word, replace_value) => {
const node_value = textNode.nodeValue
node_value = node_value.replace(input_word, replace_value)
textNode.nodeValue = node_value
}
function walk(node, v, p){
@ -62,15 +57,9 @@ function walk(node, v, p){
}
break;
case 3: // Text node
handleText(node, v, p);
replaceText(node, v, p);
break;
}
}
function handleText(textNode, val, p){
var v = textNode.nodeValue;
v = v.replace(val, p); //replaces Y/N or other value entered regardless of the case, whether it's in a bracket or not
textNode.nodeValue = v;
}
replaceAll();
replaceAll()

View File

@ -1,32 +1,38 @@
{
"update_url": "https://clients2.google.com/service/update2/crx",
"update_url": "https://clients2.google.com/service/update2/crx",
"manifest_version": 2,
"name": "InteractiveFics",
"version": "4.4",
"author": "mariamrf",
"version": "5.0",
"description": "Replaces Y/N & other variables in Reader Insert/second person fics with words of your choice.",
"browser_action": {
"default_title": "InteractiveFics",
"default_icon": "icon.png",
"default_popup": "popup.html" },
"default_popup": "popup.html"
},
"permissions": [
"storage",
"tabs"],
"icons": { "16": "icon-16.png",
"tabs"
],
"icons": {
"16": "icon-16.png",
"48": "icon-48.png",
"128": "icon-128.png" },
"content_scripts":
[
"128": "icon-128.png"
},
"content_scripts": [
{
"js": ["content_script.js"],
"run_at": "document_end",
"matches": ["*://*/*"]
"js": [
"content_script.js"
],
"run_at": "document_idle",
"matches": [
"*://*/*"
]
}
],
"incognito": "split",
"background": {
"page": "popup.html"
"page": "popup.html"
},
"homepage_url": "https://interactivefics.tumblr.com"
}
}

89
popup.css Normal file
View File

@ -0,0 +1,89 @@
body {
background-color: white;
color: #2C3531;
width: 250px;
padding:10px;
font-family: 'Rubik', sans-serif;
}
h1 {
font-size: 16px;
}
a{
color: #D9B08C;
transition-duration: 0.5s;
}
a:hover{
color: #16a085;
}
label *:not([type="checkbox"]){
display:block;
}
.other-words input:not([type="checkbox"]){
margin-top:0.2em;
width:100%;
}
.other-words .other, .other-words .replaceBy{
width:98%;
}
.other-words .change{
margin-right:0;
}
#clear-name, #deactivate{
margin-top:0.5em;
width:96%;
}
#deactivate{
background-color: #116466;
color:white;
border:0px;
border-radius:0.5em;
transition-duration: 0.5s;
font-size: 1em;
}
#deactivate:hover{
color: #116466;
background-color: white;
cursor:pointer;
}
input[type="text"]{
width:70%;
}
.strikethrough{
text-decoration: line-through;
}
.one-saved-item:hover{
background-color: #e74c3c;
color: white;
cursor: pointer;
}
.saved-items-list-wrapper{
height:100px;
overflow: auto;
}
details {
margin-top: 0.8em;
}
summary {
cursor: pointer;
}
input[type="button"]{
margin-top: 0.8em;
margin-bottom: 0.8em;
}
input[type="submit"]{
cursor: pointer;
transition-duration: 0.5s;
}
input[type="submit"]:hover {
background-color: #2C3531;
color: white;
border-radius: 0.4em;
}

View File

@ -1,116 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<link href='http://fonts.googleapis.com/css?family=Play' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
background-color: white;
color: #16a085;
width: 250px;
padding:10px;
font-family: 'Play', sans-serif;
}
h1 {
font-size: 16px;
}
a{
color: #e67e22;
}
a:hover{
color: #16a085;
}
label *:not([type="checkbox"]){
display:block;
}
.otherWords input:not([type="checkbox"]){
margin-top:0.2em;
width:100%;
}
.otherWords .other, .otherWords .replaceBy{
width:98%;
}
.otherWords .change{
margin-right:0;
}
#clear-name, #deactivate{
margin-top:0.5em;
width:96%;
}
#deactivate{
background-color: #9b59b6;
color:white;
border:0px;
border-radius:0.5em;
transition-duration: 0.5s;
}
#deactivate:hover{
color: #9b59b6;
background-color: white;
cursor:pointer;
}
input[type="text"]{
width:70%;
}
.strikethrough{
text-decoration: line-through;
}
.one-saved-item:hover{
background-color: #e74c3c;
color: white;
cursor: pointer;
}
.savedItemsList{
height:100px;
overflow: auto;
}
</style>
<script src="popup.js" type="text/javascript" >
</script>
</head>
<body>
<h1>Enter the name here:</h1>
<form><input type="text" id="inputTxt"/><input type="submit" id="submit" value="Change"/></form>
<input type="button" id="clear-name" value="Clear Name"/>
<p><details id="moreWords"><summary>Need to replace something other than Y/N?</summary>
<p><small>(This change will go away when you refresh/go to another page unless you check the box next to "Store this replacement")</small></p>
<p><form class="otherWords changeForm">
<label><span>Value [e.g L/N, E/C, etc]:</span>
<input type="text" name="replaceWord" class="other"></label>
<head>
<link href="https://fonts.googleapis.com/css?family=Rubik&display=swap" rel="stylesheet">
<link href='popup.css' rel='stylesheet' type='text/css'>
<script src="popup.js" type="text/javascript"></script>
</head>
<body>
<div id="all-but-deactivate-wrapper">
<h1>Enter the name here:</h1>
<form id="change-name-form">
<input type="text" id="change-name-form-text"/>
<input type="submit" value="Change"/>
</form>
<form id="clear-name-form">
<input type="submit" id="clear-name" value="Clear Name"/>
</form>
<details>
<summary>Need to replace something other than Y/N?</summary>
<p><small>This change will go away when you refresh/go to another page unless you check the box next to "Store this replacement".</small></p>
<p>
<form id="replace-other-words-form" class="other-words">
<label>
<span>Value (e.g. L/N, E/C, etc):</span>
<input type="text" id="replace-word" class="other"/>
</label>
<br>
<label><span>Replace with:</span>
<input type="text" name="replaceWith" class="replaceBy"></label>
<label><input type="checkbox" name="isPerm">Store this replacement</label>
<label>
<span>Replace with:</span>
<input type="text" id="replace-with" class="replaceBy"/>
</label>
<label>
<input type="checkbox" id="is-perm">Store this replacement
</label>
<input type="submit" class="change" value="Change">
</form>
</p>
</details></p>
<p>
<p><details><summary id="show-saved">STORED REPLACEMENTS</summary>
<p>To remove, simply click on a replacement. To change, re-enter in the previous section.</p>
<div class="savedItemsList">
<ul id="theList">
</details>
<details>
<summary id="show-saved">Stored Replacements</summary>
<p><small>To remove, simply click on a replacement. To change, re-enter in the previous section.</small></p>
<div class="saved-items-list-wrapper">
<ul id="saved-items-list">
</ul>
</div>
</details></p>
<p>
<details><summary>About</summary>
<a href="http://interactivefics.tumblr.com" target="_blank" title="Official tumblr">Interactive Fics</a> is a free Chrome extension developed by <a href="https://github.com/blaringsilence" target="_blank" title="her github">blaringsilence</a> to improve your online story reading experience. The extension is open source and all source code can be found <a href="https://github.com/blaringsilence/interactive-fics" title="github repo">here.</a>
</details>
<br>
</details>
<details>
<summary>About</summary>
<a href="http://interactivefics.tumblr.com" target="_blank" title="Official site">Interactive Fics</a> is a free Chrome extension built to improve your online story reading experience. The extension is open source and all source code can be found <a href="https://github.com/interactivefics/interactive-fics" target="_blank" title="github repo">here.</a>
</details>
</div>
<input type="button" id="deactivate"/>
</br>
<br>
<a href="http://interactivefics.tumblr.com/ask" target="_blank">Feedback, suggestions and requests.</a></br>
</p>
</body>
<a href="http://interactivefics.tumblr.com/ask" target="_blank">Feedback, suggestions and requests.</a></br>
</body>
</html>

210
popup.js
View File

@ -1,108 +1,122 @@
DEACTIVATE_KEY = 'deactivate-this-extension-pls-interactive-fics-yalla-bina';
DISABLE_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('clear-name-form').addEventListener('submit', clearName)
document.getElementById('replace-other-words-form').addEventListener('submit', replaceOther)
document.getElementById('show-saved').addEventListener('click', loadSaved)
document.getElementById('deactivate').addEventListener('click', toggleDeactivate)
chrome.storage.local.get(DISABLE_KEY, function(obj){
var isDeactivated = obj[DISABLE_KEY] !== true ? false : true;
var key = isDeactivated ? 'Re-activate ' : 'Deactivate ';
document.getElementById('deactivate').value = key + 'Extension';
if(isDeactivated){
document.getElementsByTagName("BODY")[0].title = "Extension is disabled";
var elements = document.getElementsByTagName("INPUT");
for(var i=0; i<elements.length; i++){
if(elements[i].id !== 'deactivate')
elements[i].disabled = 'disabled';
}
}
});
document.getElementById('deactivate').addEventListener('click', function(){
chrome.storage.local.get(DISABLE_KEY, function(obj){
// 1. previous state:
var wasDeactivated = obj[DISABLE_KEY] === undefined ? false : true;
// 2. button:
var key = wasDeactivated ? 'Deactivate ' : 'Re-activate ';
document.getElementById('deactivate').value = key + 'Extension';
// 3. storage:
if(wasDeactivated){
chrome.storage.local.remove(DISABLE_KEY);
}
else{
var obj = {};
obj[DISABLE_KEY] = true;
chrome.storage.local.set(obj);
}
chrome.tabs.reload();
window.close();
});
});
document.getElementById('submit').addEventListener('click', clickHandler);
document.getElementById('show-saved').addEventListener('click', function(){
chrome.storage.local.get(null, function(items){
var list = document.getElementById('theList');
list.innerHTML = "";
for(var key in items){
if(key !== DISABLE_KEY){
var k;
if(key=="person")
k = "Y/N";
else
k = key;
var v = items[key];
var rep = k + " -> " + v;
var text = document.createTextNode(rep);
var node = document.createElement("LI");
node.appendChild(text);
node.id = key;
node.className = 'one-saved-item';
node.addEventListener('click', function(){
chrome.storage.local.remove(this.id);
this.className+=' strikethrough';
});
list.appendChild(node);
}
}
});
});
document.getElementById('clear-name').addEventListener('click', function(){ chrome.storage.local.remove("person", chrome.tabs.reload()) } );
var others = document.getElementsByClassName('changeForm');
for(var i=0; i<others.length; i++)
others[i].addEventListener('submit', otherHandler);
}); //instead of onclick="clickHandler()" in popup.html
// set disable/enable button
setDeactivateKey()
});
function otherHandler(){
var myInput = this.replaceWord.value;
if(myInput){
var valChange = myInput;
var isYN;
var replace;
if(this.replaceWith){
isYN = false;
replace = this.replaceWith.value;
if(this.isPerm.checked){
var obj = {};
obj[valChange] = replace;
chrome.storage.local.set(obj);
}
}
else{
isYN = true;
replace = 'NOPE'; // should/will never get accessed
}
chrome.tabs.query({active:true,currentWindow:true}, function(tab){
chrome.tabs.sendMessage(tab[0].id, {stuff:valChange, isYN: isYN, replaceVal:replace});
});
const changeName = () => {
const person = document.getElementById('change-name-form-text').value
if (person) {
chrome.storage.local.set({'person': person}, chrome.tabs.reload())
}
}
function clickHandler(){
var person = document.getElementById("inputTxt").value;
if(person)
chrome.storage.local.set({"person": person}, chrome.tabs.reload());
const clearName = () => {
chrome.storage.local.remove('person', chrome.tabs.reload())
}
const replaceOther = () => {
const input_word = document.getElementById('replace-word').value
const replacement = document.getElementById('replace-with').value
if (input_word && replacement) {
if (document.getElementById('is-perm').checked) {
const obj = {}
obj[input_word] = replacement
chrome.storage.local.set(obj)
}
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{
input_word: input_word,
replace_value: replacement
})
})
}
}
const loadSaved = () => {
chrome.storage.local.get(null, items => {
const list = document.getElementById('saved-items-list')
list.innerHTML = ''
let hasItems = false
for (var key in items) {
if (key !== DEACTIVATE_KEY) {
const label = key === 'person' ? 'Y/N' : key
const representative = `${label} -> ${items[key]}`
const list_item = createListItem(key, representative, 'one-saved-item')
list.appendChild(list_item)
hasItems = true
}
}
if (!hasItems) {
list.innerHTML = '<small>No stored replacements yet!</small>'
}
})
}
const createListItem = (id, text, className) => {
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', () => {
chrome.storage.local.remove(id)
list_node.className += ' strikethrough'
})
return list_node
}
const setDeactivateKey = () => {
chrome.storage.local.get(DEACTIVATE_KEY, obj => {
const is_deactivated = obj[DEACTIVATE_KEY]
toggleDeactivateLabel(is_deactivated)
if (is_deactivated) {
const other_elements = document.getElementById('all-but-deactivate-wrapper')
other_elements.style.opacity = '0.5'
const input_elements = document.getElementsByTagName('INPUT')
Array.from(input_elements).forEach(input => {
if (input.id !== 'deactivate') {
input.disabled = 'disabled'
}
})
}
})
}
const toggleDeactivateLabel = (reactivateBool) => {
const prefix = reactivateBool ? 'Re-activate' : 'Deactivate'
const deactivate_button = document.getElementById('deactivate')
deactivate_button.value = `${prefix} Extension`
}
const toggleDeactivate = () => {
chrome.storage.local.get(DEACTIVATE_KEY, obj => {
const was_deactivated = obj[DEACTIVATE_KEY]
toggleDeactivateLabel(!was_deactivated)
if (was_deactivated) {
chrome.storage.local.remove(DEACTIVATE_KEY)
} else {
const new_object = {}
new_object[DEACTIVATE_KEY] = true
chrome.storage.local.set(new_object)
}
chrome.tabs.reload()
window.close()
})
}