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