Skip to content

Commit

Permalink
add disabled sites list, fixes #6
Browse files Browse the repository at this point in the history
  • Loading branch information
pelmers committed Dec 29, 2021
1 parent ba3b8b3 commit 1d9db3a
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 18 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ overlapping pair of patterns A -> B and B -> C, then A - > C is shown.
[Firefox](https://addons.mozilla.org/en-US/firefox/addon/text-rewriter/)

[Chrome](https://chrome.google.com/webstore/detail/abmchgifbehnkekmmfmkkgdbhcphmeoi)

## Latest changes
- Add preference to make a list of domains exempt from text replacement (https://github.com/pelmers/text-rewriter/issues/6)
8 changes: 4 additions & 4 deletions data/prefs.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
width: 60%;
height: 200px;
}
#pref_table {
#pref_table, #website_table {
width: 100%;
border-collapse: collapse;
}
Expand All @@ -20,7 +20,7 @@ td, th {
border: 1px solid #ccc;
text-align: left;
}
#saved_text {
#saved_text, #website_saved_text {
color: green;
font-family: sans-serif;
font-style: italic;
Expand All @@ -37,10 +37,10 @@ td, th {
table, thead, tbody, th, td, tr {
display: block;
}
#pref_table, .button_group, .info_message {
#pref_table, #website_table, .button_group, .info_message {
margin-left: 0;
}
#pref_table {
#pref_table, #website_table {
width: auto;
}
.button_group, .info_message, #saved_text {
Expand Down
16 changes: 13 additions & 3 deletions data/prefs.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,20 @@
<button id="clear_button" type="button">Clear All</button>
<div id="saved_text" style="display:none;">Saved</div>
</div>
<div class="info_message">
<span style="font-variant:small-caps;font-weight:bold;">Note: </span>
Empty rows are not saved.</div>
<h3>Disabled Sites
<table id="website_table">
<tr id="website_header">
<th>Pattern
</tr>
</table>
<div class="button_group">
<button id="website_add_button" type="button">Add Rule</button>
<button id="website_save_button" type="button">Save</button>
<button id="website_clear_button" type="button">Clear All</button>
<div id="website_saved_text" style="display:none;">Saved</div>
</div>
<textarea id="scratchpad"></textarea>
<script src="prefs.js"></script>
<script src="prefs_blocked_sites.js"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions data/prefs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
(function() {

const api = chrome;

const storage = api.storage.local;
Expand Down Expand Up @@ -169,3 +171,5 @@ document.addEventListener('DOMContentLoaded', function () {

add_btn.addEventListener('click', appendEmptyRow);
});

})();
119 changes: 119 additions & 0 deletions data/prefs_blocked_sites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
(function() {

const api = chrome;

const storage = api.storage.local;

// TODO: write this thing in typescript some day

const table = document.getElementById("website_table"),
save_btn = document.getElementById("website_save_button"),
clear_btn = document.getElementById("website_clear_button"),
add_btn = document.getElementById("website_add_button");

// Make a span element with the given text and class.
function makeSpan(cl, text) {
const sp = document.createElement('span');
sp.appendChild(document.createTextNode(text));
sp.classList.add(cl);
return sp;
}

function makeTD(type, value) {
const td = document.createElement('td'),
inp = document.createElement('input');
inp.type = type;
if (value)
inp.value = value;
td.insertBefore(inp, td.firstChild)
return td;
}

// Append a row to the table with given values for inputs.
function appendRow(data) {
const tr = document.createElement("tr"),
pattern = makeTD("text", data.pattern),
delrow = makeSpan('delrow', 'x');
delrow.style.float = 'right';
pattern.appendChild(delrow);
tr.appendChild(pattern);
table.appendChild(tr);
attachDelRowListener(tr.querySelector(".delrow"));
}

// Append an empty row to the table.
function appendEmptyRow() {
appendRow({pattern: ""});
}

// Call func(elem) on each element of arr.
function forEach(arr, func) {
for (let i = 0; i < arr.length; i++)
func(arr[i]);
}

// Listen on clicking delete button of a row.
function attachDelRowListener(itm) {
(function(e) {
e.addEventListener('click', function() {
table.deleteRow(e.parentNode.parentNode.rowIndex);
});
})(itm);
}

function appendFromData(blockPatterns) {
// put the data into the page
forEach(blockPatterns, appendRow);
// make sure we have at least one row in the table
for (let i = table.children.length; i <= 1; i++) {
appendEmptyRow();
}
}

let saveTimeout;
// When document ready, add current preferences and attach buttons.
document.addEventListener('DOMContentLoaded', function () {
storage.get({
blockPatterns: [],
}, function (data) {
appendFromData(data.blockPatterns);
});

// Collect all row data and save to local storage.
save_btn.addEventListener('click', function () {
const data = [],
c = table.children;
for (let i = 1; i < c.length; i++) {
const d = c[i].querySelectorAll("input");
if (d[0].value.length === 0)
continue;
data.push({
pattern: d[0].value,
});
}
if (saveTimeout) {
window.clearTimeout(saveTimeout);
}
storage.set({
blockPatterns: data,
}, function () {
document.querySelector("#website_saved_text").style.display = 'inline';
saveTimeout = window.setTimeout(function () {
document.querySelector("#website_saved_text").style.display = 'none';
}, 800);
});
});

clear_btn.addEventListener('click', function () {
// the first row is the header, so delete up to that point
for (let row = table.rows.length - 1; row > 0; row--) {
table.deleteRow(row);
}
appendFromData([]);
// don't save immediately in case it's an accident
});

add_btn.addEventListener('click', appendEmptyRow);
});

})();
49 changes: 39 additions & 10 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const storage = api.storage.local;
// changed nodes to a list and then go through that every Interval time.
const DEFAULT_DYNAMIC_REPLACE_INTERVAL_MS = 2000;

