Google & baidu Switcher (ALL in One)

谷歌、百度、必应的搜索引擎跳转工具,脚本默认自动更新检测,可在菜单自定义设置必应按钮,搜索引擎跳转的最佳体验。

当前为 2021-11-23 提交的版本,查看 最新版本

  1. /* jshint esversion: 9 */
  2. // ==UserScript==
  3. // @name Google & baidu Switcher (ALL in One)
  4. // @name:zh 谷歌、百度、必应的搜索引擎跳转工具
  5. // @name:zh-TW 谷歌、百度、必應的搜索引擎跳轉工具
  6. // @name:en Google & baidu & Bing Switcher (ALL in One)
  7. // @name:ja Google、Baidu、Bingの検索エンジンのジャンプツール
  8. // @version 4.0.20211123.2
  9. // @author F9y4ng
  10. // @description 谷歌、百度、必应的搜索引擎跳转工具,脚本默认自动更新检测,可在菜单自定义设置必应按钮,搜索引擎跳转的最佳体验。
  11. // @description:zh 谷歌、百度、必应的搜索引擎跳转工具,脚本默认自动更新检测,可在菜单自定义设置必应按钮,搜索引擎跳转的最佳体验。
  12. // @description:en Google, Baidu and Bing search engine tool, Automatically updated and detected by default, The Bing button can be customized.
  13. // @description:zh-TW 谷歌、百度、必應的搜索引擎跳轉工具,腳本默認自動更新檢測,可在菜單自定義設置必應按鈕,搜索引擎跳轉的最佳體驗。
  14. // @description:ja Google、Baidu、Bingの検索エンジンのジャンプツールは、スクリプトのデフォルトの自動更新検出は、メニューのカスタマイズに必要なボタンを設定することができます。
  15. // @namespace https://openuserjs.org/scripts/f9y4ng/Google_baidu_Switcher_(ALL_in_One)
  16. // @homepageURL https://f9y4ng.github.io/GreasyFork-Scripts
  17. // @supportURL https://github.com/F9y4ng/GreasyFork-Scripts/issues
  18. // @icon https://img.icons8.com/fluent/48/000000/google-logo.png
  19. // @include *://*.google.*/search*
  20. // @include *://*.google.*/webhp*
  21. // @include *://www.baidu.com/*
  22. // @include *://ipv6.baidu.com/*
  23. // @include *://www1.baidu.com/*
  24. // @include *://image.baidu.com/*
  25. // @include *://*.bing.com/*
  26. // @exclude *://www.baidu.com/link*
  27. // @compatible edge 兼容TamperMonkey, ViolentMonkey
  28. // @compatible Chrome 兼容TamperMonkey, ViolentMonkey
  29. // @compatible Firefox 兼容Greasemonkey4.0+, TamperMonkey, ViolentMonkey
  30. // @compatible Opera 兼容TamperMonkey, ViolentMonkey
  31. // @compatible Safari 兼容Tampermonkey • Safari
  32. // @note 新增键盘快捷键功能开关(默认:开启)\n修正MacOS下Command+字母与浏览器快捷键冲突的问题。
  33. // @grant GM_info
  34. // @grant GM_registerMenuCommand
  35. // @grant GM.registerMenuCommand
  36. // @grant GM_unregisterMenuCommand
  37. // @grant GM_openInTab
  38. // @grant GM.openInTab
  39. // @grant GM_getValue
  40. // @grant GM.getValue
  41. // @grant GM_setValue
  42. // @grant GM.setValue
  43. // @grant GM_deleteValue
  44. // @grant GM.deleteValue
  45. // @license GPL-3.0-only
  46. // @create 2015-10-07
  47. // @copyright 2015-2021, F9y4ng
  48. // @run-at document-start
  49. // ==/UserScript==
  50.  
  51. !(function () {
  52. "use strict";
  53.  
  54. /* customize */
  55.  
  56. const isdebug = false; // set "true" to debug scripts, May cause script response slower.
  57.  
  58. /* Perfectly Compatible For Greasemonkey4.0+, TamperMonkey, ViolentMonkey * F9y4ng * 20210609 */
  59.  
  60. let GMsetValue, GMgetValue, GMdeleteValue, GMregisterMenuCommand, GMunregisterMenuCommand, GMnotification, GMopenInTab;
  61. const GMinfo = GM_info;
  62. const handlerInfo = GMinfo.scriptHandler;
  63. const isGM = Boolean(handlerInfo.toLowerCase() === "greasemonkey");
  64. const debug = isdebug ? console.log.bind(console) : () => {};
  65. const error = isdebug ? console.error.bind(console) : () => {};
  66.  
  67. /* GM selector */
  68.  
  69. if (isGM) {
  70. GMsetValue = GM.setValue;
  71. GMgetValue = GM.getValue;
  72. GMdeleteValue = GM.deleteValue;
  73. GMregisterMenuCommand = GM.registerMenuCommand;
  74. GMunregisterMenuCommand = () => {};
  75. GMopenInTab = GM.openInTab;
  76. } else {
  77. GMsetValue = GM_setValue;
  78. GMgetValue = GM_getValue;
  79. GMdeleteValue = GM_deleteValue;
  80. GMregisterMenuCommand = GM_registerMenuCommand;
  81. GMunregisterMenuCommand = GM_unregisterMenuCommand;
  82. GMopenInTab = GM_openInTab;
  83. }
  84.  
  85. /* default CONST Values */
  86.  
  87. const defCon = {
  88. scriptName: GMinfo.script.name,
  89. curVersion: GMinfo.script.version,
  90. support: GMinfo.script.supportURL,
  91. encrypt: n => {
  92. return window.btoa(encodeURIComponent(n));
  93. },
  94. decrypt: n => {
  95. return decodeURIComponent(window.atob(n));
  96. },
  97. fetchResult: "success",
  98. titleCase: (str, bool) => {
  99. const RegExp = bool ? /( |^)[a-z]/g : /(^)[a-z]/g;
  100. return str
  101. .toString()
  102. .toLowerCase()
  103. .replace(RegExp, L => {
  104. return L.toUpperCase();
  105. });
  106. },
  107. isNeedUpdate: 0,
  108. updateNote: "",
  109. restTime: {},
  110. timer: 0,
  111. options: isGM ? false : { active: true, insert: true, setParent: true },
  112. durationTime: t => {
  113. let w, d, h, m, s;
  114. const wks = Math.floor(t / 1000 / 60 / 60 / 24 / 7);
  115. const ds = Math.floor(t / 1000 / 60 / 60 / 24 - wks * 7);
  116. const hs = Math.floor(t / 1000 / 60 / 60 - wks * 7 * 24 - ds * 24);
  117. const ms = Math.floor(t / 1000 / 60 - wks * 7 * 24 * 60 - ds * 24 * 60 - hs * 60);
  118. const ss = Math.floor(t / 1000 - wks * 7 * 24 * 60 * 60 - ds * 24 * 60 * 60 - hs * 60 * 60 - ms * 60);
  119. w = wks > 0 ? ` ${wks}wk` : "";
  120. d = ds > 0 ? ` ${ds}d` : "";
  121. h = hs > 0 ? ` ${hs}h` : "";
  122. m = ms > 0 ? ` ${ms}min` : "";
  123. s = wks > 0 || ds > 0 || hs > 0 || ms > 0 ? "" : ss > 0 ? ` ${ss}s` : " expired";
  124. return `${w}${d}${h}${m}${s}`;
  125. },
  126. showDate: s => {
  127. return s.replace(/w/i, " 周 ").replace(/d/i, " 天 ").replace(/h/i, " 小时 ").replace(/m/i, " 分钟 ").replace(/s/i, " 秒 ");
  128. },
  129. randString: (n, v, r, s = "") => {
  130. const a = "0123456789";
  131. const b = "abcdefghijklmnopqrstuvwxyz";
  132. const c = b.toUpperCase();
  133. n = Number.isFinite(n) ? n : 10;
  134. r = v ? b + c : a + b + a + c;
  135. for (; n > 0; --n) {
  136. s += r[Math.floor(Math.random() * r.length)];
  137. }
  138. return s;
  139. },
  140. isUpgrade: Boolean(GetUrlParam("Zn")),
  141. lastRuntime: () => {
  142. return new Date().toLocaleString("en-US", {
  143. timeZoneName: "short",
  144. hour12: false,
  145. });
  146. },
  147. };
  148. defCon.rName = defCon.randString(7, true);
  149. const qS = str => {
  150. return document.querySelector(str);
  151. };
  152. const cE = str => {
  153. return document.createElement(str);
  154. };
  155.  
  156. /* Define random aliases */
  157.  
  158. const Notice = {
  159. noticejs: defCon.randString(7, true),
  160. item: defCon.randString(5, true),
  161. close: defCon.randString(5, true),
  162. center: defCon.randString(5, true),
  163. success: defCon.randString(7, true),
  164. warning: defCon.randString(7, true),
  165. info: defCon.randString(7, true),
  166. error: defCon.randString(7, true),
  167. checkbox: defCon.randString(6, true),
  168. configuration: defCon.randString(7, true),
  169. fc: defCon.randString(8, true),
  170. fcSave: defCon.randString(5, true),
  171. fcClose: defCon.randString(5, true),
  172. fchk: defCon.randString(6, true),
  173. hotkey: defCon.randString(5, true),
  174. fcGoogle: defCon.randString(6, true),
  175. google: defCon.randString(5, true),
  176. fcKwhl: defCon.randString(6, true),
  177. kwhl: defCon.randString(5, true),
  178. localWindow: defCon.randString(6, true),
  179. lw: defCon.randString(5, true),
  180. fcUpdate: defCon.randString(6, true),
  181. isUpdate: defCon.randString(5, true),
  182. fcExpire: defCon.randString(6, true),
  183. Expire: defCon.randString(6, true),
  184. timeUnit: defCon.randString(6, true),
  185. fcFeedback: defCon.randString(6, true),
  186. fcSubmit: defCon.randString(6, true),
  187. feedback: defCon.randString(5, true),
  188. animated: defCon.randString(7, true),
  189. noticeHTML: str => {
  190. return String(`<div class="${defCon.rName}"><dl>${str}<dl></div>`);
  191. },
  192. };
  193.  
  194. /* Refactoring NoticeJs Functions */
  195.  
  196. const Defaults = {
  197. title: "",
  198. text: "",
  199. type: `${Notice.success}`,
  200. position: "bottomRight",
  201. newestOnTop: false,
  202. timeout: 30,
  203. progressBar: true,
  204. closeWith: ["button"],
  205. animation: {
  206. open: `${Notice.animated} fadeIn`,
  207. close: `${Notice.animated} fadeOut`,
  208. },
  209. modal: false,
  210. width: 400,
  211. scroll: {
  212. maxHeightContent: 400,
  213. showOnHover: true,
  214. },
  215. rtl: false,
  216. callbacks: {
  217. beforeShow: [],
  218. onShow: [],
  219. afterShow: [],
  220. onClose: [],
  221. afterClose: [],
  222. onClick: [],
  223. onHover: [],
  224. onTemplate: [],
  225. },
  226. };
  227.  
  228. const noticeJsModalClassName = `${Notice.noticejs}-modal`;
  229. const options = Defaults;
  230.  
  231. /* Get browser core & system parameters */
  232.  
  233. const getBrowser = {
  234. type: (info, system = "other", browserArray = {}, browserInfo = "unknow") => {
  235. const u = navigator.userAgent.toLowerCase();
  236. switch (info) {
  237. case "core":
  238. return {
  239. Trident: u.includes("trident") || u.includes("compatible"),
  240. Presto: u.includes("presto") || u.includes("opr"),
  241. WebKit: u.includes("applewebkit"),
  242. Gecko: u.includes("gecko") && !u.includes("khtml"),
  243. EdgeHTML: u.includes("edge"),
  244. };
  245. case "system":
  246. if (/windows|win32|win64|wow32|wow64/gi.test(u)) {
  247. system = "Windows";
  248. } else if (/macintosh|macintel|mac os x/gi.test(u) || u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/i)) {
  249. system = "MacOS";
  250. } else if (/x11/gi.test(u)) {
  251. system = "Linux";
  252. } else if (/android|adr/gi.test(u)) {
  253. system = "Android";
  254. } else if (/ios|iphone|ipad|ipod|iwatch/gi.test(u)) {
  255. system = "iOS";
  256. }
  257. return system;
  258. case "browser":
  259. browserArray = {
  260. IE: window.ActiveXObject || "ActiveXObject" in window,
  261. Chromium: u.includes("chromium"),
  262. Chrome: u.includes("chrome") && !u.includes("edg") && !u.includes("chromium"),
  263. Firefox: u.includes("firefox") && u.includes("gecko"),
  264. Opera: u.includes("presto") || u.includes("opr") || u.includes("opera"),
  265. Safari: u.includes("safari") && !u.includes("chrome"),
  266. Edge: u.includes("edg"),
  267. QQBrowser: /qqbrowser/g.test(u),
  268. Wechat: /micromessenger/g.test(u),
  269. UCBrowser: /ucbrowser/g.test(u),
  270. Sougou: /metasr/g.test(u),
  271. Maxthon: /maxthon/g.test(u),
  272. CentBrowser: /cent/g.test(u),
  273. };
  274. for (let i in browserArray) {
  275. if (browserArray[i]) {
  276. browserInfo = i;
  277. }
  278. }
  279. return browserInfo;
  280. default:
  281. return u;
  282. }
  283. },
  284. };
  285.  
  286. /* Notice */
  287.  
  288. function getCallback(ref, eventName) {
  289. if (ref.callbacks.hasOwnProperty(eventName)) {
  290. ref.callbacks[eventName].forEach(cb => {
  291. if (typeof cb === "function") {
  292. cb.apply(ref);
  293. }
  294. });
  295. }
  296. }
  297.  
  298. const AddModal = () => {
  299. if (document.getElementsByClassName(noticeJsModalClassName).length <= 0) {
  300. const element = cE("div");
  301. element.classList.add(noticeJsModalClassName);
  302. element.classList.add(`${Notice.noticejs}-modal-open`);
  303. document.body.appendChild(element);
  304. setTimeout(() => {
  305. element.className = noticeJsModalClassName;
  306. }, 200);
  307. }
  308. };
  309.  
  310. const CloseItem = item => {
  311. getCallback(options, "onClose");
  312. if (options.animation !== null && options.animation.close !== null) {
  313. item.className += " " + options.animation.close;
  314. }
  315. setTimeout(() => {
  316. item.remove();
  317. }, 200);
  318. if (options.modal === true && document.querySelectorAll(`[${Notice.noticejs}-modal='true']`).length >= 1) {
  319. qS(`.${Notice.noticejs}-modal`).className += ` ${Notice.noticejs}-modal-close`;
  320. setTimeout(() => {
  321. qS(`.${Notice.noticejs}-modal`).remove();
  322. }, 500);
  323. }
  324. const iC = item.closest(`.${Notice.noticejs}`);
  325. const iCId = iC ? iC.id.replace(`${Notice.noticejs}-`, "").trim() : `bottomRight`;
  326. const iCC = iC ? iC.className.replace(`${Notice.noticejs}`, "").trim() : `${Notice.noticejs}-bottomRight`;
  327. const position = "." + iCC;
  328. setTimeout(() => {
  329. if (document.querySelectorAll(position + ` .${Notice.item}`).length <= 0) {
  330. qS(position) && qS(position).remove();
  331. if (getBrowser.type("core").Gecko && defCon[iCId]) {
  332. document.removeEventListener("scroll", defCon[iCId]);
  333. delete defCon[iCId];
  334. }
  335. }
  336. }, 500);
  337. };
  338.  
  339. const addListener = item => {
  340. if (options.closeWith.includes("button")) {
  341. if (item.querySelector(`.${Notice.close}`)) {
  342. item.querySelector(`.${Notice.close}`).addEventListener("click", () => {
  343. CloseItem(item);
  344. });
  345. }
  346. }
  347. if (options.closeWith.includes("click")) {
  348. item.style.cursor = "pointer";
  349. item.addEventListener("click", e => {
  350. if (e.target.className !== `${Notice.close}`) {
  351. getCallback(options, "onClick");
  352. CloseItem(item);
  353. }
  354. });
  355. } else {
  356. item.addEventListener("click", e => {
  357. if (e.target.className !== `${Notice.close}`) {
  358. getCallback(options, "onClick");
  359. }
  360. });
  361. }
  362. item.addEventListener("mouseover", () => {
  363. getCallback(options, "onHover");
  364. });
  365. };
  366.  
  367. const appendNoticeJs = (noticeJsHeader, noticeJsBody, noticeJsProgressBar) => {
  368. const target_class = `.${Notice.noticejs}-` + options.position;
  369. const noticeJsItem = cE("div");
  370. noticeJsItem.classList.add(`${Notice.item}`);
  371. noticeJsItem.classList.add(options.type);
  372. if (options.rtl === true) {
  373. noticeJsItem.classList.add(`${Notice.noticejs}-rtl`);
  374. }
  375. if (options.width !== "" && Number.isInteger(options.width)) {
  376. noticeJsItem.style.width = options.width + "px";
  377. }
  378. if (noticeJsHeader && noticeJsHeader !== "" && noticeJsHeader.nodeType) {
  379. noticeJsItem.appendChild(noticeJsHeader);
  380. }
  381. if (noticeJsBody.nodeType) {
  382. noticeJsItem.appendChild(noticeJsBody);
  383. }
  384. if (noticeJsProgressBar && noticeJsProgressBar !== "" && noticeJsProgressBar.nodeType) {
  385. noticeJsItem.appendChild(noticeJsProgressBar);
  386. }
  387. if (["top", "bottom"].includes(options.position)) {
  388. qS(target_class).innerHTML = "";
  389. }
  390. if (options.animation !== null && options.animation.open !== null) {
  391. noticeJsItem.className += " " + options.animation.open;
  392. }
  393. if (options.modal === true) {
  394. noticeJsItem.setAttribute(`${Notice.noticejs}-modal`, "true");
  395. AddModal();
  396. }
  397. addListener(noticeJsItem, options.closeWith);
  398. getCallback(options, "beforeShow");
  399. getCallback(options, "onShow");
  400. if (options.newestOnTop === true) {
  401. qS(target_class) && qS(target_class).insertAdjacentElement("afterbegin", noticeJsItem);
  402. } else {
  403. qS(target_class) && qS(target_class).appendChild(noticeJsItem);
  404. }
  405. getCallback(options, "afterShow");
  406. return noticeJsItem;
  407. };
  408.  
  409. class Components {
  410. createContainer() {
  411. const element_class = `${Notice.noticejs}-` + options.position;
  412. const element = cE("gb-notice");
  413. element.classList.add(`${Notice.noticejs}`);
  414. element.classList.add(element_class);
  415. element.id = element_class;
  416. return element;
  417. }
  418.  
  419. createHeader() {
  420. let element;
  421. if (options.title && options.title !== "") {
  422. element = cE("div");
  423. element.setAttribute("class", `${Notice.noticejs}-heading`);
  424. element.textContent = options.title;
  425. }
  426. if (options.closeWith.includes("button")) {
  427. const close = cE("div");
  428. close.setAttribute("class", `${Notice.close}`);
  429. close.innerHTML = "&times;";
  430. if (element) {
  431. element.appendChild(close);
  432. } else {
  433. element = close;
  434. }
  435. }
  436. return element;
  437. }
  438.  
  439. createBody() {
  440. const element = cE("div");
  441. element.setAttribute("class", `${Notice.noticejs}-body`);
  442. const content = cE("div");
  443. content.setAttribute("class", `${Notice.noticejs}-content`);
  444. content.innerHTML = options.text;
  445. element.appendChild(content);
  446. if (options.scroll !== null && options.scroll.maxHeight !== "") {
  447. element.style.overflowY = "auto";
  448. element.style.maxHeight = options.scroll.maxHeight + "px";
  449. if (options.scroll.showOnHover === true) {
  450. element.style.visibility = "hidden";
  451. }
  452. }
  453. return element;
  454. }
  455.  
  456. createProgressBar() {
  457. const element = cE("div");
  458. element.setAttribute("class", `${Notice.noticejs}-progressbar`);
  459. const bar = cE("div");
  460. bar.setAttribute("class", `${Notice.noticejs}-bar`);
  461. element.appendChild(bar);
  462. if (options.progressBar === true && typeof options.timeout !== "boolean" && options.timeout !== false) {
  463. let width = 100;
  464. const id = setInterval(() => {
  465. if (width <= 0) {
  466. clearInterval(id);
  467. let item = element.closest(`div.${Notice.item}`);
  468. if (options.animation !== null && options.animation.close !== null) {
  469. item.className = item.className.replace(new RegExp("(?:^|\\s)" + options.animation.open + "(?:\\s|$)"), " ");
  470. item.className += " " + options.animation.close;
  471. const close_time = parseInt(options.timeout) + 500;
  472. setTimeout(() => {
  473. CloseItem(item);
  474. }, close_time);
  475. } else {
  476. CloseItem(item);
  477. }
  478. } else {
  479. width--;
  480. bar.style.width = width + "%";
  481. }
  482. }, options.timeout);
  483. }
  484. return element;
  485. }
  486. }
  487.  
  488. class NoticeJs {
  489. constructor(options = {}) {
  490. this.options = Object.assign(Defaults, options);
  491. this.component = new Components();
  492. this.on("beforeShow", this.options.callbacks.beforeShow);
  493. this.on("onShow", this.options.callbacks.onShow);
  494. this.on("afterShow", this.options.callbacks.afterShow);
  495. this.on("onClose", this.options.callbacks.onClose);
  496. this.on("afterClose", this.options.callbacks.afterClose);
  497. this.on("onClick", this.options.callbacks.onClick);
  498. this.on("onHover", this.options.callbacks.onHover);
  499. }
  500.  
  501. show() {
  502. let container = this.component.createContainer();
  503. if (document.body && qS(`.${Notice.noticejs}-` + this.options.position) === null) {
  504. document.body.appendChild(container);
  505. }
  506. let noticeJsHeader, noticeJsBody, noticeJsProgressBar;
  507. noticeJsHeader = this.component.createHeader(this.options.title, this.options.closeWith);
  508. noticeJsBody = this.component.createBody(this.options.text);
  509. if (this.options.progressBar === true) {
  510. noticeJsProgressBar = this.component.createProgressBar();
  511. }
  512. const noticeJs = appendNoticeJs(noticeJsHeader, noticeJsBody, noticeJsProgressBar);
  513. return noticeJs;
  514. }
  515.  
  516. on(eventName, cb = () => {}) {
  517. if (typeof cb === "function" && this.options.callbacks.hasOwnProperty(eventName)) {
  518. this.options.callbacks[eventName].push(cb);
  519. }
  520. return this;
  521. }
  522.  
  523. static overrideDefaults(options) {
  524. this.options = Object.assign(Defaults, options);
  525. return this;
  526. }
  527. }
  528.  
  529. /* Refactoring functions of GMsetValue/GMgetValue/GMdeleteValue with Expire */
  530.  
  531. function GMsetExpire(key, value) {
  532. const obj = {
  533. data: value,
  534. time: Date.now(),
  535. };
  536. GMsetValue(key, defCon.encrypt(JSON.stringify(obj)));
  537. }
  538.  
  539. async function GMgetExpire(key, curExpire) {
  540. let vals, expire, expires, expireTime;
  541. vals = await GMgetValue(key);
  542. if (!vals) {
  543. return vals;
  544. }
  545. vals = JSON.parse(defCon.decrypt(vals));
  546. if (curExpire) {
  547. expire = /(?!^0)^[0-9]+[smhdw]$/i.test(curExpire) ? curExpire : "24h";
  548. expire = expire.replace(/w/i, "*7*24*3600*1000").replace(/d/i, "*24*3600*1000").replace(/h/i, "*3600*1000").replace(/m/i, "*60*1000").replace(/s/i, "*1000");
  549. expires = expire.split("*");
  550. expireTime = expires.reduce((a, b) => {
  551. return a * b;
  552. }, 1);
  553. }
  554. defCon.restTime[key] = vals.time + expireTime - Date.now();
  555. if (defCon.restTime[key] <= 0) {
  556. GMdeleteValue(key);
  557. return null;
  558. }
  559. return vals.data;
  560. }
  561.  
  562. function transformFixedtoScroll(position) {
  563. if (document.body) {
  564. const zoom = Number(window.getComputedStyle(document.body, null).getPropertyValue("zoom"));
  565. const transform = window.getComputedStyle(document.body, null).getPropertyValue("transform");
  566. const thatNotice = qS(`#${Notice.noticejs}-${position}`);
  567. const rePosition = (item, ratio, _top, distTop) => {
  568. let sT = 0 - (document.body.getBoundingClientRect().top || document.documentElement.getBoundingClientRect().top || 0);
  569. item.style.top = `${(_top + sT) / ratio}px`;
  570. window.scrollTo(0, sT - 1e-5);
  571. if (item.childNodes.length === 1) {
  572. defCon[distTop] = () => {
  573. sT = 0 - (document.body.getBoundingClientRect().top || document.documentElement.getBoundingClientRect().top || 0);
  574. item.style.top = `${(_top + sT) / ratio}px`;
  575. };
  576. document.addEventListener("scroll", defCon[distTop]);
  577. }
  578. };
  579.  
  580. if (zoom && zoom !== 1) {
  581. thatNotice.style.cssText += `zoom:${1 / zoom}!important`;
  582. } else if (getBrowser.type("core").Gecko && transform && transform !== "none") {
  583. const ratio = Number(transform.split(",")[3]);
  584. if (ratio && ratio !== 1) {
  585. if (thatNotice) {
  586. thatNotice.style.cssText += `width:${document.documentElement.clientWidth / ratio}px;height:${document.documentElement.clientHeight / ratio}px;top:0;left:0`;
  587. thatNotice.childNodes.forEach((item, index, array, curItem = 0) => {
  588. switch (position) {
  589. case "topRight":
  590. item.style.cssText += String(
  591. `transform-origin:right top 0px;
  592. transform:scale(${1 / ratio});
  593. position:absolute;
  594. right:${10 / ratio}px;
  595. top:${10 / ratio}px`
  596. );
  597. break;
  598.  
  599. default:
  600. curItem = !index ? 10 / ratio : (array[index - 1].clientHeight + 10) / ratio + Number(array[index - 1].style.bottom.replace("px", ""));
  601. item.style.cssText += String(
  602. `transform-origin:right bottom 0px;
  603. transform:scale(${1 / ratio});
  604. position:absolute;
  605. right:${10 / ratio}px;
  606. bottom:${curItem}px`
  607. );
  608. break;
  609. }
  610. });
  611. rePosition(thatNotice, ratio, 0, position);
  612. }
  613. }
  614. }
  615. }
  616. }
  617.  
  618. /* Refactoring GMnotification Function */
  619.  
  620. GMnotification = (text = "", type = `${Notice.info}`, closeWith = true, timeout = 30, { ...options } = {}, position = "bottomRight") => {
  621. try {
  622. new NoticeJs({
  623. text: text,
  624. type: type,
  625. closeWith: closeWith ? ["button"] : ["click"],
  626. timeout: timeout,
  627. callbacks: { ...options },
  628. position: position,
  629. }).show();
  630. transformFixedtoScroll(position);
  631. } catch (e) {
  632. error("//-> %cGMnotification:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  633. }
  634. };
  635.  
  636. const callback_Countdown = {
  637. onShow: [
  638. (Interval = 3) => {
  639. const m = setInterval(() => {
  640. Interval ? --Interval : clearInterval(m);
  641. const emText = qS(`.${defCon.rName} dl dd em`);
  642. if (emText) {
  643. emText.innerHTML = Interval;
  644. }
  645. !Interval ? location.reload() : debug("//->", Interval);
  646. }, 1e3);
  647. },
  648. ],
  649. };
  650.  
  651. /* Common functions */
  652.  
  653. function getCookie(sKey) {
  654. const cookies = decodeURIComponent(
  655. document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")
  656. );
  657. return cookies ? cookies.replace(/[a-z=]+/gi, "") : 0;
  658. }
  659.  
  660. function GetUrlParam(paraName, arr = "") {
  661. if (!paraName) {
  662. const parameter = document.location.pathname.toString();
  663. arr = parameter.split("/");
  664. return arr[1] === undefined ? "" : arr[1];
  665. } else {
  666. const url = document.location.toString();
  667. const arrObj = url.split("?");
  668. if (arrObj.length > 1) {
  669. const arrPara = arrObj[1].split("&");
  670. for (let i = 0; i < arrPara.length; i++) {
  671. arr = arrPara[i].split("=");
  672. if (arr !== null && arr[0] === paraName) {
  673. return arr[1];
  674. }
  675. }
  676. return "";
  677. } else {
  678. return "";
  679. }
  680. }
  681. }
  682.  
  683. /* SYSTEM INFO */
  684.  
  685. if (window.self === window.top) {
  686. console.info(
  687. `%c[GB-Init]%c\nVersion: ${defCon.curVersion} %c[%s]%c\nExtension: %s\nlastRuntime: ${defCon.lastRuntime()}`,
  688. "font-weight:bold;color:dodgerblue",
  689. "color:0",
  690. "color:snow",
  691. defCon.titleCase(checkVersion(defCon.isUpgrade) instanceof Object),
  692. "color:0",
  693. defCon.titleCase(handlerInfo)
  694. );
  695. }
  696.  
  697. /* Version Detection with Cache and timeout * F9y4ng * 20210614 */
  698.  
  699. function fetchTimeout(url, time, { ...options } = {}) {
  700. const controller = new window.AbortController();
  701. const signal = controller.signal;
  702. return new Promise((resolve, reject) => {
  703. const t = setTimeout(() => {
  704. controller.abort();
  705. resolve(new Response("timeout", { status: 504, statusText: `Request timeout. (User-Defined: ${time}ms)` }));
  706. }, time);
  707. fetch(url, { signal: signal, ...options }).then(
  708. res => {
  709. clearTimeout(t);
  710. resolve(res);
  711. },
  712. err => {
  713. clearTimeout(t);
  714. reject(err);
  715. }
  716. );
  717. });
  718. }
  719.  
  720. function fetchVersion(u) {
  721. return new Promise((e, t) => {
  722. fetchTimeout(u, 2000, {
  723. method: "GET",
  724. mode: "cors",
  725. cache: "no-store",
  726. credentials: "omit",
  727. })
  728. .then(e => {
  729. debug("//-> %c%s %s %s", "color:green", new URL(u).hostname, e.ok, e.status);
  730. if (!e.ok) {
  731. throw Error(`${e.status} ${e.statusText}`);
  732. }
  733. return e.text();
  734. })
  735. .then(t => {
  736. let n = defCon.curVersion;
  737. let m = defCon.updateNote;
  738. t.split(/[\r\n]+/).forEach(item => {
  739. const key = item.match(/^(\/\/\s+@version\s+)(\S+)$/);
  740. if (key) {
  741. n = key[2];
  742. }
  743. const note = item.match(/^(\/\/\s+@note\s+)(.+)$/);
  744. if (note) {
  745. m = note[2];
  746. }
  747. });
  748. e([compareVersion(defCon.curVersion, n), defCon.encrypt(n), defCon.encrypt(m), defCon.encrypt(u)]);
  749. })
  750. .catch(e => {
  751. error("//-> %cfetchVersion:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  752. t();
  753. });
  754. });
  755. }
  756.  
  757. function compareVersion(current, compare) {
  758. const compare_array = compare.split(".");
  759. const current_array = current.split(".");
  760. let upgradeID = 0;
  761. if (compare_array.length === current_array.length) {
  762. for (let i = 0; i < compare_array.length; i++) {
  763. if (parseInt(compare_array[i]) < parseInt(current_array[i])) {
  764. upgradeID = 3;
  765. break;
  766. } else {
  767. if (parseInt(compare_array[i]) === parseInt(current_array[i])) {
  768. continue;
  769. } else {
  770. upgradeID = 1;
  771. break;
  772. }
  773. }
  774. }
  775. } else {
  776. upgradeID = 2;
  777. }
  778. return upgradeID;
  779. }
  780.  
  781. async function checkVersion(s = false) {
  782. let t, setResult, useBing, VerDetAuto, checkUpdate, timeNumber, timeUnit, GoogleJump, Hotkey, keywordHighlight, localWindow, _data;
  783. const _configuration = await GMgetValue("_configuration_");
  784. if (!_configuration) {
  785. useBing = 0;
  786. VerDetAuto = true;
  787. checkUpdate = true;
  788. timeNumber = 24;
  789. timeUnit = "h";
  790. GoogleJump = false;
  791. Hotkey = true;
  792. keywordHighlight = false;
  793. localWindow = false;
  794. _data = {
  795. useBing,
  796. VerDetAuto,
  797. checkUpdate,
  798. timeNumber,
  799. timeUnit,
  800. GoogleJump,
  801. Hotkey,
  802. keywordHighlight,
  803. localWindow,
  804. };
  805. console.warn("%c[GB-Warning]%c\nThis is your first visit, the Bing search button will not be inserted by default.", "font-weight:bold;color:salmon", "color:1");
  806. // initialization
  807. GMdeleteValue("_Check_Version_Expire_");
  808. GMdeleteValue("_expire_time_");
  809. GMdeleteValue("_nCount_");
  810. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  811. } else {
  812. _data = JSON.parse(defCon.decrypt(_configuration));
  813. useBing = _data.useBing;
  814. VerDetAuto = _data.VerDetAuto;
  815. checkUpdate = _data.checkUpdate;
  816. timeNumber = _data.timeNumber;
  817. timeUnit = _data.timeUnit;
  818. GoogleJump = _data.GoogleJump;
  819. Hotkey = _data.Hotkey !== undefined ? _data.Hotkey : true;
  820. keywordHighlight = _data.keywordHighlight;
  821. localWindow = _data.localWindow;
  822. }
  823. setResult = checkUpdate ? Boolean(VerDetAuto) : false;
  824. const _expire_time = String(timeNumber + timeUnit);
  825. const _expire_time_ = /(?!^0)^[0-9]+[smhdw]$/i.test(_expire_time) ? _expire_time : "24h";
  826. if (setResult) {
  827. if (window.self === window.top) {
  828. const cache = await GMgetExpire("_Check_Version_Expire_", _expire_time_);
  829. if (!cache) {
  830. // first: greasyfork
  831. t = await fetchVersion(`https://greasyfork.org/scripts/12909/code/${defCon.randString(32)}.meta.js`).catch(async () => {
  832. defCon.fetchResult = "GreasyFork - Failed to fetch";
  833. error(defCon.fetchResult);
  834. });
  835. // second: github
  836. if (defCon.fetchResult.includes("GreasyFork")) {
  837. t = await fetchVersion(`https://raw.githubusercontent.com/F9y4ng/GreasyFork-Scripts/master/Google%20%26%20Baidu%20Switcher.meta.js`).catch(async () => {
  838. defCon.fetchResult = "Github - Failed to fetch";
  839. error(defCon.fetchResult);
  840. });
  841. }
  842. // final: Jsdelivr points to gitee
  843. if (defCon.fetchResult.includes("Github")) {
  844. t = await fetchVersion(`https://cdn.jsdelivr.net/gh/F9y4ng/GreasyFork-Scripts@master/Google%20%26%20Baidu%20Switcher.meta.js`).catch(async () => {
  845. defCon.fetchResult = "Jsdelivr - Failed to fetch";
  846. error(defCon.fetchResult);
  847. });
  848. }
  849. // Set value with expire
  850. if (t !== undefined) {
  851. GMsetExpire("_Check_Version_Expire_", t);
  852. debug("//-> %ccheckVersion: Loading Data from Server.", "background-color:darkorange;color:snow");
  853. } else {
  854. console.error(
  855. "%c[GB-Update]\n%cSome unknown exceptions cause version detection failure, most likely by a network error. Please try again later.",
  856. "font-weight:bold;color:red",
  857. "font-weight:bold;color:darkred"
  858. );
  859. }
  860. } else {
  861. t = cache;
  862. debug("//-> %ccheckVersion: Loading Data from Cache.", "background-color:green;color:snow");
  863. }
  864. // Resolution return data
  865. if (typeof t !== "undefined") {
  866. const lastestVersion = defCon.decrypt(t[1]);
  867. defCon.isNoticed = Boolean(await GMgetExpire("_nCount_", _expire_time_));
  868. defCon.isNeedUpdate = cache ? compareVersion(defCon.curVersion, lastestVersion) : t[0];
  869. const updateNote = ((w = "") => {
  870. if (defCon.decrypt(t[2])) {
  871. defCon
  872. .decrypt(t[2])
  873. .split(/\\n/)
  874. .forEach(item => {
  875. w += `<li>${item}</li>`;
  876. });
  877. }
  878. return w ? `<dd class="disappear"><ul>${w}</ul></dd>` : "";
  879. })();
  880. const updateUrl = defCon.decrypt(t[3]).replace("meta", "user");
  881. const recheckURLs = new URL(
  882. updateUrl
  883. .replace("raw.githubusercontent.com", "github.com")
  884. .replace("cdn.jsdelivr.net/gh", "gitee.com")
  885. .replace("@", "/")
  886. .replace("master", "blob/master")
  887. .replace(/code\/[^/]+\.js/, "")
  888. );
  889. let sourceSite = defCon.titleCase(recheckURLs.hostname).split(".")[0];
  890. sourceSite = cache ? `${sourceSite} on Cache` : sourceSite;
  891. const repo = cache
  892. ? `\nCache expire:${defCon.durationTime(defCon.restTime._Check_Version_Expire_)}\nDetect time: ${defCon.lastRuntime()}\n`
  893. : `\nExpire time: ${_expire_time_}\nDetect time: ${defCon.lastRuntime()}\n`;
  894. switch (defCon.isNeedUpdate) {
  895. case 2:
  896. if (window.self === window.top) {
  897. console.warn(
  898. String(
  899. `%c[GB-Update]%c\nWe found your local version %c${defCon.curVersion} %cis not current.\nPlease confirm whether you had edited your local script, then you need to update it manually.\n${repo}(${sourceSite})`
  900. ),
  901. "font-weight:bold;color:crimson",
  902. "color:0",
  903. "font-weight:bold;color:tomato",
  904. "color:0"
  905. );
  906. }
  907. if (!defCon.isNoticed || s || isdebug) {
  908. setTimeout(() => {
  909. GMnotification(
  910. Notice.noticeHTML(
  911. `<dt>${defCon.scriptName}</dt>
  912. <dd><span>发现版本异常</span>版本号 <i>${defCon.curVersion}</i> 错误。由于您手动编辑过本地脚本,为避免未知错误的出现,脚本将自动设置为禁止检测更新。</dd><dd style="text-align: center;margin-top:8px!important"><img src="https://z3.ax1x.com/2021/08/14/fyvfk6.png" alt="开启自动检测"></dd><dd style="color:lemonchiffon;font-style:italic">注:若要重新启用自动更新,您需要在<a href="${recheckURLs}" target="_blank" style="padding:0 2px;font-weight:700;color:gold">脚本源网站</a>覆盖安装正式版本后,从脚本菜单重新开启更新检测。</dd><dd>[ ${sourceSite} ]</dd>`
  913. ),
  914. `${Notice.error}`,
  915. true,
  916. 150,
  917. {
  918. onClose: [
  919. () => {
  920. location.reload();
  921. },
  922. ],
  923. }
  924. );
  925. }, 100);
  926. _data.VerDetAuto = false;
  927. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  928. GMsetExpire("_nCount_", true);
  929. }
  930. return false;
  931. case 1:
  932. if (window.self === window.top) {
  933. console.info(
  934. String(`%c[GB-Update]%c\nWe found a new version: %c${lastestVersion}%c.\nPlease upgrade from your update source to the latest version.${repo}(${sourceSite})`),
  935. "font-weight:bold;color:crimson",
  936. "color:0",
  937. "color:crimson",
  938. "color:0"
  939. );
  940. }
  941. if (!defCon.isNoticed || s || isdebug) {
  942. let showdDetail = "";
  943. if (updateNote) {
  944. showdDetail = `<dd onmouseover="this.previousElementSibling.previousElementSibling.style.display='block';this.style.display='none'" style="text-align:center">&gt;&gt; 查看更新内容 &lt;&lt;</dd>`;
  945. }
  946. setTimeout(() => {
  947. GMnotification(
  948. Notice.noticeHTML(
  949. `<dt>${defCon.scriptName}</dt>
  950. <dd><span>发现版本更新</span>最新版本 <i>${lastestVersion}</i>,如果您现在需要更新脚本,请点击这里完成升级安装。</dd>${updateNote}
  951. <dd>[ ${sourceSite} ]<kbd style="float:right;font-size:11px!important;">( 缓存时间:${defCon.showDate(_expire_time_)} )</kbd></dd>${showdDetail}`
  952. ),
  953. `${Notice.warning}`,
  954. false,
  955. 60,
  956. {
  957. onClick: [
  958. (n = 3) => {
  959. const w = window.open(updateUrl, "Update.Scripts");
  960. const t = setTimeout(() => {
  961. if (isGM) {
  962. window.opener = null;
  963. }
  964. w.close();
  965. }, n * 1e3);
  966. let p = n;
  967. const m = setInterval(() => {
  968. if (w.closed) {
  969. GMdeleteValue("_Check_Version_Expire_");
  970. GMnotification(
  971. Notice.noticeHTML(
  972. `<dd class="${Notice.center}">如果您已更新了脚本,请点击<a href="javascript:void(0)" onclick="location.replace(location.href.replace(/&zn=[^&]*/gi,'')+'&Zn=1')" class="im">这里</a>刷新使其生效。</a></dd>`
  973. ),
  974. `${Notice.info}`,
  975. true,
  976. 80
  977. );
  978. clearInterval(m);
  979. clearTimeout(t);
  980. }
  981. p ? --p : clearInterval(m);
  982. }, 1e3);
  983. },
  984. ],
  985. }
  986. );
  987. }, 100);
  988. GMsetExpire("_nCount_", true);
  989. }
  990. return false;
  991. default:
  992. if (window.self === window.top && (s || isdebug)) {
  993. console.info(
  994. `%c[GB-Update]%c\nCurretVersion: %c${defCon.curVersion}%c is up-to-date!${repo}(${sourceSite})`,
  995. "font-weight:bold;color:darkcyan",
  996. "color:0",
  997. "color:red",
  998. "color:0"
  999. );
  1000. setTimeout(() => {
  1001. GMnotification(
  1002. Notice.noticeHTML(
  1003. `<dt>${defCon.scriptName}</dt>
  1004. <dd><span>更新成功</span>当前版本 <i>${defCon.curVersion}</i> 已为最新!</dd>` +
  1005. String(defCon.isNeedUpdate === 3 ? `<dd style="color:yellow;font-style:italic">(注意:您的本地版本高于服务器版本,请核验)</dd>` : ``) +
  1006. `<dd>[ ${sourceSite} ]<kbd style="float:right;font-size:11px!important">( 缓存时间:${defCon.showDate(_expire_time_)} )</kbd></dd>`
  1007. ),
  1008. `${Notice.success}`,
  1009. false,
  1010. defCon.isNeedUpdate === 3 ? 50 : 30
  1011. );
  1012. GMdeleteValue("_nCount_");
  1013. }, 100);
  1014. }
  1015. return true;
  1016. }
  1017. }
  1018. }
  1019. } else {
  1020. if (window.self === window.top) {
  1021. console.log(`%c[GB-Update]%c\nUpdate detection has been ${!checkUpdate ? "manually" : "automatically"} turned off.`, "font-weight:bold;color:red", "color:0");
  1022. }
  1023. return false;
  1024. }
  1025. }
  1026.  
  1027. /* Menus & Button insert */
  1028.  
  1029. !(async function () {
  1030. let useBing, VerDetAuto, checkUpdate, timeNumber, timeUnit, GoogleJump, Hotkey, keywordHighlight, localWindow, _data;
  1031.  
  1032. /* Set Default Value & initialize */
  1033.  
  1034. const _configuration = await GMgetValue("_configuration_");
  1035. if (!_configuration) {
  1036. useBing = 0;
  1037. VerDetAuto = true;
  1038. checkUpdate = true;
  1039. timeNumber = 24;
  1040. timeUnit = "h";
  1041. GoogleJump = false;
  1042. Hotkey = true;
  1043. keywordHighlight = false;
  1044. localWindow = false;
  1045. _data = {
  1046. useBing,
  1047. VerDetAuto,
  1048. checkUpdate,
  1049. timeNumber,
  1050. timeUnit,
  1051. GoogleJump,
  1052. Hotkey,
  1053. keywordHighlight,
  1054. localWindow,
  1055. };
  1056. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  1057. } else {
  1058. _data = JSON.parse(defCon.decrypt(_configuration));
  1059. useBing = _data.useBing;
  1060. VerDetAuto = _data.VerDetAuto;
  1061. checkUpdate = _data.checkUpdate;
  1062. timeNumber = _data.timeNumber;
  1063. timeUnit = _data.timeUnit;
  1064. GoogleJump = _data.GoogleJump;
  1065. Hotkey = _data.Hotkey !== undefined ? _data.Hotkey : true;
  1066. keywordHighlight = _data.keywordHighlight;
  1067. localWindow = _data.localWindow;
  1068. }
  1069.  
  1070. const CONST = {
  1071. isSecurityPolicy: false,
  1072. rndidName: defCon.randString(9, true),
  1073. rndclassName: defCon.randString(12, true),
  1074. bdyx: defCon.randString(5, true),
  1075. ggyx: defCon.randString(5, true),
  1076. bbyx: defCon.randString(5, true),
  1077. scrollspan: defCon.randString(8, true),
  1078. scrollspan2: defCon.randString(8, true),
  1079. scrollbars: defCon.randString(8, true),
  1080. scrollbars2: defCon.randString(8, true),
  1081. isUseBing: Boolean(useBing),
  1082. isVDResult: checkUpdate ? Boolean(VerDetAuto) : false,
  1083. };
  1084. CONST.noticeCss = String(
  1085. `@charset "UTF-8";.${Notice.animated}{animation-duration:1s;animation-fill-mode:both}.${Notice.animated}.infinite{animation-iteration-count:infinite}.${Notice.animated}.hinge{animation-duration:2s}.${Notice.animated}.bounceIn,.${Notice.animated}.bounceOut,.${Notice.animated}.flipOutX,.${Notice.animated}.flipOutY{animation-duration:1.25s}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.fadeIn{animation-name:fadeIn}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.fadeOut{animation-name:fadeOut}#${CONST.rndidName} *,.${Notice.noticejs},.${Notice.noticejs} *{font-family:'Microsoft YaHei','Helvetica Neue',sans-serif!important;text-stroke:initial!important;-webkit-text-stroke:initial!important;text-shadow:initial!important}.${Notice.noticejs}-top{top:0;width:100%}.${Notice.noticejs}-top .${Notice.item}{border-radius:0!important;margin:0!important}.${Notice.noticejs}-topRight{top:10px;right:10px;z-index:10059!important}.${Notice.noticejs}-topLeft{top:10px;left:10px}.${Notice.noticejs}-topCenter{top:10px;left:50%;transform:translate(-50%)}.${Notice.noticejs}-middleLeft,.${Notice.noticejs}-middleRight{right:10px;top:50%;transform:translateY(-50%)}.${Notice.noticejs}-middleLeft{left:10px}.${Notice.noticejs}-middleCenter{top:50%;left:50%;transform:translate(-50%,-50%)}.${Notice.noticejs}-bottom{bottom:0;width:100%}.${Notice.noticejs}-bottom .${Notice.item}{border-radius:0!important;margin:0!important}.${Notice.noticejs}-bottomRight{bottom:10px;right:10px;z-index:10055!important}.${Notice.noticejs}-bottomLeft{bottom:10px;left:10px}.${Notice.noticejs}-bottomCenter{bottom:10px;left:50%;transform:translate(-50%)}.${Notice.noticejs}{font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.${Notice.noticejs} .${Notice.item}{margin:0 0 10px;border-radius:3px;overflow:hidden}` +
  1086. `.${Notice.noticejs} .${Notice.item} .${Notice.close}{float:right;font-size:18px!important;font-weight:700;line-height:1;color:#fff;text-shadow:0 1px 0 #fff;opacity:1;margin-right:7px}.${Notice.noticejs} .${Notice.item} .${Notice.close}:hover{opacity:.5;color:#000;cursor:pointer}.${Notice.noticejs} .${Notice.item} a{color:#fff;border-bottom:1px dashed #fff}.${Notice.noticejs} .${Notice.item} a,.${Notice.noticejs} .${Notice.item} a:hover{text-decoration:none}.${Notice.noticejs} .${Notice.success}{background-color:#64ce83}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-heading{background-color:#3da95c;color:#fff;padding:10px}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-body{color:#fff;padding:10px!important}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-body:hover{visibility:visible!important}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-content{visibility:visible}.${Notice.noticejs} .${Notice.info}{background-color:#3ea2ff}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-heading{background-color:#067cea;color:#fff;padding:10px}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-body{color:#fff;padding:10px!important}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-body:hover{visibility:visible!important}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-content{visibility:visible}.${Notice.noticejs} .${Notice.warning}{background-color:#ff7f48}.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-heading{background-color:#f44e06;color:#fff;padding:10px!important}.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-body{color:#fff;padding:10px}.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-body:hover{visibility:visible!important}.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-content{visibility:visible}.${Notice.noticejs} .${Notice.error}{background-color:#e74c3c}.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-heading{background-color:#ba2c1d;color:#fff;padding:10px!important}.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-body{color:#fff;padding:10px}.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-body:hover{visibility:visible!important}` +
  1087. `.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-content{visibility:visible}.${Notice.configuration} input[disabled],.${Notice.configuration} select[disabled]{color:#bbb;background:linear-gradient(45deg,#ffe9e9 0,#ffe9e9 25%,transparent 25%,transparent 50%,#ffe9e9 50%,#ffe9e9 75%,transparent 75%,transparent)!important;background-size:20px 20px!important;background-color:#fff7f7!important}.${Notice.noticejs} .${Notice.configuration}{background-color:linear-gradient(to right,#fcfcfc,#f2f2f7);background:-webkit-gradient(linear,0 0,0 100%,from(#fcfcfc),to(#f2f2f7));box-shadow:0 0 5px #888}.${Notice.noticejs} .${Notice.configuration} .${Notice.close}{float:right;font-size:18px!important;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #aaa;opacity:1;margin-right:7px}.${Notice.noticejs} .${Notice.configuration} .${Notice.close}:hover{opacity:.5;color:#555;cursor:pointer}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-heading{background-color:#F2F2F7;color:#333;padding:10px!important}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-body{color:#333;padding:10px}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-body ul{color:#333!important;list-style:none;margin:5px;padding:2px;font:italic 14px/140% "Microsoft YaHei",sans-serif}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-body ul ol{list-style:none;font-style:normal;margin:5px 0;cursor:default}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-body:hover{visibility:visible!important}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-content{visibility:visible}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-progressbar{width:100%;background-color:#64ce83;margin-top:-1px}.${Notice.noticejs} .${Notice.success} .${Notice.noticejs}-progressbar .${Notice.noticejs}-bar{width:100%;height:5px;background:#3da95c}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-progressbar{width:100%;background-color:#3ea2ff;margin-top:-1px}.${Notice.noticejs} .${Notice.info} .${Notice.noticejs}-progressbar .${Notice.noticejs}-bar{width:100%;height:5px;background:#067cea}.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-progressbar{width:100%;background-color:#ff7f48;margin-top:-1px}` +
  1088. `.${Notice.noticejs} .${Notice.warning} .${Notice.noticejs}-progressbar .${Notice.noticejs}-bar{width:100%;height:5px;background:#f44e06}.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-progressbar{width:100%;background-color:#e74c3c;margin-top:-1px}.${Notice.noticejs} .${Notice.error} .${Notice.noticejs}-progressbar .${Notice.noticejs}-bar{width:100%;height:5px;background:#ba2c1d}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-progressbar{width:100%;background-color:#efefef;margin-top:-1px}.${Notice.noticejs} .${Notice.configuration} .${Notice.noticejs}-progressbar .${Notice.noticejs}-bar{background:#ccc;width:100%;height:5px}@keyframes ${Notice.noticejs}-fadeOut{0%{opacity:1}to{opacity:0}}.${Notice.noticejs}-fadeOut{animation-name:${Notice.noticejs}-fadeOut}@keyframes ${Notice.noticejs}-modal-in{to{opacity:.3}}@keyframes ${Notice.noticejs}-modal-out{to{opacity:0}}.${Notice.noticejs}{position:fixed;z-index:10050}.${Notice.noticejs} ::-webkit-scrollbar{width:8px}.${Notice.noticejs} ::-webkit-scrollbar-button{width:8px;height:5px}.${Notice.noticejs} ::-webkit-scrollbar-track{border-radius:10px}.${Notice.noticejs} ::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.5);border-radius:10px}.${Notice.noticejs} ::-webkit-scrollbar-thumb:hover{background:#fff}.${Notice.noticejs}-modal{position:fixed;width:100%;height:100%;background-color:#000;z-index:999999;opacity:.3;left:0;top:0}.${Notice.noticejs}-modal-open{opacity:0;animation:${Notice.noticejs}-modal-in .3s ease-out}.${Notice.noticejs}-modal-close{animation:${Notice.noticejs}-modal-out .3s ease-out;animation-fill-mode:forwards}.${defCon.rName}{padding:2px!important}.${defCon.rName} dl{margin:0!important;padding:1px!important}.${defCon.rName} dl dt{margin:2px 0 6px 0!important;font-size:16px!important;font-weight:900!important}.${defCon.rName} dl dd{margin:2px 2px 0 0!important;font-size:14px!important;line-height:180%!important;margin-inline-start:10px!important}.${defCon.rName} .${Notice.center}{width:100%;text-align:center!important}.${defCon.rName} dl dd em{color:#fff;font-family:Candara,sans-serif!important;font-size:24px!important;padding:0 5px}.${defCon.rName} dl dd span{font-weight:700;font-size:15px!important;margin-right:8px}` +
  1089. `.${defCon.rName} dl dd i{font-family:Candara,sans-serif!important;font-size:20px!important}.${defCon.rName} dl dd .im{color:gold;font-size:16px!important;font-weight:900;padding:0 3px}.${defCon.rName} ul{width:90%;display:inline-block;text-align:left;vertical-align:top;color:rgba(255, 255, 255, 0.8);padding:0.2em;margin:0 0 0 1em;counter-reset:xxx 0}.${defCon.rName} li{list-style:none;font-style:italic!important;position:relative;padding:0 0 0 0.1em;margin:0 0 0 2px;-webkit-transition:.12s;transition:.12s}.${defCon.rName} li::before{content:counter(xxx,decimal) "、";counter-increment:xxx 1;font-family:Candara,sans-serif;font-size:1em;display:inline-block;width:1.5em;margin-left:-1.5em;-webkit-transition:.5s;transition:.5s}.${defCon.rName} .disappear{display:none}/* checkbox */.${Notice.checkbox}{display:none!important}.${Notice.checkbox}+label{cursor:pointer;padding:11px 9px;margin:0 0 0 25px;border-radius:7px;display:inline-block;position:relative;background:#f7836d;width:58px;height:10px;box-shadow:inset 0 0 20px rgba(0,0,0,.1),0 0 10px rgba(245,146,146,.4);-webkit-box-sizing:content-box;box-sizing:content-box;word-wrap:normal!important}.${Notice.checkbox}+label::before{position:absolute;top:0;left:0;z-index:99;-webkit-border-radius:7px;border-radius:7px;width:24px;height:32px;color:#fff;background:#fff;box-shadow:0 0 1px rgba(0,0,0,.6);content:" "}.${Notice.checkbox}+label::after{position:absolute;top:0;left:28px;-webkit-box-sizing:content-box;box-sizing:content-box;-webkit-border-radius:100px;border-radius:100px;padding:5px;font-size:1em;font-weight:700;color:#fff;content:"OFF"}.${Notice.checkbox}:checked+label{cursor:pointer;margin:0 0 0 25px;-webkit-box-sizing:content-box;box-sizing:content-box;background:#67a5df!important;box-shadow:inset 0 0 20px rgba(0,0,0,.1),0 0 10px rgba(146,196,245,.4)}` +
  1090. `.${Notice.checkbox}:checked+label::after{content:"ON";left:10px}.${Notice.checkbox}:checked+label::before{content:" ";position:absolute;z-index:99;left:52px}#${Notice.fcUpdate},#${Notice.fcExpire},#${Notice.fcGoogle},#${Notice.fchk},#${Notice.fcFeedback},#${Notice.fcKwhl},#${Notice.localWindow}{padding:2px 10px;height:36px;width:100%;font:bold 16px/140% "Microsoft YaHei",sans-serif}#${Notice.Expire}{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:4px;border-radius:4px;width:46px;padding:2px;height:30px;border:2px solid #777;background:#fff;font-size:15px!important;font-weight:normal;font-family:Impact,sans-serif!important;text-align:center}#${Notice.timeUnit}{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:4px;border-radius:4px;width:60px;height:30px;padding:2px;background:#fff;font-size:15px!important;font-weight:normal;font-family:"Microsoft YaHei",sans-serif!important;border:2px solid #777}#${Notice.fcFeedback} .${Notice.feedback}{cursor:help;font-weight:normal;font-size:16px!important;margin:0}#${Notice.fcFeedback} .${Notice.feedback}>span{font-size:16px!important;font-weight:700!important}#${Notice.fcFeedback} .${Notice.feedback}:hover{color:crimson}#${Notice.fcSubmit}{padding:2px 10px;height:30px;width:100%}#${Notice.fcSubmit} button{color:#333;font-weight:600;border:1px solid #777;font-size:16px!important;padding:5px 15px;margin-left:10px;border-radius:4px}#${Notice.fcSubmit} .${Notice.fcSave}{cursor:pointer;background-color:linear-gradient(to bottom,#fff7f7,#ffe9e9);background:-webkit-gradient(linear,0 0,0 100%,from(#fff7f7),to(#ffe9e9))}#${Notice.fcSubmit} .${Notice.fcClose}{cursor:pointer}`
  1091. );
  1092.  
  1093. let curretSite = {
  1094. SiteTypeID: 0,
  1095. SiteName: "",
  1096. SplitName: "",
  1097. MainType: "",
  1098. HtmlCode: "",
  1099. StyleType: "",
  1100. keyStyle: "",
  1101. };
  1102.  
  1103. const listSite = {
  1104. baidu: {
  1105. SiteTypeID: 1,
  1106. SiteName: "Baidu",
  1107. SplitName: "tn",
  1108. MainType: ".s_btn_wr",
  1109. HtmlCode: CONST.isUseBing
  1110. ? String(`
  1111. <span id="${CONST.ggyx}">
  1112. <input type="button" title="Google一下" value="Google"/>
  1113. </span>
  1114. <span id="${CONST.bbyx}">
  1115. <input type="button" title="Bing一下" value="Bing ®"/>
  1116. </span>`)
  1117. : String(`
  1118. <span id="${CONST.ggyx}">
  1119. <input type="button" title="Google一下" value="Google一下"/>
  1120. </span>`),
  1121. StyleCode: CONST.isUseBing
  1122. ? `#form{white-space:nowrap}#u{z-index:1!important}#${CONST.rndidName}{position:relative;z-index:999999}#${CONST.rndidName} #${CONST.bbyx}{margin-left:-1.5px}#${CONST.rndidName} #${CONST.ggyx}{margin-left:2px}#${CONST.bbyx} input{background:#4e6ef2;border-top-right-radius:10px;border-bottom-right-radius:10px;cursor:pointer;height:40px;color:#fff;width:80px;border:1px solid #3476d2;font-size:16px!important;font-weight:bold}#${CONST.ggyx} input{background:#4e6ef2;border-top-left-radius:10px;border-bottom-left-radius:10px;cursor:pointer;height:40px;color:#fff;width:80px;border:1px solid #3476d2;font-size:16px!important;font-weight:bold}#${CONST.ggyx} input:hover,#${CONST.bbyx} input:hover{background: #4662D9;border:1px solid #3476d2}`
  1123. : `#form{white-space:nowrap}#u{z-index:1!important}#${CONST.rndidName}{position:relative;margin-left:2px;z-index:999999999}#${CONST.ggyx} input{background:#4e6ef2;border-radius:10px;cursor:pointer;height:40px;color:#fff;width:112px;border:1px solid #3476d2;text-shadow:0 0 2px #ffffff!important;font-size:16px!important}#${CONST.ggyx} input:hover{background:#4662D9;border:1px solid #3476d2;}`,
  1124. keyStyle: keywordHighlight ? "#wrapper_wrapper em{color:#f73131!important;background-color:yellow!important;font-weight:900!important}" : "",
  1125. },
  1126. google: {
  1127. SiteTypeID: 2,
  1128. SiteName: "Google",
  1129. SplitName: "tbm",
  1130. MainType: "form button[type='submit']",
  1131. HtmlCode: CONST.isUseBing
  1132. ? String(`
  1133. <span id="${CONST.bdyx}">
  1134. <input type="button" title="百度一下" value="百度一下"/>
  1135. </span>
  1136. <span id="${CONST.bbyx}">
  1137. <input type="button" title="Bing一下" value="Bing一下"/>
  1138. </span>`)
  1139. : String(`
  1140. <span id="${CONST.bdyx}">
  1141. <input type="button" title="百度一下" value="百度一下"/>
  1142. </span>`),
  1143. StyleCode: CONST.isUseBing
  1144. ? `#${CONST.rndidName}{position:relative;margin:3px 4px 0 -5px;z-index:100}#${CONST.rndidName} #${CONST.bdyx}{padding:5px 0 4px 18px;border-left:1px solid #ddd;}#${CONST.rndidName} #${CONST.bbyx}{margin-left:-2px}.${CONST.scrollspan}{display:inline-block;margin:0;min-height:26px}.${CONST.scrollbars}{display:inline-block;margin:0;height:26px!important;font-size:13px!important;font-weight:normal!important;text-shadow:0 0 1px #ffffff!important}.${CONST.scrollbars2}{display:inline-block;margin-top:-4px;height:30px!important;font-size:13px!important;font-weight:normal!important;text-shadow:0 0 1px #ffffff!important}#${CONST.bdyx} input{cursor:pointer;padding:1px 1px 1px 6px!important;border:1px solid transparent;background:#1a73e8;box-shadow:none;border-top-left-radius:24px;border-bottom-left-radius:24px;width:90px;height:38px;font-size:15px!important;font-weight:600;color:#fff;}#${CONST.bbyx} input{cursor:pointer;padding:1px 6px 1px 1px!important;border:1px solid transparent;background:#1a73e8;box-shadow:none;border-top-right-radius:24px;border-bottom-right-radius:24px;width:90px;height:38px;font-size:15px!important;font-weight:600;color:#fff;}#${CONST.bdyx} input:hover,#${CONST.bbyx} input:hover{background:#2b7de9;}`
  1145. : `#${CONST.rndidName}{position:relative;margin:3px 4px 0 -5px;z-index:100}#${CONST.rndidName} #${CONST.bdyx}{padding:5px 0 4px 18px;border-left:1px solid #ddd}.${CONST.scrollspan}{display:inline-block;margin:0;min-height:26px}.${CONST.scrollbars}{display:inline-block;margin:0;height:26px!important;font-size:13px!important;font-weight:normal!important; text-shadow:0 0 1px #fff!important}.${CONST.scrollbars2}{display:inline-block;margin-top:-4px;height:30px!important;font-size:13px!important;font-weight:normal!important;text-shadow:0 0 1px #fff!important}#${CONST.bdyx} input{cursor:pointer;border:1px solid transparent;background:#1a73e8;box-shadow:none;border-radius:24px;width:90px;height:38px;font-size:14px!important;font-weight:600;color:#fff;}#${CONST.bdyx} input:hover{background:#2b7de9;}`,
  1146. keyStyle: keywordHighlight
  1147. ? ".aCOpRe em,.aCOpRe a em,.yXK7lf em,.yXK7lf a em,.st em,.st a em,.c2xzTb b,em.qkunPe{color:#ea4335!important;background-color:yellow!important;font-weight:900!important}"
  1148. : "",
  1149. },
  1150. bing: {
  1151. SiteTypeID: 3,
  1152. SiteName: "Bing",
  1153. SplitName: "",
  1154. MainType: "#sb_search",
  1155. HtmlCode: CONST.isUseBing
  1156. ? String(`
  1157. <span id="${CONST.bdyx}">
  1158. <input type="button" title="百度一下" value="百度一下"/>
  1159. </span>
  1160. <span id="${CONST.ggyx}">
  1161. <input type="button" title="Google一下" value="Google"/>
  1162. </span>`)
  1163. : ``,
  1164. StyleCode: CONST.isUseBing
  1165. ? `#${CONST.rndidName}{position:relative;z-index:999;display:inline-block;height:40px;min-width:193px;width:max-content;vertical-align:top;margin:0 0 0 8px}#${CONST.bdyx},#${CONST.ggyx}{display:inline-block}#${CONST.rndidName} span>input{box-sizing:border-box;cursor:pointer;min-width:96px;height:40px;background-color:#f7faff;border:1px solid #0095B7;color:#0095B7;font:normal 900 16px/1.5 "Microsoft YaHei",sans-serif!important}#${CONST.bdyx} input{border-top-left-radius:24px;border-bottom-left-radius:24px;margin:0;padding:0 12px 0 18px}#${CONST.ggyx} input{border-top-right-radius:24px;border-bottom-right-radius:24px;margin:0 0 0 -3px;padding:0 18px 0 12px}.${CONST.scrollspan}{max-height:33px;margin:3px 3px 0 8px!important}.${CONST.scrollspan2}{max-height:30px;margin:5px 0 0 8px!important}.${CONST.scrollbars}{border-radius:4px!important;max-height:33px;padding:0 12px!important;margin-right:1px!important}.${CONST.scrollbars2}{max-height:30px}#${CONST.bdyx} input:hover,#${CONST.ggyx} input:hover{background-color:#fff;transition:border linear .1s,box-shadow linear .3s;box-shadow:1px 1px 8px #08748D;border:2px solid #0095B7;text-shadow:0 0 1px #0095B7!important;color:#0095B7}`
  1166. : ``,
  1167. keyStyle: keywordHighlight
  1168. ? String(
  1169. Number(GetUrlParam("ensearch")) || Number(getCookie("ENSEARCH"))
  1170. ? ".b_caption p strong, .b_caption .b_factrow strong, .b_secondaryText strong,th, h2 strong, h3 strong"
  1171. : "#sp_requery strong, #sp_recourse strong, #tile_link_cn strong, .b_ad .ad_esltitle~div strong, h2 strong, .b_caption p strong, .b_snippetBigText strong, .recommendationsTableTitle+.b_slideexp strong, .recommendationsTableTitle+table strong, .recommendationsTableTitle+ul strong, .pageRecoContainer .b_module_expansion_control strong, .b_rs strong, .b_rrsr strong, #dict_ans strong, .b_listnav>.b_ans_stamp>strong, .adltwrnmsg strong"
  1172. ) + "{font-weight:900!important;color:#c00!important;background-color:yellow!important}"
  1173. : "",
  1174. },
  1175. other: { SiteTypeID: 0 },
  1176. };
  1177.  
  1178. const newSiteType = {
  1179. BAIDU: listSite.baidu.SiteTypeID,
  1180. GOOGLE: listSite.google.SiteTypeID,
  1181. BING: listSite.bing.SiteTypeID,
  1182. OTHERS: 0,
  1183. };
  1184.  
  1185. debug("//-> initialized complete, start running...");
  1186.  
  1187. if (location.host.includes(".baidu.com")) {
  1188. // Includes baidu
  1189. curretSite = listSite.baidu;
  1190. } else if (location.host.includes(".bing.com")) {
  1191. // Includes bing
  1192. curretSite = listSite.bing;
  1193. } else if (/^([0-9a-z-]+\.)?google(\.[a-z]{2,3}){1,3}$/.test(location.host)) {
  1194. // Regular google
  1195. curretSite = listSite.google;
  1196. } else {
  1197. curretSite = listSite.other;
  1198. }
  1199.  
  1200. CONST.vim = GetUrlParam(curretSite.SplitName);
  1201.  
  1202. if (
  1203. (curretSite.SiteTypeID === newSiteType.GOOGLE && /^(lcl|flm|fin)$/.test(CONST.vim)) ||
  1204. (curretSite.SiteTypeID === newSiteType.BING && /^(maps)$/.test(CONST.vim)) ||
  1205. (curretSite.SiteTypeID === newSiteType.BAIDU && /^(news|vsearch|baiduimagedetail)$/.test(CONST.vim))
  1206. ) {
  1207. CONST.isSecurityPolicy = true;
  1208. }
  1209.  
  1210. /* insert Menus */
  1211.  
  1212. function addAction_Configure() {
  1213. if (!qS(`.${Notice.noticejs} .${Notice.configuration}`)) {
  1214. GMnotification(
  1215. Notice.noticeHTML(
  1216. `<dt style="color:darkred">
  1217. 搜索引擎跳转工具 设置
  1218. <span style="font:italic 14px/14px Candara,sans-serif!important">
  1219. (Version ${defCon.curVersion})
  1220. <span>
  1221. </dt>
  1222. <dd>
  1223. <ul id="${Notice.fc}">
  1224. <ol id="${Notice.fchk}">
  1225. <div style="float:left">键盘快捷键功能开关</div>
  1226. <div style="float:right;margin:-2px 2px 0 10px">
  1227. <input type="checkbox" id="${Notice.hotkey}" class="${Notice.checkbox}" ${Hotkey ? "checked" : ""} />
  1228. <label for="${Notice.hotkey}"></label>
  1229. </div>
  1230. </ol>
  1231. <ol id="${Notice.fcGoogle}">
  1232. <div style="float:left">Google 国际站跳转</div>
  1233. <div style="float:right;margin:-2px 2px 0 10px">
  1234. <input type="checkbox" id="${Notice.google}" class="${Notice.checkbox}" ${GoogleJump ? "checked" : ""} />
  1235. <label for="${Notice.google}"></label>
  1236. </div>
  1237. </ol>
  1238. <ol id="${Notice.localWindow}">
  1239. <div style="float:left">在当前浏览器窗口跳转</div>
  1240. <div style="float:right;margin:-2px 2px 0 10px">
  1241. <input type="checkbox" id="${Notice.lw}" class="${Notice.checkbox}" ${localWindow ? "checked" : ""} />
  1242. <label for="${Notice.lw}"></label>
  1243. </div>
  1244. </ol>
  1245. <ol id="${Notice.fcKwhl}">
  1246. <div style="float:left">搜索关键词高亮增强</div>
  1247. <div style="float:right;margin:-2px 2px 0 10px">
  1248. <input type="checkbox" id="${Notice.kwhl}" class="${Notice.checkbox}" ${keywordHighlight ? "checked" : ""} />
  1249. <label for="${Notice.kwhl}"></label>
  1250. </div>
  1251. </ol>
  1252. <ol id="${Notice.fcUpdate}">
  1253. <div style="float:left">更新检测(默认:开)</div>
  1254. <div style="float:right;margin:-2px 2px 0 10px">
  1255. <input type="checkbox" id="${Notice.isUpdate}" class="${Notice.checkbox}" ${checkUpdate ? "checked" : ""} />
  1256. <label for="${Notice.isUpdate}"></label>
  1257. </div>
  1258. </ol>
  1259. <ol id="${Notice.fcExpire}">
  1260. <div>更新频率(分/时/天/周)
  1261. <input id="${Notice.Expire}" maxlength="3" placeholder="24" value="${timeNumber}"/>
  1262. <select id="${Notice.timeUnit}" style="cursor:pointer">
  1263. <option ${timeUnit === "m" ? "selected" : ""} value ="m">分钟</option>
  1264. <option ${timeUnit === "h" ? "selected" : ""} value ="h">小时</option>
  1265. <option ${timeUnit === "d" ? "selected" : ""} value="d">天</option>
  1266. <option ${timeUnit === "w" ? "selected" : ""} value="w">周</option>
  1267. </select>
  1268. </div>
  1269. </ol>
  1270. <ol id="${Notice.fcFeedback}">
  1271. <div class="${Notice.feedback}">\ud83e\udde1<span>\u0020如果您遇到问题,请向我反馈\u0020</span>\ud83e\udde1</div>
  1272. </ol>
  1273. <ol id="${Notice.fcSubmit}">
  1274. <button class="${Notice.fcClose}">关闭</button>
  1275. <button class="${Notice.fcSave}">保存</button>
  1276. </ol>
  1277. </ul>
  1278. </dd>`
  1279. ),
  1280. `${Notice.configuration}`,
  1281. true,
  1282. 600,
  1283. {},
  1284. "topRight"
  1285. );
  1286. if (!qS(`#${Notice.isUpdate}`).checked) {
  1287. qS(`#${Notice.Expire}`).setAttribute("disabled", "disabled");
  1288. qS(`#${Notice.timeUnit}`).setAttribute("disabled", "disabled");
  1289. }
  1290. qS(`#${Notice.isUpdate}`).addEventListener("change", function () {
  1291. if (this.checked) {
  1292. qS(`#${Notice.Expire}`).removeAttribute("disabled");
  1293. qS(`#${Notice.timeUnit}`).removeAttribute("disabled");
  1294. } else {
  1295. qS(`#${Notice.Expire}`).setAttribute("disabled", "disabled");
  1296. qS(`#${Notice.timeUnit}`).setAttribute("disabled", "disabled");
  1297. }
  1298. });
  1299. qS(`#${Notice.Expire}`).addEventListener("input", function () {
  1300. this.value = this.value.replace(/[^0-9]/g, "");
  1301. });
  1302. qS(`#${Notice.fcFeedback} .${Notice.feedback}`).addEventListener("click", () => {
  1303. GMopenInTab(`${defCon.support ? defCon.support : "https://greasyfork.org/scripts/12909/feedback"}`, defCon.options);
  1304. });
  1305. qS(`#${Notice.fcSubmit} .${Notice.fcClose}`).addEventListener("click", () => {
  1306. qS(`.${Notice.noticejs} .${Notice.configuration} .${Notice.close}`).click();
  1307. });
  1308. qS(`#${Notice.fcSubmit} .${Notice.fcSave}`).addEventListener("click", () => {
  1309. try {
  1310. const GoogleJump = qS(`#${Notice.google}`).checked;
  1311. const isHotkey = qS(`#${Notice.hotkey}`).checked;
  1312. const keywordHighlight = qS(`#${Notice.kwhl}`).checked;
  1313. const checkUpdate = qS(`#${Notice.isUpdate}`).checked;
  1314. const localWindow = qS(`#${Notice.lw}`).checked;
  1315. let timeNumber = qS(`#${Notice.Expire}`).value;
  1316. let timeUnit = qS(`#${Notice.timeUnit}`).value;
  1317. _data.checkUpdate = checkUpdate;
  1318. _data.timeNumber = timeNumber.length ? Number(timeNumber) : 24;
  1319. _data.timeUnit = timeUnit.length ? timeUnit : "h";
  1320. _data.GoogleJump = GoogleJump;
  1321. _data.Hotkey = isHotkey;
  1322. _data.keywordHighlight = keywordHighlight;
  1323. _data.localWindow = localWindow;
  1324. if (!checkUpdate) {
  1325. GMdeleteValue("_Check_Version_Expire_");
  1326. }
  1327. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  1328. qS(`.${Notice.noticejs} .${Notice.configuration} .${Notice.close}`).click();
  1329. GMnotification(
  1330. Notice.noticeHTML(`<dd class="${Notice.center}">设置数据已<kbd class="im">成功保存</kbd>,网页在<em>3</em>秒后刷新!</dd>`),
  1331. `${Notice.info}`,
  1332. true,
  1333. 30,
  1334. callback_Countdown
  1335. );
  1336. } catch (e) {
  1337. error("//-> configuration:", e);
  1338. }
  1339. });
  1340. }
  1341. }
  1342.  
  1343. const isMac = getBrowser.type("system") === "MacOS";
  1344.  
  1345. const menuManager = {
  1346. inUse_switch: (_status, _data, Tips) => {
  1347. const info = x => {
  1348. return Notice.noticeHTML(`<dd class="${Notice.center}">${Tips}已<kbd class="im">${x}</kbd>,网页在<em>3</em>秒后刷新!</dd>`);
  1349. };
  1350. _data.useBing = !_status;
  1351. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  1352. if (_status) {
  1353. GMnotification(info("\u6e05\u9664"), `${Notice.info}`, true, 30, callback_Countdown);
  1354. } else {
  1355. GMnotification(info("\u6dfb\u52a0"), `${Notice.info}`, true, 30, callback_Countdown);
  1356. }
  1357. },
  1358.  
  1359. menuRemove: t => {
  1360. if (t) {
  1361. GMunregisterMenuCommand(t);
  1362. }
  1363. },
  1364.  
  1365. registerMenuCommand: function (e) {
  1366. let _Use_Bing__, in_Use_Configure, _use_Bing_ID, in_UpdateCheck_ID;
  1367.  
  1368. this.menuRemove(_use_Bing_ID);
  1369. this.menuRemove(in_Use_Configure);
  1370. this.menuRemove(in_UpdateCheck_ID);
  1371.  
  1372. in_Use_Configure = GMregisterMenuCommand(`\ufff0\ud83c\udfaf【脚本参数】功能设置开关(${isMac ? "Y" : "E"})`, () => {
  1373. addAction_Configure();
  1374. });
  1375. _Use_Bing__ = e ? "\ufff2\u2714\ufe0f【已开启】" : "\ufff2\u274c【已关闭】";
  1376. _use_Bing_ID = GMregisterMenuCommand(`${_Use_Bing__}Bing 搜索跳转(B)`, () => {
  1377. if (Date.now() - defCon.timer > 4e3) {
  1378. this.inUse_switch(e, _data, "Bing 按钮");
  1379. defCon.timer = Date.now();
  1380. }
  1381. });
  1382.  
  1383. if (checkUpdate) {
  1384. if (CONST.isVDResult) {
  1385. in_UpdateCheck_ID = GMregisterMenuCommand(`\ufff5\ud83e\udded【版本更新】从服务器实时检查(${isMac ? "L" : "V"})`, async () => {
  1386. if (Date.now() - defCon.timer > 30e3) {
  1387. GMdeleteValue("_Check_Version_Expire_");
  1388. debug("//-> up-to-date? ", Boolean(await checkVersion(checkUpdate)));
  1389. defCon.timer = Date.now();
  1390. } else {
  1391. const remainTimer = 30 - Math.floor((Date.now() - defCon.timer) / 1e3);
  1392. GMnotification(Notice.noticeHTML(`<dd>更新检测过于频繁,服务器受不鸟啦,请${remainTimer}秒后重试!</dd>`), `${Notice.info}`, false, 15);
  1393. }
  1394. });
  1395. } else {
  1396. in_UpdateCheck_ID = GMregisterMenuCommand(`\ufff5\ud83d\udcdb【版本更新】已关闭 \u267b 重新开启(${isMac ? "L" : "V"})`, () => {
  1397. if (Date.now() - defCon.timer > 4e3) {
  1398. _data.VerDetAuto = true;
  1399. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  1400. GMdeleteValue("_Check_Version_Expire_");
  1401. GMdeleteValue("_nCount_");
  1402. debug("//-> Destroy cache & session when restart detection.");
  1403. GMnotification(
  1404. Notice.noticeHTML(`<dd class="${Notice.center}">更新检测已<kbd class="im">开启</kbd>,网页在<em>3</em>秒后刷新!</dd>`),
  1405. `${Notice.info}`,
  1406. true,
  1407. 30,
  1408. callback_Countdown
  1409. );
  1410. defCon.timer = Date.now();
  1411. }
  1412. });
  1413. }
  1414. }
  1415. },
  1416.  
  1417. menuDisplay: function () {
  1418. if (!CONST.isSecurityPolicy) {
  1419. this.registerMenuCommand(CONST.isUseBing);
  1420. }
  1421. if (window.self === window.top) {
  1422. console.log(
  1423. "%c[GB-Status]%c\nInsert the Bing Search Button: %c%s",
  1424. "font-weight:bold;color:darkorange",
  1425. "color:0",
  1426. "font-weight:bold;color:red",
  1427. defCon.titleCase(CONST.isUseBing && !CONST.isSecurityPolicy)
  1428. );
  1429. }
  1430. },
  1431.  
  1432. init: function () {
  1433. this.menuDisplay();
  1434. },
  1435. };
  1436.  
  1437. /* hotkey setting */
  1438.  
  1439. if (Hotkey) {
  1440. document.addEventListener("keydown", async event => {
  1441. const e = event || window.Event;
  1442. const ekey = (isMac ? e.metaKey : e.altKey) && !e.ctrlKey && !e.shiftKey;
  1443. if (e.keyCode === (isMac ? 89 : 69) && ekey) {
  1444. e.preventDefault();
  1445. if (Date.now() - defCon.timer > 1e3) {
  1446. defCon.timer = Date.now();
  1447. addAction_Configure();
  1448. }
  1449. }
  1450. if (e.keyCode === 66 && ekey) {
  1451. e.preventDefault();
  1452. if (Date.now() - defCon.timer > 4e3) {
  1453. defCon.timer = Date.now();
  1454. menuManager.inUse_switch(CONST.isUseBing, _data, "Bing 按钮");
  1455. }
  1456. }
  1457. if (e.keyCode === (isMac ? 76 : 86) && ekey && checkUpdate) {
  1458. e.preventDefault();
  1459. if (Date.now() - defCon.timer > 30e3) {
  1460. defCon.timer = Date.now();
  1461. if (CONST.isVDResult) {
  1462. GMdeleteValue("_Check_Version_Expire_");
  1463. debug("//-> up-to-date? ", Boolean(await checkVersion(checkUpdate)));
  1464. } else {
  1465. _data.VerDetAuto = true;
  1466. GMsetValue("_configuration_", defCon.encrypt(JSON.stringify(_data)));
  1467. GMdeleteValue("_Check_Version_Expire_");
  1468. GMdeleteValue("_nCount_");
  1469. debug("//-> Destroy cache & session when restart detection.");
  1470. GMnotification(
  1471. Notice.noticeHTML(`<dd class="${Notice.center}">更新检测已<kbd class="im">开启</kbd>,网页在<em>3</em>秒后刷新!</dd>`),
  1472. `${Notice.info}`,
  1473. true,
  1474. 30,
  1475. callback_Countdown
  1476. );
  1477. }
  1478. } else {
  1479. const remainTimer = 30 - Math.floor((Date.now() - defCon.timer) / 1e3);
  1480. GMnotification(Notice.noticeHTML(`<dd>你的快捷键按得太快了,我受不鸟啦……请慢点儿!(${remainTimer})</dd>`), `${Notice.info}`, false, 20);
  1481. }
  1482. }
  1483. });
  1484. }
  1485.  
  1486. /* Insert search Button */
  1487.  
  1488. const searchManager = {
  1489. insertCSS: () => {
  1490. try {
  1491. const doStyName = `${CONST.rndclassName}`;
  1492. const doStyle = CONST.noticeCss + curretSite.StyleCode + curretSite.keyStyle;
  1493. addStyle(doStyle, doStyName, "head");
  1494. } catch (e) {
  1495. error("//-> %csearchManager.insertCSS:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  1496. }
  1497. },
  1498.  
  1499. insertSearchButton: () => {
  1500. try {
  1501. const getTarget = curretSite.MainType;
  1502. const doHtml = curretSite.HtmlCode;
  1503. const indexPage = location.pathname === "/";
  1504. const userSpan = cE("span");
  1505. userSpan.id = `${CONST.rndidName}`;
  1506. userSpan.innerHTML = doHtml;
  1507. const SpanID = `#${userSpan.id}`;
  1508. let Target = qS(getTarget);
  1509. if (!indexPage && Target) {
  1510. if (!qS(SpanID) && getSearchValue()) {
  1511. if (/^(nws|vid|bks)$/.test(CONST.vim.trim())) {
  1512. Target = Target.parentNode.parentNode.firstChild;
  1513. Target.insertBefore(userSpan, Target.firstChild);
  1514. if (qS(SpanID)) {
  1515. qS(SpanID).setAttribute("style", "float:right");
  1516. }
  1517. } else if (curretSite.SiteTypeID === newSiteType.BING) {
  1518. if (CONST.isUseBing) {
  1519. Target.appendChild(userSpan);
  1520. if (Target.parentNode.childNodes[0].tagName === "INPUT") {
  1521. Target.parentNode.childNodes[0].style.width = "400px";
  1522. }
  1523. // Bing image fixed
  1524. if (qS(".b_searchboxForm") && /^images$/.test(CONST.vim.trim())) {
  1525. if (location.search.includes("view=detailV2") && CONST.isUseBing) {
  1526. qS(".b_searchboxForm").setAttribute("style", "width:max-content!important;padding-right:5px!important");
  1527. document.querySelectorAll(`#${CONST.rndidName} input`).forEach(item => {
  1528. item.style.cssText += "height:36px!important;border-radius:6px!important;padding:0 12px!important;margin:2px -2px 0 0!important;";
  1529. });
  1530. }
  1531. }
  1532. }
  1533. } else {
  1534. insterAfter(userSpan, Target);
  1535. // Baidu image fixed
  1536. if (qS(SpanID) && /^baiduimage$/.test(CONST.vim.trim())) {
  1537. qS(SpanID).setAttribute("style", "margin-left:12px");
  1538. }
  1539. // Google fixed
  1540. if (curretSite.SiteTypeID === newSiteType.GOOGLE) {
  1541. qS(SpanID).parentNode.style.width = "100%";
  1542. qS(SpanID).parentNode.style.minWidth = "max-content";
  1543. }
  1544. }
  1545.  
  1546. debug(`//-> searchManager $(Target): ${Target}`);
  1547.  
  1548. document.querySelectorAll(`#${CONST.ggyx}, #${CONST.bbyx}, #${CONST.bdyx}`).forEach(per => {
  1549. per.addEventListener("click", () => {
  1550. let gotoUrl = "about:blank";
  1551. switch (per.id) {
  1552. case `${CONST.ggyx}`:
  1553. if (/^(baiduimage|images)$/.test(CONST.vim.trim())) {
  1554. gotoUrl = "https://www.google.com/search?hl=zh-CN&source=lnms&tbm=isch&sa=X&q=";
  1555. } else {
  1556. gotoUrl = "https://www.google.com/search?hl=zh-CN&source=hp&newwindow=1&q=";
  1557. }
  1558. break;
  1559. case `${CONST.bbyx}`:
  1560. if (/^(isch|baiduimage)$/.test(CONST.vim.trim())) {
  1561. gotoUrl = "https://cn.bing.com/images/search?first=1&tsc=ImageBasicHover&q=";
  1562. } else {
  1563. gotoUrl = "https://cn.bing.com/search?q=";
  1564. }
  1565. break;
  1566. case `${CONST.bdyx}`:
  1567. if (/^(images|isch)$/.test(CONST.vim.trim())) {
  1568. gotoUrl = "https://image.baidu.com/search/index?tn=baiduimage&ps=1&ie=utf-8&word=";
  1569. } else {
  1570. gotoUrl = "https://www.baidu.com/s?ie=utf-8&rqlang=cn&wd=";
  1571. }
  1572. break;
  1573. default:
  1574. break;
  1575. }
  1576. if (localWindow) {
  1577. top.location.href = decodeURI(gotoUrl + getSearchValue());
  1578. } else {
  1579. GMopenInTab(decodeURI(gotoUrl + getSearchValue()), defCon.options);
  1580. }
  1581. });
  1582. });
  1583. }
  1584. }
  1585. } catch (e) {
  1586. error("//-> %csearchManager.insertSearchButton:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  1587. }
  1588. },
  1589.  
  1590. scrollDetect: () => {
  1591. let scrollbars, height, e;
  1592. const getTarget = curretSite.MainType;
  1593. const indexPage = location.pathname === "/";
  1594. if (!indexPage && qS(getTarget)) {
  1595. switch (curretSite.SiteTypeID) {
  1596. case newSiteType.GOOGLE:
  1597. // Google image fixed
  1598. e = /^isch$/.test(CONST.vim.trim());
  1599. scrollbars = e ? `${CONST.scrollbars2}` : `${CONST.scrollbars}`;
  1600. height = e ? -14 : 35;
  1601. scrollButton(`#${CONST.rndidName}`, `${CONST.scrollspan}`, height);
  1602. scrollButton(`#${CONST.rndidName} #${CONST.bdyx} input`, scrollbars, height);
  1603. if (CONST.isUseBing) {
  1604. scrollButton(`#${CONST.rndidName} #${CONST.bbyx} input`, scrollbars, height);
  1605. }
  1606. break;
  1607. case newSiteType.BING:
  1608. if (CONST.isUseBing) {
  1609. const spanCssName = /^(images|videos)$/.test(CONST.vim.trim()) ? CONST.scrollspan : CONST.scrollspan2;
  1610. const barsCssName = /^(images|videos)$/.test(CONST.vim.trim()) ? CONST.scrollbars : CONST.scrollbars2;
  1611. scrollButton(`#${CONST.rndidName}`, `${spanCssName}`, 50);
  1612. scrollButton(`#${CONST.rndidName} #${CONST.bdyx} input`, `${barsCssName}`, 50);
  1613. scrollButton(`#${CONST.rndidName} #${CONST.ggyx} input`, `${barsCssName}`, 50);
  1614. } else {
  1615. debug(`//-> No scrolling detecting.`);
  1616. }
  1617. break;
  1618. default:
  1619. debug(`//-> No scrolling detecting.`);
  1620. break;
  1621. }
  1622. }
  1623. },
  1624.  
  1625. startRAFInterval: function () {
  1626. RAFInterval(
  1627. () => {
  1628. if (!qS(`.${CONST.rndclassName}`)) {
  1629. this.insertCSS();
  1630. }
  1631. if (!qS(`#${CONST.rndidName}`)) {
  1632. this.insertSearchButton();
  1633. this.scrollDetect();
  1634. }
  1635. return qS(`.${CONST.rndclassName}`) && qS(`#${CONST.rndidName}`);
  1636. },
  1637. 200,
  1638. true
  1639. );
  1640. },
  1641.  
  1642. doSwitch: function () {
  1643. try {
  1644. if (curretSite.SiteTypeID !== newSiteType.OTHERS) {
  1645. if (CONST.isSecurityPolicy) {
  1646. if (window.self === window.top) {
  1647. console.log(
  1648. "%c[GB-Prohibit]%c\nBlocked By: %c%s Security Policy",
  1649. "font-weight:bold;color:indigo",
  1650. "color:0",
  1651. "font-weight:bold;color:darkred",
  1652. curretSite.SiteName
  1653. );
  1654. }
  1655. return;
  1656. } else {
  1657. this.startRAFInterval();
  1658. const callback = mutations => {
  1659. mutations.forEach(mutation => {
  1660. if (!(qS(`.${CONST.rndclassName}`) && qS(`#${CONST.rndidName}`))) {
  1661. debug(
  1662. "%c[GB-MutationObserver]\n%c(%c%s%c: %c%s%c)",
  1663. "font-weight:bold;color:olive",
  1664. "color:0",
  1665. "color:olive",
  1666. mutation.type,
  1667. "color:0",
  1668. "font-weight:bold;color:red",
  1669. defCon.titleCase(!this.startRAFInterval()),
  1670. "color:0"
  1671. );
  1672. }
  1673. });
  1674. };
  1675. const opts = { childList: true, subtree: true };
  1676. const observer = new MutationObserver(callback);
  1677. observer.observe(document, opts);
  1678. if (window.self === window.top) {
  1679. console.log(
  1680. "%c[GB-Switch]%c\nWe are using The %c%s%c Search Engine.",
  1681. "font-weight:bold;color:Green",
  1682. "color:0",
  1683. "font-weight:bold;color:darkcyan",
  1684. curretSite.SiteName,
  1685. "font-weight:normal;color:0"
  1686. );
  1687. }
  1688. }
  1689. }
  1690. } catch (e) {
  1691. error("//-> %csearchManager.doSwitch:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  1692. }
  1693. },
  1694.  
  1695. init: function () {
  1696. if (curretSite.SiteTypeID === newSiteType.GOOGLE) {
  1697. getGlobalGoogle("www.google.com", GoogleJump);
  1698. }
  1699. this.doSwitch();
  1700. },
  1701. };
  1702.  
  1703. /* important functions */
  1704.  
  1705. function getGlobalGoogle(google, checkGoogleJump) {
  1706. if (checkGoogleJump) {
  1707. if (getRealHostName() !== getRealHostName(google) && !sessionStorage.getItem("_global_google_")) {
  1708. sessionStorage.setItem("_global_google_", 1);
  1709. try {
  1710. setTimeout(() => {
  1711. defCon.s = GMopenInTab(`https://${google}/ncr`, true);
  1712. GMnotification(Notice.noticeHTML(`<dd class="${Notice.center}"><span>智能跳转</span>即将跳转至Google国际站:<br/>${google}</dd>`), `${Notice.info}`, true, 20, {
  1713. onClose: [
  1714. () => {
  1715. if (defCon.s) {
  1716. defCon.s.close();
  1717. }
  1718. location.href = top.location.href.replace(top.location.hostname, google);
  1719. },
  1720. ],
  1721. });
  1722. }, 500);
  1723. } catch (e) {
  1724. error("//-> getGlobalGoogle:", e);
  1725. }
  1726. }
  1727. }
  1728. }
  1729.  
  1730. function getRealHostName(_index) {
  1731. const index = _index ? _index : top.location.hostname;
  1732. return index.substring(index.indexOf("google"));
  1733. }
  1734.  
  1735. function scrollButton(paraName, classNameIn, scrollSize) {
  1736. debug(`//-> ${curretSite.SiteName} Scrolling Detecting: ${paraName}`);
  1737. const oDiv = qS(paraName);
  1738. let H = 0;
  1739. let Y = oDiv;
  1740. if (Y !== null) {
  1741. while (Y) {
  1742. H += Y.offsetTop;
  1743. Y = Y.offsetParent;
  1744. }
  1745. document.addEventListener("scroll", () => {
  1746. const s = document.body.scrollTop || document.documentElement.scrollTop;
  1747. debug(`//-> H=${H} S=${s} (${s - H})`);
  1748. if (s > H + scrollSize) {
  1749. oDiv.setAttribute("class", classNameIn);
  1750. } else {
  1751. oDiv.removeAttribute("class");
  1752. }
  1753. });
  1754. }
  1755. }
  1756.  
  1757. function insterAfter(newElement, targetElement) {
  1758. if (targetElement !== null) {
  1759. const parent = targetElement.parentNode;
  1760. if (parent.lastChild === targetElement) {
  1761. parent.appendChild(newElement);
  1762. } else {
  1763. parent.insertBefore(newElement, targetElement.nextSibling);
  1764. }
  1765. }
  1766. }
  1767.  
  1768. function addStyle(css, className, addToTarget, isReload = false, initType = "text/css", reNew = false) {
  1769. RAFInterval(
  1770. () => {
  1771. let addTo = qS(addToTarget);
  1772. if (typeof addToTarget === "undefined") {
  1773. addTo = document.head || document.body || document.documentElement || document;
  1774. }
  1775. if (typeof addToTarget === "undefined" || (typeof addToTarget !== "undefined" && qS(addToTarget))) {
  1776. if (isReload === true && qS(`.${className}`)) {
  1777. safeRemove(`.${className}`);
  1778. reNew = true;
  1779. } else if (isReload === false && qS(`.${className}`)) {
  1780. return true;
  1781. }
  1782. const cssNode = cE("style");
  1783. if (className !== null) {
  1784. cssNode.className = className;
  1785. }
  1786. cssNode.id = "S" + Date.now().toString().slice(-8);
  1787. cssNode.setAttribute("type", initType);
  1788. cssNode.innerHTML = css;
  1789. addTo.appendChild(cssNode);
  1790. if (reNew && qS(`.${className}`)) {
  1791. return true;
  1792. }
  1793. }
  1794. },
  1795. 20,
  1796. true
  1797. );
  1798. }
  1799.  
  1800. function safeRemove(Css) {
  1801. try {
  1802. const removeNodes = document.querySelectorAll(Css);
  1803. for (let i = 0; i < removeNodes.length; i++) {
  1804. removeNodes[i].remove();
  1805. }
  1806. } catch (e) {
  1807. error("//-> safeRemove:", e.name);
  1808. }
  1809. }
  1810.  
  1811. function getSearchValue(val) {
  1812. document.querySelectorAll('input[name="wd"], input[name="q"], input[name="word"]').forEach((item, index, arr) => {
  1813. val = arr[0].value;
  1814. if (val) {
  1815. debug(`//-> INPUT: ${val} - INDEX: ${index} - OLD: ${item.value}`);
  1816. }
  1817. });
  1818. if (val === null || val === "" || typeof val === "undefined") {
  1819. const kvl = location.search.substr(1).split("&");
  1820. if (kvl) {
  1821. for (let i = 0; i < kvl.length; i++) {
  1822. const value = kvl[i].replace(/^(wd|word|kw|query|q)=/, "");
  1823. if (value !== kvl[i]) {
  1824. val = value;
  1825. }
  1826. }
  1827. if (val) {
  1828. val = val.replace(/\+/g, " ");
  1829. debug(`//-> QUERY: ${val}`);
  1830. } else {
  1831. val = "";
  1832. error(`//-> QUERY is null`);
  1833. }
  1834. } else {
  1835. return "";
  1836. }
  1837. }
  1838. return encodeURIComponent(val);
  1839. }
  1840.  
  1841. function ContentSecurityPolicy() {
  1842. if (window.trustedTypes && window.trustedTypes.createPolicy) {
  1843. window.trustedTypes.createPolicy("default", {
  1844. createHTML: (string, sink) => {
  1845. return string;
  1846. },
  1847. });
  1848. }
  1849. }
  1850.  
  1851. function RAFInterval(callback, period, runNow, times = 0) {
  1852. const needCount = (period / 1000) * 60;
  1853. if (runNow === true) {
  1854. const shouldFinish = callback();
  1855. if (shouldFinish) {
  1856. return;
  1857. }
  1858. }
  1859. const step = () => {
  1860. if (times < needCount) {
  1861. times++;
  1862. requestAnimationFrame(step);
  1863. } else {
  1864. const shouldFinish = callback() || false;
  1865. if (!shouldFinish) {
  1866. times = 0;
  1867. requestAnimationFrame(step);
  1868. } else {
  1869. return;
  1870. }
  1871. }
  1872. };
  1873.  
  1874. requestAnimationFrame(step);
  1875. }
  1876.  
  1877. /* Let`s enjoy it! */
  1878.  
  1879. !(function () {
  1880. try {
  1881. debug("//-> Content-Security-Policy: trusted-types.");
  1882. ContentSecurityPolicy();
  1883. debug("//-> Insert Ext Menu.");
  1884. menuManager.init();
  1885. debug("//-> Insert Search Button.");
  1886. searchManager.init();
  1887. } catch (e) {
  1888. console.error("%c[GB-Error]%c\n%s", "font-weight:bold;color:red", "font-weight:bold;color:darkred", e);
  1889. }
  1890. })();
  1891. })();
  1892. })();