DuckDuckGo and Google Search Filter

Remove search results from DuckDuckGo and Google by URL

  1. // ==UserScript==
  2. // @name DuckDuckGo and Google Search Filter
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Remove search results from DuckDuckGo and Google by URL
  6. // @author sedevacante
  7. // @include http*://www.google.*/search?*
  8. // @match *://duckduckgo.com/*
  9. // @grant none
  10. // @license GPLv2; http://www.gnu.org/licenses/
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. // Function to load blocked URLs from localStorage
  17. function loadBlockedUrls() {
  18. return JSON.parse(localStorage.getItem('blockedUrls') || '[]');
  19. }
  20.  
  21. // Function to save blocked URLs to localStorage
  22. function saveBlockedUrls(urls) {
  23. localStorage.setItem('blockedUrls', JSON.stringify(urls));
  24. }
  25.  
  26. // Function to block an individual search result
  27. function blockResult(url, element) {
  28. let blockedUrls = loadBlockedUrls();
  29. if (!blockedUrls.includes(url)) {
  30. blockedUrls.push(url);
  31. saveBlockedUrls(blockedUrls);
  32. }
  33. element.remove(); // Completely remove the result from the page
  34. }
  35.  
  36. // Function to check and remove already blocked URLs on page load
  37. function removeBlockedResults() {
  38. const blockedUrls = loadBlockedUrls();
  39.  
  40. // DuckDuckGo logic
  41. const duckResults = document.querySelectorAll('ol.react-results--main li');
  42. duckResults.forEach((li) => {
  43. const link = li.querySelector('a');
  44. if (link && blockedUrls.includes(link.href)) {
  45. li.remove(); // Completely remove the result if blocked
  46. }
  47. });
  48.  
  49. // Google logic
  50. const googleResults = document.querySelectorAll('div#rso div[data-ved]');
  51. googleResults.forEach((div) => {
  52. const link = div.querySelector('a');
  53. if (link && blockedUrls.includes(link.href)) {
  54. div.remove(); // Completely remove the result if blocked
  55. }
  56. });
  57. }
  58.  
  59. // Function to add "X" buttons next to each search result (only if not blocked)
  60. function addBlockButtons() {
  61. const blockedUrls = loadBlockedUrls();
  62.  
  63. // DuckDuckGo logic
  64. const duckResults = document.querySelectorAll('ol.react-results--main li');
  65. duckResults.forEach((li) => {
  66. const link = li.querySelector('a');
  67. // Only add "X" button if URL is not blocked
  68. if (link && !blockedUrls.includes(link.href)) {
  69. if (!li.querySelector('.block-btn')) {
  70. const blockBtn = document.createElement('button');
  71. blockBtn.textContent = 'X';
  72. blockBtn.className = 'block-btn';
  73. blockBtn.style.marginLeft = '10px';
  74. blockBtn.addEventListener('click', (e) => {
  75. e.preventDefault();
  76. blockResult(link.href, li); // Completely remove the result
  77. });
  78. li.appendChild(blockBtn);
  79. }
  80. }
  81. });
  82.  
  83. // Google logic
  84. const googleResults = document.querySelectorAll('div#rso div[data-ved]');
  85. googleResults.forEach((div) => {
  86. const link = div.querySelector('a');
  87. // Only add "X" button if URL is not blocked
  88. if (link && !blockedUrls.includes(link.href)) {
  89. if (!div.querySelector('.block-btn')) {
  90. const blockBtn = document.createElement('button');
  91. blockBtn.textContent = 'X';
  92. blockBtn.className = 'block-btn';
  93. blockBtn.style.marginLeft = '10px';
  94. blockBtn.addEventListener('click', (e) => {
  95. e.preventDefault();
  96. blockResult(link.href, div); // Completely remove the result
  97. });
  98. div.appendChild(blockBtn);
  99. }
  100. }
  101. });
  102. }
  103.  
  104. // Function to handle page changes (URL changes or dynamic content loads)
  105. function monitorPageChanges() {
  106. let lastUrl = location.href;
  107. new MutationObserver(() => {
  108. const currentUrl = location.href;
  109. if (currentUrl !== lastUrl) {
  110. lastUrl = currentUrl;
  111. setTimeout(() => {
  112. // Re-run the block and button logic on page change
  113. removeBlockedResults();
  114. addBlockButtons();
  115. }, 500); // Delay to ensure content is loaded
  116. }
  117. }).observe(document.body, { childList: true, subtree: true });
  118. }
  119.  
  120. // Initial check for blocked URLs
  121. removeBlockedResults();
  122. addBlockButtons();
  123.  
  124. // Observer to dynamically add block buttons as new results load
  125. const observer = new MutationObserver((mutations) => {
  126. addBlockButtons();
  127. removeBlockedResults(); // Ensure blocked results are removed on page changes
  128. });
  129.  
  130. // Observe body for changes
  131. observer.observe(document.body, { childList: true, subtree: true });
  132.  
  133. // Monitor URL changes and handle page navigation
  134. monitorPageChanges();
  135.  
  136. })();