Greasy Fork

Greasy Fork is available in English.

套壳油猴的广告拦截脚本.副本

将 ABP 中的元素隐藏规则转换为 CSS 使用

当前为 2022-12-07 提交的版本,查看 最新版本

// ==UserScript==
// @name 套壳油猴的广告拦截脚本.副本
// @author Lemon399
// @version 2.4.0.4
// @description 将 ABP 中的元素隐藏规则转换为 CSS 使用
// @require http://greasyfork.icu/scripts/452263-extended-css/code/extended-css.js?version=1124696
// @resource jiekouAD https://code.gitlink.org.cn/damengzhu/banad/raw/branch/main/jiekouAD.txt
// @resource CSSRule https://code.gitlink.org.cn/damengzhu/abpmerge/raw/branch/main/CSSRule.txt
// @match *://*/*
// @run-at document-start
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_addStyle
// @namespace https://lemon399-bitbucket-io.vercel.app/
// @source https://gitee.com/lemon399/tampermonkey-cli/tree/master/projects/abp_parse
// @connect code.gitlink.org.cn
// @copyright GPL-3.0
// @license GPL-3.0
// ==/UserScript==

(function (tm, ExtendedCss) {
 "use strict";

 function __awaiter(thisArg, _arguments, P, generator) {
 function adopt(value) {
 return value instanceof P
 ? value
 : new P(function (resolve) {
 resolve(value);
 });
 }
 return new (P || (P = Promise))(function (resolve, reject) {
 function fulfilled(value) {
 try {
 step(generator.next(value));
 } catch (e) {
 reject(e);
 }
 }
 function rejected(value) {
 try {
 step(generator["throw"](value));
 } catch (e) {
 reject(e);
 }
 }
 function step(result) {
 result.done
 ? resolve(result.value)
 : adopt(result.value).then(fulfilled, rejected);
 }
 step((generator = generator.apply(thisArg, _arguments || [])).next());
 });
 }

 const onlineRules = [];
 onlineRules.push(
 {
 标识: "jiekouAD",
 地址: "https://code.gitlink.org.cn/damengzhu/banad/raw/branch/main/jiekouAD.txt",
 在线更新: !!1,
 筛选后存储: !!1,
 },
 {
 标识: "CSSRule",
 地址: "https://code.gitlink.org.cn/damengzhu/abpmerge/raw/branch/main/CSSRule.txt",
 在线更新: !!1,
 筛选后存储: !!0,
 }
 );
 let defaultRules = `
! 没有 ## #@# #?# #@?#
! #$# #@$# #$?# #@$?# 的行和
! 开头为 ! 的行会忽略
!
! 由于语法限制,内置规则中
! 一个反斜杠需要改成两个,像这样 \\
!
! 若要修改地址,请注意同步修改
! 头部的 @connect 和 @resource

`;

 const ruleRE = [
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?##([^\s^+].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@#([^\s+].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\?#([^\s].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\?#([^\s].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\$#([^\s].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\$#([^\s].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\$\?#([^\s].*)/,
 /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\$\?#([^\s].*)/,
 ];
 function findMatches(string, res) {
 let result = [-1, null];
 res.forEach((re, i) => {
 const match = string.match(re);
 if (match) result = [i, match];
 });
 return result;
 }
 function getEtag(header) {
 const result = findMatches(header, [
 /(e|E)tag: \"(\w+)\"/,
 // WebMonkey 系
 /(e|E)tag: \[\"(\w+)\"\]/,
 // 书签地球
 /(e|E)tag=\"(\w+)\"/,
 ]);
 return result[1] ? result[1][2] : null;
 }
 function makeRuleBox() {
 return {
 black: [],
 white: [],
 };
 }
 function domainChecker(domains) {
 const results = [],
 invResults = [],
 urlSuffix = /\.+?[\w-]+$/.exec(location.hostname);
 let totalResult = [0, false],
 black = false,
 white = false;
 domains.forEach((domain) => {
 if (domain.endsWith(".*") && Array.isArray(urlSuffix)) {
 domain = domain.replace(".*", urlSuffix[0]);
 }
 const invert = domain[0] == "~";
 if (invert) domain = domain.slice(1);
 const result = location.hostname.endsWith(domain);
 if (invert) {
 if (result) white = true;
 invResults.push([domain.length, !result]);
 } else {
 if (result) black = true;
 results.push([domain.length, result]);
 }
 });
 if (results.length > 0 && !black) {
 return false;
 } else if (invResults.length > 0 && !white) {
 return true;
 } else {
 results.forEach((r) => {
 if (r[0] >= totalResult[0] && r[1]) {
 totalResult = r;
 }
 });
 invResults.forEach((r) => {
 if (r[0] >= totalResult[0] && !r[1]) {
 totalResult = r;
 }
 });
 return totalResult[1];
 }
 }
 function hasSome(str, arr) {
 return arr.some((word) => str.includes(word));
 }
 function ruleSpliter(rule) {
 const result = findMatches(rule, ruleRE),
 group = result[1];
 if (group && (!group[1] || domainChecker(group[1].split(",")))) {
 const sel = group.pop();
 if (sel) {
 return {
 black: result[0] % 2 ? "white" : "black",
 type: Math.floor(result[0] / 2),
 sel,
 };
 }
 }
 }
 function ruleLoader(rule) {
 if (
 hasSome(rule, [
 ":matches-path(",
 ":min-text-length(",
 ":watch-attr(",
 ":-abp-properties(",
 ":matches-property(",
 "if-not(",
 ])
 )
 return;
 // 去掉开头空格
 rule = rule.replace(/^ +/, "");
 // 如果 #$# 不包含 {} 就排除
 // 可以尽量排除 Snippet Filters
 if (/(\w|^)#\$#/.test(rule) && !/{.+}/.test(rule)) return;
 // ## -> #?#
 if (
 /(\w|^)#@?#/.test(rule) &&
 hasSome(rule, [
 ":has(",
 ":-abp-has(",
 "[-ext-has=",
 ":has-text(",
 "contains(",
 "-abp-contains(",
 "[-ext-contains=",
 "matches-css(",
 "[-ext-matches-css=",
 "matches-css-before(",
 "[-ext-matches-css-before=",
 "matches-css-after(",
 "[-ext-matches-css-after=",
 "matches-attr(",
 "nth-ancestor(",
 "upward(",
 "xpath(",
 "remove()",
 "not(",
 ])
 ) {
 rule = rule.replace(/(\w|^)##/, "$1#?#").replace(/(\w|^)#@#/, "$1#@?#");
 }
 // :style(...) 转换
 // example.com#?##id:style(color: red)
 // example.com#$?##id { color: red }
 if (rule.includes(":style(")) {
 rule = rule
 .replace(/(\w|^)##/, "$1#$#")
 .replace(/(\w|^)#@#/, "$1#@$#")
 .replace(/(\w|^)#\?#/, "$1#$?#")
 .replace(/(\w|^)#@\?#/, "$1#@$?#")
 .replace(/:style\(/, " { ")
 .replace(/\)$/, " }");
 }
 return ruleSpliter(rule);
 }
 function logger(type, ...data) {
 switch (type) {
 case "info":
 console.info(...data);
 break;
 case "warn":
 console.warn(...data);
 break;
 case "error":
 console.error(...data);
 break;
 case "data":
 console.table(data[0]);
 break;
 case "color":
 console.log(
 `%c ${data[0]} `,
 `display: inline-block; color: white; background: ${data[1]}; border-radius: .75em; padding: 2px 5px`,
 ...data.splice(2)
 );
 break;
 case "count":
 console.count(data[0]);
 break;
 }
 }

 var _a, _b, _c;
 const selectors = makeRuleBox(),
 extSelectors = makeRuleBox(),
 styles = makeRuleBox(),
 extStyles = makeRuleBox(),
 values = {
 get black() {
 const arrStr = gmValue("get", false, "ajs_disabled_domains", "");
 return typeof arrStr == "string" && arrStr.length > 0
 ? arrStr.split(",")
 : [];
 },
 set black(v) {
 gmValue(
 "set",
 false,
 "ajs_disabled_domains",
 v === null || v === void 0 ? void 0 : v.join()
 );
 },
 get rules() {
 return gmValue("get", true, "ajs_saved_abprules", {});
 },
 set rules(v) {
 gmValue("set", true, "ajs_saved_abprules", v);
 },
 get css() {
 return gmValue("get", true, `ajs_saved_styles_${location.hostname}`, {
 needUpdate: true,
 hideCss: "",
 extraCss: "",
 });
 },
 set css(v) {
 gmValue("set", true, `ajs_saved_styles_${location.hostname}`, v);
 },
 get hasSave() {
 const arrStr = gmValue("get", false, "ajs_hasSave_domains", "");
 return typeof arrStr == "string" && arrStr.length > 0
 ? arrStr.split(",")
 : [];
 },
 set hasSave(v) {
 gmValue(
 "set",
 false,
 "ajs_hasSave_domains",
 v === null || v === void 0 ? void 0 : v.join()
 );
 },
 get time() {
 return gmValue("get", false, "ajs_rules_ver", "0/0/0 0:0:0");
 },
 set time(v) {
 gmValue("set", false, "ajs_rules_ver", v);
 },
 get drlen() {
 return gmValue("get", false, "ajs_drule_length", 0);
 },
 set drlen(v) {
 gmValue("set", false, "ajs_drule_length", v);
 },
 get etags() {
 return gmValue("get", true, "ajs_rules_etags", {});
 },
 set etags(v) {
 gmValue("set", true, "ajs_rules_etags", v);
 },
 },
 data = {
 disabled: false,
 saved: false,
 update: true,
 updating: false,
 receivedRules: "",
 customRules: defaultRules,
 allRules: "",
 presetCss:
 " {display: none !important;width: 0 !important;height: 0 !important;} ",
 hideCss: "",
 extraCss: "",
 appliedCount: 0,
 isFrame: tm.unsafeWindow.self !== tm.unsafeWindow.top,
 isClean: false,
 mutex: "__lemon__abp__parser__$__",
 timeout: 6000,
 xTimeout: 700,
 },
 menus = {
 disable: {
 id: undefined,
 get text() {
 return data.disabled ? "在此网站启用拦截" : "在此网站禁用拦截";
 },
 },
 update: {
 id: undefined,
 get text() {
 const time = values.time;
 return data.updating
 ? "正在更新..."
 : `点击更新: ${time.slice(0, 1) === "0" ? "未知时间" : time}`;
 },
 },
 count: {
 id: undefined,
 get text() {
 const cssCount = (data.hideCss + data.extraCss).match(/{/g);
 return data.isClean
 ? "已清空,点击刷新重新加载规则"
 : `${
 data.saved
 ? "CSS: " +
 (cssCount === null || cssCount === void 0
 ? void 0
 : cssCount.length)
 : "规则: " +
 data.appliedCount +
 "/" +
 data.allRules.split("\n").length
 },点击清空规则`;
 },
 },
 export: {
 id: undefined,
 text: "导出此网站规则为独立脚本",
 },
 };
 data.customRules +=
 "\n" +
 ((_c =
 (_b =
 (_a = tm.GM_info.script) === null || _a === void 0
 ? void 0
 : _a.options) === null || _b === void 0
 ? void 0
 : _b.comment) !== null && _c !== void 0
 ? _c
 : "") +
 "\n";
 function gmMenu(name, cb) {
 var _a;
 const id = (_a = menus[name].id) !== null && _a !== void 0 ? _a : false;
 if (
 typeof tm.GM_registerMenuCommand != "function" ||
 typeof tm.GM_unregisterMenuCommand != "function" ||
 data.isFrame
 )
 return;
 if (typeof id == "number") {
 tm.GM_unregisterMenuCommand(id);
 menus[name].id = undefined;
 }
 if (typeof cb == "function") {
 menus[name].id = tm.GM_registerMenuCommand(menus[name].text, cb);
 }
 }
 function gmValue(action, json, key, value) {
 switch (action) {
 case "get":
 let v;
 try {
 v = tm.GM_getValue(key, json ? JSON.stringify(value) : value);
 } catch (error) {
 return;
 }
 return json && typeof v == "string" ? JSON.parse(v) : v;
 case "set":
 try {
 value === null || value === undefined
 ? tm.GM_deleteValue(key)
 : tm.GM_setValue(key, json ? JSON.stringify(value) : value);
 } catch (error) {
 tm.GM_deleteValue(key);
 }
 break;
 }
 }
 function promiseXhr(details) {
 return __awaiter(this, void 0, void 0, function* () {
 let loaded = false;
 try {
 return yield new Promise((resolve, reject) => {
 tm.GM_xmlhttpRequest(
 Object.assign(
 {
 onload(e) {
 loaded = true;
 resolve(e);
 },
 onabort: reject.bind(null, "abort"),
 onerror(e) {
 reject({
 error: "error",
 resp: e,
 });
 },
 ontimeout: reject.bind(null, "timeout"),
 onreadystatechange(e) {
 // X 浏览器超时中断
 if (e.readyState === 4) {
 setTimeout(() => {
 if (!loaded)
 reject({
 error: "X timeout",
 resp: e,
 });
 }, data.xTimeout);
 }
 // Via 浏览器超时中断,不给成功状态...
 if (e.readyState === 3) {
 setTimeout(() => {
 if (!loaded)
 reject({
 error: "Via timeout",
 resp: e,
 });
 }, data.timeout);
 }
 },
 timeout: data.timeout,
 },
 details
 )
 );
 });
 } catch (error) {}
 });
 }
 function storeRule(rule, resp) {
 const savedRules = values.rules,
 savedEtags = values.etags;
 if (resp.responseHeaders) {
 const etag = getEtag(resp.responseHeaders);
 if (etag) {
 savedEtags[rule.标识] = etag;
 values.etags = savedEtags;
 }
 }
 if (resp.responseText) {
 if (rule.筛选后存储) {
 let parsed = "";
 resp.responseText.split("\n").forEach((rule) => {
 if (ruleRE.some((re) => re.test(rule))) parsed += rule + "\n";
 });
 savedRules[rule.标识] = parsed;
 } else {
 savedRules[rule.标识] = resp.responseText;
 }
 values.rules = savedRules;
 if (Object.keys(values.rules).length === 0) {
 data.receivedRules += "\n" + savedRules[rule.标识] + "\n";
 }
 }
 }
 function fetchRuleBody(rule) {
 var _a;
 return __awaiter(this, void 0, void 0, function* () {
 const getResp = yield promiseXhr({
 method: "GET",
 responseType: "text",
 url: rule.地址,
 });
 if (
 getResp &&
 (getResp === null || getResp === void 0
 ? void 0
 : getResp.responseText) &&
 ((_a = getResp.responseText) === null || _a === void 0
 ? void 0
 : _a.length) > 0
 ) {
 storeRule(rule, getResp);
 return true;
 } else return false;
 });
 }
 function fetchRule(rule) {
 return new Promise((resolve, reject) =>
 __awaiter(this, void 0, void 0, function* () {
 var _a, _b, _e;
 const headResp = yield promiseXhr({
 method: "HEAD",
 responseType: "text",
 url: rule.地址,
 });
 if (!headResp) {
 reject("HEAD 失败");
 } else {
 const etag = getEtag(
 typeof headResp.responseHeaders == "string"
 ? headResp.responseHeaders
 : (_b = (_a = headResp).getAllResponseHeaders) === null ||
 _b === void 0
 ? void 0
 : _b.call(_a)
 ),
 savedEtags = values.etags;
 if (
 (headResp === null || headResp === void 0
 ? void 0
 : headResp.responseText) &&
 ((_e = headResp.responseText) === null || _e === void 0
 ? void 0
 : _e.length) > 0
 ) {
 storeRule(rule, headResp);
 !etag || etag !== savedEtags[rule.标识]
 ? resolve()
 : reject("ETag 一致");
 } else {
 if (!etag || etag !== savedEtags[rule.标识]) {
 (yield fetchRuleBody(rule)) ? resolve() : reject("GET 失败");
 } else reject("ETag 一致");
 }
 }
 })
 );
 }
 function fetchRules(apply) {
 return __awaiter(this, void 0, void 0, function* () {
 const has = values.hasSave;
 let hasUpdate = onlineRules.length;
 data.updating = true;
 gmMenu("update", () => undefined);
 for (const rule of onlineRules) {
 if (rule.在线更新) {
 yield fetchRule(rule).catch((error) => {
 hasUpdate--;
 });
 }
 }
 values.time = new Date().toLocaleString("zh-CN");
 if (has.length > 0 && hasUpdate > 0) {
 has.forEach((host) => {
 const save = gmValue("get", true, `ajs_saved_styles_${host}`);
 save.needUpdate = true;
 gmValue("set", true, `ajs_saved_styles_${host}`, save);
 });
 }
 initRules(apply);
 });
 }
 function performUpdate(force, apply) {
 if (data.isFrame) return Promise.reject();
 return force || new Date(values.time).getDate() !== new Date().getDate()
 ? fetchRules(apply)
 : Promise.resolve();
 }
 function switchDisabledStat() {
 const disaList = values.black;
 data.disabled = !disaList.includes(location.hostname);
 if (data.disabled) {
 disaList.push(location.hostname);
 } else {
 disaList.splice(disaList.indexOf(location.hostname), 1);
 }
 values.black = disaList;
 location.reload();
 }
 function makeInitMenu() {
 gmMenu("update", () =>
 __awaiter(this, void 0, void 0, function* () {
 yield performUpdate(true, false);
 location.reload();
 })
 );
 gmMenu("count", cleanRules);
 }
 function initRules(apply) {
 const abpRules = values.rules;
 if (typeof tm.GM_getResourceText == "function") {
 onlineRules.forEach((rule) => {
 let resRule;
 try {
 resRule = tm.GM_getResourceText(rule.标识);
 } catch (error) {
 resRule = "";
 }
 if (resRule && !abpRules[rule.标识]) abpRules[rule.标识] = resRule;
 });
 }
 const abpKeys = Object.keys(abpRules);
 abpKeys.forEach((name) => {
 data.receivedRules += "\n" + abpRules[name] + "\n";
 });
 values.drlen = data.customRules.length;
 data.allRules = data.customRules + data.receivedRules;
 data.updating = false;
 makeInitMenu();
 if (apply) splitRules();
 return data.receivedRules.length;
 }
 function styleApply() {
 if (data.hideCss.length > 0) {
 if (typeof tm.GM_addStyle == "function") {
 tm.GM_addStyle(data.hideCss);
 } else {
 const elem = document.createElement("style");
 elem.textContent = data.hideCss;
 document.documentElement.appendChild(elem);
 }
 }
 if (data.extraCss.length > 0) {
 data.extraCss.split("\n").forEach((css) => {
 new ExtendedCss({ styleSheet: css }).apply();
 });
 }
 gmMenu("export", downScript);
 }
 function genManifest() {
 const header = [],
 tmpl = {
 name: `用于 ${location.hostname} 的广告拦截脚本`,
 namespace: "exported_css_script",
 version: new Date().getTime(),
 description: `用于 ${location.hostname} 的广告拦截脚本`,
 author: "You",
 match: `${location.protocol}//${location.hostname}/*`,
 grant: "GM_addStyle",
 "run-at": "document-start",
 require:
 "http://greasyfork.icu/scripts/452263-extended-css/code/extended-css.js?version=1124696",
 };
 let result = "";
 header.push("==UserScript==");
 Object.keys(tmpl).forEach((prop) => header.push(`@${prop} ${tmpl[prop]}`));
 header.push("==/UserScript==");
 header.forEach((line) => {
 result += `// ${line}\n`;
 });
 return result;
 }
 function genScript() {
 return `${genManifest()}
(function() {
 'use strict';

 const hc = "${data.presetCss}",
 data = {
 hide: ${JSON.stringify(
 data.hideCss.split("\n").map((v) => v.replaceAll(data.presetCss, "")),
 undefined,
 2
 )},
 extra: ${JSON.stringify(
 data.extraCss.split("\n").map((v) => v.replaceAll(data.presetCss, "")),
 undefined,
 2
 )},
 };

 if (typeof GM_addStyle !== "function") {
 const GM_addStyle = css => {
 const elem = document.createElement("style");
 elem.textContent = css;
 document.documentElement.appendChild(elem);
 };
 }

 function cssApply() {
 GM_addStyle(data.hide.map(r => r.endsWith("} ") ? r : r + hc).join(" "));
 data.extra.map(r => r.endsWith("} ") ? r : r + hc).forEach((css) => {
 new ExtendedCss({ styleSheet: css }).apply();
 });
 }

 cssApply();
})();`;
 }
 function downScript() {
 const a = document.createElement("a"),
 b = new Blob([genScript()]);
 a.href = URL.createObjectURL(b);
 a.download = `${location.hostname}.user.js`;
 Object.assign(a.style, {
 position: "fixed",
 top: "200%",
 });
 document.body.appendChild(a);
 setTimeout(() => {
 a.click();
 a.remove();
 }, 0);
 }
 function cleanRules() {
 if (confirm(`是否清空存储规则 (${Object.keys(values.rules).length}) ?`)) {
 const has = values.hasSave;
 values.rules = {};
 values.time = "0/0/0 0:0:0";
 values.drlen = 0;
 values.etags = {};
 if (has.length > 0) {
 has.forEach((host) => {
 gmValue("set", true, `ajs_saved_styles_${host}`);
 });
 values.hasSave = null;
 }
 data.appliedCount = 0;
 data.allRules = "";
 data.isClean = true;
 gmMenu("update");
 gmMenu("export");
 gmMenu("count", () => location.reload());
 }
 }
 function parseRules() {
 const boxes = ["hideCss", "extraCss"];
 data.hideCss = "";
 data.extraCss = "";
 [styles, extStyles].forEach((r, t) => {
 r.black
 .filter((v) => !r.white.includes(v))
 .forEach((s) => {
 const checkResult = ExtendedCss.validate(s.split("{")[0]);
 if (checkResult.ok) {
 data[boxes[t]] += `${s} \n`;
 data.appliedCount++;
 } else {
 logger(
 "color",
 "选择器检查错误:",
 "maroon",
 s.split("{")[0],
 checkResult.error
 );
 }
 });
 });
 [selectors, extSelectors].forEach((r, t) => {
 r.black
 .filter((v) => !r.white.includes(v))
 .forEach((s, i) => {
 const checkResult = ExtendedCss.validate(s);
 if (checkResult.ok) {
 data[boxes[t]] += `${i == 0 ? "" : "\n"}${s + data.presetCss}`;
 data.appliedCount++;
 } else {
 logger("color", "选择器检查错误:", "maroon", s, checkResult.error);
 }
 });
 });
 gmMenu("count", cleanRules);
 saveCss();
 if (!data.saved) styleApply();
 }
 function splitRules() {
 data.allRules.split("\n").forEach((rule) => {
 const ruleObj = ruleLoader(rule),
 boxes = [selectors, extSelectors, styles, extStyles];
 if (typeof ruleObj != "undefined") {
 if (
 ruleObj.black == "black" &&
 boxes[ruleObj.type].white.includes(ruleObj.sel)
 )
 return;
 boxes[ruleObj.type][ruleObj.black].push(ruleObj.sel);
 }
 });
 parseRules();
 }
 function saveCss() {
 const styles = {
 needUpdate: false,
 hideCss: data.hideCss,
 extraCss: data.extraCss,
 },
 has = values.hasSave;
 values.css = styles;
 if (!has.includes(location.hostname)) has.push(location.hostname);
 values.hasSave = has;
 }
 function readCss() {
 var _a;
 const styles = values.css;
 if (styles.hideCss.length > 0) {
 data.saved = true;
 data.update =
 (_a = styles.needUpdate) !== null && _a !== void 0 ? _a : true;
 data.hideCss = styles.hideCss;
 data.extraCss = styles.extraCss;
 return true;
 } else return false;
 }
 function main() {
 var _a, _b;
 return __awaiter(this, void 0, void 0, function* () {
 if (
 ((_b =
 (_a = tm.unsafeWindow.mbrowser) === null || _a === void 0
 ? void 0
 : _a.getVersionCode) === null || _b === void 0
 ? void 0
 : _b.call(_a)) >= 662
 ) {
 const vars = [
 "ajs_disabled_domains",
 "ajs_saved_abprules",
 "ajs_rules_etags",
 "ajs_rules_ver",
 ],
 stor = tm.unsafeWindow.localStorage;
 vars.forEach((key) => {
 if (stor.getItem(key)) {
 stor.removeItem(key);
 }
 });
 }
 data.disabled = values.black.includes(location.hostname);
 gmMenu("disable", switchDisabledStat);
 if (data.disabled) return;
 if (values.drlen === data.customRules.length) readCss();
 saved: {
 if (data.saved) {
 styleApply();
 makeInitMenu();
 if (!data.update) break saved;
 }
 if (initRules(false) === 0) yield performUpdate(true, true);
 splitRules();
 }
 try {
 yield performUpdate(false, false);
 } catch (error) {
 logger("warn", "iframe: ", location.href, " 取消更新");
 }
 });
 }
 function runOnce(key, func) {
 if (key in tm.unsafeWindow) return;
 tm.unsafeWindow[key] = true;
 func();
 }
 runOnce(data.mutex, main);
})(
 {
 GM_info: typeof GM_info == "object" ? GM_info : {},
 unsafeWindow: typeof unsafeWindow == "object" ? unsafeWindow : window,
 GM_registerMenuCommand:
 typeof GM_registerMenuCommand == "function"
 ? GM_registerMenuCommand
 : undefined,
 GM_unregisterMenuCommand:
 typeof GM_unregisterMenuCommand == "function"
 ? GM_unregisterMenuCommand
 : undefined,
 GM_getValue: typeof GM_getValue == "function" ? GM_getValue : undefined,
 GM_deleteValue:
 typeof GM_deleteValue == "function" ? GM_deleteValue : undefined,
 GM_setValue: typeof GM_setValue == "function" ? GM_setValue : undefined,
 GM_xmlhttpRequest:
 typeof GM_xmlhttpRequest == "function" ? GM_xmlhttpRequest : undefined,
 GM_getResourceText:
 typeof GM_getResourceText == "function" ? GM_getResourceText : undefined,
 GM_addStyle: typeof GM_addStyle == "function" ? GM_addStyle : undefined,
 },
 ExtendedCss
);