Greasy Fork is available in English.
abp规则转换js脚本
当前为
// ==UserScript==
// @name 优雅的广告拦截脚本
// @author 酷安@耗子Sky
// @description abp规则转换js脚本
// @version 3.1
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_xmlhttpRequest
// @run-at document-start
// @connect code.gitlink.org.cn
// @namespace http://greasyfork.icu/users/452911
// ==/UserScript==
(function () {
let rules = `
! 没有两个 # 的行和 开头为 ! 的行会忽略
! baidu.com##.ec_wise_ad
!
! :remove() 会用 js 移除元素,:remove() 必须放在行尾
! baidu.com###ad:remove()
! :click() 会用 js 模拟点击元素,必须放在行尾
! baidu.com###btn:click()
! 上面两个可以带参数,格式
! remove(100, 4, 200)
! 代表 首先延时 100 ms,然后执行 4 次,两次间隔 200 ms
!
! 由于语法限制,一个反斜杠需要改成两个,像这样 \\
!
! 脚本会首先尝试从下面的地址获取规则覆盖此处,如果失败,
! 才会使用此处的规则
!
! 若要修改地址,请注意同步修改头部的 @connect 的域名
`,
rulesUrl = "https://code.gitlink.org.cn/damengzhu/abpmerge/raw/branch/main/abpmerge.txt",
selarray = [],
welarray = [],
seloarray = [],
menuNum = null,
valKey = "ajs_disabled_domains",
disas = GM_getValue(valKey, "").split(",");
function gmMenuMgmt(disabled) {
let c = seloarray.length;
if (menuNum) {
GM_unregisterMenuCommand(menuNum);
}
menuNum = GM_registerMenuCommand(
disabled
? "在此网站启用拦截"
: `在此网站禁用拦截${c > 0 ? ` (${c})` : ""}`,
gmValuesMgmt.bind(this, !disabled)
);
}
function gmValuesMgmt(add) {
if (add) {
if (!disas.includes(location.hostname)) {
disas.push(location.hostname);
}
GM_setValue(valKey, disas.join(","));
disas = GM_getValue(valKey, "").split(",");
gmMenuMgmt(true);
} else {
if (disas.includes(location.hostname)) {
disas.splice(disas.indexOf(location.hostname), 1);
}
GM_setValue(valKey, disas.join(","));
disas = GM_getValue(valKey, "").split(",");
gmMenuMgmt(false);
}
}
function execOperation(sel, param, click) {
setTimeout(() => {
for (let c = parseInt(param[1]); c >= 1; --c) {
setTimeout(() => {
document
.querySelectorAll(sel)
.forEach((a) => (click ? a.click() : a.remove()));
}, parseInt(param[2]) * (c - 1));
}
}, parseInt(param[0]));
}
function pushOperation(sel, op, type) {
let tempParamArray = ["0", "1", "0"];
if (sel.split(op)[1].indexOf(",") > 0) {
tempParamArray = sel.split(op)[1].slice(0, -1).split(",");
}
seloarray.push({
sel: sel.split(op)[0],
type: type,
param: tempParamArray,
});
}
function parseFunc(sel) {
if (sel.indexOf(":remove(") > 0) {
pushOperation(sel, ":remove(", 1);
} else if (sel.indexOf(":click(") > 0) {
pushOperation(sel, ":click(", 2);
} else {
seloarray.push({ sel: sel, type: 0 });
}
}
function parseDomains(rule, sep) {
let domains = rule.split(sep)[0].split(","),
selector = rule.split(sep)[1];
domains.forEach((domain) => {
if (domain.slice(0, 1) == "~") {
if (location.hostname.indexOf(domain.slice(1)) >= 0) return;
} else {
if (location.hostname.indexOf(domain) < 0 && domain !== "*") return;
}
if (sep == "#@#") {
welarray.push(selector);
} else {
selarray.push(selector);
}
});
};
function myfun() {
let styelem = document.createElement("style");
gmMenuMgmt(false);
rules.split("\n").forEach((rule) => {
if (rule.indexOf("!") == 0) {
return;
} else if (rule.indexOf("[") == 0) {
return;
} else if (rule.indexOf("##+js") >= 0) {
return;
} else if (rule.indexOf("##^") >= 0) {
return;
} else if (rule.indexOf("#@#") > 0) {
parseDomains(rule, "#@#");
} else if (rule.indexOf("#@#") == 0) {
welarray.push(rule.slice(3));
} else if (rule.indexOf("##") > 0) {
parseDomains(rule, "##");
} else if (rule.indexOf("##") == 0) {
selarray.push(rule.slice(2));
}
});
selarray.forEach((sel) => {
if (!welarray.includes(sel)) parseFunc(sel);
});
gmMenuMgmt(disa);
document.documentElement.appendChild(styelem);
let csel = "";
seloarray.forEach((selo) => {
switch (selo.type) {
case 0:
csel += `,${selo.sel}`;
break;
case 1:
execOperation(selo.sel, selo.param, 0);
break;
case 2:
execOperation(selo.sel, selo.param, 1);
break;
}
});
if (csel.length >= 2) {
styelem.textContent = csel.slice(1) + " {display: none !important;};";
}
}
let disa = disas.includes(location.hostname);
gmMenuMgmt(disa);
if (disa) return;
GM_xmlhttpRequest({
url: rulesUrl,
onload: (r) => {
rules = r.responseText;
myfun();
},
onabort: myfun.bind(this),
onerror: myfun.bind(this),
ontimeout: myfun.bind(this)
});
})();