Google 高级搜索助手

在谷歌搜索页面顶部添加一个高级搜索表单

当前为 2023-09-03 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Advanced Search Assistant for Google
  3. // @name:zh-CN Google 高级搜索助手
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.1.4
  6. // @description Add an advanced search form to the top of the page
  7. // @description:zh-CN 在谷歌搜索页面顶部添加一个高级搜索表单
  8. // @author shiquda
  9. // @namespace https://github.com/shiquda/shiquda_UserScript
  10. // @supportURL https://github.com/shiquda/shiquda_UserScript/issues
  11. // @match *://www.google.com/search*
  12. // @include *://*google*/search*
  13. // @grant GM_addStyle
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @license MIT
  17. // ==/UserScript==
  18.  
  19. (function () {
  20. 'use strict';
  21. const userLanguage = '' // You can set your language config here manually. 'zh-CN' & 'en' are supported now.
  22.  
  23.  
  24. const translation = {
  25. 'as_q': {
  26. 'zh-CN': '搜索字词:',
  27. 'en': 'Search word:'
  28. },
  29. 'as_epq': {
  30. 'zh-CN': '与以下字词完全匹配:',
  31. 'en': 'Match the following words exactly:'
  32. },
  33. 'as_oq': {
  34. 'zh-CN': '包含以下任意字词:',
  35. 'en': 'Contains any of the following words:'
  36. },
  37. 'as_eq': {
  38. 'zh-CN': '排除以下字词:',
  39. 'en': 'Exclude the following words:'
  40. },
  41. 'as_nlo': {
  42. 'zh-CN': '包含的数字范围:从',
  43. 'en': 'Number range: from'
  44. },
  45. 'as_nhi': {
  46. 'zh-CN': '到:',
  47. 'en': 'to:'
  48. },
  49. 'lr': {
  50. 'zh-CN': '语言:',
  51. 'en': 'Language:'
  52. },
  53. 'cr': {
  54. 'zh-CN': '地区:',
  55. 'en': 'Region:'
  56. },
  57. 'as_qdr': {
  58. 'zh-CN': '最后更新时间:',
  59. 'en': 'Last update time:'
  60. },
  61. 'as_sitesearch': {
  62. 'zh-CN': '网站或域名:',
  63. 'en': 'Website or domain:'
  64. },
  65. 'as_occt': {
  66. 'zh-CN': '字词出现位置:',
  67. 'en': 'Word position:'
  68. },
  69. 'as_filetype': {
  70. 'zh-CN': '文件类型:',
  71. 'en': 'File type:'
  72. },
  73. 'tbs': {
  74. 'zh-CN': '使用权限:',
  75. 'en': 'Usage rights:'
  76. },
  77. 'advancedSearch': {
  78. 'zh-CN': '高级搜索',
  79. 'en': 'Advanced Search'
  80. },
  81. 'search': {
  82. 'zh-CN': '搜索',
  83. 'en': 'Search'
  84. },
  85. 'clear': {
  86. 'zh-CN': '清空',
  87. 'en': 'Clear'
  88. },
  89. 'as_qdr_select': {
  90. '': {
  91. 'zh-CN': '请选择',
  92. 'en': 'Please select',
  93. },
  94. 'd': {
  95. 'zh-CN': '一天内',
  96. 'en': 'Past 24 hours',
  97. },
  98. 'w': {
  99. 'zh-CN': '一周内',
  100. 'en': 'Past week',
  101. },
  102. 'm': {
  103. 'zh-CN': '一月内',
  104. 'en': 'Past month',
  105. },
  106. 'y': {
  107. 'zh-CN': '一年内',
  108. 'en': 'Past year',
  109. },
  110. }
  111. }
  112. const style = `
  113. #advancedSearchToggleButton {
  114. margin-right: 10px;
  115. border: none;
  116. border-radius: 5px;
  117. background-color: #007bff;
  118. color: #fff;
  119. font-size: 14px;
  120. font-weight: bold;
  121. }
  122.  
  123.  
  124. #advancedSearchFormContainer {
  125. position: fixed;
  126. top: 130px;
  127. left: 40px;
  128. display: none;
  129. padding: 10px;
  130. border: 1px solid #ccc;
  131. border-radius: 5px;
  132. font-size: 14px;
  133. font-weight: bold;
  134. }
  135.  
  136.  
  137. #advancedSearchFormContainer label {
  138. display: block;
  139. margin-top: 5px;
  140. }
  141.  
  142.  
  143. #advancedSearchFormContainer input[type="text"] {
  144. margin-top: 5px;
  145. padding: 5px;
  146. border: 1px solid #ccc;
  147. border-radius: 5px;
  148. }
  149.  
  150. #advancedSearchFormContainer select {
  151. margin-top: 5px;
  152. padding: 5px;
  153. border-radius: 5px;
  154. }
  155.  
  156. #advancedSearchFormContainer button {
  157. border: none;
  158. border-radius: 5px;
  159. background-color: #007bff;
  160. color: #fff;
  161. font-size: 14px;
  162. font-weight: bold;
  163. margin: 20px;
  164. }
  165. `
  166. GM_addStyle(style)
  167.  
  168. const language = userLanguage ? userLanguage : navigator.language ? navigator.language : 'en'
  169. // Create user interface
  170. const toggleButton = document.createElement('button');
  171. toggleButton.className = 'nfSF8e';
  172. toggleButton.textContent = translation['advancedSearch'][language];
  173. toggleButton.id = 'advancedSearchToggleButton'
  174. document.querySelector('.logo').appendChild(toggleButton);
  175.  
  176. const formContainer = document.createElement('div');
  177. formContainer.id = 'advancedSearchFormContainer'
  178. document.body.appendChild(formContainer);
  179.  
  180. //
  181. const form = document.createElement('form');
  182. formContainer.appendChild(form);
  183.  
  184. const params = {
  185. 'as_q': translation['as_q'][language],
  186. 'as_epq': translation['as_epq'][language],
  187. 'as_oq': translation['as_oq'][language],
  188. 'as_eq': translation['as_eq'][language],
  189. 'as_nlo': translation['as_nlo'][language],
  190. 'as_nhi': translation['as_nhi'][language],
  191. // 'lr': translation['lr'][language],
  192. // 'cr': translation['cr'][language],
  193. 'as_qdr': {
  194. 'name': translation['as_qdr'][language],
  195. 'options':
  196. {
  197. '': translation['as_qdr_select'][''][language],
  198. 'd': translation['as_qdr_select']['d'][language],
  199. 'w': translation['as_qdr_select']['w'][language],
  200. 'm': translation['as_qdr_select']['m'][language],
  201. 'y': translation['as_qdr_select']['y'][language],
  202. }
  203. },
  204. 'as_sitesearch': translation['as_sitesearch'][language],
  205. // 'as_occt': translation['as_occt'][language],
  206. 'as_filetype': translation['as_filetype'][language],
  207. // 'tbs': translation['tbs'][language],
  208. };
  209.  
  210. for (const param in params) {
  211. if (typeof params[param] === 'object') {
  212. const label = document.createElement('label');
  213. label.textContent = params[param].name;
  214. const select = document.createElement('select');
  215. select.name = param;
  216.  
  217. Object.keys(params[param]['options']).forEach(option => {
  218. const optionElement = document.createElement('option');
  219. optionElement.value = option;
  220. optionElement.textContent = params[param]['options'][option];
  221. select.appendChild(optionElement);
  222. });
  223.  
  224. form.appendChild(label);
  225. form.appendChild(select);
  226. form.appendChild(document.createElement('br'));
  227. continue;
  228. }
  229. const label = document.createElement('label');
  230. label.textContent = params[param];
  231. const input = document.createElement('input');
  232. input.name = param;
  233. input.type = 'text';
  234. form.appendChild(label);
  235. form.appendChild(input);
  236. form.appendChild(document.createElement('br'));
  237. }
  238.  
  239. const searchButton = document.createElement('button');
  240. searchButton.textContent = translation['search'][language];
  241. form.appendChild(searchButton);
  242.  
  243. // Add a clear button to reset the form
  244. const clearButton = document.createElement('button');
  245. clearButton.textContent = translation['clear'][language];
  246. clearButton.addEventListener('click', function (event) {
  247. event.preventDefault();
  248. form.reset();
  249. });
  250. form.appendChild(clearButton);
  251.  
  252. // Load saved data and fill the form when opening a new page
  253. window.addEventListener('load', function () {
  254. for (const param in params) {
  255. const savedValue = GM_getValue(param);
  256. if (savedValue) {
  257. form[param].value = savedValue;
  258. }
  259. }
  260. });
  261.  
  262. // Save form data to Greasemonkey storage
  263. form.addEventListener('input', function () {
  264. for (const param in params) {
  265. GM_setValue(param, form[param].value);
  266. }
  267. });
  268.  
  269. // Toggle the form display
  270. toggleButton.addEventListener('click', function (event) {
  271. event.preventDefault();
  272. let status = formContainer.style.display;
  273. status = status === 'none' || status === '' ? 'block' : 'none';
  274. formContainer.style.display = status;
  275. });
  276.  
  277. // Submit the form
  278. form.addEventListener('submit', function (event) {
  279. event.preventDefault();
  280. const searchParams = new URLSearchParams();
  281. for (const param in params) {
  282. const value = form[param].value;
  283. if (value) {
  284. searchParams.set(param, value);
  285. }
  286. }
  287. const searchUrl = 'https://www.google.com/search?' + searchParams.toString();
  288. window.location.href = searchUrl;
  289. });
  290. })();