Google 高级搜索助手

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

当前为 2023-08-30 提交的版本,查看 最新版本

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