AlwaysBing

Always search with Bing

  1. // ==UserScript==
  2. // @name AlwaysBing
  3. // @namespace AlwaysBing
  4. // @version 1.0.0
  5. // @description Always search with Bing
  6. // @description:en Always search with Bing
  7. // @description:zh-CN 永远使用 Bing 搜索
  8. // @description:zh-TW 永遠使用 Bing 搜索
  9. // @icon https://cn.bing.com/favicon.ico
  10. // @author lingbopro
  11. // @homepage https://github.com/lingbopro/AlwaysBing
  12. // @license MIT
  13. // @match *://*.bing.com/*
  14. // @match *://*.baidu.com/*
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @grant GM_registerMenuCommand
  18. // @grant GM_addStyle
  19. // @grant GM_log
  20. // @grant window.location
  21. // @noframes
  22. // ==/UserScript==
  23.  
  24. (function () {
  25. 'use strict';
  26.  
  27. /*
  28. * AlwaysBing
  29. * 这是一个开源的用户脚本
  30. * 遵循 MIT 协议
  31. * GitHub 存储库: https://github.com/lingbopro/AlwaysBing
  32. * GreasyFork: https://gf.qytechs.cn/zh-CN/scripts/496648
  33. * 贡献代码前,先用 Prettier 格式化啊~
  34. */
  35.  
  36. //SECTION - 配置 / CONFIG
  37. /*
  38. * --------------------
  39. * 这里是配置内容。
  40. * 如果你要修改配置,请在这里修改。
  41. * PS: 不要删JSDoc啊
  42. * --------------------
  43. */
  44.  
  45. /**
  46. * 规则列表
  47. * @type {array}
  48. */
  49. let rules = [
  50. // TODO: 完善规则
  51. {
  52. name: '百度', // 名称
  53. matches: [
  54. // 子规则
  55. {
  56. type: 'search', // 类型(用来匹配下方的Bing URL)
  57. url: 'baidu.com/s', // URL匹配
  58. query: 'wd', // 包含搜索内容的参数名称
  59. },
  60. {
  61. type: 'image',
  62. url: 'image.baidu.com/search',
  63. query: 'word',
  64. },
  65. {
  66. type: 'video',
  67. url: 'baidu.com/sf/vsearch',
  68. query: 'wd',
  69. },
  70. ],
  71. },
  72. ];
  73. /**
  74. * 必应的 URL
  75. * @type {object}
  76. */
  77. let bing = {
  78. search: 'https://bing.com/search?q=',
  79. image: 'https://bing.com/images/search?q=',
  80. video: 'https://bing.com/videos/search?q=',
  81. };
  82. /**
  83. * 读取的配置
  84. * @type {object}
  85. */
  86. let config = {
  87. rules: [
  88. // 每项分别对应规则的对应项
  89. {
  90. action: 'redirect',
  91. },
  92. ],
  93. };
  94. //!SECTION
  95.  
  96. //SECTION - 逻辑 / LOGIC
  97. /*
  98. * --------------------
  99. * 这里是核心逻辑。
  100. * 如果你要修改配置,就别动这。
  101. * 注释不太多,将就看吧:D
  102. * :)
  103. * --------------------
  104. */
  105.  
  106. let modal_open = false; // 防止叠弹窗
  107. /**
  108. * 读取配置
  109. */
  110. let readConfig = function () {
  111. GM_log(`AlwaysBing: read config`);
  112. config = GM_getValue('config', config); // 读取配置
  113. config.rules.forEach((value, index) => {
  114. // 将配置写到规则表中
  115. rules[index].action = value.action;
  116. });
  117. GM_log(`AlwaysBing: config:\n${JSON.stringify(config)}`);
  118. };
  119. /**
  120. * 写入配置
  121. */
  122. let writeConfig = function () {
  123. GM_log(`AlwaysBing: write config`);
  124. rules.forEach((value, index) => {
  125. // 将配置从规则表再写回到配置表
  126. config.rules[index].action = value.action;
  127. });
  128. GM_setValue('config', config); // 写入配置
  129. };
  130. /**
  131. * 上下文菜单回调
  132. * @param {number} index
  133. */
  134. let menuCallback = function (index) {
  135. GM_log(`AlwaysBing: menu callback: ${index}`);
  136. let rule = rules[index];
  137. switch (rule.action) {
  138. case 'redirect':
  139. rule.action = 'modal';
  140. break;
  141. case 'modal':
  142. rule.action = 'modal_closeable';
  143. break;
  144. case 'modal_closeable':
  145. rule.action = 'nothing';
  146. break;
  147. case 'nothing':
  148. rule.action = 'redirect';
  149. break;
  150. default:
  151. break;
  152. }
  153. rules[index] = rule;
  154. writeConfig();
  155. refreshMenu();
  156. };
  157. /**
  158. * 刷新上下文菜单
  159. */
  160. let refreshMenu = function () {
  161. GM_log(`AlwaysBing: refresh menu`);
  162. rules.forEach((value, index) => {
  163. let text = '';
  164. switch (value.action) {
  165. case 'redirect':
  166. text = '🔗重定向';
  167. break;
  168. case 'modal':
  169. text = '💬提示';
  170. break;
  171. case 'modal_closeable':
  172. text = '💬提示(可关闭)';
  173. break;
  174. case 'nothing':
  175. text = '❌什么也不做';
  176. break;
  177. default:
  178. break;
  179. }
  180. GM_registerMenuCommand(
  181. `🔍${value.name}: ${text}`,
  182. function () {
  183. menuCallback(index);
  184. },
  185. {
  186. id: 'menu-' + index,
  187. autoClose: false,
  188. title: `🔍规则: ${value.name}\n▶动作: ${text}`,
  189. }
  190. );
  191. });
  192. };
  193. /**
  194. * 处理和匹配规则
  195. */
  196. let process = function () {
  197. GM_log(`AlwaysBing: process`);
  198. rules.forEach((value, index) => {
  199. // 遍历规则
  200. let currentRule = value;
  201. GM_log(`AlwaysBing: process rule ${value.name}`);
  202. value.matches.forEach((value, index) => {
  203. // 遍历子规则
  204. if (window.location.href.includes(value.url)) {
  205. // URL匹配
  206. GM_log(`AlwaysBing: URL matches rule ${currentRule.name}`);
  207. let searchParams = new URLSearchParams(
  208. window.location.search
  209. );
  210. let query = searchParams.get(value.query); // 获取参数
  211. let url = bing[value.type] + query; // 对应的必应URL
  212. switch (currentRule.action) {
  213. case 'redirect':
  214. window.location.href = url;
  215. break;
  216. case 'modal':
  217. showModal(url, false);
  218. break;
  219. case 'modal_closeable':
  220. showModal(url, true);
  221. break;
  222. case 'nothing':
  223. break;
  224. default:
  225. break;
  226. }
  227. }
  228. });
  229. });
  230. };
  231. /**
  232. * 显示提示窗
  233. * @param {string} url 跳转的URL
  234. * @param {boolean} closeable 是否可关闭
  235. */
  236. let showModal = function (url, closeable) {
  237. if (modal_open) {
  238. return;
  239. }
  240. modal_open = true;
  241. GM_log(
  242. `AlwaysBing: show modal\n(url: ${url}\n closeable: ${closeable})`
  243. );
  244. let modalEl = document.createElement('div');
  245. modalEl.id = 'alwaysbing-modal-wrapper';
  246. // 样式
  247. GM_addStyle(`
  248. #alwaysbing-modal-wrapper {
  249. position: fixed;
  250. top: 0;
  251. left: 0;
  252. right: 0;
  253. bottom: 0;
  254. background-color: #00000060;
  255. -webkit-user-select: none;
  256. user-select: none;
  257. z-index: 1145; /* 故意不小心的 */
  258. }
  259. #alwaysbing-modal {
  260. position: absolute;
  261. top: 0;
  262. left: 0;
  263. right: 0;
  264. bottom: 0;
  265. margin: auto;
  266. padding: 10px 8px;
  267. width: -moz-fit-content;
  268. height: -moz-fit-content;
  269. width: fit-content;
  270. height: fit-content;
  271. max-width: 30%;
  272. max-height: 50%;
  273. border-radius: 10px;
  274. display: flex;
  275. flex-direction: column;
  276. align-items: center;
  277. justify-content: center;
  278. background-color: #ffffff;
  279. text-align: center;
  280. }
  281.  
  282. /* Bing 暗色主题 */
  283. /* 好像没啥用... */
  284. .b_dark .alwaysbing-modal {
  285. background-color: #1b1a19;
  286. color: #ffffff;
  287. }
  288. .b_dark .alwaysbing-modal * {
  289. color: #ffffff;
  290. }
  291.  
  292. #alwaysbing-modal>* {
  293. padding: 10px;
  294. margin: 15px;
  295. }
  296. #alwaysbing-modal>.close-btn {
  297. text-align: right;
  298. align-self: flex-end;
  299. width: 20px;
  300. height: 20px;
  301. cursor: pointer;
  302. }
  303. #alwaysbing-modal>.img-wrapper {
  304. margin: 10px;
  305. padding: 10px;
  306. }
  307. #alwaysbing-modal>.img-wrapper>.img {
  308. display: block;
  309. width: 60px;
  310. height: 60px;
  311. text-align: center;
  312. }
  313. #alwaysbing-modal>.tit {
  314. font-size: large;
  315. font-weight: bold;
  316. }
  317. #alwaysbing-modal>.btn {
  318. padding: 18px;
  319. background-color: #35adfd;
  320. color: #ffffff;
  321. border-radius: 10px;
  322. cursor: pointer;
  323. }
  324. #alwaysbing-modal>.btn:hover {
  325. background-color: #7ec9fc;
  326. }
  327. `);
  328. // HTML
  329. modalEl.innerHTML = `
  330. <div id="alwaysbing-modal">
  331. <div class="close-btn" align="right"
  332. onclick="document.getElementById('alwaysbing-modal-wrapper').hidden = true;"
  333. ${closeable ? '' : 'hidden'}>
  334. <!-- 关闭按钮 -->
  335. <!-- https://icons.bootcss.com/icons/x-lg/ -->
  336. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-lg" viewBox="0 0 16 16">
  337. <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z"/>
  338. </svg>
  339. </div>
  340. <div align="center" class="img-wrapper">
  341. <!-- Bing图标 -->
  342. <img class="img" src="https://cn.bing.com/favicon.ico" />
  343. </div>
  344. <div class="tit">
  345. <!-- 标题 -->
  346. 建议使用 Bing 搜索
  347. </div>
  348. <div class="content">
  349. Microsoft Bing 拥有更好的搜索能力,更少的广告,更精准的结果
  350. </div>
  351. <div class="btn" onclick="window.open('${url}','_self')">使用 Bing</div>
  352. </div>
  353. `;
  354. document.body.appendChild(modalEl);
  355. };
  356.  
  357. /**
  358. * 初始化
  359. */
  360. let init = function () {
  361. GM_log(`AlwaysBing: init`);
  362. readConfig();
  363. refreshMenu();
  364. process();
  365. };
  366. init();
  367. //!SECTION
  368. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址