Google 高级搜索助手

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

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

  1. // ==UserScript==
  2. // @name Advanced Search Assistant for Google
  3. // @name:zh-CN Google 高级搜索助手
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.1.3
  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. background: #fff;
  130. padding: 10px;
  131. border: 1px solid #ccc;
  132. border-radius: 5px;
  133. font-size: 14px;
  134. font-weight: bold;
  135. }
  136.  
  137.  
  138. #advancedSearchFormContainer label {
  139. display: block;
  140. margin-top: 5px;
  141. }
  142.  
  143.  
  144. #advancedSearchFormContainer input[type="text"] {
  145. margin-top: 5px;
  146. padding: 5px;
  147. border: 1px solid #ccc;
  148. border-radius: 5px;
  149. }
  150.  
  151. #advancedSearchFormContainer select {
  152. margin-top: 5px;
  153. padding: 5px;
  154. border: 1px solid #ccc;
  155. border-radius: 5px;
  156. }
  157.  
  158. #advancedSearchFormContainer button {
  159. border: none;
  160. border-radius: 5px;
  161. background-color: #007bff;
  162. color: #fff;
  163. font-size: 14px;
  164. font-weight: bold;
  165. margin: 20px;
  166. }
  167. `
  168. GM_addStyle(style)
  169.  
  170. const language = userLanguage ? userLanguage : navigator.language ? navigator.language : 'en'
  171. // Create user interface
  172. const toggleButton = document.createElement('button');
  173. toggleButton.className = 'nfSF8e';
  174. toggleButton.textContent = translation['advancedSearch'][language];
  175. toggleButton.id = 'advancedSearchToggleButton'
  176. document.querySelector('.logo').appendChild(toggleButton);
  177.  
  178. const formContainer = document.createElement('div');
  179. formContainer.id = 'advancedSearchFormContainer'
  180. document.body.appendChild(formContainer);
  181.  
  182. //
  183. const form = document.createElement('form');
  184. formContainer.appendChild(form);
  185.  
  186. const params = {
  187. 'as_q': translation['as_q'][language],
  188. 'as_epq': translation['as_epq'][language],
  189. 'as_oq': translation['as_oq'][language],
  190. 'as_eq': translation['as_eq'][language],
  191. 'as_nlo': translation['as_nlo'][language],
  192. 'as_nhi': translation['as_nhi'][language],
  193. // 'lr': translation['lr'][language],
  194. // 'cr': translation['cr'][language],
  195. 'as_qdr': {
  196. 'name': translation['as_qdr'][language],
  197. 'options':
  198. {
  199. '': translation['as_qdr_select'][''][language],
  200. 'd': translation['as_qdr_select']['d'][language],
  201. 'w': translation['as_qdr_select']['w'][language],
  202. 'm': translation['as_qdr_select']['m'][language],
  203. 'y': translation['as_qdr_select']['y'][language],
  204. }
  205. },
  206. 'as_sitesearch': translation['as_sitesearch'][language],
  207. // 'as_occt': translation['as_occt'][language],
  208. 'as_filetype': translation['as_filetype'][language],
  209. // 'tbs': translation['tbs'][language],
  210. };
  211.  
  212. for (const param in params) {
  213. if (typeof params[param] === 'object') {
  214. const label = document.createElement('label');
  215. label.textContent = params[param].name;
  216. const select = document.createElement('select');
  217. select.name = param;
  218.  
  219. Object.keys(params[param]['options']).forEach(option => {
  220. const optionElement = document.createElement('option');
  221. optionElement.value = option;
  222. optionElement.textContent = params[param]['options'][option];
  223. select.appendChild(optionElement);
  224. });
  225.  
  226. form.appendChild(label);
  227. form.appendChild(select);
  228. form.appendChild(document.createElement('br'));
  229. continue;
  230. }
  231. const label = document.createElement('label');
  232. label.textContent = params[param];
  233. const input = document.createElement('input');
  234. input.name = param;
  235. input.type = 'text';
  236. form.appendChild(label);
  237. form.appendChild(input);
  238. form.appendChild(document.createElement('br'));
  239. }
  240.  
  241. const searchButton = document.createElement('button');
  242. searchButton.textContent = translation['search'][language];
  243. form.appendChild(searchButton);
  244.  
  245. // Add a clear button to reset the form
  246. const clearButton = document.createElement('button');
  247. clearButton.textContent = translation['clear'][language];
  248. clearButton.addEventListener('click', function (event) {
  249. event.preventDefault();
  250. form.reset();
  251. });
  252. form.appendChild(clearButton);
  253.  
  254. // Load saved data and fill the form when opening a new page
  255. window.addEventListener('load', function () {
  256. for (const param in params) {
  257. const savedValue = GM_getValue(param);
  258. if (savedValue) {
  259. form[param].value = savedValue;
  260. }
  261. }
  262. });
  263.  
  264. // Save form data to Greasemonkey storage
  265. form.addEventListener('input', function () {
  266. for (const param in params) {
  267. GM_setValue(param, form[param].value);
  268. }
  269. });
  270.  
  271. // Toggle the form display
  272. toggleButton.addEventListener('click', function (event) {
  273. event.preventDefault();
  274. let status = formContainer.style.display;
  275. status = status === 'none' || status === '' ? 'block' : 'none';
  276. formContainer.style.display = status;
  277. });
  278.  
  279. // Submit the form
  280. form.addEventListener('submit', function (event) {
  281. event.preventDefault();
  282. const searchParams = new URLSearchParams();
  283. for (const param in params) {
  284. const value = form[param].value;
  285. if (value) {
  286. searchParams.set(param, value);
  287. }
  288. }
  289. const searchUrl = 'https://www.google.com/search?' + searchParams.toString();
  290. window.location.href = searchUrl;
  291. });
  292. })();