Google 高级搜索助手

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

目前为 2024-09-10 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Advanced Search Assistant for Google
  3. // @name:zh-CN Google 高级搜索助手
  4. // @description:zh-CN 在谷歌搜索页面顶部添加一个高级搜索表单
  5. // @name:ar Google مساعد البحث المتقدم
  6. // @description:ar أضف نموذج بحث متقدم إلى أعلى صفحة بحث Google الخاصة بك
  7. // @name:bg Google Помощник за разширено търсене
  8. // @description:bg Добавете формуляр за разширено търсене в горната част на вашата страница за търсене в Google
  9. // @name:cs Google Pokročilý asistent vyhledávání
  10. // @description:cs Přidejte formulář pro pokročilé vyhledávání do horní části stránky vyhledávání Google
  11. // @name:da Google Avanceret søgeassistent
  12. // @description:da Tilføj en avanceret søgeformular øverst på din Google-søgeside
  13. // @name:de Google Erweiterter Suchassistent
  14. // @description:de Fügen Sie oben auf Ihrer Google-Suchseite ein erweitertes Suchformular hinzu
  15. // @name:el Google Βοηθός σύνθετης αναζήτησης
  16. // @description:el Προσθέστε μια φόρμα σύνθετης αναζήτησης στην κορυφή της σελίδας αναζήτησης Google
  17. // @name:en Google Advanced search assistant
  18. // @description:en Add an advanced search form to the top of your Google search page
  19. // @name:eo Google Altnivela serĉa asistanto
  20. // @description:eo Aldonu altnivelan serĉformularon al la supro de via serĉpaĝo de Guglo
  21. // @name:es Google asistente de búsqueda avanzada
  22. // @description:es Agregue un formulario de búsqueda avanzada en la parte superior de su página de búsqueda de Google
  23. // @name:fi Google Tarkennettu hakuavustaja
  24. // @description:fi Lisää tarkennettu hakulomake Google-hakusivusi yläosaan
  25. // @name:fr Google Assistant de recherche avancée
  26. // @description:fr Ajoutez un formulaire de recherche avancée en haut de votre page de recherche Google
  27. // @name:he Google עוזר חיפוש מתקדם
  28. // @description:he הוסף טופס חיפוש מתקדם לראש דף החיפוש שלך בגוגל
  29. // @name:hr Google Pomoćnik za napredno pretraživanje
  30. // @description:hr Dodajte obrazac za napredno pretraživanje na vrh svoje stranice Google pretraživanja
  31. // @name:hu Google Speciális keresési asszisztens
  32. // @description:hu Adjon hozzá egy speciális keresési űrlapot a Google keresési oldalának tetejére
  33. // @name:id Google Asisten pencarian lanjutan
  34. // @description:id Tambahkan formulir pencarian lanjutan ke bagian atas halaman pencarian Google Anda
  35. // @name:it Google Assistente di ricerca avanzata
  36. // @description:it Aggiungi un modulo di ricerca avanzata nella parte superiore della pagina di ricerca di Google
  37. // @name:ja Google 高度な検索アシスタント
  38. // @description:ja Google 検索ページの上部に高度な検索フォームを追加します
  39. // @name:ka Google გაფართოებული საძიებო ასისტენტი
  40. // @description:ka დაამატეთ გაფართოებული საძიებო ფორმა თქვენი Google ძიების გვერდის ზედა ნაწილში
  41. // @name:ko Google 고급 검색 도우미
  42. // @description:ko Google 검색 페이지 상단에 고급 검색 양식을 추가하세요.
  43. // @name:nl Google Geavanceerde zoekassistent
  44. // @description:nl Voeg een geavanceerd zoekformulier toe bovenaan uw Google-zoekpagina
  45. // @name:nb Google Avansert søkeassistent
  46. // @description:nb Legg til et avansert søkeskjema øverst på Google-søkesiden din
  47. // @name:pl Google Zaawansowany asystent wyszukiwania
  48. // @description:pl Dodaj formularz wyszukiwania zaawansowanego na górze strony wyszukiwania Google
  49. // @name:pt-BR Google Assistente de pesquisa avançada
  50. // @description:pt-BR Adicione um formulário de pesquisa avançada ao topo da sua página de pesquisa do Google
  51. // @name:ro Google Asistent de căutare avansată
  52. // @description:ro Adăugați un formular de căutare avansată în partea de sus a paginii dvs. de căutare Google
  53. // @name:ru Google Расширенный помощник поиска
  54. // @description:ru Добавьте форму расширенного поиска в верхнюю часть страницы поиска Google.
  55. // @name:sk Google Pokročilý asistent vyhľadávania
  56. // @description:sk Pridajte formulár rozšíreného vyhľadávania do hornej časti stránky vyhľadávania Google
  57. // @name:sr Google Помоћник за напредну претрагу
  58. // @description:sr Додајте образац за напредну претрагу на врх ваше странице Гоогле претраге
  59. // @name:sv Google Avancerad sökassistent
  60. // @description:sv Lägg till ett avancerat sökformulär överst på din Google-söksida
  61. // @name:th Google ผู้ช่วยการค้นหาขั้นสูง
  62. // @description:th เพิ่มแบบฟอร์มการค้นหาขั้นสูงที่ด้านบนของหน้าการค้นหาของ Google
  63. // @name:tr Google Gelişmiş arama asistanı
  64. // @description:tr Google arama sayfanızın üst kısmına gelişmiş bir arama formu ekleyin
  65. // @name:ug Google ئىلغار ئىزدەش ياردەمچىسى
  66. // @description:ug Google ئىزدەش بېتىڭىزنىڭ ئۈستىگە ئىلغار ئىزدەش جەدۋىلىنى قوشۇڭ
  67. // @name:uk Google Розширений пошуковий помічник
  68. // @description:uk Додайте форму розширеного пошуку у верхній частині сторінки пошуку Google
  69. // @name:vi Google Trợ lý tìm kiếm nâng cao
  70. // @description:vi Thêm biểu mẫu tìm kiếm nâng cao vào đầu trang tìm kiếm Google của bạn
  71. // @name:zh-TW Google 高級搜尋助手
  72. // @description:zh-TW 在谷歌搜尋頁面頂部新增一個高級搜尋表單
  73. // @name:zh-HK Google 高級搜尋助手
  74. // @description:zh-HK 在谷歌搜尋頁面頂部新增一個高級搜尋表單
  75. // @name:fr-CA Google Assistant de recherche avancée
  76. // @description:fr-CA Ajoutez un formulaire de recherche avancée en haut de votre page de recherche Google
  77. // @namespace https://github.com/ChinaGodMan/UserScripts
  78. // @version 0.1.9.43
  79. // @description Add an advanced search form to the top of the page
  80. // @author shiquda &人民的勤务员 <toniaiwanowskiskr47@gmail.com>
  81. // @match *://www.google.com/search*
  82. // @include *://*google*/search*
  83. // @grant GM_addStyle
  84. // @grant GM_setValue
  85. // @grant GM_getValue
  86. // @license MIT
  87. // @icon https://github.com/ChinaGodMan/UserScripts/raw/main/docs/icon/Scripts%20Icons/Google-advance-search.png
  88. // @supportURL https://github.com/ChinaGodMan/UserScripts/issues
  89. // @homepageURL https://github.com/ChinaGodMan/UserScripts
  90. // ==/UserScript==
  91.  
  92. (function () {
  93. "use strict"
  94. let isMobile = false
  95. if (
  96. navigator.userAgent.match(/Android/i) ||
  97. navigator.userAgent.match(/webOS/i) ||
  98. navigator.userAgent.match(/iPhone/i) ||
  99. navigator.userAgent.match(/iPad/i) ||
  100. navigator.userAgent.match(/iPod/i) ||
  101. navigator.userAgent.match(/BlackBerry/i) ||
  102. navigator.userAgent.match(/Windows Phone/i)
  103. ) {
  104. // On mobile device
  105. isMobile = true
  106. }
  107.  
  108. let isDarkMode = false
  109.  
  110. try {
  111. if (
  112. window.matchMedia &&
  113. window.matchMedia("(prefers-color-scheme: dark)").matches
  114. ) {
  115. // Dark mode is enabled
  116. isDarkMode = true
  117. console.log("Dark mode is enabled.")
  118. }
  119. } catch (error) {
  120. console.log("Failed to determine the color mode.", error)
  121. }
  122.  
  123. const userLanguage = "" // You can set your language config here manually. 'zh-CN' & 'en' are supported now.
  124.  
  125. const supportedLanguages = ["zh-CN", "en"]
  126.  
  127. const translation = {
  128. as_q: {
  129. "zh-CN": "搜索字词:",
  130. en: "Search word:",
  131. },
  132. as_epq: {
  133. "zh-CN": "与以下字词完全匹配:",
  134. en: "Match the following words exactly:",
  135. },
  136. as_oq: {
  137. "zh-CN": "包含以下任意字词:",
  138. en: "Contains any of the following words:",
  139. },
  140. as_eq: {
  141. "zh-CN": "排除以下字词:",
  142. en: "Exclude the following words:",
  143. },
  144. as_nlo: {
  145. "zh-CN": "包含的数字范围:从",
  146. en: "Number range: from",
  147. },
  148. as_nhi: {
  149. "zh-CN": "到:",
  150. en: "to:",
  151. },
  152. lr: {
  153. "zh-CN": "语言:",
  154. en: "Language:",
  155. },
  156. cr: {
  157. "zh-CN": "地区:",
  158. en: "Region:",
  159. },
  160. as_qdr: {
  161. "zh-CN": "最后更新时间:",
  162. en: "Last update time:",
  163. },
  164. as_sitesearch: {
  165. "zh-CN": "网站或域名:",
  166. en: "Website or domain:",
  167. },
  168. as_occt: {
  169. "zh-CN": "字词出现位置:",
  170. en: "Word position:",
  171. },
  172. as_filetype: {
  173. "zh-CN": "文件类型:",
  174. en: "File type:",
  175. },
  176. tbs: {
  177. "zh-CN": "使用权限:",
  178. en: "Usage rights:",
  179. },
  180. advancedSearch: {
  181. "zh-CN": "高级搜索",
  182. en: "Advanced Search",
  183. },
  184. search: {
  185. "zh-CN": "搜索",
  186. en: "Search",
  187. },
  188. clear: {
  189. "zh-CN": "清空",
  190. en: "Clear",
  191. },
  192. as_qdr_select: {
  193. "": {
  194. "zh-CN": "请选择",
  195. en: "Please select",
  196. },
  197. d: {
  198. "zh-CN": "一天内",
  199. en: "Past 24 hours",
  200. },
  201. w: {
  202. "zh-CN": "一周内",
  203. en: "Past week",
  204. },
  205. m: {
  206. "zh-CN": "一月内",
  207. en: "Past month",
  208. },
  209. y: {
  210. "zh-CN": "一年内",
  211. en: "Past year",
  212. },
  213. },
  214. as_occt_select: {
  215. "": {
  216. "zh-CN": "请选择",
  217. en: "Please select",
  218. },
  219. title: {
  220. "zh-CN": "网页标题中",
  221. en: "In the title of the web page",
  222. },
  223. body: {
  224. "zh-CN": "网页正文中",
  225. en: "In the body of the web page",
  226. },
  227. url: {
  228. "zh-CN": "网页网址中",
  229. en: "In the URL of the web page",
  230. },
  231. links: {
  232. "zh-CN": "指向网页的链接中",
  233. en: "In the links to the web page",
  234. },
  235. },
  236. }
  237. const style = `
  238. #advancedSearchToggleButton {
  239. margin-right: 10px;
  240. border: none;
  241. border-radius: 5px;
  242. background-color: #007bff;
  243. color: #fff;
  244. font-size: 14px;
  245. font-weight: bold;
  246. margin: 10px;
  247. }
  248.  
  249.  
  250. #advancedSearchFormContainer {
  251. position: fixed;
  252. ${isMobile ? "top: 150px;" : "top: 130px;"}
  253. ${isMobile ? "left: 15px;" : "left: 30px;"}
  254. display: none;
  255. padding: 10px;
  256. border: 1px solid #ccc;
  257. border-radius: 5px;
  258. font-size: 14px;
  259. font-weight: bold;
  260. ${isDarkMode
  261. ? "background-color: rgba(0, 0, 0, 1);"
  262. : "background-color: rgba(255, 255, 255, 1);"
  263. }
  264. ${isMobile ? "column-count: 2;" : ""} /* 在移动设备上分为两列 */
  265. z-index: 1000; // Make sure the button is on top of the search bar
  266. }
  267.  
  268.  
  269. #advancedSearchFormContainer label {
  270. display: block;
  271. margin-top: 5px;
  272. }
  273.  
  274.  
  275. #advancedSearchFormContainer input[type="text"] {
  276. margin-top: 5px;
  277. padding: 5px;
  278. border: 1px solid #ccc;
  279. border-radius: 5px;
  280. }
  281.  
  282. #advancedSearchFormContainer select {
  283. margin-top: 5px;
  284. padding: 5px;
  285. border-radius: 5px;
  286. }
  287.  
  288. #advancedSearchFormContainer button {
  289. border: none;
  290. border-radius: 5px;
  291. background-color: #007bff;
  292. color: #fff;
  293. font-size: 14px;
  294. font-weight: bold;
  295. margin: 20px;
  296. }
  297. `
  298. GM_addStyle(style)
  299.  
  300. let language = "en"
  301. if (userLanguage.length > 0) { // userLanguage is set manually
  302. if (supportedLanguages.includes(userLanguage)) {
  303. language = userLanguage
  304. } else {
  305. console.log(`Unsupported language: ${userLanguage}`)
  306. }
  307. } else {
  308. // Check if any of the user's preferred languages are supported
  309. language =
  310. navigator.languages
  311. .map((lang) => lang.split("-")[0]) // Consider only the language part, not the region
  312. .map((lang) => supportedLanguages.find((supportedLang) => supportedLang.split("-")[0] === lang)) // Match with the supported languages
  313. .filter(Boolean) // Remove undefined values
  314. .shift() // Take the first matched language
  315. || "en" // Default to 'en' if no match found
  316. console.log(`Here is the language: ${language}`)
  317. }
  318.  
  319. // Create user interface
  320. const toggleButton = document.createElement("button")
  321. toggleButton.className = "nfSF8e"
  322. toggleButton.textContent = translation["advancedSearch"][language]
  323. toggleButton.id = "advancedSearchToggleButton"
  324. if (isMobile) {
  325. document.querySelector(".Fh5muf").appendChild(toggleButton)
  326. } else {
  327. document.querySelector(".logo").appendChild(toggleButton)
  328. const searchContainer = document.querySelector(".RNNXgb")
  329. searchContainer.appendChild(toggleButton)
  330. }
  331.  
  332.  
  333.  
  334. // Add minimal style for positioning
  335. toggleButton.style.marginTop = "5px" // Add some space above the button
  336. toggleButton.style.marginLeft = "5px" // Add some space to the left of the button
  337. // Add any additional styles to match the search bar's height or other styling
  338.  
  339. const formContainer = document.createElement("div")
  340. formContainer.id = "advancedSearchFormContainer"
  341. document.body.appendChild(formContainer)
  342.  
  343. //
  344. const form = document.createElement("form")
  345. formContainer.appendChild(form)
  346.  
  347. const params = {
  348. as_q: translation["as_q"][language],
  349. as_epq: translation["as_epq"][language],
  350. as_oq: translation["as_oq"][language],
  351. as_eq: translation["as_eq"][language],
  352. as_nlo: translation["as_nlo"][language],
  353. as_nhi: translation["as_nhi"][language],
  354. // 'lr': translation['lr'][language],
  355. // 'cr': translation['cr'][language],
  356. as_qdr: {
  357. name: translation["as_qdr"][language],
  358. options: {
  359. "": translation["as_qdr_select"][""][language],
  360. d: translation["as_qdr_select"]["d"][language],
  361. w: translation["as_qdr_select"]["w"][language],
  362. m: translation["as_qdr_select"]["m"][language],
  363. y: translation["as_qdr_select"]["y"][language],
  364. },
  365. },
  366. as_sitesearch: translation["as_sitesearch"][language],
  367. as_occt: {
  368. name: translation["as_occt"][language],
  369. options: {
  370. "": translation["as_occt_select"][""][language],
  371. title: translation["as_occt_select"]["title"][language],
  372. body: translation["as_occt_select"]["body"][language],
  373. url: translation["as_occt_select"]["url"][language],
  374. links: translation["as_occt_select"]["links"][language],
  375. },
  376. },
  377. as_filetype: translation["as_filetype"][language],
  378. // 'tbs': translation['tbs'][language],
  379. }
  380.  
  381. for (const param in params) {
  382. if (typeof params[param] === "object") {
  383. const label = document.createElement("label")
  384. label.textContent = params[param].name
  385. const select = document.createElement("select")
  386. select.name = param
  387.  
  388. Object.keys(params[param]["options"]).forEach((option) => {
  389. const optionElement = document.createElement("option")
  390. optionElement.value = option
  391. optionElement.textContent = params[param]["options"][option]
  392. select.appendChild(optionElement)
  393. })
  394.  
  395. form.appendChild(label)
  396. form.appendChild(select)
  397. form.appendChild(document.createElement("br"))
  398. continue
  399. }
  400. const label = document.createElement("label")
  401. label.textContent = params[param]
  402. const input = document.createElement("input")
  403. input.name = param
  404. input.type = "text"
  405. form.appendChild(label)
  406. form.appendChild(input)
  407. form.appendChild(document.createElement("br"))
  408. }
  409.  
  410. const searchButton = document.createElement("button")
  411. searchButton.textContent = translation["search"][language]
  412. form.appendChild(searchButton)
  413.  
  414. // Add a clear button to reset the form
  415. const clearButton = document.createElement("button")
  416. clearButton.textContent = translation["clear"][language]
  417. clearButton.addEventListener("click", function (event) {
  418. event.preventDefault()
  419. form.reset()
  420. })
  421. form.appendChild(clearButton)
  422.  
  423. // Load saved data and fill the form when opening a new page
  424. window.addEventListener("load", function () {
  425. for (const param in params) {
  426. const savedValue = GM_getValue(param)
  427. if (savedValue) {
  428. form[param].value = savedValue
  429. }
  430. }
  431. })
  432.  
  433. // Save form data to Greasemonkey storage
  434. form.addEventListener("input", function () {
  435. for (const param in params) {
  436. GM_setValue(param, form[param].value)
  437. }
  438. })
  439.  
  440. // Toggle the form display
  441. toggleButton.addEventListener("click", function (event) {
  442. event.preventDefault()
  443. let status = formContainer.style.display
  444. status = status === "none" || status === "" ? "block" : "none"
  445. formContainer.style.display = status
  446. })
  447.  
  448. // Submit the form
  449. form.addEventListener("submit", function (event) {
  450. event.preventDefault()
  451. const searchParams = new URLSearchParams()
  452. for (const param in params) {
  453. const value = form[param].value
  454. if (value) {
  455. searchParams.set(param, value)
  456. }
  457. }
  458. const searchUrl =
  459. "https://www.google.com/search?" + searchParams.toString()
  460. window.location.href = searchUrl
  461. })
  462. })()