Remove Admiral adblock walls

This commit is contained in:
2026-05-16 22:45:23 -07:00
parent 73b5313a0c
commit 0ef0360fde
2 changed files with 103 additions and 2 deletions

View File

@@ -64,6 +64,27 @@ const COMMON_ANNOYANCE_ROOT_CLASSES = [
"iubenda-cs-visible"
];
const COMMON_ANNOYANCE_TRIGGER_SELECTORS = [
"a[href*=\"getadmiral.com\" i]",
"a[href*=\"%67e%74%61%64mi%72%61l.com\" i]",
"a[href*=\"admiraladblock\" i]",
"button",
"[role=\"dialog\"]",
"[aria-modal=\"true\"]"
];
const COMMON_ANNOYANCE_TEXT_PATTERNS = [
"ad blocker detected",
"allow ads",
"allowlist",
"continue using your ad blocker",
"disable your ad blocker",
"support us by disabling",
"support the verge by allowing ads",
"turn off your ad blocker",
"you are using an ad blocker"
];
const COMMON_ANNOYANCE_CSS = `
${COMMON_ANNOYANCE_SELECTORS.join(",\n")} {
display: none !important;
@@ -1253,7 +1274,57 @@ async function injectCosmeticFilters(page, hostname) {
async function removeCommonAnnoyances(page) {
try {
await page.evaluate(({ selectors, rootClasses }) => {
await page.evaluate(({ selectors, rootClasses, triggerSelectors, textPatterns }) => {
const annoyanceText = textPatterns.map((pattern) => pattern.toLowerCase());
const textFor = (element) => (element.innerText || element.textContent || "")
.replace(/\s+/g, " ")
.trim()
.toLowerCase();
const isTextTrigger = (element) => {
const text = textFor(element);
if (!text) return false;
if (annoyanceText.some((pattern) => text.includes(pattern))) return true;
return text.includes("ad blocker") && /allow|disable|turn off|subscribe|support/.test(text);
};
const isLinkTrigger = (element) => {
const href = `${element.getAttribute("href") || ""} ${element.href || ""}`.toLowerCase();
return href.includes("getadmiral.com") ||
href.includes("%67e%74%61%64mi%72%61l.com") ||
href.includes("admiraladblock");
};
const findModalRoot = (element) => {
let node = element;
let best = null;
while (node && node !== document.body && node !== document.documentElement) {
const style = window.getComputedStyle(node);
const rect = node.getBoundingClientRect();
const zIndex = Number.parseInt(style.zIndex, 10);
const positioned = /fixed|absolute|sticky/i.test(style.position);
const wide = rect.width >= window.innerWidth * 0.5;
const tall = rect.height >= window.innerHeight * 0.4;
const fullScreen = rect.width >= window.innerWidth * 0.9 && rect.height >= window.innerHeight * 0.9;
if ((positioned && (wide || tall || zIndex >= 1000)) || fullScreen) {
best = node;
}
node = node.parentElement;
}
return best || element.closest("[role=\"dialog\"], [aria-modal=\"true\"]") || element;
};
for (const selector of triggerSelectors) {
try {
document.querySelectorAll(selector).forEach((element) => {
if (!isLinkTrigger(element) && !isTextTrigger(element)) return;
const root = findModalRoot(element);
if (root && root !== document.body && root !== document.documentElement) {
root.remove();
}
});
} catch {
// Ignore selectors unsupported by the current browser.
}
}
for (const selector of selectors) {
try {
document.querySelectorAll(selector).forEach((element) => element.remove());
@@ -1280,7 +1351,9 @@ async function removeCommonAnnoyances(page) {
}
}, {
selectors: COMMON_ANNOYANCE_SELECTORS,
rootClasses: COMMON_ANNOYANCE_ROOT_CLASSES
rootClasses: COMMON_ANNOYANCE_ROOT_CLASSES,
triggerSelectors: COMMON_ANNOYANCE_TRIGGER_SELECTORS,
textPatterns: COMMON_ANNOYANCE_TEXT_PATTERNS
});
} catch {
// Ignore cleanup failures; the archive is still useful.

View File

@@ -100,6 +100,34 @@ test("renderPage removes common cookie consent overlays before snapshot", async
assert.doesNotMatch(rendered, /<body[^>]*class="[^"]*didomi-popup-open/i);
});
test("renderPage removes Admiral adblock walls before snapshot", async () => {
const html = `<!doctype html>
<html style="overflow: hidden;">
<body style="overflow: hidden;">
<main>Article text</main>
<div style="position: fixed; inset: 0; z-index: 2147483647; overflow: auto;">
<section>
<h2>Support The Verge by allowing ads</h2>
<p>Or <a href="https://www.theverge.com/subscribe?itm_campaign=admiraladblock&itm_source=popup">subscribe</a> to continue using your ad blocker uninterrupted.</p>
<button>ALLOW ADS</button>
<a href="https://%67e%74%61%64mi%72%61l.com/pb/">Powered By</a>
</section>
</div>
</body>
</html>`;
const rendered = await renderPage(`data:text/html,${encodeURIComponent(html)}`, {
userscriptDelay: 0
});
assert.match(rendered, /Article text/);
assert.doesNotMatch(rendered, /Support The Verge by allowing ads/);
assert.doesNotMatch(rendered, /ALLOW ADS/);
assert.doesNotMatch(rendered, /getadmiral|%67e%74%61%64mi%72%61l/i);
assert.doesNotMatch(rendered, /<html[^>]*style="[^"]*overflow:\s*hidden/i);
assert.doesNotMatch(rendered, /<body[^>]*style="[^"]*overflow:\s*hidden/i);
});
test("renderPage serializes CSSOM-inserted style rules", async () => {
const html = `<!doctype html>
<html>