// ==UserScript==
// @name RemoveAds
// @name:en RemoveAds
// @version 1.9.6
// @description 需要配合AdBlock类软件使用!该脚本可以移除那些规避反广告功能或要求解除反广告功能的广告,仅此而已。
// @description:en This script can remove the ads which avoiding or requesting you to stop blocking them. Just it.
// @author AnnAngela
// @match *://*/*
// @run-at document-start
// @grant unsafeWindow
// @namespace https://greasyfork.org/users/129402
// @license GNU General Public License v3.0 or later
// ==/UserScript==
"use strict";
(function () {
/* 防止重复加载 */
if (unsafeWindow.RemoveAds) { return; }
// console.info('RemoveAds running.');
unsafeWindow.removedAds = [];
const MutationObserver = unsafeWindow.MutationObserver;
const $ = unsafeWindow.document.querySelector.bind(unsafeWindow.document);
const $$ = unsafeWindow.document.querySelectorAll.bind(unsafeWindow.document);
const info = (that) => {
console.info("RemoveAds: ", unsafeWindow.removedAds.push(that), "\nTarget:", that, "\nParentNode:", that.parentNode, "\nInnerText:", that.innerText);
};
let localstorage;
try {
localstorage = unsafeWindow.localStorage;
} catch (e) {
console.info("RemoveAds: Tried to get `localStorage` but got an error - ", e);
localstorage = {
length: 0,
key: () => null,
getItem: () => null,
setItem: () => { },
removeItem: () => { },
};
}
if (location.hostname.endsWith(".ff14angler.com")) {
const removeChild = unsafeWindow.Node.prototype.removeChild;
unsafeWindow.Node.prototype.removeChild = function (e) {
if (e.id === "contents") {
console.info("RemoveAds: Tried to remove contents", e, "but rejected");
return false;
}
return removeChild.bind(this)(e);
};
} else if ((location.host.includes("bbs.nga.cn") || location.host.includes("bbs.ngacn.cc")) && location.pathname.includes("adpage_insert")) {
const stylesheet = document.createElement("style");
stylesheet.innerText = "html, body, * { display: none!important; }";
unsafeWindow.document.body.appendChild(stylesheet);
const jump = function jump() {
if (unsafeWindow.getJump) {
const _getJump = unsafeWindow.getJump.bind(unsafeWindow);
unsafeWindow.getJump = function () { };
_getJump();
}
};
setInterval(jump, 10);
} else if (location.hostname === "www.ruanyifeng.com") {
console.info("RemoveAds: removed the anti-adb checker.");
const c = setInterval(() => {
const img = $('a > img[src*="wangbase.com/blogimg/asset/"]');
if (img) {
img.remove();
} else {
const entrySponsor = $(".entry-sponsor");
if (entrySponsor) {
entrySponsor.remove();
clearInterval(c);
}
}
/* const mainContent = $("#main-content");
if (mainContent) {
Object.defineProperty(mainContent, "innerHTML", {
configurable: false,
enumerable: false,
get: function () {
const temp = document.createElement("div");
temp.innerHTML = mainContent.outerHTML;
return $("#main-content").innerHTML;
},
set: function (value) {
if (value === "") {
const mainContentOuterHTML = mainContent.outerHTML;
setTimeout(() => {
mainContent.outerHTML = mainContentOuterHTML;
}, 1);
throw new Error("RemoveAds: Got a call from blockAdBlock tring removing the content of page.");
}
const temp = document.createElement("div");
temp.innerHTML = unsafeWindow.document.body.outerHTML;
let tag = unsafeWindow.document.body.outerHTML.replace(temp.innerHTML, "$$$$$$$$$$$$");
tag = tag.replace("$$$$$$</body>", value + "</body>");
unsafeWindow.document.body.outerHTML = tag;
},
});
clearInterval(c);
} */
}, 10);
}
const props = {
admiral: {
configurable: false,
enumerable: false,
writable: false,
value: function () {
console.info("RemoveAds: Got a call to admiral but denied.");
},
},
};
const secretKey = `${Math.random().toString(36).substring(2)}${Math.random().toString(36).substring(2)}${Math.random().toString(36).substring(2)}`;
class Stack extends Error {
constructor(...a) {
super(...a);
}
getStack(offset = 4) {
return typeof this.stack === "string" ? this.stack.replace(/^Error\n +/, "").replace(/\n +/g, `\n${" ".repeat(offset)}`) : this.stack;
}
}
class BlockAdBlock {
constructor(...args) {
if (args[0] !== secretKey) { console.info("RemoveAds: Got a call to construct BlockAdBlock but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9)); }
}
check(...args) {
console.info("RemoveAds: Got a call to blockAdBlock.check but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
}
clearEvent(...args) {
console.info("RemoveAds: Got a call to blockAdBlock.clearEvent but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
}
emitEvent(...args) {
console.info("RemoveAds: Got a call to blockAdBlock.emitEvent but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
}
setOption(...args) {
console.info("RemoveAds: Got a call to blockAdBlock.setOption but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
}
on(detected, fn) {
this[detected === true ? "onDetected" : "onNotDetected"](fn);
return this;
}
onDetected(...args) {
console.info("RemoveAds: Got a call to blockAdBlock.onDetected but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
return this;
}
onNotDetected(...args) {
if (typeof args[0] === "function") {
args[0]();
}
console.info("RemoveAds: Got a call to blockAdBlock.onNotDetected but denied,\nwith arguments", ...args, ",\nin stack", new Stack().getStack(9));
return this;
}
}
const blockAdBlockProps = {
configurable: false,
enumerable: false,
writable: false,
value: new BlockAdBlock(secretKey),
};
const BlockAdBlockProps = {
configurable: false,
enumerable: false,
writable: false,
value: BlockAdBlock,
};
const fabList = ["fuckAdBlock", "blockAdBlock", "sniffAdBlock"];
const FABList = ["FuckAdBlock", "BlockAdBlock", "SniffAdBlock"];
fabList.forEach((n) => {
if (Object.prototype.hasOwnProperty.bind(unsafeWindow)(n)) {
unsafeWindow[n].__proto__ = new BlockAdBlock(secretKey);
} else {
Object.defineProperty(unsafeWindow, n, blockAdBlockProps);
}
});
FABList.forEach((n) => {
if (Object.prototype.hasOwnProperty.bind(unsafeWindow)(n)) {
unsafeWindow[n].prototype = BlockAdBlock;
} else {
Object.defineProperty(unsafeWindow, n, BlockAdBlockProps);
}
});
Object.defineProperties(unsafeWindow, props);
let blockBlockAdBlockFlag = false;
unsafeWindow.removeAd = function removeAd() {
if (!location.host.includes("getadmiral.com")) {
Array.from($$("body > :not([rmAd-admiral])")).forEach((that) => {
that.setAttribute("rmAd-admiral", "");
if (that.querySelector('a[href^="https://getadmiral.com/pb"]')) {
info(that);
that.remove();
}
});
}
if (unsafeWindow.document.body.dataset.blockBlockAdBlock !== "true") {
unsafeWindow.document.body.dataset.blockBlockAdBlock = "true";
Object.defineProperty(unsafeWindow.document.body, "innerHTML", {
configurable: false,
enumerable: false,
get: function () {
const temp = document.createElement("div");
temp.innerHTML = unsafeWindow.document.body.outerHTML;
return temp.innerHTML;
},
set: function (value) {
if (value === "") {
blockBlockAdBlockFlag = true;
throw new Error("RemoveAds: Got a call from blockAdBlock tring removing the content of page.");
}
const temp = document.createElement("div");
temp.innerHTML = unsafeWindow.document.body.outerHTML;
let tag = unsafeWindow.document.body.outerHTML.replace(temp.innerHTML, "$$$$$$$$$$$$");
tag = tag.replace("$$$$$$</body>", `${value}</body>`);
unsafeWindow.document.body.outerHTML = tag;
},
});
}
if (blockBlockAdBlockFlag) {
Array.from($$("style:not([rmAd-blockAdBlock])")).forEach((that) => {
that.setAttribute("rmAd-blockAdBlock", "");
if (that.innerText.includes("#yui3-css-stamp.cssreset{display:none}")) {
console.info("RemoveAds: Remove the blockAdBlock CSS", unsafeWindow.removedAds.push(that), "\n", that);
that.remove();
}
});
}
/* if (location.host.endsWith("baidu.com")) {
Array.from($$("span:not([rmAd-baidu])")).forEach(function(that) {
that.setAttribute("rmAd-baidu", "");
if (/^(广告)+$/.test(that.innerText.replace(/s/g, ""))) {
info(that);
that.remove();
}
});
} else */
if (location.host.endsWith("gamepedia.com")) {
const siderail = $("#siderail");
if (siderail) { siderail.remove(); }
const globalWrapper = $("#global-wrapper.with-siderail");
if (globalWrapper) { globalWrapper.classList.remove("with-siderail"); }
} else if (!location.host.includes("amplitude.com")) {
try {
const keys = [];
const length = (localstorage || unsafeWindow.localStorage).length;
for (let i = 0; i < length; i++) {
keys.push((localstorage || unsafeWindow.localStorage).key(i));
}
keys.filter((k) => k.startsWith("amplitude_")).forEach((k) => {
const c = (localstorage || unsafeWindow.localStorage).getItem(k);
(localstorage || unsafeWindow.localStorage).removeItem(k);
console.info("RemoveAds: Remove the track info from amplitude", unsafeWindow.removedAds.push([k, c]), "\n", `${k}: ${c}`);
});
} catch (e) { }
}
/* else if (location.host.includes("twitter.co")) {
if (!$("style#rmAd-twitter-style")) {
const style = unsafeWindow.document.createElement("style");
style.id = "rmAd-twitter-style";
style.innerText = "html body div .rmAd-twitter-hidden { display: none !important; visibility: hidden !important; speak: none !important; position: fixed !important; top: 101vh !important; left: 101vw !important;}";
unsafeWindow.document.body.appendChild(style);
}
Array.from($$('[data-testid="primaryColumn"] section > h1 + div > div > div > div:not([rmAd-twitter]):not(.rmAd-twitter-hidden), [data-testid="sidebarColumn"] > div > div > div > div > div > div:not([rmAd-twitter]):not(.rmAd-twitter-hidden)')).forEach(function (that) {
that.setAttribute("rmAd-twitter", "");
if (that.innerText.trim() === "") {
that.classList.add("rmAd-twitter-emptyblock");
}
if (that.querySelector('h2[role="heading"] > div[dir="auto"] > span')) {
that.classList.add("rmAd-twitter-h2");
}
if (that.querySelector('div[data-testid="UserCell"][role="button"]')
|| that.querySelector('a[href*="/i/related_users/"]')) {
that.classList.add("rmAd-twitter-need2remove");
}
});
Array.from($$(".rmAd-twitter-emptyblock + .rmAd-twitter-emptyblock:not(.rmAd-twitter-hidden)")).forEach(ele => ele.classList.add("rmAd-twitter-hidden"));
const emptyblockRemove = (that) => {
if (that.previousElementSibling && that.previousElementSibling.classList && that.previousElementSibling.classList.contains("rmAd-twitter-emptyblock") && !that.previousElementSibling.classList.contains("rmAd-twitter-hidden")) {
info(that.previousElementSibling);
that.previousElementSibling.classList.add("rmAd-twitter-hidden");
}
if (that.nextElementSibling && that.nextElementSibling.classList && that.nextElementSibling.classList.contains("rmAd-twitter-emptyblock") && !that.nextElementSibling.classList.contains("rmAd-twitter-hidden")) {
info(that.nextElementSibling);
that.nextElementSibling.classList.add("rmAd-twitter-hidden");
}
};
Array.from($$(".rmAd-twitter-h2:not(.rmAd-twitter-hidden)")).forEach(that => {
if (that.nextElementSibling && that.nextElementSibling.classList && that.nextElementSibling.classList.contains(".rmAd-twitter-need2remove")) {
info(that);
emptyblockRemove(that);
that.classList.add("rmAd-twitter-hidden");
}
});
Array.from($$(".rmAd-twitter-need2remove:not(.rmAd-twitter-hidden)")).forEach(that => {
if (that.previousElementSibling && that.previousElementSibling.classList && that.previousElementSibling.classList.contains("rmAd-twitter-h2")) {
info(that.previousElementSibling);
emptyblockRemove(that.previousElementSibling);
that.previousElementSibling.classList.add("rmAd-twitter-hidden");
}
info(that);
emptyblockRemove(that);
that.classList.add("rmAd-twitter-hidden");
});
} */
if (!location.host.endsWith("gitee.com")) {
// gitte 不知道为啥老喜欢用important,就很奇怪,暂时先不执行
const nodes = Array.from($$('[style*="important"]:not([removeAd-has-checked-for-inline-style])'));
if (!nodes.length) { return; }
nodes.forEach((that) => {
that.setAttribute("removeAd-has-checked-for-inline-style", "");
const style = `${that.attributes.style.textContent}`.replace(/\s/g, "");
const display = (style.match(/display:([a-z-]+)!important/ig) || []).map(n => n.match(/display:([a-z-]+)!important/i)[1]);
const displayCheck = [];
display.forEach((n) => {
if (n !== "none") { displayCheck.push(n); }
});
if (displayCheck.length === 0) { return; }
that.attributes.style.textContent = style.replace(/display:([a-z-]+)!important/ig, "");
if (getComputedStyle(that).display === "none" || /^(广告)+$/.test(that.innerText.replace(/s/g, ""))) {
that.attributes.style.textContent = `${style}`;
info(that);
that.remove();
} else { that.attributes.style.textContent = `${style}`; }
});
}
};
document.addEventListener("DOMContentLoaded", () => {
const callback = function () {
unsafeWindow.removeAd();
if (location.href.indexOf("www.baidu.com/s") !== -1) {
Array.from($$("#content_left .c-container:not([rmAd-baidu])")).forEach((ele) => {
ele.setAttribute("rmAd-baidu", "");
if (ele.querySelector(".icon-unsafe-icon")) { ele.remove(); }
if (!ele.createShadowRoot && !ele.attachShadow) {
console.info("RemoveAds (shadowRoot): ", unsafeWindow.removedAds.push(ele), "\nTarget:", ele, "\nParentNode:", ele.parentNode, "\nInnerText", ele.innerText);
const html = ele.outerHTML;
const node = unsafeWindow.document.createElement("div");
ele.before(node);
node.outerHTML = html;
ele.remove();
}
});
}
};
const observer = new MutationObserver(callback);
observer.observe(unsafeWindow.document.body, { attributes: true, childList: true, subtree: true });
unsafeWindow.removeAd();
});
})();