套壳油猴的广告拦截脚本

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

目前为 2022-12-15 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name AdBlock Script for WebView
  3. // @name:zh-CN 套壳油猴的广告拦截脚本
  4. // @author Lemon399
  5. // @version 2.3.0
  6. // @description Parse ABP Cosmetic rules to CSS and apply it.
  7. // @description:zh-CN 将 ABP 中的元素隐藏规则转换为 CSS 使用
  8. // @require https://greasyfork.org/scripts/452263-extended-css/code/extended-css.js?version=1099366
  9. // @resource jiekouAD https://code.gitlink.org.cn/damengzhu/banad/raw/branch/main/jiekouAD.txt
  10. // @resource CSSRule https://code.gitlink.org.cn/damengzhu/abpmerge/raw/branch/main/CSSRule.txt
  11. // @match *://*/*
  12. // @run-at document-start
  13. // @grant unsafeWindow
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_unregisterMenuCommand
  16. // @grant GM_getValue
  17. // @grant GM_deleteValue
  18. // @grant GM_setValue
  19. // @grant GM_xmlhttpRequest
  20. // @grant GM_getResourceText
  21. // @grant GM_addStyle
  22. // @namespace https://lemon399-bitbucket-io.vercel.app/
  23. // @source https://gitee.com/lemon399/tampermonkey-cli/tree/master/projects/abp_parse
  24. // @connect code.gitlink.org.cn
  25. // @copyright GPL-3.0
  26. // @license GPL-3.0
  27. // ==/UserScript==
  28.  
  29. (function (vm, ExtendedCss) {
  30. "use strict";
  31.  
  32. function __awaiter(thisArg, _arguments, P, generator) {
  33. function adopt(value) {
  34. return value instanceof P
  35. ? value
  36. : new P(function (resolve) {
  37. resolve(value);
  38. });
  39. }
  40. return new (P || (P = Promise))(function (resolve, reject) {
  41. function fulfilled(value) {
  42. try {
  43. step(generator.next(value));
  44. } catch (e) {
  45. reject(e);
  46. }
  47. }
  48. function rejected(value) {
  49. try {
  50. step(generator["throw"](value));
  51. } catch (e) {
  52. reject(e);
  53. }
  54. }
  55. function step(result) {
  56. result.done
  57. ? resolve(result.value)
  58. : adopt(result.value).then(fulfilled, rejected);
  59. }
  60. step((generator = generator.apply(thisArg, _arguments || [])).next());
  61. });
  62. }
  63.  
  64. const onlineRules = [];
  65. onlineRules.push(
  66. {
  67. 标识: "jiekouAD",
  68. 地址: "https://code.gitlink.org.cn/damengzhu/banad/raw/branch/main/jiekouAD.txt",
  69. 在线更新: !!1,
  70. 筛选后存储: !!1,
  71. },
  72. {
  73. 标识: "CSSRule",
  74. 地址: "https://code.gitlink.org.cn/damengzhu/abpmerge/raw/branch/main/CSSRule.txt",
  75. 在线更新: !!1,
  76. 筛选后存储: !!0,
  77. }
  78. );
  79. let defaultRules = `
  80. ! 没有 ## #@# #?# #@?#
  81. ! #$# #@$# #$?# #@$?# 的行和
  82. ! 开头为 ! 的行会忽略
  83. !
  84. ! 由于语法限制,内置规则中
  85. ! 一个反斜杠需要改成两个,像这样 \\
  86. !
  87. ! 若要修改地址,请注意同步修改
  88. ! 头部的 @connect @resource
  89.  
  90. `;
  91.  
  92. const ruleRE = [
  93. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?##([^\s^+].*)/,
  94. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@#([^\s+].*)/,
  95. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\?#([^\s].*)/,
  96. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\?#([^\s].*)/,
  97. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\$#([^\s].*)/,
  98. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\$#([^\s].*)/,
  99. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#\$\?#([^\s].*)/,
  100. /^(~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*)(,~?[\w-]+(\.[\w-]+)*(\.[\w-]+|\.\*))*)?#@\$\?#([^\s].*)/,
  101. ];
  102. function findMatches(string, res) {
  103. let result = [-1, null];
  104. res.forEach((re, i) => {
  105. const match = string.match(re);
  106. if (match) result = [i, match];
  107. });
  108. return result;
  109. }
  110. function getEtag(header) {
  111. const result = findMatches(header, [
  112. /(e|E)tag: \"(\w+)\"/,
  113. // WebMonkey 系
  114. /(e|E)tag: \[\"(\w+)\"\]/,
  115. // 书签地球
  116. /(e|E)tag=\"(\w+)\"/,
  117. ]);
  118. return result[1] ? result[1][2] : null;
  119. }
  120. function makeRuleBox() {
  121. return {
  122. black: [],
  123. white: [],
  124. };
  125. }
  126. function domainChecker(domains) {
  127. const results = [],
  128. urlSuffix = /\.+?[\w-]+$/.exec(location.hostname);
  129. let mostMatch = {
  130. long: 0,
  131. result: false,
  132. };
  133. domains.forEach((domain) => {
  134. if (domain.endsWith(".*") && Array.isArray(urlSuffix)) {
  135. domain = domain.replace(".*", urlSuffix[0]);
  136. }
  137. const invert = domain[0] == "~";
  138. if (invert) domain = domain.slice(1);
  139. const result = location.hostname.endsWith(domain);
  140. results.push(result !== invert);
  141. if (result) {
  142. if (domain.length > mostMatch.long) {
  143. mostMatch = {
  144. long: domain.length,
  145. result: result !== invert,
  146. };
  147. }
  148. }
  149. });
  150. return mostMatch.long > 0 ? mostMatch.result : results.includes(true);
  151. }
  152. function hasSome(str, arr) {
  153. return arr.some((word) => str.includes(word));
  154. }
  155. function ruleSpliter(rule) {
  156. const result = findMatches(rule, ruleRE),
  157. group = result[1];
  158. if (group && (!group[1] || domainChecker(group[1].split(",")))) {
  159. const sel = group.pop();
  160. if (sel) {
  161. return {
  162. black: result[0] % 2 ? "white" : "black",
  163. type: Math.floor(result[0] / 2),
  164. sel,
  165. };
  166. }
  167. }
  168. }
  169. function ruleLoader(rule) {
  170. if (
  171. hasSome(rule, [
  172. ":matches-path(",
  173. ":min-text-length(",
  174. ":watch-attr(",
  175. ":-abp-properties(",
  176. ":matches-property(",
  177. ])
  178. )
  179. return;
  180. // 如果 #$# 不包含 {} 就排除
  181. // 可以尽量排除 Snippet Filters
  182. if (/(\w|^)#\$#/.test(rule) && !/{.+}/.test(rule)) return;
  183. // ## -> #?#
  184. if (
  185. /(\w|^)#@?#/.test(rule) &&
  186. hasSome(rule, [
  187. ":has(",
  188. ":-abp-has(",
  189. "[-ext-has=",
  190. ":has-text(",
  191. "contains(",
  192. "-abp-contains(",
  193. "[-ext-contains=",
  194. "matches-css(",
  195. "[-ext-matches-css=",
  196. "matches-css-before(",
  197. "[-ext-matches-css-before=",
  198. "matches-css-after(",
  199. "[-ext-matches-css-after=",
  200. "matches-attr(",
  201. "nth-ancestor(",
  202. "upward(",
  203. "xpath(",
  204. "remove()",
  205. "not(",
  206. "if-not(",
  207. ])
  208. ) {
  209. rule = rule.replace(/(\w|^)##/, "$1#?#").replace(/(\w|^)#@#/, "$1#@?#");
  210. }
  211. // :style(...) 转换
  212. // example.com#?##id:style(color: red)
  213. // example.com#$?##id { color: red }
  214. if (rule.includes(":style(")) {
  215. rule = rule
  216. .replace(/(\w|^)##/, "$1#$#")
  217. .replace(/(\w|^)#@#/, "$1#@$#")
  218. .replace(/(\w|^)#\?#/, "$1#$?#")
  219. .replace(/(\w|^)#@\?#/, "$1#@$?#")
  220. .replace(/:style\(/, " { ")
  221. .replace(/\)$/, " }");
  222. }
  223. return ruleSpliter(rule);
  224. }
  225. function storAutoClean() {
  226. const vars = [
  227. "ajs_disabled_domains",
  228. "ajs_saved_abprules",
  229. "ajs_rules_etags",
  230. "ajs_rules_ver",
  231. ],
  232. stor = vm.unsafeWindow.localStorage;
  233. vars.forEach((key) => {
  234. if (stor.getItem(key)) {
  235. stor.removeItem(key);
  236. }
  237. });
  238. }
  239.  
  240. const selectors = makeRuleBox(),
  241. extSelectors = makeRuleBox(),
  242. styles = makeRuleBox(),
  243. extStyles = makeRuleBox(),
  244. values = {
  245. get black() {
  246. const arrStr = gmValue("get", false, "ajs_disabled_domains", "");
  247. return typeof arrStr == "string" && arrStr.length > 0
  248. ? arrStr.split(",")
  249. : [];
  250. },
  251. set black(v) {
  252. gmValue(
  253. "set",
  254. false,
  255. "ajs_disabled_domains",
  256. v === null || v === void 0 ? void 0 : v.join()
  257. );
  258. },
  259. get rules() {
  260. return gmValue("get", true, "ajs_saved_abprules", {});
  261. },
  262. set rules(v) {
  263. gmValue("set", true, "ajs_saved_abprules", v);
  264. },
  265. get css() {
  266. return gmValue("get", true, `ajs_saved_styles_${location.hostname}`, {
  267. needUpdate: true,
  268. hideCss: "",
  269. extraCss: "",
  270. });
  271. },
  272. set css(v) {
  273. gmValue("set", true, `ajs_saved_styles_${location.hostname}`, v);
  274. },
  275. get hasSave() {
  276. const arrStr = gmValue("get", false, "ajs_hasSave_domains", "");
  277. return typeof arrStr == "string" && arrStr.length > 0
  278. ? arrStr.split(",")
  279. : [];
  280. },
  281. set hasSave(v) {
  282. gmValue(
  283. "set",
  284. false,
  285. "ajs_hasSave_domains",
  286. v === null || v === void 0 ? void 0 : v.join()
  287. );
  288. },
  289. get time() {
  290. return gmValue("get", false, "ajs_rules_ver", "0/0/0 0:0:0");
  291. },
  292. set time(v) {
  293. gmValue("set", false, "ajs_rules_ver", v);
  294. },
  295. get etags() {
  296. return gmValue("get", true, "ajs_rules_etags", {});
  297. },
  298. set etags(v) {
  299. gmValue("set", true, "ajs_rules_etags", v);
  300. },
  301. },
  302. data = {
  303. disabled: false,
  304. saved: false,
  305. update: true,
  306. updating: false,
  307. receivedRules: "",
  308. allRules: "",
  309. presetCss:
  310. " {display: none !important;width: 0 !important;height: 0 !important;} ",
  311. hideCss: "",
  312. extraCss: "",
  313. appliedCount: 0,
  314. isFrame: vm.unsafeWindow.self !== vm.unsafeWindow.top,
  315. isClean: false,
  316. mutex: "__lemon__abp__parser__$__",
  317. timeout: 6000,
  318. xTimeout: 700,
  319. },
  320. menus = {
  321. disable: {
  322. id: undefined,
  323. get text() {
  324. return data.disabled ? "在此网站启用拦截" : "在此网站禁用拦截";
  325. },
  326. },
  327. update: {
  328. id: undefined,
  329. get text() {
  330. const time = values.time;
  331. return data.updating
  332. ? "正在更新..."
  333. : `点击更新: ${time.slice(0, 1) === "0" ? "未知时间" : time}`;
  334. },
  335. },
  336. count: {
  337. id: undefined,
  338. get text() {
  339. const cssCount = (data.hideCss + data.extraCss).match(/,/g);
  340. return data.isClean
  341. ? "已清空,点击刷新重新加载规则"
  342. : `${
  343. data.saved
  344. ? "CSS: " +
  345. (cssCount === null || cssCount === void 0
  346. ? void 0
  347. : cssCount.length)
  348. : "规则: " +
  349. data.appliedCount +
  350. "/" +
  351. data.allRules.split("\n").length
  352. },点击清空规则`;
  353. },
  354. },
  355. };
  356. function gmMenu(name, cb) {
  357. if (
  358. typeof vm.GM_registerMenuCommand != "function" ||
  359. typeof vm.GM_unregisterMenuCommand != "function" ||
  360. data.isFrame
  361. )
  362. return;
  363. if (typeof menus[name].id != "undefined") {
  364. vm.GM_unregisterMenuCommand(menus[name].id);
  365. menus[name].id = undefined;
  366. }
  367. if (typeof cb == "function") {
  368. menus[name].id = vm.GM_registerMenuCommand(menus[name].text, cb);
  369. }
  370. }
  371. function gmValue(action, json, key, value) {
  372. switch (action) {
  373. case "get":
  374. let v;
  375. try {
  376. v = vm.GM_getValue(key, json ? JSON.stringify(value) : value);
  377. } catch (error) {
  378. return;
  379. }
  380. return json && typeof v == "string" ? JSON.parse(v) : v;
  381. case "set":
  382. try {
  383. value === null || value === undefined
  384. ? vm.GM_deleteValue(key)
  385. : vm.GM_setValue(key, json ? JSON.stringify(value) : value);
  386. } catch (error) {
  387. vm.GM_deleteValue(key);
  388. }
  389. break;
  390. }
  391. }
  392. function promiseXhr(details) {
  393. return __awaiter(this, void 0, void 0, function* () {
  394. let loaded = false;
  395. try {
  396. return yield new Promise((resolve, reject) => {
  397. vm.GM_xmlhttpRequest(
  398. Object.assign(
  399. {
  400. onload(e) {
  401. loaded = true;
  402. resolve(e);
  403. },
  404. onabort: reject.bind(null, "abort"),
  405. onerror(e) {
  406. reject({
  407. error: "error",
  408. resp: e,
  409. });
  410. },
  411. ontimeout: reject.bind(null, "timeout"),
  412. onreadystatechange(e) {
  413. // X 浏览器超时中断
  414. if (e.readyState === 4) {
  415. setTimeout(() => {
  416. if (!loaded)
  417. reject({
  418. error: "X timeout",
  419. resp: e,
  420. });
  421. }, data.xTimeout);
  422. }
  423. // Via 浏览器超时中断,不给成功状态...
  424. if (e.readyState === 3) {
  425. setTimeout(() => {
  426. if (!loaded)
  427. reject({
  428. error: "Via timeout",
  429. resp: e,
  430. });
  431. }, data.timeout);
  432. }
  433. },
  434. timeout: data.timeout,
  435. },
  436. details
  437. )
  438. );
  439. });
  440. } catch (error) {}
  441. });
  442. }
  443. function storeRule(rule, resp) {
  444. const savedRules = values.rules,
  445. savedEtags = values.etags;
  446. if (resp.responseHeaders) {
  447. const etag = getEtag(resp.responseHeaders);
  448. if (etag) {
  449. savedEtags[rule.标识] = etag;
  450. values.etags = savedEtags;
  451. }
  452. }
  453. if (resp.responseText) {
  454. if (rule.筛选后存储) {
  455. let parsed = "";
  456. resp.responseText.split("\n").forEach((rule) => {
  457. if (ruleRE.some((re) => re.test(rule))) parsed += rule + "\n";
  458. });
  459. savedRules[rule.标识] = parsed;
  460. } else {
  461. savedRules[rule.标识] = resp.responseText;
  462. }
  463. values.rules = savedRules;
  464. if (Object.keys(values.rules).length === 0) {
  465. data.receivedRules += "\n" + savedRules[rule.标识] + "\n";
  466. }
  467. }
  468. }
  469. function fetchRuleBody(rule) {
  470. var _a;
  471. return __awaiter(this, void 0, void 0, function* () {
  472. const getResp = yield promiseXhr({
  473. method: "GET",
  474. responseType: "text",
  475. url: rule.地址,
  476. });
  477. if (
  478. getResp &&
  479. (getResp === null || getResp === void 0
  480. ? void 0
  481. : getResp.responseText) &&
  482. ((_a = getResp.responseText) === null || _a === void 0
  483. ? void 0
  484. : _a.length) > 0
  485. ) {
  486. storeRule(rule, getResp);
  487. return true;
  488. } else return false;
  489. });
  490. }
  491. function fetchRule(rule) {
  492. return new Promise((resolve, reject) =>
  493. __awaiter(this, void 0, void 0, function* () {
  494. var _a, _b, _e;
  495. const headResp = yield promiseXhr({
  496. method: "HEAD",
  497. responseType: "text",
  498. url: rule.地址,
  499. });
  500. if (!headResp) {
  501. reject("HEAD 失败");
  502. } else {
  503. const etag = getEtag(
  504. typeof headResp.responseHeaders == "string"
  505. ? headResp.responseHeaders
  506. : (_b = (_a = headResp).getAllResponseHeaders) === null ||
  507. _b === void 0
  508. ? void 0
  509. : _b.call(_a)
  510. ),
  511. savedEtags = values.etags;
  512. if (
  513. (headResp === null || headResp === void 0
  514. ? void 0
  515. : headResp.responseText) &&
  516. ((_e = headResp.responseText) === null || _e === void 0
  517. ? void 0
  518. : _e.length) > 0
  519. ) {
  520. storeRule(rule, headResp);
  521. !etag || etag !== savedEtags[rule.标识]
  522. ? resolve()
  523. : reject("ETag 一致");
  524. } else {
  525. if (!etag || etag !== savedEtags[rule.标识]) {
  526. (yield fetchRuleBody(rule)) ? resolve() : reject("GET 失败");
  527. } else reject("ETag 一致");
  528. }
  529. }
  530. })
  531. );
  532. }
  533. function fetchRules(apply) {
  534. return __awaiter(this, void 0, void 0, function* () {
  535. const has = values.hasSave;
  536. let hasUpdate = onlineRules.length;
  537. data.updating = true;
  538. gmMenu("update", () => undefined);
  539. for (const rule of onlineRules) {
  540. if (rule.在线更新) {
  541. yield fetchRule(rule).catch((error) => {
  542. hasUpdate--;
  543. });
  544. }
  545. }
  546. values.time = new Date().toLocaleString("zh-CN");
  547. if (has.length > 0 && hasUpdate > 0) {
  548. has.forEach((host) => {
  549. const save = gmValue("get", true, `ajs_saved_styles_${host}`);
  550. save.needUpdate = true;
  551. gmValue("set", true, `ajs_saved_styles_${host}`, save);
  552. });
  553. }
  554. initRules(apply);
  555. });
  556. }
  557. function performUpdate(force, apply) {
  558. if (data.isFrame) Promise.reject();
  559. return force || new Date(values.time).getDate() !== new Date().getDate()
  560. ? fetchRules(apply)
  561. : Promise.resolve();
  562. }
  563. function switchDisabledStat() {
  564. const disaList = values.black;
  565. data.disabled = !disaList.includes(location.hostname);
  566. if (data.disabled) {
  567. disaList.push(location.hostname);
  568. } else {
  569. disaList.splice(disaList.indexOf(location.hostname), 1);
  570. }
  571. values.black = disaList;
  572. location.reload();
  573. }
  574. function makeInitMenu() {
  575. gmMenu("update", () =>
  576. __awaiter(this, void 0, void 0, function* () {
  577. yield performUpdate(true, false);
  578. location.reload();
  579. })
  580. );
  581. gmMenu("count", cleanRules);
  582. }
  583. function initRules(apply) {
  584. const abpRules = values.rules;
  585. if (typeof vm.GM_getResourceText == "function") {
  586. onlineRules.forEach((rule) => {
  587. let resRule;
  588. try {
  589. resRule = vm.GM_getResourceText(rule.标识);
  590. } catch (error) {
  591. resRule = "";
  592. }
  593. if (resRule && !abpRules[rule.标识]) abpRules[rule.标识] = resRule;
  594. });
  595. }
  596. const abpKeys = Object.keys(abpRules);
  597. abpKeys.forEach((name) => {
  598. data.receivedRules += "\n" + abpRules[name] + "\n";
  599. });
  600. data.allRules = defaultRules + data.receivedRules;
  601. data.updating = false;
  602. makeInitMenu();
  603. if (apply) splitRules();
  604. return data.receivedRules.length;
  605. }
  606. function styleApply() {
  607. if (data.hideCss.length > 0) {
  608. if (typeof vm.GM_addStyle == "function") {
  609. vm.GM_addStyle(data.hideCss);
  610. } else {
  611. const elem = document.createElement("style");
  612. elem.textContent = data.hideCss;
  613. document.documentElement.appendChild(elem);
  614. }
  615. }
  616. if (data.extraCss.length > 0) {
  617. new ExtendedCss({ styleSheet: data.extraCss }).apply();
  618. }
  619. }
  620. function cleanRules() {
  621. if (confirm(`是否清空存储规则 (${Object.keys(values.rules).length}) ?`)) {
  622. const has = values.hasSave;
  623. values.rules = {};
  624. values.time = "0/0/0 0:0:0";
  625. values.etags = {};
  626. if (has.length > 0) {
  627. has.forEach((host) => {
  628. gmValue("set", true, `ajs_saved_styles_${host}`);
  629. });
  630. values.hasSave = null;
  631. }
  632. data.appliedCount = 0;
  633. data.allRules = "";
  634. data.isClean = true;
  635. gmMenu("update");
  636. gmMenu("count", () => location.reload());
  637. }
  638. }
  639. function parseRules() {
  640. const boxes = ["hideCss", "extraCss"];
  641. data.hideCss = "";
  642. data.extraCss = "";
  643. [styles, extStyles].forEach((r, t) => {
  644. r.black
  645. .filter((v) => !r.white.includes(v))
  646. .forEach((s, i, a) => {
  647. data[boxes[t]] += `${s} `;
  648. if (i == 0) data.appliedCount += a.length;
  649. });
  650. });
  651. [selectors, extSelectors].forEach((r, t) => {
  652. r.black
  653. .filter((v) => !r.white.includes(v))
  654. .forEach((s, i, a) => {
  655. data[boxes[t]] += `${i == 0 ? "" : ","}${s}`;
  656. if (i == a.length - 1) {
  657. data[boxes[t]] += data.presetCss;
  658. data.appliedCount += a.length;
  659. }
  660. });
  661. });
  662. gmMenu("count", cleanRules);
  663. saveCss();
  664. if (!data.saved) styleApply();
  665. }
  666. function splitRules() {
  667. data.allRules.split("\n").forEach((rule) => {
  668. const ruleObj = ruleLoader(rule),
  669. boxes = [selectors, extSelectors, styles, extStyles];
  670. if (typeof ruleObj != "undefined") {
  671. if (
  672. ruleObj.black == "black" &&
  673. boxes[ruleObj.type].white.includes(ruleObj.sel)
  674. )
  675. return;
  676. boxes[ruleObj.type][ruleObj.black].push(ruleObj.sel);
  677. }
  678. });
  679. parseRules();
  680. }
  681. function saveCss() {
  682. const styles = {
  683. needUpdate: false,
  684. hideCss: data.hideCss,
  685. extraCss: data.extraCss,
  686. },
  687. has = values.hasSave;
  688. values.css = styles;
  689. if (!has.includes(location.hostname)) has.push(location.hostname);
  690. values.hasSave = has;
  691. }
  692. function readCss() {
  693. var _a;
  694. const styles = values.css;
  695. if (styles.hideCss.length > 0) {
  696. data.saved = true;
  697. data.update =
  698. (_a = styles.needUpdate) !== null && _a !== void 0 ? _a : true;
  699. data.hideCss = styles.hideCss;
  700. data.extraCss = styles.extraCss;
  701. return true;
  702. } else return false;
  703. }
  704. function main() {
  705. var _a, _b;
  706. return __awaiter(this, void 0, void 0, function* () {
  707. if (
  708. ((_b =
  709. (_a = vm.unsafeWindow.mbrowser) === null || _a === void 0
  710. ? void 0
  711. : _a.getVersionCode) === null || _b === void 0
  712. ? void 0
  713. : _b.call(_a)) >= 662
  714. )
  715. storAutoClean();
  716. data.disabled = values.black.includes(location.hostname);
  717. gmMenu("disable", switchDisabledStat);
  718. if (data.disabled) return;
  719. readCss();
  720. saved: {
  721. if (data.saved) {
  722. styleApply();
  723. makeInitMenu();
  724. if (!data.update) break saved;
  725. }
  726. if (initRules(false) === 0) yield performUpdate(true, true);
  727. splitRules();
  728. }
  729. yield performUpdate(false, false);
  730. });
  731. }
  732. function runOnce(key, func) {
  733. if (key in vm.unsafeWindow) return;
  734. vm.unsafeWindow[key] = true;
  735. func();
  736. }
  737. runOnce(data.mutex, main);
  738. })(
  739. {
  740. unsafeWindow: typeof unsafeWindow == "object" ? unsafeWindow : window,
  741. GM_registerMenuCommand:
  742. typeof GM_registerMenuCommand == "function"
  743. ? GM_registerMenuCommand
  744. : undefined,
  745. GM_unregisterMenuCommand:
  746. typeof GM_unregisterMenuCommand == "function"
  747. ? GM_unregisterMenuCommand
  748. : undefined,
  749. GM_getValue: typeof GM_getValue == "function" ? GM_getValue : undefined,
  750. GM_deleteValue:
  751. typeof GM_deleteValue == "function" ? GM_deleteValue : undefined,
  752. GM_setValue: typeof GM_setValue == "function" ? GM_setValue : undefined,
  753. GM_xmlhttpRequest:
  754. typeof GM_xmlhttpRequest == "function" ? GM_xmlhttpRequest : undefined,
  755. GM_getResourceText:
  756. typeof GM_getResourceText == "function" ? GM_getResourceText : undefined,
  757. GM_addStyle: typeof GM_addStyle == "function" ? GM_addStyle : undefined,
  758. },
  759. ExtendedCss
  760. );