You take care now.
I think I'll ask codex to write me a Chrome extension to censor you. :)
EDIT: Done!
(() => { "use strict";
const BLOCKED_USER = "bopbopbop7";
// -------- helpers --------
/** True if the node (or its descendants) contain a user link matching blocked user */
function containsBlockedUserLink(root) {
if (!root || !(root instanceof Element)) return false;
const sel = `a[href^="user?id="], a[href*="user?id="]`;
const links = root.querySelectorAll(sel);
for (const a of links) {
const href = a.getAttribute("href") || "";
// HN uses relative href like "user?id=pg"
// Algolia uses full/relative links; check query portion.
if (href.includes(`user?id=${BLOCKED_USER}`)) return true;
if ((a.textContent || "").trim() === BLOCKED_USER && href.includes("user?id=")) return true;
}
return false;
}
/** Remove the closest HN listing block (table row pairs) for a story */
function removeHNStoryFromListing(anchorUserLink) {
// On HN listings, a story is typically 2 consecutive <tr>:
// 1) title row (class="athing"), 2) subtext row.
const userTr = anchorUserLink.closest("tr");
if (!userTr) return;
// If we are in the subtext row, the associated title row is usually previousElementSibling
// The title row has class "athing".
const maybeTitleTr = userTr.previousElementSibling;
const titleTr = maybeTitleTr && maybeTitleTr.classList && maybeTitleTr.classList.contains("athing")
? maybeTitleTr
: userTr.classList && userTr.classList.contains("athing")
? userTr
: null;
if (titleTr) {
const subtextTr = titleTr.nextElementSibling;
titleTr.remove();
if (subtextTr && subtextTr.tagName === "TR") subtextTr.remove();
// Sometimes there is a spacing row after; remove if it's just spacing
const spacer = (subtextTr && subtextTr.nextElementSibling) || null;
if (spacer && spacer.tagName === "TR" && spacer.textContent.trim() === "") {
spacer.remove();
}
} else {
// Fallback: remove just the row containing the user link
userTr.remove();
}
}
/** Collapse/remove comments by the blocked user on item pages */
function collapseHNComment(anchorUserLink) {
// HN comments are in <tr class="athing comtr"> (or similar)
const comtr = anchorUserLink.closest("tr.athing.comtr, tr.comtr");
if (!comtr) return;
// Remove the comment row plus the following "spacer" row if present
const next = comtr.nextElementSibling;
comtr.remove();
if (next && next.tagName === "TR" && next.textContent.trim() === "") {
next.remove();
}
}
/** Algolia results: remove the result item container */
function removeAlgoliaResult(anchorUserLink) {
// Algolia HN search commonly uses .item-title-and-infos or .Story or .Comment containers.
// We'll just walk up to a reasonable container.
const container =
anchorUserLink.closest("li, .item, .Story, .Comment, .SearchResults__item, .search-result, article, .result") ||
anchorUserLink.parentElement;
if (container) container.remove();
}
function handleUserLink(a) {
const href = a.getAttribute("href") || "";
const isBlocked =
href.includes(`user?id=${BLOCKED_USER}`) || (a.textContent || "").trim() === BLOCKED_USER;
if (!isBlocked) return;
const host = location.hostname;
if (host === "news.ycombinator.com") {
// Distinguish listing pages vs item pages by presence of "item?id="
const isItemPage = location.pathname === "/item";
if (isItemPage) {
collapseHNComment(a);
// Also on item page: if OP is blocked, remove the top submission block.
// We can try removing the whole "athing" story block if the subtext shows blocked user.
const topStoryTr = document.querySelector("tr.athing");
if (topStoryTr && containsBlockedUserLink(topStoryTr.nextElementSibling)) {
topStoryTr.remove();
const sub = topStoryTr.nextElementSibling;
if (sub && sub.tagName === "TR") sub.remove();
}
} else {
removeHNStoryFromListing(a);
}
} else if (host === "hn.algolia.com") {
removeAlgoliaResult(a);
}
}
function scanAndRemove(root = document) {
const links = root.querySelectorAll(`a[href*="user?id=${BLOCKED_USER}"]`);
for (const a of links) handleUserLink(a);
// Extra safety: sometimes the link text is present but href format differs.
// Catch those too.
const maybeTextLinks = root.querySelectorAll(`a`);
for (const a of maybeTextLinks) {
if ((a.textContent || "").trim() === BLOCKED_USER && (a.getAttribute("href") || "").includes("user?id=")) {
handleUserLink(a);
}
}
}
// Initial sweep
scanAndRemove(document);
// Keep it working with infinite scroll / dynamic loads
const obs = new MutationObserver((mutations) => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node instanceof Element) scanAndRemove(node);
}
}
});
obs.observe(document.documentElement, { childList: true, subtree: true });
})();