Skip to content

Instantly share code, notes, and snippets.

@Arnavion
Created September 1, 2022 17:51
Show Gist options
  • Save Arnavion/a6d68f5e1071ab3fa23fc614c661697b to your computer and use it in GitHub Desktop.
Save Arnavion/a6d68f5e1071ab3fa23fc614c661697b to your computer and use it in GitHub Desktop.
HN Blocklist Extension
browser.runtime.onMessage.addListener(async message => {
const { param } = message;
switch (param) {
case "get":
return getRecords();
case "set":
return setRecords(message.records);
default:
break;
}
});
async function getRecords() {
const { records = [] } = await browser.storage.local.get("records");
return records;
}
async function setRecords(records) {
await browser.storage.local.set({ records });
}
browser.runtime.sendMessage({ param: "get" }).then(records => {
for (const { username, action } of records) {
for (const usernameElement of document.querySelectorAll(`.hnuser[href$="=${ username }"]`)) {
let defaultElement = usernameElement.parentElement.parentElement;
while (!defaultElement.classList.contains("default")) {
defaultElement = defaultElement.parentElement;
}
const commentElement = defaultElement.querySelector(".comment > .commtext");
switch (action) {
case "invisible":
commentElement.style = "color: #f6f6ef;";
break;
case "flagged":
commentElement.style = "color: #dddddd;";
break;
}
}
}
});
{
"manifest_version": 2,
"name": "HN Blocklist",
"version": "1.0",
"description": "Block users on HN",
"applications": {
"gecko": {
"id": "[email protected]"
}
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": [ "https://news.ycombinator.com/*" ],
"css": [],
"js": [ "content_script.js" ],
"run_at": "document_end",
"all_frames": true
}],
"options_ui": {
"page": "options.xhtml"
},
"permissions": [ "storage", "tabs", "https://news.ycombinator.com/*" ]
}
let recordsTbody;
addEventListener("DOMContentLoaded", () => {
recordsTbody = document.getElementById("records");
const saveRecordsButton = document.getElementById("save_records");
saveRecordsButton.addEventListener("click", () => {
saveRecordsButton.textContent = "Saving...";
saveRecordsButton.disabled = true;
const records = [];
const trs = recordsTbody.getElementsByTagName("tr");
for (const tr of recordsTbody.getElementsByTagName("tr")) {
const [{ firstChild: { value: username } }, { firstChild: { value: action } }, { firstChild: { value: notes } }] = tr.children;
if (username !== "" && (action !== "" || notes !== "")) {
records.push({ username, action, notes });
}
}
browser.runtime.sendMessage({ param: "set", records }).then(response => {
prepareRecords();
saveRecordsButton.textContent = "Save";
saveRecordsButton.disabled = false;
});
});
prepareRecords();
});
function prepareRecords() {
while (recordsTbody.firstChild) {
recordsTbody.removeChild(recordsTbody.firstChild);
}
browser.runtime.sendMessage({ param: "get" }).then(response => {
for (const { username, action, notes } of response) {
addNewRecordRow(username, action, notes);
}
addNewRecordRow("", null, "");
});
}
function addNewRecordRow(username, action, notes) {
const tr = document.createElement("tr");
recordsTbody.appendChild(tr);
{
const td = document.createElement("td");
tr.appendChild(td);
const input = document.createElement("input");
td.appendChild(input);
input.type = "text";
input.value = username;
}
{
const td = document.createElement("td");
tr.appendChild(td);
const select = document.createElement("select");
td.appendChild(select);
const option1 = document.createElement("option");
select.appendChild(option1);
option1.value = "invisible";
option1.innerText = "Invisible";
const option2 = document.createElement("option");
select.appendChild(option2);
option2.value = "flagged";
option2.innerText = "Flagged";
switch (action) {
case "invisible":
select.value = "invisible";
break;
case "flagged":
select.value = "flagged";
break;
default:
break;
}
}
{
const td = document.createElement("td");
tr.appendChild(td);
const textArea = document.createElement("textarea");
td.appendChild(textArea);
textArea.rows = "1";
textArea.cols = "20";
textArea.value = notes;
}
{
const td = document.createElement("td");
tr.appendChild(td);
const deleteButton = document.createElement("button");
td.appendChild(deleteButton);
deleteButton.appendChild(document.createTextNode("Delete"));
deleteButton.addEventListener("click", () => recordsTbody.removeChild(tr));
}
}
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>HN Blocklist Options</title>
<script src="options.js" />
</head>
<body>
<table>
<thead>
<tr>
<th>Username</th>
<th>Action</th>
<th>Notes</th>
</tr>
</thead>
<tbody id="records">
</tbody>
</table>
<div>
<button id="save_records">Save</button>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment