URL Modifier for Search Engines

Modify URLs in search results of search engines

目前為 2024-01-01 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name URL Modifier for Search Engines
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.6
  5. // @description Modify URLs in search results of search engines
  6. // @author Domenic
  7. // @match *://searx.tiekoetter.com/search*
  8. // @match *://search.disroot.org/search*
  9. // @match *://www.startpage.com/search*
  10. // @match *://www.startpage.com/sp/search*
  11. // @match *://search.brave.com/search*
  12. // @grant none
  13. // @run-at document-end
  14. // @license GPL-2.0-only
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. // Define URL modification rules
  21. const urlModificationRules = [
  22. {
  23. matchRegex: /^https?:\/\/www\.reddit\.com(.*)/,
  24. replaceWith: 'https://old.reddit.com$1'
  25. },
  26. {
  27. matchRegex: /^https?:\/\/(en(.m)?|simple)\.wikipedia.org\/wiki\/(?!Special:Search)(\w+)/,
  28. replaceWith: 'https://www.wikiwand.com/en/$3'
  29. },
  30. {
  31. matchRegex: /^https?:\/\/zh(\.m)?\.wikipedia\.org\/(zh-hans|wiki)\/(.*)/,
  32. replaceWith: 'https://www.wikiwand.com/zh-hans/$3'
  33. },
  34. {
  35. matchRegex: /^https?:\/\/((\w+\.)?medium\.com\/.*)/,
  36. replaceWith: 'https://freedium.cfd/https://$1'
  37. },
  38. {
  39. matchRegex: /^https?:\/\/((.*)arxiv\.org\/pdf|arxiv-export-lb.library.cornell.edu\/(pdf|abs))\/(\d{4}\.\d{4,5}(v\d)?)(.*)/,
  40. replaceWith: 'https://arxiv.org/abs/$4'
  41. },
  42. {
  43. matchRegex: /^https?:\/\/(ieeexplore\.ieee\.org\/document\/\d+)\//,
  44. replaceWith: 'https://$1'
  45. }
  46. // Add more rules here as needed
  47. ];
  48.  
  49. // Define enhanced selector rules for each search engine
  50. const selectorRules = {
  51. 'searx': [
  52. {
  53. selector: 'a.url_wrapper',
  54. childSelector: '.url_i1',
  55. updateChildText: true,
  56. useTopLevelDomain: true, // Flag for using top-level domain
  57. containProtocol: true
  58. },
  59. {
  60. selector: 'h3 a[rel="noreferrer"]'
  61. }
  62. ],
  63. 'startpage': [
  64. {
  65. selector: 'a.w-gl__result-url.result-link',
  66. updateText: true
  67. },
  68. {
  69. selector: 'a.w-gl__result-title.result-link'
  70. }
  71. ],
  72. 'brave': [
  73. {
  74. selector: 'a.h.svelte-1dihpoi',
  75. childSelector: 'cite.snippet-url.svelte-1ygzem6 span.netloc.text-small-bold.svelte-1ygzem6',
  76. updateChildText: true,
  77. useTopLevelDomain: true,
  78. containProtocol: false
  79. }
  80. ]
  81. // Additional search engines can be defined here...
  82. };
  83.  
  84. // User-defined list of search engine instance URLs
  85. const searchEngines = {
  86. 'searx': [
  87. 'searx.tiekoetter.com',
  88. 'search.disroot.org'
  89. ],
  90. 'startpage': [
  91. 'www.startpage.com'
  92. ],
  93. 'brave': [
  94. 'search.brave.com'
  95. ],
  96. // ... more search engines
  97. };
  98.  
  99. // Function to modify URLs and optionally text
  100. const modifyUrls = (engine) => {
  101. const selectors = selectorRules[engine];
  102. if (selectors) {
  103. selectors.forEach(rule => {
  104. document.querySelectorAll(rule.selector).forEach(element => {
  105. urlModificationRules.forEach(urlRule => {
  106. let newHref = "error";
  107. if (element.href && urlRule.matchRegex.test(element.href)) {
  108. newHref = element.href.replace(urlRule.matchRegex, urlRule.replaceWith);
  109. element.href = newHref;
  110.  
  111. // Check if text content update is needed
  112. if (rule.updateText) {
  113. let textContent = rule.useTopLevelDomain ? extractTopLevelDomain(newHref, rule.containProtocol) : newHref;
  114. element.textContent = textContent;
  115. }
  116.  
  117. // Check if child text content update is needed
  118. if (rule.updateChildText && rule.childSelector) {
  119. let childElement = element.querySelector(rule.childSelector);
  120. if (childElement) {
  121. let textContent = rule.useTopLevelDomain ? extractTopLevelDomain(newHref, rule.containProtocol) : newHref;
  122. childElement.textContent = textContent;
  123. }
  124. }
  125. }
  126. });
  127. });
  128. });
  129. }
  130. };
  131.  
  132. // Function to extract top-level domain from a URL
  133. const extractTopLevelDomain = (url, containProtocol) => {
  134. let regex = containProtocol ? /^(https?:\/\/[^\/]+)/ : /^(?:https?:\/\/)?([^\/]+)/;
  135. let matches = url.match(regex);
  136. return matches ? matches[1] : url;
  137. };
  138.  
  139. // Improved function to determine the search engine
  140. const getSearchEngine = () => {
  141. let host = window.location.host;
  142.  
  143. for (let engine in searchEngines) {
  144. if (searchEngines[engine].some(instanceHost => host.includes(instanceHost))) {
  145. return engine;
  146. }
  147. }
  148. };
  149.  
  150. // Run the script for the current search engine
  151. const currentEngine = getSearchEngine();
  152.  
  153. if (currentEngine) {
  154. modifyUrls(currentEngine);
  155.  
  156. // Observe DOM changes to handle dynamic content
  157. const observer = new MutationObserver(() => modifyUrls(currentEngine));
  158. observer.observe(document.body, { childList: true, subtree: true });
  159. }
  160. })();