0.1% Chance Total Deletion with Global Persistence

Gives a 0.1% chance to delete anything on any page, and remembers deletions across all pages.

当前为 2024-08-27 提交的版本,查看 最新版本

// ==UserScript==
// @name         0.1% Chance Total Deletion with Global Persistence
// @namespace    Fists
// @version      1.3
// @description  Gives a 0.1% chance to delete anything on any page, and remembers deletions across all pages.
// @author       You
// @license      CC BY 4.0; https://creativecommons.org/licenses/by/4.0/
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY = 'globalDeletedNodes_v3';

    // Load deleted nodes from localStorage
    let deletedNodes = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];

    // Function to generate a unique identifier for nodes
    function getNodeIdentifier(node) {
        if (node.nodeType === Node.ELEMENT_NODE) {
            return `${node.tagName}_${node.id}_${node.className}_${node.name}_${node.innerText.length}`;
        } else if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.COMMENT_NODE) {
            return `${node.nodeType}_${node.nodeValue.trim().slice(0, 50)}`;
        }
        return '';
    }

    // Function to check if a node has been previously deleted
    function isNodeDeleted(node) {
        const identifier = getNodeIdentifier(node);
        return deletedNodes.includes(identifier);
    }

    // Function to store deleted node identifiers
    function storeDeletedNode(node) {
        const identifier = getNodeIdentifier(node);
        if (!deletedNodes.includes(identifier)) {
            deletedNodes.push(identifier);
            localStorage.setItem(STORAGE_KEY, JSON.stringify(deletedNodes));
        }
    }

    // Function to attempt deletion of any node
    function tryDeleteNode(node) {
        if (Math.random() < 0.001 && !isNodeDeleted(node)) { // 0.1% chance
            if (node.nodeType === Node.ELEMENT_NODE) {
                node.remove();
                console.log('Element deleted:', node);
            } else if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.COMMENT_NODE) {
                node.remove();
                console.log('Text or comment node deleted:', node);
            }
            storeDeletedNode(node);
        }
    }

    // Observer to watch for new elements, attributes, and nodes being added or modified in the DOM
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            // Try to delete the target node
            mutation.addedNodes.forEach(node => {
                if (!isNodeDeleted(node)) {
                    tryDeleteNode(node);
                }
            });
        });
    });

    // Configuration to observe child nodes and text content
    observer.observe(document.documentElement, {
        childList: true,
        subtree: true,
        characterData: true
    });

    // Initial pass to try deleting elements, text nodes, and comments that are already loaded
    const allNodes = document.querySelectorAll('*');
    allNodes.forEach(element => {
        // Try to delete the element itself
        if (!isNodeDeleted(element)) {
            tryDeleteNode(element);
        }
        // Try to delete text nodes and comments within the element
        element.childNodes.forEach(child => {
            if (!isNodeDeleted(child)) {
                tryDeleteNode(child);
            }
        });
    });
})();