🏠 Home 

Hacker News Filter

Filter HN posts based on words in the title


Install this script?
// ==UserScript==
// @name         Hacker News Filter
// @namespace    https://news.ycombinator.com/
// @version      1.0
// @license      GPLv3
// @description  Filter HN posts based on words in the title
// @author       xdpirate
// @match        https://news.ycombinator.com/
// @match        https://news.ycombinator.com/?p*
// @include      /^https:\/\/news\.ycombinator\.com\/(news|newest|front|best|ask|show).*$/
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ycombinator.com
// @run-at       document-end
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// ==/UserScript==
GM_addStyle(`
#HNFToggleButton {
cursor: pointer;
}
#HNFBlacklistArea {
background-color: black;
color: white;
font-family: monospace;
}
#HNFOuterDiv {
float: left;
background-color: black;
color: white;
padding: 5px;
border: 1px solid white;
border-radius: 10px;
z-index: 2147483647;
position: absolute;
top: 50px;
left: 100px;
}
#HNFCloseButton {
cursor: pointer;
}
.hidden {
display: none;
}
`);
let blacklist = GM_getValue("blacklist", []);
let empty = false;
if(blacklist.length == 0 || (blacklist.length == 1 && blacklist[0] == "") || blacklist == undefined || blacklist == null) {
empty = true;
}
let regexStr = "\\b(";
if(!empty) {
for(let j = 0; j < blacklist.length; j++) {
// Don't start with a pipe
if(j > 0) {
regexStr = regexStr + "|";
}
regexStr = regexStr + blacklist[j];
}
}
regexStr = regexStr + ")\\b";
let regex = new RegExp(regexStr, "i");
let newBox = document.createElement("div");
newBox.innerHTML = `
<div id="HNFOuterDiv" class="hidden">
<div id="HNFInnerDiv">
<span id="HNFCloseButton" title="Close">❌</span> <b>Hacker News Filter</b><br />
Comma-separated list of blacklisted phrases:<br />
<textarea id="HNFBlacklistArea" rows="10" cols="80">${blacklist}</textarea><br />
<input type="button" value="Save and reload" id="HNFSaveButton"></input>
<div>
</div>
`;
document.body.append(newBox);
document.getElementById("HNFCloseButton").onclick = function() {
document.getElementById("HNFOuterDiv").classList.toggle("hidden");
};
document.getElementById("HNFSaveButton").onclick = function() {
GM_setValue("blacklist", document.getElementById("HNFBlacklistArea").value.split(","));
location.reload();
};
let c = 0;
if(!empty) {
let things = document.querySelectorAll("tr.athing");
for(let i = 0; i < things.length; i++) {
if(regex.test(things[i].querySelector("span.titleline > a").innerHTML)) {
things[i].nextElementSibling.remove(); // Remove comments line
things[i].nextElementSibling.remove(); // Remove spacer
things[i].remove();                    // Remove the thing itself
c++;
}
}
console.log(`HNF hid ${c} posts on this page (${Math.round((c / things.length) * 100)}%)`);
}
let pageTop = document.querySelector("span.pagetop");
let filterLink = document.createElement("a");
filterLink.innerHTML = `filter (${c})`;
filterLink.href = "#";
filterLink.onclick = function() {
document.getElementById("HNFOuterDiv").classList.toggle("hidden");
};
pageTop.appendChild(document.createTextNode(" | "));
pageTop.appendChild(filterLink);