const DISABLED_MSG = "⛔️";

// Send replacement lists to the given tab id.
function updateTab(id) {
storage.get({
Expand All @@ -23,13 +25,31 @@ function updateTab(id) {
});
}

function isBlocked(blocklist, url) {
for (const {pattern} of blocklist) {
const re = new RegExp(pattern);
if (re.test(url)) {
return true;
}
}
}

function makePattern(url) {
// Find the domain/subdomain part of the url and escape the periods
return new URL(url).origin.replace(/\./g, '\\.');
}

// Listen to messages from content scripts.
api.runtime.onMessage.addListener(function (message, sender) {
const {event} = message;
if (event === "pageLoad") {
storage.get({ enabled: true }, function (data) {
if (data.enabled) {
storage.get({ blockPatterns: [] }, function (data) {
const {url} = sender.tab;
if (!isBlocked(data.blockPatterns, url)) {
updateTab(sender.tab.id);
} else {
api.browserAction.setBadgeText({text: DISABLED_MSG, tabId: sender.tab.id});
api.browserAction.setBadgeBackgroundColor({color: [102,102,102,255]});
}
});
} else if (event === "replaceCount") {
Expand All @@ -41,15 +61,24 @@ api.runtime.onMessage.addListener(function (message, sender) {

// When enable state changes, change the icon and update the current tab.
api.browserAction.onClicked.addListener(function (tab) {
storage.get({ enabled: true }, function (data) {
if (data.enabled) {
storage.set({ enabled: false });
api.browserAction.setIcon({path: { 48: "data/icon-disabled.png" }});
api.tabs.reload(tab.id);
storage.get({ blockPatterns: [] }, function (data) {
if (!isBlocked(data.blockPatterns, tab.url)) {
data.blockPatterns.push({pattern: makePattern(tab.url)})
storage.set({blockPatterns: data.blockPatterns}, () => {
api.browserAction.setBadgeText({text: "🔄", tabId: tab.id});
api.browserAction.setBadgeBackgroundColor({color: [102,102,102,255]});
});
} else {
storage.set({ enabled: true });
api.browserAction.setIcon({path: { 48: "data/icon.png" }});
updateTab(tab.id);
api.browserAction.getBadgeText({tabId: tab.id}, (text) => {
if (text === DISABLED_MSG) {
// Bypass the disable state for this tab (if not already bypassed)
updateTab(tab.id);
} else {
// in this case it's already disabled, but it was bypassed (ask user to reload)
api.browserAction.setBadgeText({text: "🔄", tabId: tab.id});
api.browserAction.setBadgeBackgroundColor({color: [102,102,102,255]});
}
});
}
});
});
3 changes: 2 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
}
],
"permissions": [
"storage"
"storage",
"tabs"
],
"background": {
"scripts": [
Expand Down

0 comments on commit 1d9db3a

Please # to comment.