RamiEjailat / Investopedia Next Video AutoPlay Stopper

// ==UserScript==
// @name         Investopedia Next Video AutoPlay Stopper
// @description  Prevents the next video from auto-playing on Investopedia by pausing the main video just before it ends.
// @author       Rami S Ejailat
// @copyright    RamiEjailat (https://openuserjs.org/users/RamiEjailat)
// @updateURL    https://openuserjs.org/meta/RamiEjailat/Investopedia_Next_Video_AutoPlay_Stopper.meta.js
// @downloadURL  https://openuserjs.org/install/RamiEjailat/Investopedia_Next_Video_AutoPlay_Stopper.user.js
// @license      MIT
// @version      20250429
// @namespace    http://tampermonkey.net/
// @match        *://*.investopedia.com/*
// @grant        none
// @icon         https://cdn-icons-png.flaticon.com/64/3308/3308698.png
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // Function to attach the time tracking listener to a video
    function attachListener(video) {
        // Prevent attaching multiple listeners to the same video
        if (video.dataset.autoplayStopperAttached) return;

        video.addEventListener('timeupdate', function() {
            // Check if the video is within 0.5 seconds of finishing
            if (video.duration > 0 && video.currentTime >= video.duration - 0.5) {

                // Pause it only once so you can manually force it to finish if desired
                if (!video.dataset.autoPaused) {
                    video.pause();
                    video.dataset.autoPaused = "true";
                }
            }
        });

        video.dataset.autoplayStopperAttached = "true";
    }

    // Find and attach listeners to any videos already on the page
    document.querySelectorAll('video').forEach(attachListener);

    // Watch for dynamically added videos (since players often load after the page)
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.tagName === 'VIDEO') {
                    attachListener(node);
                } else if (node.querySelectorAll) {
                    // Search inside newly added containers
                    node.querySelectorAll('video').forEach(attachListener);
                }
            });
        });
    });

    // Start observing the page for dynamic video loads
    observer.observe(document.body, { childList: true, subtree: true });
})();