Google & baidu Switcher (ALL in One)

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

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

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