Google & baidu Switcher (ALL in One)

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

目前为 2021-06-14 提交的版本。查看 最新版本

  1. /* jshint esversion: 8 */
  2. // ==UserScript==
  3. // @name Google & baidu Switcher (ALL in One)
  4. // @name:en Google & baidu & Bing Switcher (ALL in One)
  5. // @name:zh-TW 谷歌、百度、必應的搜索引擎跳轉工具
  6. // @version 3.2.20210614.2
  7. // @author F9y4ng
  8. // @description 谷歌、百度、必应的搜索引擎跳转工具,脚本默认自动更新检测,可在菜单自定义设置必应按钮,搜索引擎跳转的最佳体验。
  9. // @description:en Google, Baidu and Bing search engine tool, Automatically updated and detected by default, The Bing button can be customized.
  10. // @description:zh-TW 谷歌、百度、必應的搜索引擎跳轉工具,腳本默認自動更新檢測,可在菜單自定義設置必應按鈕,搜索引擎跳轉的最佳體驗。
  11. // @namespace https://openuserjs.org/scripts/t3xtf0rm4tgmail.com/Google_baidu_Switcher_(ALL_in_One)
  12. // @supportURL https://github.com/F9y4ng/GreasyFork-Scripts/issues
  13. // @icon https://www.google.com/favicon.ico
  14. // @include *://*.google.*/search*
  15. // @include *://*.google.*/webhp*
  16. // @include *://www.baidu.com/*
  17. // @include *://ipv6.baidu.com/*
  18. // @include *://www1.baidu.com/*
  19. // @include *://image.baidu.com/*
  20. // @include *://*.bing.com/*
  21. // @exclude *://*.google.*/sorry*
  22. // @exclude *://*.google.*/url*
  23. // @exclude *://www.baidu.com/link*
  24. // @compatible Chrome 兼容TamperMonkey, ViolentMonkey
  25. // @compatible Firefox 兼容Greasemonkey4.0+, TamperMonkey, ViolentMonkey
  26. // @compatible Opera 兼容TamperMonkey, ViolentMonkey
  27. // @compatible Safari 兼容Tampermonkey • Safari
  28. // @note 紧急更新:修正更新检查缓存时间的永久化问题,此版本可永久固化过期时间不会因脚本升级而失效,脚本菜单中设有对应操作选项。
  29. // @grant GM_info
  30. // @grant GM_registerMenuCommand
  31. // @grant GM.registerMenuCommand
  32. // @grant GM_unregisterMenuCommand
  33. // @grant GM_openInTab
  34. // @grant GM_getValue
  35. // @grant GM.getValue
  36. // @grant GM_setValue
  37. // @grant GM.setValue
  38. // @grant GM_deleteValue
  39. // @grant GM.deleteValue
  40. // @license GPL-3.0-only
  41. // @create 2015-10-07
  42. // @copyright 2015-2021, F9y4ng
  43. // @run-at document-start
  44. // ==/UserScript==
  45.  
  46. !(function () {
  47. "use strict";
  48.  
  49. /* customize */
  50.  
  51. const isVersionDetection = true; // Set "false" to turn off the Version Detection forever.
  52. const isdebug = false; // set "true" to debug scripts, May cause script response slower.
  53.  
  54. /* The following variable is used to define the expiration time of version detection.
  55. * In order to reduce the query pressure on the script source server as much as possible,
  56. * Please don`t set the Query-cache expiration time too short. So we set 4 hours by default,
  57. * And to reduce update-tips frequency, you can extend the expireTime to a few days, or even weeks.
  58. * (s = second, m = minute, h = hour, d = day, w = week) */
  59.  
  60. const expireTime = "4h";
  61.  
  62. /* Perfectly Compatible For Greasemonkey4.0+, TamperMonkey, ViolentMonkey * F9y4ng * 20210609 */
  63.  
  64. let GMsetValue, GMgetValue, GMdeleteValue, GMregisterMenuCommand, GMunregisterMenuCommand, GMnotification, GMopenInTab;
  65. const GMinfo = GM_info;
  66. const handlerInfo = GMinfo.scriptHandler;
  67. const isGM = Boolean(handlerInfo.toLowerCase() === "greasemonkey");
  68. const debug = isdebug ? console.log.bind(console) : () => {};
  69. const error = isdebug ? console.error.bind(console) : () => {};
  70. const defCon = {
  71. scriptName: GMinfo.script.name,
  72. curVersion: GMinfo.script.version,
  73. support: GMinfo.script.supportURL,
  74. encrypt: n => {
  75. return window.btoa(encodeURIComponent(n));
  76. },
  77. decrypt: n => {
  78. return decodeURIComponent(window.atob(n));
  79. },
  80. fetchResult: "success",
  81. titleCase: (str, bool) => {
  82. // bool: true for Whole sentence.
  83. const RegExp = bool ? /( |^)[a-z]/g : /(^)[a-z]/g;
  84. return str
  85. .toString()
  86. .toLowerCase()
  87. .replace(RegExp, L => {
  88. return L.toUpperCase();
  89. });
  90. },
  91. isNoticed: sessionStorage.getItem("nCount") || 0,
  92. isNeedUpdate: 0,
  93. updateNote: "",
  94. restTime: 0,
  95. durationTime: t => {
  96. let w, d, h, m, s;
  97. const wks = Math.floor(t / 1000 / 60 / 60 / 24 / 7);
  98. const ds = Math.floor(t / 1000 / 60 / 60 / 24 - wks * 7);
  99. const hs = Math.floor(t / 1000 / 60 / 60 - wks * 7 * 24 - ds * 24);
  100. const ms = Math.floor(t / 1000 / 60 - wks * 7 * 24 * 60 - ds * 24 * 60 - hs * 60);
  101. const ss = Math.floor(t / 1000 - wks * 7 * 24 * 60 * 60 - ds * 24 * 60 * 60 - hs * 60 * 60 - ms * 60);
  102. wks > 0 ? (w = ` ${wks}wk`) : (w = "");
  103. ds > 0 ? (d = ` ${ds}d`) : (d = "");
  104. hs > 0 ? (h = ` ${hs}h`) : (h = "");
  105. ms > 0 ? (m = ` ${ms}min`) : (m = "");
  106. wks > 0 || ds > 0 || hs > 0 || ms > 0 ? (s = "") : ss > 0 ? (s = ` ${ss}s`) : (s = " Destroying cache.");
  107. return `${w}${d}${h}${m}${s}`;
  108. },
  109. showDate: s => {
  110. return s.replace(/w/i, " 周 ").replace(/d/i, " 天 ").replace(/h/i, " 小时 ").replace(/m/i, " 分钟 ").replace(/s/i, " 秒 ");
  111. },
  112. randString: (n, v, r, s = "") => {
  113. // v: true for only letters.
  114. let a = "0123456789";
  115. let b = "abcdefghijklmnopqrstuvwxyz";
  116. let c = b.toUpperCase();
  117. n = Number.isFinite(n) ? n : 10;
  118. v ? (r = b + c) : (r = a + b + a + c);
  119. for (; n > 0; --n) {
  120. s += r[Math.floor(Math.random() * r.length)];
  121. }
  122. return s;
  123. },
  124. isUpgrade: Boolean(GetUrlParam("Zn")),
  125. lastRuntime: new Date().toLocaleString("en-US", {
  126. timeZoneName: "short",
  127. hour12: false,
  128. }),
  129. };
  130. const _expireTime = /(?!^0)^[0-9]+[smhdw]$/i.test(expireTime) ? expireTime : "4h";
  131. defCon.rName = defCon.randString(7, true);
  132. defCon.noticeHTML = str => {
  133. return String(`<div class="${defCon.rName}"><dl>${str}<dl></div>`);
  134. };
  135.  
  136. if (isGM) {
  137. GMsetValue = GM.setValue;
  138. GMgetValue = GM.getValue;
  139. GMdeleteValue = GM.deleteValue;
  140. GMregisterMenuCommand = GM.registerMenuCommand;
  141. GMunregisterMenuCommand = () => {};
  142. GMopenInTab = (a, b) => {
  143. window.open(a, defCon.randString(b ? b.length : 10).slice(-6));
  144. };
  145. } else {
  146. GMsetValue = GM_setValue;
  147. GMgetValue = GM_getValue;
  148. GMdeleteValue = GM_deleteValue;
  149. GMregisterMenuCommand = GM_registerMenuCommand;
  150. GMunregisterMenuCommand = GM_unregisterMenuCommand;
  151. GMopenInTab = GM_openInTab;
  152. }
  153.  
  154. /* Refactoring functions of GMsetValue/GMgetValue/GMdeleteValue with Expire */
  155.  
  156. function GMsetExpire(key, value, expire) {
  157. let obj = {
  158. data: value,
  159. time: Date.now(),
  160. expire: /(?!^0)^[0-9]+[smhdw]$/i.test(expire) ? expire : "4h",
  161. };
  162. GMsetValue(key, JSON.stringify(obj));
  163. }
  164.  
  165. function GMgetExpire(key, val) {
  166. let expire, expires, expireTime;
  167. if (!val) {
  168. return val;
  169. }
  170. val = JSON.parse(val);
  171. if (val.expire) {
  172. /(?!^0)^[0-9]+[smhdw]$/i.test(val.expire) ? (expire = val.expire) : (expire = "4h");
  173. expire = expire
  174. .replace(/w/i, "*7*24*3600*1000")
  175. .replace(/d/i, "*24*3600*1000")
  176. .replace(/h/i, "*3600*1000")
  177. .replace(/m/i, "*60*1000")
  178. .replace(/s/i, "*1000");
  179. expires = expire.split("*");
  180. expireTime = expires.reduce(function (a, b) {
  181. return a * b;
  182. }, 1);
  183. }
  184. defCon.restTime = val.time + expireTime - Date.now();
  185. if (defCon.restTime <= 0) {
  186. GMdeleteValue(key);
  187. return null;
  188. }
  189. return val.data;
  190. }
  191.  
  192. /* Refactoring GMnotification Function */
  193.  
  194. GMnotification = (text = "", type = "info", closeWith = true, timeout = 30, { ...options } = {}) => {
  195. try {
  196. new NoticeJs({
  197. text: text,
  198. type: type,
  199. closeWith: closeWith ? ["button"] : ["click"],
  200. timeout: timeout,
  201. callbacks: { ...options },
  202. }).show();
  203. } catch (e) {
  204. error("//-> %cGMnotification:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  205. }
  206. };
  207.  
  208. const callback_Countdown = {
  209. onShow: [
  210. function (Interval = 3) {
  211. const m = setInterval(() => {
  212. Interval ? --Interval : clearInterval(m);
  213. const emText = document.querySelector(`.${defCon.rName} dl dd em`);
  214. if (emText) {
  215. emText.innerHTML = Interval;
  216. }
  217. }, 1e3);
  218. },
  219. ],
  220. };
  221.  
  222. /* Common functions */
  223.  
  224. function GetUrlParam(paraName) {
  225. if (!paraName) {
  226. const parameter = document.location.pathname.toString();
  227. const arr = parameter.split("/");
  228. return arr[1] === undefined ? "" : arr[1];
  229. } else {
  230. const url = document.location.toString();
  231. const arrObj = url.split("?");
  232. if (arrObj.length > 1) {
  233. const arrPara = arrObj[1].split("&");
  234. let arr;
  235. for (let i = 0; i < arrPara.length; i++) {
  236. arr = arrPara[i].split("=");
  237. if (arr !== null && arr[0] === paraName) {
  238. return arr[1];
  239. }
  240. }
  241. return "";
  242. } else {
  243. return "";
  244. }
  245. }
  246. }
  247.  
  248. function safeFunction(func) {
  249. try {
  250. func();
  251. } catch (e) {
  252. error("//-> %cFunctions:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  253. }
  254. }
  255.  
  256. /* SYSTEM INFO */
  257.  
  258. console.info(
  259. `%c[GB-Init]%c\nVersion: ${defCon.curVersion} %c[%s]%c\nExtension: %s\nlastRuntime: ${defCon.lastRuntime}`,
  260. "font-weight:bold;color:dodgerblue",
  261. "color:0",
  262. "color:snow",
  263. checkVersion(defCon.isUpgrade) instanceof Object === isVersionDetection,
  264. "color:0",
  265. defCon.titleCase(handlerInfo)
  266. );
  267.  
  268. /* Version Detection with Cache and timeout * F9y4ng * 20210614 */
  269.  
  270. function fetchTimeout(url, time, { ...options } = {}) {
  271. const controller = new AbortController();
  272. const signal = controller.signal;
  273. return new Promise((resolve, reject) => {
  274. let t = setTimeout(() => {
  275. controller.abort();
  276. resolve(new Response("timeout", { status: 504, statusText: `Request timeout. (User-Defined: ${time}ms)` }));
  277. }, time);
  278. fetch(url, { signal: signal, ...options }).then(
  279. res => {
  280. clearTimeout(t);
  281. resolve(res);
  282. },
  283. err => {
  284. clearTimeout(t);
  285. reject(err);
  286. }
  287. );
  288. });
  289. }
  290.  
  291. function fetchVersion(u) {
  292. return new Promise((e, t) => {
  293. fetchTimeout(u, 2000, {
  294. method: "GET",
  295. mode: "cors",
  296. cache: "no-store",
  297. credentials: "omit",
  298. })
  299. .then(e => {
  300. debug("//-> %c%s %s", "color:green", e.ok, e.status);
  301. if (!e.ok) {
  302. throw Error(`${e.status} ${e.statusText}`);
  303. }
  304. return e.text();
  305. })
  306. .then(t => {
  307. let n = defCon.curVersion;
  308. let m = defCon.updateNote;
  309. t.split(/[\r\n]+/).forEach(function (item) {
  310. let key = item.match(/^(\/\/\s+@version\s+)(\S+)$/);
  311. if (key) {
  312. n = key[2];
  313. }
  314. let note = item.match(/^(\/\/\s+@note\s+)(.+)$/);
  315. if (note) {
  316. m = note[2];
  317. }
  318. });
  319. e([compareVersion(defCon.curVersion, n), defCon.encrypt(n), defCon.encrypt(m), defCon.encrypt(u)]);
  320. })
  321. .catch(e => {
  322. error("//-> %cfetchVersion:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  323. t();
  324. });
  325. });
  326. }
  327.  
  328. function compareVersion(current, compare) {
  329. let compare_array = compare.split(".");
  330. let current_array = current.split(".");
  331. let upgradeID = 0;
  332. if (compare_array.length === current_array.length) {
  333. for (let i = 0; i < compare_array.length; i++) {
  334. if (parseInt(compare_array[i]) < parseInt(current_array[i])) {
  335. upgradeID = 2;
  336. break;
  337. } else {
  338. if (parseInt(compare_array[i]) === parseInt(current_array[i])) {
  339. continue;
  340. } else {
  341. upgradeID = 1;
  342. break;
  343. }
  344. }
  345. }
  346. } else {
  347. upgradeID = 2;
  348. }
  349. return upgradeID;
  350. }
  351.  
  352. async function checkVersion(s = false) {
  353. let t, setResult, info;
  354. const m = await GMgetValue("_is_Ver_Det_");
  355. isVersionDetection ? (setResult = m === undefined ? isVersionDetection : Boolean(m)) : (setResult = false);
  356. const _expire_time_ = await GMgetValue("_expire_time_");
  357. if (_expire_time_) {
  358. defCon._expireTime = _expire_time_;
  359. debug("//-> Load expireTime from cache.");
  360. } else {
  361. if (_expireTime !== "4h") {
  362. GMsetValue("_expire_time_", _expireTime);
  363. console.warn(`%c[GB-Update]%c\nThe expireTime is set to ${_expireTime}.`, "font-weight:bold;color:crimson", "color:0");
  364. }
  365. defCon._expireTime = _expireTime;
  366. }
  367. if (setResult) {
  368. // load cache
  369. const exp = await GMgetValue("_Check_Version_Expire_");
  370. const cache = GMgetExpire("_Check_Version_Expire_", exp);
  371. // Checking the local cache to reduce server requests
  372. if (!cache) {
  373. // first: greasyfork
  374. t = await fetchVersion(`https://greasyfork.org/scripts/12909/code/${defCon.randString(32)}.meta.js`).catch(async () => {
  375. defCon.fetchResult = "GreasyFork - Failed to fetch";
  376. error(defCon.fetchResult);
  377. });
  378. // second: github
  379. if (defCon.fetchResult.includes("GreasyFork")) {
  380. t = await fetchVersion(`https://raw.githubusercontent.com/F9y4ng/GreasyFork-Scripts/master/Google%20%26%20Baidu%20Switcher.meta.js`).catch(
  381. async () => {
  382. defCon.fetchResult = "Github - Failed to fetch";
  383. error(defCon.fetchResult);
  384. }
  385. );
  386. }
  387. // final: Jsdelivr points to gitee
  388. if (defCon.fetchResult.includes("Github")) {
  389. t = await fetchVersion(`https://cdn.jsdelivr.net/gh/F9y4ng/GreasyFork-Scripts@master/Google%20&%20Baidu%20Switcher.meta.js`).catch(
  390. async () => {
  391. defCon.fetchResult = "Jsdelivr - Failed to fetch";
  392. error(defCon.fetchResult);
  393. }
  394. );
  395. }
  396. // Set value with expire
  397. if (t !== undefined) {
  398. GMsetExpire("_Check_Version_Expire_", t, defCon._expireTime);
  399. debug("//-> checkVersion: Loading Data from Server.");
  400. } else {
  401. console.error(
  402. "%c[GB-Update]\n%cSome unknown exceptions cause version detection failure, most likely by a network error. Please try again.",
  403. "font-weight:bold;color:red",
  404. "font-weight:bold;color:darkred"
  405. );
  406. }
  407. } else {
  408. t = cache;
  409. debug("//-> checkVersion: Loading Data from Cache.");
  410. }
  411. // Resolution return data
  412. if (typeof t !== "undefined") {
  413. const lastestVersion = defCon.decrypt(t[1]);
  414. defCon.isNeedUpdate = cache ? compareVersion(defCon.curVersion, lastestVersion) : t[0];
  415. const updateNote = ((w = "") => {
  416. if (defCon.decrypt(t[2])) {
  417. defCon
  418. .decrypt(t[2])
  419. .split(/\\n/)
  420. .forEach(function (item) {
  421. w += `<li>${item}</li>`;
  422. });
  423. }
  424. return w ? `<dd class="disappear"><ul>${w}</ul></dd>` : "";
  425. })();
  426. const updateUrl = defCon.decrypt(t[3]).replace("meta", "user");
  427. const recheckURLs = new URL(
  428. updateUrl
  429. .replace("raw.githubusercontent", "github")
  430. .replace("cdn.jsdelivr.net/gh", "gitee.com")
  431. .replace("@", "/")
  432. .replace("master", "blob/master")
  433. .replace(/code\/[^/]+\.js/, "")
  434. );
  435. let sourceSite = defCon.titleCase(recheckURLs.hostname).split(".")[0];
  436. sourceSite = cache ? `${sourceSite} on Cache` : sourceSite;
  437. const repo = cache ? `\nCache expire:${defCon.durationTime(defCon.restTime)}\n` : `\n`;
  438.  
  439. switch (defCon.isNeedUpdate) {
  440. case 2:
  441. console.warn(
  442. String(
  443. `%c[GB-Update]%c\nWe found a new version, But %cthe latest version ` +
  444. `%c${lastestVersion}%c is lower than your local version %c${defCon.curVersion}.%c\n\n` +
  445. `Please confirm whether you need to upgrade your local script, and then you need to update it manually.\n\n` +
  446. `If you no longer need the update prompt, please set "isVersionDetection" to "false" in your local code!\n` +
  447. `${repo}(${sourceSite})`
  448. ),
  449. "font-weight:bold;color:crimson",
  450. "font-weight:bold;color:0",
  451. "color:0",
  452. "font-weight:bold;color:tomato",
  453. "color:0",
  454. "font-weight:bold;color:darkred",
  455. "color:0"
  456. );
  457. if (defCon.isNoticed < 2 || s) {
  458. setTimeout(function () {
  459. GMnotification(
  460. defCon.noticeHTML(
  461. `<dt>${defCon.scriptName}</dt>
  462. <dd><span>发现版本异常</span>检测到新版本 <i>${lastestVersion}</i> 低于您的本地版本 <i>${defCon.curVersion}</i>。</dd>\
  463. <dd>由于您编辑过本地脚本,或是手动在脚本网站上升级过新版本,从而造成缓存错误。为避免未知错误的出现,脚本将自动设置为禁止检测更新,\
  464. 直至您手动从脚本菜单中再次开启它。</dd><dd>[ ${sourceSite} ]</dd><dd style="font-size:12px!important;\
  465. color:lemonchiffon;font-style:italic">注:若要重新启用自动更新,您需要在<a href="${recheckURLs}"\
  466. target="_blank" style="padding:0 2px;font-size:14px;color:gold">脚本源网站</a>覆盖安装新版本后,从脚本菜单重新开启检测功能。</dd>\
  467. <dd style="text-align: center"><img src="https://i.niupic.com/images/2021/06/13/9kVe.png" alt="开启自动检测"></dd>`
  468. ),
  469. "error",
  470. true,
  471. 300,
  472. {
  473. onClose: [
  474. function () {
  475. location.reload();
  476. },
  477. ],
  478. }
  479. );
  480. }, 100);
  481. GMsetValue("_is_Ver_Det_", false);
  482. sessionStorage.setItem("nCount", ++defCon.isNoticed);
  483. }
  484. break;
  485. case 1:
  486. console.info(
  487. String(
  488. `%c[GB-Update]%c\nWe found a new version: %c${lastestVersion}%c.\n` +
  489. `Please upgrade from your update source to the latest version.` +
  490. `${repo}(${sourceSite})`
  491. ),
  492. "font-weight:bold;color:crimson",
  493. "color:0",
  494. "color:crimson",
  495. "color:0"
  496. );
  497. if (defCon.isNoticed < 2 || s) {
  498. let showdDetail = "";
  499. if (updateNote) {
  500. showdDetail = `<dd onmouseover="this.parentNode.children[2].style.display='block';\
  501. this.style.display='none'" style="text-align:center">&gt;&gt; 查看更新内容 &lt;&lt;</dd>`;
  502. }
  503. setTimeout(function () {
  504. GMnotification(
  505. defCon.noticeHTML(
  506. `<dt>${defCon.scriptName}</dt>\
  507. <dd><span>发现版本更新</span>最新版本 <i>${lastestVersion}</i>,如果您现在需要更新,请点击这里完成自动升级安装。</dd>\
  508. ${updateNote}<dd>[ ${sourceSite} ]</dd>${showdDetail}`
  509. ),
  510. "warning",
  511. false,
  512. 80,
  513. {
  514. onClick: [
  515. function () {
  516. const w = window.open(updateUrl, "Update.Scripts");
  517. setTimeout(() => {
  518. isGM ? (window.opener = null) : debug("Not Greasemonkey");
  519. w ? w.close() : debug("window not exsits.");
  520. // Destroy cache when upgraded.
  521. GMdeleteValue("_Check_Version_Expire_");
  522. debug("//-> Destroy cache when upgraded.");
  523. GMnotification(
  524. defCon.noticeHTML(
  525. `<dd>如果您已更新了脚本,请点击<a href="javascript:void(0)"\
  526. onclick="location.replace(location.href.replace(/&zn=[^&]*/i,'')+'&Zn=1')"\
  527. class="im">这里</a>刷新使其生效。</a></dd>`
  528. ),
  529. "info",
  530. true,
  531. 200
  532. );
  533. }, 2e3);
  534. },
  535. ],
  536. }
  537. );
  538. }, 100);
  539. sessionStorage.setItem("nCount", ++defCon.isNoticed);
  540. }
  541. break;
  542. default:
  543. s ? (info = console.info.bind(console)) : (info = debug.bind(console));
  544. info(
  545. `%c[GB-Update]%c\nCurretVersion: %c${defCon.curVersion}%c is up-to-date!${repo}(${sourceSite})`,
  546. "font-weight:bold;color:darkcyan",
  547. "color:0",
  548. "color:red",
  549. "color:0"
  550. );
  551. if (s) {
  552. GMnotification(
  553. defCon.noticeHTML(
  554. `<dt>${defCon.scriptName}</dt>\
  555. <dd><span>更新成功</span>当前版本 <i>${defCon.curVersion}</i> 已为最新!</dd>\
  556. <dd>[ ${sourceSite} ]</dd>`
  557. ),
  558. "success"
  559. );
  560. }
  561. break;
  562. }
  563. }
  564. } else {
  565. console.warn(
  566. `%c[GB-Update]%c\nVersion detection has been turned off forever, %cBye!`,
  567. "font-weight:bold;color:red",
  568. "color:0",
  569. "color:darkred"
  570. );
  571. }
  572. }
  573.  
  574. /* Menus & Button insert */
  575.  
  576. !(async function () {
  577. // Get Promise Value
  578. const is_Use_Bing = parseInt(await GMgetValue("_if_Use_Bing_"));
  579. const is_Ver_Det = await GMgetValue("_is_Ver_Det_");
  580.  
  581. /* Set Default Value & initialize */
  582.  
  583. const CONST = {
  584. isSecurityPolicy: false,
  585. rndidName: defCon.randString(9, true),
  586. rndclassName: defCon.randString(12, true),
  587. bdyx: defCon.randString(5, true),
  588. ggyx: defCon.randString(5, true),
  589. bbyx: defCon.randString(5, true),
  590. isUseBing: (() => {
  591. if (isNaN(is_Use_Bing)) {
  592. GMsetValue("_if_Use_Bing_", 0);
  593. console.warn(
  594. "%c[GB-Warning]%c\nThis is your first visit, the Bing search button will not be inserted by default.",
  595. "font-weight:bold;color:salmon",
  596. "color:1"
  597. );
  598. return false;
  599. } else {
  600. return Boolean(is_Use_Bing);
  601. }
  602. })(),
  603. isVDResult: isVersionDetection ? (is_Ver_Det === undefined ? isVersionDetection : Boolean(is_Ver_Det)) : false,
  604. noticeCss: `@charset "UTF-8";.animated{animation-duration:1s;animation-fill-mode:both}.animated.infinite{animation-iteration-count:infinite}.animated.hinge{animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{animation-duration:.75s}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.fadeIn{animation-name:fadeIn}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.fadeOut{animation-name:fadeOut}.noticejs-top{top:0;width:100%}.noticejs-top .item{border-radius:0!important;margin:0!important}.noticejs-topRight{top:10px;right:10px}.noticejs-topLeft{top:10px;left:10px}.noticejs-topCenter{top:10px;left:50%;transform:translate(-50%)}.noticejs-middleLeft,.noticejs-middleRight{right:10px;top:50%;transform:translateY(-50%)}.noticejs-middleLeft{left:10px}.noticejs-middleCenter{top:50%;left:50%;transform:translate(-50%,-50%)}.noticejs-bottom{bottom:0;width:100%}.noticejs-bottom .item{border-radius:0!important;margin:0!important}.noticejs-bottomRight{bottom:10px;right:10px}.noticejs-bottomLeft{bottom:10px;left:10px}.noticejs-bottomCenter{bottom:10px;left:50%;transform:translate(-50%)}.noticejs{z-index:99999!important;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.noticejs .item{margin:0 0 10px;border-radius:3px;overflow:hidden}.noticejs .item .close{float:right;font-size:18px;font-weight:700;line-height:1;color:#fff;text-shadow:0 1px 0 #fff;opacity:1;margin-right:7px}.noticejs .item .close:hover{opacity:.5;color:#000;cursor:pointer}.noticejs .item a{color:#fff;border-bottom:1px dashed #fff}.noticejs .item a,.noticejs .item a:hover{text-decoration:none}.noticejs .success{background-color:#64ce83}.noticejs .success .noticejs-heading{background-color:#3da95c;color:#fff;padding:10px}.noticejs .success .noticejs-body{color:#fff;padding:10px!important}.noticejs .success .noticejs-body:hover{visibility:visible!important}.noticejs .success .noticejs-content{visibility:visible}.noticejs .info{background-color:#3ea2ff}.noticejs .info .noticejs-heading{background-color:#067cea;color:#fff;padding:10px}.noticejs .info .noticejs-body{color:#fff;padding:10px!important}.noticejs .info .noticejs-body:hover{visibility:visible!important}.noticejs .info .noticejs-content{visibility:visible}.noticejs .warning{background-color:#ff7f48}.noticejs .warning .noticejs-heading{background-color:#f44e06;color:#fff;padding:10px!important}.noticejs .warning .noticejs-body{color:#fff;padding:10px}.noticejs .warning .noticejs-body:hover{visibility:visible!important}.noticejs .warning .noticejs-content{visibility:visible}.noticejs .error{background-color:#e74c3c}.noticejs .error .noticejs-heading{background-color:#ba2c1d;color:#fff;padding:10px!important}.noticejs .error .noticejs-body{color:#fff;padding:10px}.noticejs .error .noticejs-body:hover{visibility:visible!important}.noticejs .error .noticejs-content{visibility:visible}.noticejs .progressbar{width:100%}.noticejs .progressbar .bar{width:1%;height:30px;background-color:#4caf50}.noticejs .success .noticejs-progressbar{width:100%;background-color:#64ce83;margin-top:-1px}.noticejs .success .noticejs-progressbar .noticejs-bar{width:100%;height:5px;background:#3da95c}.noticejs .info .noticejs-progressbar{width:100%;background-color:#3ea2ff;margin-top:-1px}.noticejs .info .noticejs-progressbar .noticejs-bar{width:100%;height:5px;background:#067cea}.noticejs .warning .noticejs-progressbar{width:100%;background-color:#ff7f48;margin-top:-1px}.noticejs .warning .noticejs-progressbar .noticejs-bar{width:100%;height:5px;background:#f44e06}.noticejs .error .noticejs-progressbar{width:100%;background-color:#e74c3c;margin-top:-1px}.noticejs .error .noticejs-progressbar .noticejs-bar{width:100%;height:5px;background:#ba2c1d}@keyframes noticejs-fadeOut{0%{opacity:1}to{opacity:0}}.noticejs-fadeOut{animation-name:noticejs-fadeOut}@keyframes noticejs-modal-in{to{opacity:.3}}@keyframes noticejs-modal-out{to{opacity:0}}.noticejs{position:fixed;z-index:10050}.noticejs ::-webkit-scrollbar{width:8px}.noticejs ::-webkit-scrollbar-button{width:8px;height:5px}.noticejs ::-webkit-scrollbar-track{border-radius:10px}.noticejs ::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.5);border-radius:10px}.noticejs ::-webkit-scrollbar-thumb:hover{background:#fff}.noticejs-modal{position:fixed;width:100%;height:100%;background-color:#000;z-index:10000;opacity:.3;left:0;top:0}.noticejs-modal-open{opacity:0;animation:noticejs-modal-in .3s ease-out}.noticejs-modal-close{animation:noticejs-modal-out .3s ease-out;animation-fill-mode:forwards}.${defCon.rName}{padding:4px 4px 0 4px!important}.${defCon.rName} dl{margin:0!important;padding:2px!important}.${defCon.rName} dl dt{margin:2px 0 8px 0!important;font-size:16px!important;font-weight:900!important}.${defCon.rName} dl dd{margin:3px 6px 0 0!important;font-size:14px!important;line-height:180%!important;margin-inline-start:10px!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}.${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;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.5);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:'Roboto Condensed';font-size:1em;display:inline-block;width:1.5em;margin-left:-1.5em;-webkit-transition:.5s;transition:.5s}.${defCon.rName} .disappear{display:none}`,
  605. };
  606.  
  607. let curretSite = {
  608. SiteTypeID: 0,
  609. SiteName: "",
  610. SplitName: "",
  611. MainType: "",
  612. HtmlCode: "",
  613. StyleType: "",
  614. };
  615.  
  616. const listSite = {
  617. baidu: {
  618. SiteTypeID: 1,
  619. SiteName: "Baidu",
  620. SplitName: "tn",
  621. MainType: ".s_btn_wr",
  622. HtmlCode: CONST.isUseBing
  623. ? String(`
  624. <span id="${CONST.ggyx}">
  625. <input type="button" title="Google一下" value="Google"/>
  626. </span>
  627. <span id="${CONST.bbyx}">
  628. <input type="button" title="Bing一下" value="Bing ®"/>
  629. </span>`)
  630. : String(`
  631. <span id="${CONST.ggyx}">
  632. <input type="button" title="Google一下" value="Google一下"/>
  633. </span>`),
  634. StyleCode: CONST.isUseBing
  635. ? `#form{white-space:nowrap}#u{z-index:1!important}#${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;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;font-weight:bold}#${CONST.ggyx} input:hover,#${CONST.bbyx} input:hover{background: #4662D9;border:1px solid #3476d2}`
  636. : `#form{white-space:nowrap}#u{z-index:1!important}#${CONST.rndidName}{margin-left:6px}#${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}#${CONST.ggyx} input:hover{background:#4662D9;border:1px solid #3476d2;}`,
  637. },
  638. google: {
  639. SiteTypeID: 2,
  640. SiteName: "Google",
  641. SplitName: "tbm",
  642. MainType: "form button[type='submit']",
  643. HtmlCode: CONST.isUseBing
  644. ? String(`
  645. <span id="${CONST.bdyx}">
  646. <input type="button" title="百度一下" value="百度一下"/>
  647. </span>
  648. <span id="${CONST.bbyx}">
  649. <input type="button" title="Bing一下" value="Bing一下"/>
  650. </span>`)
  651. : String(`
  652. <span id="${CONST.bdyx}">
  653. <input type="button" title="百度一下" value="百度一下"/>
  654. </span>`),
  655. StyleCode: CONST.isUseBing
  656. ? `#${CONST.rndidName}{margin:3px 4px 0 -5px}#${CONST.rndidName} #${CONST.bdyx}{padding:5px 0 4px 18px;border-left:1px solid #ddd;}#${CONST.rndidName} #${CONST.bbyx}{margin-left:-2px}.scrollspan{display:block;margin: 3px 3px 0 0}.scrollbars{height:26px!important;font-size:13px!important;font-weight:normal!important;text-shadow:0 0 1px #ffffff!important}.scrollbars2{display:inline-block;margin-top:-3px;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;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;}`
  657. : `#${CONST.rndidName}{margin:3px 4px 0 -5px}#${CONST.rndidName} #${CONST.bdyx}{padding:5px 0 4px 18px;border-left:1px solid #ddd}.scrollspan{display:block;margin:3px 3px 0 0}.scrollbars{height:26px!important;font-size:13px!important;font-weight:normal!important; text-shadow:0 0 1px #fff!important}.scrollbars2{display:inline-block;margin-top:-3px;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;font-weight:600;color:#fff;}#${CONST.bdyx} input:hover{background:#2b7de9;}`,
  658. },
  659. bing: {
  660. SiteTypeID: 3,
  661. SiteName: "Bing",
  662. SplitName: "",
  663. MainType: "#sb_go_par",
  664. HtmlCode: CONST.isUseBing
  665. ? String(`
  666. <span id="${CONST.bdyx}">
  667. <input type="button" title="百度一下" value="百度"/>
  668. </span>
  669. <span id="${CONST.ggyx}">
  670. <input type="button" title="Google一下" value="Google"/>
  671. </span>`)
  672. : ``,
  673. StyleCode: CONST.isUseBing
  674. ? `#${CONST.rndidName}{height:44px;width:120px;margin:2px 5px 2px 0}#${CONST.bdyx} input,#${CONST.ggyx} input{cursor:pointer;width:auto 60px;height:40px;background-color:#f7faff;border:1px solid #0095B7;color:#0095B7;margin-left:-1px;font-family:"Microsoft YaHei",sans-serif!important;font-size:16px;font-weight:700;border-radius:4px}.scrollspan{height:32px!important}.scrollbars{height:30px!important;padding:4px}#${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;}`
  675. : ``,
  676. },
  677. other: { SiteTypeID: 0 },
  678. };
  679.  
  680. const newSiteType = {
  681. BAIDU: listSite.baidu.SiteTypeID,
  682. GOOGLE: listSite.google.SiteTypeID,
  683. BING: listSite.bing.SiteTypeID,
  684. OTHERS: 0,
  685. };
  686.  
  687. debug("//-> initialized complete, start running...");
  688.  
  689. if (location.host.includes(".baidu.com")) {
  690. // Includes baidu
  691. curretSite = listSite.baidu;
  692. } else if (location.host.includes(".bing.com")) {
  693. // Includes bing
  694. curretSite = listSite.bing;
  695. } else if (/^([0-9a-z-]+\.)?google(\.[a-z]{2,3}){1,3}$/.test(location.host)) {
  696. // Regular google
  697. curretSite = listSite.google;
  698. } else {
  699. curretSite = listSite.other;
  700. }
  701.  
  702. CONST.vim = GetUrlParam(curretSite.SplitName);
  703.  
  704. if (
  705. (curretSite.SiteTypeID === newSiteType.GOOGLE && /^(lcl|flm|fin)$/.test(CONST.vim)) ||
  706. (curretSite.SiteTypeID === newSiteType.BING && /^(maps)$/.test(CONST.vim)) ||
  707. (curretSite.SiteTypeID === newSiteType.BAIDU && /^(news|vsearch|baiduimagedetail)$/.test(CONST.vim))
  708. ) {
  709. CONST.isSecurityPolicy = true;
  710. }
  711.  
  712. /* insert Menus */
  713.  
  714. let menuManager = {
  715. inUse_switch: (_status, Name, Tips) => {
  716. const info = x => {
  717. return defCon.noticeHTML(`<dd>${Tips}已<a class="im">${x}</a>,网页将在<em>3</em>秒后自动刷新!</dd>`);
  718. };
  719. if (_status) {
  720. GMsetValue(`${Name}`, 0);
  721. GMnotification(info("\u6e05\u9664"), "info", true, 30, callback_Countdown);
  722. } else {
  723. GMsetValue(`${Name}`, 1);
  724. GMnotification(info("\u6dfb\u52a0"), "info", true, 30, callback_Countdown);
  725. }
  726. setTimeout(() => {
  727. location.reload();
  728. }, 3e3);
  729. },
  730.  
  731. menuRemove: t => {
  732. t ? GMunregisterMenuCommand(t) : debug("//-> menuRemove() not found item: %s.", typeof t);
  733. },
  734.  
  735. registerMenuCommand: function (e) {
  736. let yet, _Use_Bing__;
  737. let _use_Bing_ID, in_Use_feedBack_ID, in_UpdateCheck_ID;
  738.  
  739. // Remove menus if the menus exists.
  740. this.menuRemove(_use_Bing_ID);
  741. this.menuRemove(in_Use_feedBack_ID);
  742. this.menuRemove(in_UpdateCheck_ID);
  743.  
  744. e ? (_Use_Bing__ = "\ufff0\u2705 【已开启】") : (_Use_Bing__ = "\ufff0\u274c 【已关闭】");
  745.  
  746. _use_Bing_ID = GMregisterMenuCommand(`${_Use_Bing__}Bing 搜索跳转`, () => {
  747. if (!yet) {
  748. this.inUse_switch(e, "_if_Use_Bing_", "Bing 按钮");
  749. yet = true;
  750. }
  751. });
  752. // "false" is disabled forever.
  753. if (isVersionDetection) {
  754. // check VDR value to insert menu.
  755. if (CONST.isVDResult) {
  756. if (defCon._expireTime === _expireTime) {
  757. in_UpdateCheck_ID = GMregisterMenuCommand(`\ufff5\ud83d\udd0e 【版本更新】手动实时检查`, () => {
  758. // Destroy cache before manual check.
  759. GMdeleteValue("_Check_Version_Expire_");
  760. checkVersion(true);
  761. });
  762. } else {
  763. if (_expireTime !== "4h") {
  764. in_UpdateCheck_ID = GMregisterMenuCommand(
  765. `\ufff5\ud83d\udd0e 【变更缓存时间】${defCon.showDate(defCon._expireTime)} \u21D2 ${defCon.showDate(_expireTime)}`,
  766. () => {
  767. // Destroy cache before change expireTime.
  768. GMdeleteValue("_Check_Version_Expire_");
  769. GMdeleteValue("_expire_time_");
  770. GMnotification(
  771. defCon.noticeHTML(`<dd>缓存时间已重新设定,网页将在<em>3</em>秒后自动刷新!</dd>`),
  772. "info",
  773. true,
  774. 30,
  775. callback_Countdown
  776. );
  777. setTimeout(() => {
  778. location.reload();
  779. }, 3e3);
  780. }
  781. );
  782. } else {
  783. in_UpdateCheck_ID = GMregisterMenuCommand(
  784. `\ufff5\ud83d\udd0e 【重置缓存】检查更新 ( 重置为 ${defCon.showDate(_expireTime)} )`,
  785. () => {
  786. // Destroy cache before change expireTime.
  787. GMdeleteValue("_Check_Version_Expire_");
  788. GMdeleteValue("_expire_time_");
  789. checkVersion(true);
  790. setTimeout(() => {
  791. location.reload();
  792. }, 4e3);
  793. }
  794. );
  795. }
  796. }
  797. } else {
  798. in_UpdateCheck_ID = GMregisterMenuCommand("\ufff5\ud83d\udcdb 【版本更新】已关闭 \u267b 重新开启", () => {
  799. GMsetValue("_is_Ver_Det_", true);
  800. // Destroy cache & session when restart detection.
  801. GMdeleteValue("_Check_Version_Expire_");
  802. sessionStorage.removeItem("nCount");
  803. debug("//-> Destroy cache & session when restart detection.");
  804. GMnotification(defCon.noticeHTML(`<dd>更新检测已开启,网页将在<em>3</em>秒后自动刷新!</dd>`), "info", true, 30, callback_Countdown);
  805. setTimeout(() => {
  806. location.reload();
  807. }, 3e3);
  808. });
  809. }
  810. }
  811. in_Use_feedBack_ID = GMregisterMenuCommand("\ufff9\ud83e\udde1 【建议反馈】说出您的意见!", () => {
  812. GMopenInTab(`${defCon.support ? defCon.support : "https://greasyfork.org/scripts/12909/feedback"}`, {
  813. active: true,
  814. insert: true,
  815. setParent: true,
  816. });
  817. });
  818. },
  819.  
  820. menuDisplay: function () {
  821. // disabled menus if set SecurityPolicy.
  822. if (!CONST.isSecurityPolicy) {
  823. safeFunction(() => {
  824. this.registerMenuCommand(CONST.isUseBing);
  825. });
  826. }
  827. console.log(
  828. "%c[GB-Status]%c\nInsert the Bing Search Button: %c%s",
  829. "font-weight:bold;color:darkorange",
  830. "color:0",
  831. "font-weight:bold;color:red",
  832. defCon.titleCase(CONST.isUseBing && !CONST.isSecurityPolicy)
  833. );
  834. },
  835.  
  836. init: function () {
  837. this.menuDisplay();
  838. },
  839. };
  840.  
  841. /* Insert search Button */
  842.  
  843. let searchManager = {
  844. insertSearchButton: function () {
  845. try {
  846. const getTarget = curretSite.MainType;
  847. const doHtml = curretSite.HtmlCode;
  848. const doStyName = `${CONST.rndclassName}`;
  849. const doStyle = CONST.noticeCss + curretSite.StyleCode;
  850. const indexPage = location.pathname === "/";
  851. const userSpan = document.createElement("span");
  852. userSpan.id = `${CONST.rndidName}`;
  853. userSpan.innerHTML = doHtml;
  854. const SpanID = `#${userSpan.id}`;
  855. let Target = document.querySelector(getTarget);
  856.  
  857. addStyle(doStyle, doStyName, "head");
  858.  
  859. if (!document.querySelector(SpanID) && getSearchValue() && !indexPage && Target) {
  860. if (/^(nws|vid|bks)$/.test(CONST.vim.trim())) {
  861. Target = Target.parentNode.parentNode.firstChild;
  862. Target.insertBefore(userSpan, Target.firstChild);
  863. if (document.querySelector(SpanID)) {
  864. document.querySelector(SpanID).setAttribute("style", "float:right");
  865. }
  866. } else {
  867. insterAfter(userSpan, Target);
  868. // Baidu image fixed
  869. if (document.querySelector(SpanID) && /^baiduimage$/.test(CONST.vim.trim())) {
  870. document.querySelector(SpanID).setAttribute("style", "margin-left:12px");
  871. }
  872. // Bing image fixed
  873. if (document.querySelector(".b_searchboxForm") && /^images$/.test(CONST.vim.trim())) {
  874. if (location.href.includes("view=detailV2") && CONST.isUseBing) {
  875. document.querySelector(".b_searchboxForm").setAttribute("style", "width:122.5%!important");
  876. document.querySelectorAll(`#${CONST.rndidName} input`).forEach(item => {
  877. item.style = "height:35px!important";
  878. });
  879. }
  880. }
  881. }
  882.  
  883. debug(`//-> searchManager $(Target): ${Target}`);
  884.  
  885. document.querySelectorAll(`#${CONST.ggyx}, #${CONST.bbyx}, #${CONST.bdyx}`).forEach(per => {
  886. per.addEventListener("click", () => {
  887. let gotoUrl = "about:blank";
  888. switch (per.id) {
  889. case `${CONST.ggyx}`:
  890. if (/^(baiduimage|images)$/.test(CONST.vim.trim())) {
  891. gotoUrl = "https://www.google.com/search?hl=zh-CN&source=lnms&tbm=isch&sa=X&q=";
  892. } else {
  893. gotoUrl = "https://www.google.com/search?hl=zh-CN&source=hp&newwindow=1&q=";
  894. }
  895. break;
  896. case `${CONST.bbyx}`:
  897. if (/^(isch|baiduimage)$/.test(CONST.vim.trim())) {
  898. gotoUrl = "https://cn.bing.com/images/search?first=1&tsc=ImageBasicHover&q=";
  899. } else {
  900. gotoUrl = "https://cn.bing.com/search?q=";
  901. }
  902. break;
  903. case `${CONST.bdyx}`:
  904. if (/^(images|isch)$/.test(CONST.vim.trim())) {
  905. gotoUrl = "https://image.baidu.com/search/index?tn=baiduimage&ps=1&ie=utf-8&word=";
  906. } else {
  907. gotoUrl = "https://www.baidu.com/s?ie=utf-8&rqlang=cn&wd=";
  908. }
  909. break;
  910. default:
  911. break;
  912. }
  913. GMopenInTab(decodeURI(gotoUrl + getSearchValue()), {
  914. active: true,
  915. insert: true,
  916. setParent: true,
  917. });
  918. });
  919. });
  920. }
  921. return true;
  922. } catch (e) {
  923. error("//-> %csearchManager.insertSearchButton:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  924. return false;
  925. }
  926. },
  927.  
  928. scrollDetect: function () {
  929. let scrollbars, height, e;
  930. switch (curretSite.SiteTypeID) {
  931. case newSiteType.GOOGLE:
  932. // Google image fixed
  933. e = /^isch$/.test(CONST.vim.trim());
  934. e ? (scrollbars = "scrollbars2") : (scrollbars = "scrollbars");
  935. e ? (height = -14) : (height = 35);
  936. scrollButton(`#${CONST.rndidName}`, "scrollspan", height);
  937. scrollButton(`#${CONST.rndidName} #${CONST.bdyx} input`, scrollbars, height);
  938. if (CONST.isUseBing) {
  939. scrollButton(`#${CONST.rndidName} #${CONST.bbyx} input`, scrollbars, height);
  940. }
  941. break;
  942. case newSiteType.BING:
  943. if (/^(images|videos)$/.test(CONST.vim.trim()) && CONST.isUseBing) {
  944. scrollButton(`#${CONST.rndidName}`, "scrollspan", 50);
  945. scrollButton(`#${CONST.rndidName} #${CONST.bdyx} input`, "scrollbars", 50);
  946. scrollButton(`#${CONST.rndidName} #${CONST.ggyx} input`, "scrollbars", 50);
  947. } else {
  948. debug(`//-> No scrolling detecting.`);
  949. }
  950. break;
  951. default:
  952. debug(`//-> No scrolling detecting.`);
  953. break;
  954. }
  955. return true;
  956. },
  957.  
  958. RAF: function () {
  959. RAFInterval(
  960. () => {
  961. if (!document.querySelector(`#${CONST.rndidName}`) || !document.querySelector(`.${CONST.rndclassName}`)) {
  962. return this.insertSearchButton() && this.scrollDetect();
  963. }
  964. },
  965. 200,
  966. true
  967. );
  968. },
  969.  
  970. doSwitch: function () {
  971. try {
  972. if (curretSite.SiteTypeID !== newSiteType.OTHERS) {
  973. if (CONST.isSecurityPolicy) {
  974. console.log(
  975. "%c[GB-Prohibit]%c\nBlocked By: %c%s Security Policy",
  976. "font-weight:bold;color:indigo",
  977. "color:0",
  978. "font-weight:bold;color:darkred",
  979. curretSite.SiteName
  980. );
  981. return;
  982. } else {
  983. const callback = mutations => {
  984. mutations.forEach(mutation => {
  985. if (document.querySelector(`.${CONST.rndclassName}`) && document.querySelector(`#${CONST.rndidName}`)) {
  986. debug(`//-> Already Insert Button & CSS.`);
  987. } else {
  988. debug(
  989. "%c[GB-MutationObserver]\n%c(%c%s%c has changed: %c%s%c)",
  990. "font-weight:bold;color:olive",
  991. "color:0",
  992. "color:olive",
  993. mutation.type,
  994. "color:0",
  995. "font-weight:bold;color:red",
  996. defCon.titleCase(!(this.RAF() instanceof Object)),
  997. "color:0"
  998. );
  999. }
  1000. });
  1001. };
  1002. const opts = { childList: true, subtree: true };
  1003. let observer = new MutationObserver(callback);
  1004. observer.observe(document, opts);
  1005. console.log(
  1006. "%c[GB-Switch]%c\nWe are using The %c%s%c Search Engine.",
  1007. "font-weight:bold;color:Green",
  1008. "color:0",
  1009. "font-weight:bold;color:darkcyan",
  1010. curretSite.SiteName,
  1011. "font-weight:normal;color:0"
  1012. );
  1013. }
  1014. }
  1015. } catch (e) {
  1016. error("//-> %csearchManager.doSwitch:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  1017. }
  1018. },
  1019.  
  1020. init: function () {
  1021. this.doSwitch();
  1022. },
  1023. };
  1024.  
  1025. /* important functions */
  1026.  
  1027. function scrollButton(paraName, classNameIn, scrollSize) {
  1028. debug(`//-> ${curretSite.SiteName} Scrolling Detecting: ${paraName}`);
  1029. const oDiv = document.querySelector(paraName);
  1030. let H = 0;
  1031. let Y = oDiv;
  1032. if (Y !== null) {
  1033. while (Y) {
  1034. H += Y.offsetTop;
  1035. Y = Y.offsetParent;
  1036. }
  1037. document.addEventListener("scroll", () => {
  1038. const s = document.body.scrollTop || document.documentElement.scrollTop;
  1039. debug(`//-> H=${H} S=${s} (${s - H})`);
  1040. if (s > H + scrollSize) {
  1041. oDiv.setAttribute("class", classNameIn);
  1042. } else {
  1043. oDiv.removeAttribute("class");
  1044. }
  1045. });
  1046. }
  1047. }
  1048.  
  1049. function insterAfter(newElement, targetElement) {
  1050. if (targetElement !== null) {
  1051. const parent = targetElement.parentNode;
  1052. if (parent.lastChild === targetElement) {
  1053. parent.appendChild(newElement);
  1054. } else {
  1055. parent.insertBefore(newElement, targetElement.nextSibling);
  1056. }
  1057. }
  1058. }
  1059.  
  1060. function addStyle(css, className, addToTarget, isReload, initType) {
  1061. RAFInterval(
  1062. () => {
  1063. try {
  1064. let addTo = document.querySelector(addToTarget);
  1065. if (typeof addToTarget === "undefined") {
  1066. addTo = document.head || document.body || document.documentElement || document;
  1067. }
  1068. isReload = isReload || false;
  1069. initType = initType || "text/css";
  1070. if (typeof addToTarget === "undefined" || (typeof addToTarget !== "undefined" && document.querySelector(addToTarget))) {
  1071. if (isReload === true) {
  1072. safeRemove(`.${className}`);
  1073. } else if (isReload === false && document.querySelector(`.${className}`)) {
  1074. return true;
  1075. }
  1076. const cssNode = document.createElement("style");
  1077. if (className !== null) {
  1078. cssNode.className = className;
  1079. }
  1080. cssNode.setAttribute("type", initType);
  1081. cssNode.innerHTML = css;
  1082. addTo.appendChild(cssNode);
  1083. }
  1084. return true;
  1085. } catch (e) {
  1086. error("//-> %caddStyle:\n%c%s", "font-weight:bold", "font-weight:normal", e);
  1087. return false;
  1088. }
  1089. },
  1090. 20,
  1091. true
  1092. );
  1093. }
  1094.  
  1095. function safeRemove(Css) {
  1096. safeFunction(() => {
  1097. const removeNodes = document.querySelectorAll(Css);
  1098. for (let i = 0; i < removeNodes.length; i++) {
  1099. removeNodes[i].remove();
  1100. }
  1101. });
  1102. }
  1103.  
  1104. function getSearchValue(val) {
  1105. document.querySelectorAll('input[name="wd"], input[name="q"], input[name="word"]').forEach((item, index, arr) => {
  1106. val = arr[0].value;
  1107. if (val) {
  1108. debug(`//-> INPUT: ${val} - INDEX: ${index} - OLD: ${item.value}`);
  1109. }
  1110. });
  1111. if (val === null || val === "" || typeof val === "undefined") {
  1112. const kvl = location.search.substr(1).split("&");
  1113. if (kvl) {
  1114. for (let i = 0; i < kvl.length; i++) {
  1115. let value = kvl[i].replace(/^(wd|word|kw|query|q)=/, "");
  1116. if (value !== kvl[i]) {
  1117. val = value;
  1118. }
  1119. }
  1120. if (val) {
  1121. val = val.replace(/\+/g, " ");
  1122. debug(`//-> QUERY: ${val}`);
  1123. } else {
  1124. val = "";
  1125. error(`//-> QUERY is null`);
  1126. }
  1127. } else {
  1128. return "";
  1129. }
  1130. }
  1131. return encodeURIComponent(val);
  1132. }
  1133.  
  1134. function RAFInterval(callback, period, runNow) {
  1135. const needCount = (period / 1000) * 60;
  1136. let times = 0;
  1137. if (runNow === true) {
  1138. const shouldFinish = callback();
  1139. if (shouldFinish) {
  1140. return;
  1141. }
  1142. }
  1143.  
  1144. function step() {
  1145. if (times < needCount) {
  1146. times++;
  1147. requestAnimationFrame(step);
  1148. } else {
  1149. const shouldFinish = callback() || false;
  1150. if (!shouldFinish) {
  1151. times = 0;
  1152. requestAnimationFrame(step);
  1153. } else {
  1154. return;
  1155. }
  1156. }
  1157. }
  1158. requestAnimationFrame(step);
  1159. }
  1160.  
  1161. /* Refactoring NoticeJs Functions */
  1162.  
  1163. (function (q, d) {
  1164. typeof exports === "object" && typeof module === "object"
  1165. ? (window.module.exports = d())
  1166. : typeof define === "function" && window.define.amd
  1167. ? window.define("NoticeJs", [], d)
  1168. : typeof exports === "object"
  1169. ? (window.exports.NoticeJs = d())
  1170. : (q.NoticeJs = d());
  1171. })("undefined" !== typeof self ? self : this, function () {
  1172. return (function (q) {
  1173. let m = {};
  1174. function d(g) {
  1175. if (m[g]) {
  1176. return m[g].exports;
  1177. }
  1178. let l = (m[g] = {
  1179. i: g,
  1180. l: !1,
  1181. exports: {},
  1182. });
  1183. q[g].call(l.exports, l, l.exports, d);
  1184. l.l = !0;
  1185. return l.exports;
  1186. }
  1187. d.m = q;
  1188. d.c = m;
  1189. d.d = function (g, l, f) {
  1190. d.o(g, l) ||
  1191. Object.defineProperty(g, l, {
  1192. configurable: !1,
  1193. enumerable: !0,
  1194. get: f,
  1195. });
  1196. };
  1197. d.n = function (g) {
  1198. let l =
  1199. g && g.__esModule
  1200. ? function () {
  1201. return g.default;
  1202. }
  1203. : function () {
  1204. return g;
  1205. };
  1206. d.d(l, "a", l);
  1207. return l;
  1208. };
  1209. d.o = function (g, l) {
  1210. return Object.prototype.hasOwnProperty.call(g, l);
  1211. };
  1212. d.p = "dist/";
  1213. return d((d.s = 2));
  1214. })([
  1215. function (q, d, m) {
  1216. Object.defineProperty(d, "__esModule", { value: !0 });
  1217. d.noticeJsModalClassName = "noticejs-modal";
  1218. d.closeAnimation = "noticejs-fadeOut";
  1219. d.Defaults = {
  1220. title: "",
  1221. text: "",
  1222. type: "success",
  1223. position: "bottomRight",
  1224. newestOnTop: !1,
  1225. timeout: 30,
  1226. progressBar: !0,
  1227. indeterminate: !1,
  1228. closeWith: ["button"],
  1229. animation: {
  1230. open: "animated fadeIn",
  1231. close: "animated fadeOut",
  1232. },
  1233. modal: !1,
  1234. width: 400,
  1235. scroll: {
  1236. maxHeightContent: 400,
  1237. showOnHover: !0,
  1238. },
  1239. rtl: !1,
  1240. callbacks: {
  1241. beforeShow: [],
  1242. onShow: [],
  1243. afterShow: [],
  1244. onClose: [],
  1245. afterClose: [],
  1246. onClick: [],
  1247. onHover: [],
  1248. onTemplate: [],
  1249. },
  1250. };
  1251. },
  1252. function (q, d, m) {
  1253. function g(a, b) {
  1254. a.callbacks.hasOwnProperty(b) &&
  1255. a.callbacks[b].forEach(function (c) {
  1256. typeof c === "function" && c.apply(a);
  1257. });
  1258. }
  1259. Object.defineProperty(d, "__esModule", { value: !0 });
  1260. d.appendNoticeJs = d.addListener = d.CloseItem = d.AddModal = void 0;
  1261. d.getCallback = g;
  1262. let l = (function (a) {
  1263. if (a && a.__esModule) {
  1264. return a;
  1265. }
  1266. let b = {};
  1267. if (null !== a) {
  1268. for (let c in a) {
  1269. Object.prototype.hasOwnProperty.call(a, c) && (b[c] = a[c]);
  1270. }
  1271. }
  1272. b.default = a;
  1273. return b;
  1274. })(m(0));
  1275. let f = l.Defaults;
  1276. let h = (d.AddModal = function () {
  1277. if (0 >= document.getElementsByClassName(l.noticeJsModalClassName).length) {
  1278. let a = document.createElement("div");
  1279. a.classList.add(l.noticeJsModalClassName);
  1280. a.classList.add("noticejs-modal-open");
  1281. document.body.appendChild(a);
  1282. setTimeout(function () {
  1283. a.className = l.noticeJsModalClassName;
  1284. }, 200);
  1285. }
  1286. });
  1287. let n = (d.CloseItem = function (a) {
  1288. g(f, "onClose");
  1289. null !== f.animation && null !== f.animation.close && (a.className += " " + f.animation.close);
  1290. setTimeout(function () {
  1291. a.remove();
  1292. }, 200);
  1293. !0 === f.modal &&
  1294. 1 <= document.querySelectorAll("[noticejs-modal='true']").length &&
  1295. ((document.querySelector(".noticejs-modal").className += " noticejs-modal-close"),
  1296. setTimeout(function () {
  1297. document.querySelector(".noticejs-modal").remove();
  1298. }, 500));
  1299. let b = a.closest(".noticejs");
  1300. let c = b ? "." + b.className.replace("noticejs", "").trim() : ".null";
  1301. setTimeout(function () {
  1302. 0 >= document.querySelectorAll(c + " .item").length && document.querySelector(c) && document.querySelector(c).remove();
  1303. }, 500);
  1304. });
  1305. let e = (d.addListener = function (a) {
  1306. f.closeWith.includes("button") &&
  1307. a.querySelector(".close").addEventListener("click", function () {
  1308. n(a);
  1309. });
  1310. f.closeWith.includes("click")
  1311. ? ((a.style.cursor = "pointer"),
  1312. a.addEventListener("click", function (b) {
  1313. "close" !== b.target.className && (g(f, "onClick"), n(a));
  1314. }))
  1315. : a.addEventListener("click", function (b) {
  1316. "close" !== b.target.className && g(f, "onClick");
  1317. });
  1318. a.addEventListener("mouseover", function () {
  1319. g(f, "onHover");
  1320. });
  1321. });
  1322. d.appendNoticeJs = function (a, b, c) {
  1323. let p = ".noticejs-" + f.position;
  1324. let k = document.createElement("div");
  1325. k.classList.add("item");
  1326. k.classList.add(f.type);
  1327. !0 === f.rtl && k.classList.add("noticejs-rtl");
  1328. "" !== f.width && Number.isInteger(f.width) && (k.style.width = f.width + "px");
  1329. a && "" !== a && k.appendChild(a);
  1330. k.appendChild(b);
  1331. c && "" !== c && k.appendChild(c);
  1332. ["top", "bottom"].includes(f.position) && (document.querySelector(p).innerHTML = "");
  1333. null !== f.animation && null !== f.animation.open && (k.className += " " + f.animation.open);
  1334. !0 === f.modal && (k.setAttribute("noticejs-modal", "true"), h());
  1335. e(k, f.closeWith);
  1336. g(f, "beforeShow");
  1337. g(f, "onShow");
  1338. !0 === f.newestOnTop ? document.querySelector(p).insertAdjacentElement("afterbegin", k) : document.querySelector(p).appendChild(k);
  1339. g(f, "afterShow");
  1340. return k;
  1341. };
  1342. },
  1343. function (q, d, m) {
  1344. function g(a) {
  1345. if (a && a.__esModule) {
  1346. return a;
  1347. }
  1348. let b = {};
  1349. if (null !== a) {
  1350. for (let c in a) {
  1351. Object.prototype.hasOwnProperty.call(a, c) && (b[c] = a[c]);
  1352. }
  1353. }
  1354. b.default = a;
  1355. return b;
  1356. }
  1357. Object.defineProperty(d, "__esModule", { value: !0 });
  1358. let l = (function () {
  1359. function a(b, c) {
  1360. for (let p = 0; p < c.length; p++) {
  1361. let k = c[p];
  1362. k.enumerable = k.enumerable || !1;
  1363. k.configurable = !0;
  1364. "value" in k && (k.writable = !0);
  1365. Object.defineProperty(b, k.key, k);
  1366. }
  1367. }
  1368. return function (b, c, p) {
  1369. c && a(b.prototype, c);
  1370. p && a(b, p);
  1371. return b;
  1372. };
  1373. })();
  1374. m(3);
  1375. let f = m(0);
  1376. let h = g(f);
  1377. let n = m(4);
  1378. m = m(1);
  1379. let e = g(m);
  1380. m = (function () {
  1381. class a {
  1382. constructor() {
  1383. let b = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {};
  1384. if (!(this instanceof a)) {
  1385. throw new TypeError("Cannot call a class as a function");
  1386. }
  1387. this.options = Object.assign(h.Defaults, b);
  1388. this.component = new n.Components();
  1389. this.id = "noticejs-" + Math.random();
  1390. this.on("beforeShow", this.options.callbacks.beforeShow);
  1391. this.on("onShow", this.options.callbacks.onShow);
  1392. this.on("afterShow", this.options.callbacks.afterShow);
  1393. this.on("onClose", this.options.callbacks.onClose);
  1394. this.on("afterClose", this.options.callbacks.afterClose);
  1395. this.on("onClick", this.options.callbacks.onClick);
  1396. this.on("onHover", this.options.callbacks.onHover);
  1397. }
  1398. }
  1399. l(
  1400. a,
  1401. [
  1402. {
  1403. key: "show",
  1404. value: function () {
  1405. let b = this.component.createContainer();
  1406. document.querySelector(".noticejs-" + this.options.position) === null && document.body.appendChild(b);
  1407. let c = void 0;
  1408. b = this.component.createHeader(this.options.title, this.options.closeWith);
  1409. let p = this.component.createBody(this.options.text);
  1410. !0 === this.options.progressBar && (c = this.component.createProgressBar());
  1411. b = e.appendNoticeJs(b, p, c);
  1412. b.setAttribute("id", this.id);
  1413. return (this.dom = b);
  1414. },
  1415. },
  1416. {
  1417. key: "on",
  1418. value: function (b) {
  1419. let c = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : function () {};
  1420. typeof c === "function" && this.options.callbacks.hasOwnProperty(b) && this.options.callbacks[b].push(c);
  1421. return this;
  1422. },
  1423. },
  1424. {
  1425. key: "close",
  1426. value: function () {
  1427. e.CloseItem(this.dom);
  1428. },
  1429. },
  1430. ],
  1431. [
  1432. {
  1433. key: "overrideDefaults",
  1434. value: function (b) {
  1435. this.options = Object.assign(h.Defaults, b);
  1436. return this;
  1437. },
  1438. },
  1439. ]
  1440. );
  1441. return a;
  1442. })();
  1443. d.default = m;
  1444. q.exports = d.default;
  1445. },
  1446. function (q, d) {},
  1447. function (q, d, m) {
  1448. function g(n) {
  1449. if (n && n.__esModule) {
  1450. return n;
  1451. }
  1452. let e = {};
  1453. if (n === null) {
  1454. for (let a in n) {
  1455. Object.prototype.hasOwnProperty.call(n, a) && (e[a] = n[a]);
  1456. }
  1457. }
  1458. e.default = n;
  1459. return e;
  1460. }
  1461. Object.defineProperty(d, "__esModule", { value: !0 });
  1462. d.Components = void 0;
  1463. let l = (function () {
  1464. function n(e, a) {
  1465. for (let b = 0; b < a.length; b++) {
  1466. let c = a[b];
  1467. c.enumerable = c.enumerable || !1;
  1468. c.configurable = !0;
  1469. "value" in c && (c.writable = !0);
  1470. Object.defineProperty(e, c.key, c);
  1471. }
  1472. }
  1473. return function (e, a, b) {
  1474. a && n(e.prototype, a);
  1475. b && n(e, b);
  1476. return e;
  1477. };
  1478. })();
  1479. q = m(0);
  1480. q = g(q);
  1481. m = m(1);
  1482. let f = g(m);
  1483. let h = q.Defaults;
  1484. d.Components = (function () {
  1485. function n() {
  1486. if (!(this instanceof n)) {
  1487. throw new TypeError("Cannot call a class as a function");
  1488. }
  1489. }
  1490. l(n, [
  1491. {
  1492. key: "createContainer",
  1493. value: function () {
  1494. let e = "noticejs-" + h.position;
  1495. let a = document.createElement("div");
  1496. a.classList.add("noticejs");
  1497. a.classList.add(e);
  1498. return a;
  1499. },
  1500. },
  1501. {
  1502. key: "createHeader",
  1503. value: function () {
  1504. let e = void 0;
  1505. h.title &&
  1506. "" !== h.title &&
  1507. ((e = document.createElement("div")), e.setAttribute("class", "noticejs-heading"), (e.textContent = h.title));
  1508. if (h.closeWith.includes("button")) {
  1509. let a = document.createElement("div");
  1510. a.setAttribute("class", "close");
  1511. a.innerHTML = "&times;";
  1512. e ? e.appendChild(a) : (e = a);
  1513. }
  1514. return e;
  1515. },
  1516. },
  1517. {
  1518. key: "createBody",
  1519. value: function () {
  1520. let e = document.createElement("div");
  1521. e.setAttribute("class", "noticejs-body");
  1522. let a = document.createElement("div");
  1523. a.setAttribute("class", "noticejs-content");
  1524. a.innerHTML = h.text;
  1525. e.appendChild(a);
  1526. null !== h.scroll &&
  1527. "" !== h.scroll.maxHeight &&
  1528. ((e.style.overflowY = "auto"),
  1529. (e.style.maxHeight = h.scroll.maxHeight + "px"),
  1530. !0 === h.scroll.showOnHover && (e.style.visibility = "hidden"));
  1531. return e;
  1532. },
  1533. },
  1534. {
  1535. key: "createProgressBar",
  1536. value: function () {
  1537. let e = document.createElement("div");
  1538. e.setAttribute("class", "noticejs-progressbar");
  1539. let a = document.createElement("div");
  1540. a.setAttribute("class", "noticejs-bar");
  1541. e.appendChild(a);
  1542. let b = 100;
  1543. let c = 0;
  1544. let p = 0;
  1545. let k = "";
  1546. if (!0 === h.progressBar && "boolean" !== typeof h.timeout && !1 !== h.timeout) {
  1547. let u = function () {
  1548. if (0 >= b) {
  1549. clearInterval(p);
  1550. let r = e.closest("div.item");
  1551. if (null !== h.animation && null !== h.animation.close) {
  1552. r.className = r.className.replace(new RegExp("(?:^|\\s)" + h.animation.open + "(?:\\s|$)"), " ");
  1553. r.className += " " + h.animation.close;
  1554. let t = parseInt(h.timeout) + 500;
  1555. setTimeout(function () {
  1556. f.CloseItem(r);
  1557. }, t);
  1558. } else {
  1559. f.CloseItem(r);
  1560. }
  1561. } else {
  1562. b--;
  1563. a.style.width = b + "%";
  1564. }
  1565. };
  1566. let v = function () {
  1567. c === 0 ? (b--, b === 0 && (c = 1)) : (b++, b === 100 && (c = 0));
  1568. document.getElementById(k) === null ? clearInterval(p) : (a.style.width = b + "%");
  1569. };
  1570. !0 === h.indeterminate
  1571. ? ((p = setInterval(v, h.timeout)), (k = "noticejs-progressbar-" + p), e.setAttribute("id", k))
  1572. : (p = setInterval(u, h.timeout));
  1573. }
  1574. return e;
  1575. },
  1576. },
  1577. ]);
  1578. return n;
  1579. })();
  1580. },
  1581. ]);
  1582. });
  1583.  
  1584. /* Let`s enjoy it! */
  1585.  
  1586. !(function () {
  1587. try {
  1588. debug("//-> Insert Ext Menu.");
  1589. menuManager.init();
  1590. debug("//-> Insert Search Button.");
  1591. searchManager.init();
  1592. } catch (e) {
  1593. console.error("%c[GB-Error]%c\n%s", "font-weight:bold;color:red", "font-weight:bold;color:darkred", e);
  1594. } finally {
  1595. if (isVersionDetection && !CONST.isVDResult) {
  1596. debug("//-> Ready to Insert Random Tips.");
  1597. if (Math.floor(Math.random() * 20) > 18) {
  1598. setTimeout(function () {
  1599. GMnotification(
  1600. defCon.noticeHTML(
  1601. `<dd title="随机提示">若要恢复自动更新功能,请在覆盖安装新代码后,\
  1602. 从脚本菜单中重新开启"版本更新"功能。</dd><dd style="text-align: center" title="随机提示">\
  1603. <img src="https://i.niupic.com/images/2021/06/13/9kVe.png" alt="开启自动检测"></dd>`
  1604. ),
  1605. "info",
  1606. true,
  1607. 80
  1608. );
  1609. }, Math.random() * 10e3);
  1610. }
  1611. }
  1612. }
  1613. })();
  1614. })();
  1615. })();