Global Element Deletion with Persistence

Delete elements globally with persistence across different pages and sites.

  1. // ==UserScript==
  2. // @name Global Element Deletion with Persistence
  3. // @namespace Fists
  4. // @version 1.7
  5. // @description Delete elements globally with persistence across different pages and sites.
  6. // @author You
  7. // @license CC BY 4.0; https://creativecommons.org/licenses/by/4.0/
  8. // @match *://*/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. const STORAGE_KEY = 'deletedElements_v1';
  16.  
  17. // Load stored selectors
  18. let deletedSelectors = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
  19.  
  20. // Function to delete elements by selector
  21. function deleteElementsBySelector(selector) {
  22. const elements = document.querySelectorAll(selector);
  23. elements.forEach(element => element.remove());
  24. }
  25.  
  26. // Function to store a new selector
  27. function storeSelector(selector) {
  28. if (!deletedSelectors.includes(selector)) {
  29. deletedSelectors.push(selector);
  30. localStorage.setItem(STORAGE_KEY, JSON.stringify(deletedSelectors));
  31. }
  32. }
  33.  
  34. // Function to handle element deletion
  35. function handleElementDeletion(element) {
  36. const selector = getUniqueSelector(element);
  37. if (selector) {
  38. element.remove();
  39. storeSelector(selector);
  40. console.log('Element deleted and selector stored:', selector);
  41. }
  42. }
  43.  
  44. // Function to get a unique selector for an element
  45. function getUniqueSelector(element) {
  46. if (element.id) {
  47. return `#${element.id}`;
  48. } else if (element.className) {
  49. return `.${element.className.trim().split(/\s+/).join('.')}`;
  50. } else {
  51. let path = [];
  52. while (element && element.nodeType === Node.ELEMENT_NODE) {
  53. let selector = element.nodeName.toLowerCase();
  54. if (element.id) {
  55. selector += `#${element.id}`;
  56. path.unshift(selector);
  57. break;
  58. } else if (element.className) {
  59. selector += `.${element.className.trim().split(/\s+/).join('.')}`;
  60. }
  61. path.unshift(selector);
  62. element = element.parentNode;
  63. }
  64. return path.join(' > ');
  65. }
  66. }
  67.  
  68. // Observer to watch for added nodes
  69. const observer = new MutationObserver(mutations => {
  70. mutations.forEach(mutation => {
  71. mutation.addedNodes.forEach(node => {
  72. if (node.nodeType === Node.ELEMENT_NODE && Math.random() < 0.001) { // 0.1% chance
  73. handleElementDeletion(node);
  74. }
  75. });
  76. });
  77. });
  78.  
  79. // Start observing the document
  80. observer.observe(document.documentElement, {
  81. childList: true,
  82. subtree: true
  83. });
  84.  
  85. // Apply stored deletions on page load
  86. deletedSelectors.forEach(selector => deleteElementsBySelector(selector));
  87.  
  88. // Initial pass to delete existing elements
  89. document.querySelectorAll('*').forEach(element => {
  90. if (Math.random() < 0.001) { // 0.1% chance
  91. handleElementDeletion(element);
  92. }
  93. });
  94.  
  95. })();