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