Greasy Fork is available in English.

Add redirect confirmation to reddit links (written for old)

Confirm navigation for links containing 'user', 'permalink', or 'parent' on Reddit

// ==UserScript==
// @name         Add redirect confirmation to reddit links (written for old)
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Confirm navigation for links containing 'user', 'permalink', or 'parent' on Reddit
// @author       cgpt
// @match        *://*.reddit.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to create and show the modal
    function showModal(link) {
        // Create the modal container
        const modal = document.createElement('div');
        modal.style.position = 'fixed';
        modal.style.left = '0';
        modal.style.top = '0';
        modal.style.width = '100vw';
        modal.style.height = '100vh';
        modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
        modal.style.display = 'flex';
        modal.style.justifyContent = 'center';
        modal.style.alignItems = 'center';
        modal.style.zIndex = '10000';

        // Function to remove the modal
        function removeModal() {
            document.body.removeChild(modal);
        }

        // Event listener for modal close scenarios
        modal.addEventListener('click', function(event) {
            if (event.target === modal) {
                removeModal();
            }
        });

        // Escape key handler
        document.addEventListener('keydown', function(event) {
            if (event.key === 'Escape') {
                removeModal();
            }
        }, { once: true }); // Automatically removes listener after first use

        // Create the modal content
        const modalContent = document.createElement('div');
        modalContent.style.padding = '20px';
        modalContent.style.backgroundColor = 'white';
        modalContent.style.borderRadius = '5px';
        modalContent.innerText = `Navigate to ${link.href}?`;

        // Create Yes button
        const yesButton = document.createElement('button');
        yesButton.innerText = 'Yes';
        yesButton.onclick = function() {
            window.location.href = link.href;
        };

        // Create No button
        const noButton = document.createElement('button');
        noButton.innerText = 'No';
        noButton.onclick = removeModal;

        modalContent.appendChild(yesButton);
        modalContent.appendChild(document.createTextNode(' ')); // Spacer
        modalContent.appendChild(noButton);

        modal.appendChild(modalContent);
        document.body.appendChild(modal);
    }

    // Function to check if the hash fragment has a significant change
    function isHashFragmentChanged(oldUrl, newUrl) {
        const oldUrlObj = new URL(oldUrl);
        const newUrlObj = new URL(newUrl);

        // Check if the base URL (without the hash) is the same
        if (oldUrlObj.origin + oldUrlObj.pathname !== newUrlObj.origin + newUrlObj.pathname) {
            return true; // Base URL is different, so show the modal
        }

        // Check if the hash has significantly changed
        if (oldUrlObj.hash !== newUrlObj.hash && newUrlObj.hash) {
            const oldHash = oldUrlObj.hash.replace(/^#/, '');
            const newHash = newUrlObj.hash.replace(/^#/, '');
            // Compare hash changes. If they are not minor, return true to show the modal
            return oldHash !== newHash;
        }

        // No significant change
        return false;
    }

    // Function to determine if a URL is just appending a query or fragment
    function isNavigationRelevant(oldUrl, newUrl) {
        const ignoredParameters = ['utm_source', 'utm_medium', 'utm_name', 'utm_content'];
        const newUrlObj = new URL(newUrl);

        // Check if the URL has any ignored parameters or a new fragment
        if (newUrlObj.hash || ignoredParameters.some(param => newUrlObj.searchParams.has(param))) {
            // Check for relevant hash changes
            return isHashFragmentChanged(oldUrl, newUrl);
        }

        // No utm params and no relevant fragment change, so navigation is not relevant
        return true;
    }

    // Event listener for all 'a' elements
    document.addEventListener('click', function(e) {
        const target = e.target.closest('a');
        const currentUrl = window.location.href;

        if (target && isNavigationRelevant(currentUrl, target.href) &&
            (target.href.includes('user') || target.textContent.toLowerCase().includes('permalink') || target.textContent.toLowerCase().includes('parent'))) {
            e.preventDefault();
            showModal(target);
        }
    }, true);
})();