X adblock script
This commit is contained in:
parent
b5072717d3
commit
59a945728d
@ -0,0 +1,5 @@
|
||||
Scripts are in the script folder. Please use a userscript manager like [greasemonkey](https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/) to use them.
|
||||
|
||||
## X-adblock
|
||||
|
||||
Script to automatically block accounts posting ads on x.com. [Ublock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/) is a much better option. But this script was written thinking "If I block every single account posting ads would I stop seeing ads on twitter? How much time would it take?", still unanswered for now.
|
95
scripts/X-adblock.user.js
Normal file
95
scripts/X-adblock.user.js
Normal file
@ -0,0 +1,95 @@
|
||||
// ==UserScript==
|
||||
// @name X Ad Auto-Blocker
|
||||
// @version 0.1
|
||||
// @description Automatically block accounts posting ads on x.com
|
||||
// @match https://x.com/*
|
||||
// @grant none
|
||||
// @run-at document-end
|
||||
// ==/UserScript==
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const processed = new WeakSet();
|
||||
|
||||
function waitForSelector(selector, timeout = 3000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const element = document.querySelector(selector);
|
||||
if (element) return resolve(element);
|
||||
|
||||
const observer = new MutationObserver((_, obs) => {
|
||||
const el = document.querySelector(selector);
|
||||
if (el) {
|
||||
obs.disconnect();
|
||||
resolve(el);
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
setTimeout(() => {
|
||||
observer.disconnect();
|
||||
reject(new Error(`Timeout waiting for selector: ${selector}`));
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
async function processAdSpan(span) {
|
||||
try {
|
||||
processed.add(span);
|
||||
const container = span.parentElement?.parentElement;
|
||||
if (!container) return;
|
||||
|
||||
const moreBtn = container.querySelector('button[data-testid="caret"]');
|
||||
if (!moreBtn) return;
|
||||
moreBtn.click();
|
||||
|
||||
const blockItem = await waitForSelector('div[data-testid="block"]');
|
||||
if (/^\s*Block\s+@.+/i.test(blockItem.innerText)) {
|
||||
blockItem.click();
|
||||
} else {
|
||||
const closeBtn = await waitForSelector('button[aria-label="Close"]');
|
||||
closeBtn.click();
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmBtn = await waitForSelector('button[data-testid="confirmationSheetConfirm"]');
|
||||
confirmBtn.click();
|
||||
|
||||
// close "buy X premium" popup
|
||||
const sheetClose = await waitForSelector('button[data-testid="app-bar-close"]');
|
||||
sheetClose.click();
|
||||
|
||||
console.log('Blocked account posting ads');
|
||||
} catch (err) {
|
||||
console.error('Error processing ad span:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
for (const m of mutations) {
|
||||
m.addedNodes.forEach(node => {
|
||||
if (node.nodeType !== 1) return;
|
||||
|
||||
// observe these spans to spot ads
|
||||
const spans = node.matches && node.matches('span.css-1jxf684.r-bcqeeo.r-1ttztb7.r-qvutc0.r-poiln3')
|
||||
? [node]
|
||||
: Array.from(node.querySelectorAll('span.css-1jxf684.r-bcqeeo.r-1ttztb7.r-qvutc0.r-poiln3'));
|
||||
|
||||
spans.forEach(span => {
|
||||
if (span.textContent.trim() === 'Ad' && !processed.has(span)) {
|
||||
processAdSpan(span);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
// Initial scan
|
||||
document.querySelectorAll('span.css-1jxf684.r-bcqeeo.r-1ttztb7.r-qvutc0.r-poiln3').forEach(span => {
|
||||
if (span.textContent.trim() === 'Ad' && !processed.has(span)) {
|
||||
processAdSpan(span);
|
||||
}
|
||||
});
|
||||
})();
|
Loading…
x
Reference in New Issue
Block a user