YouTube Watch Later Remove Button on Hover

Show a remove button on hover over video thumbnails in the Watch Later list

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         YouTube Watch Later Remove Button on Hover
// @namespace    http://tampermonkey.net/
// @version      0.6.2
// @description  Show a remove button on hover over video thumbnails in the Watch Later list
// @license MIT
// @match        https://www.youtube.com/*
// @run-at              document-start
// @grant               none
// @inject-into         page
// ==/UserScript==

(function () {
    'use strict';

    let scriptEnable = false;

    const insp = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0);

    function getItemData(menu) {
        if (!menu) return;
        let items = ((menu || 0).menuRenderer || 0).items || 0;
        if (!(items.length >= 1)) return;
        const filtered = items.filter((entry) => {
            if (!entry || typeof entry !== 'object') return false;
            try {
                const t = (JSON.stringify(entry) || '');
                return t.includes('ACTION_REMOVE_VIDEO');
            } catch (e) {
                return false;
            }
        });
        if (filtered.length !== 1) return;
        let itemData = filtered[0];
        itemData = Object.values(itemData).filter(e => e.serviceEndpoint || e.command)[0];
        if (!itemData) return;
        return itemData;
    }

    const removeButtonOnclick = function (e) {
        const button = this;
        if (!scriptEnable) return;

        let videoElement = button.closest('ytd-thumbnail');
        if (!videoElement) return;
        let renderer = videoElement.closest('ytd-playlist-video-renderer.style-scope.ytd-playlist-video-list-renderer');
        if (!renderer) return;

        let data = insp(renderer).data || 0;
        const itemData = getItemData(data.menu);
        if (!itemData) return;

        e.preventDefault(); // Prevent the default action of the event
        e.stopPropagation(); // Stop the event from bubbling up
        e.stopImmediatePropagation(); // Prevents other listeners of the same event from being called

        const cntNode = (document.querySelector('ytd-app') || renderer);

        (function (data) {

            const a = data.serviceEndpoint;
            const b = data.command;

            a && this.ytComponentBehavior.resolveCommand(a);
            b && this.ytComponentBehavior.resolveCommand(b);

        }).call(insp(cntNode), itemData);

    };

    function createRemoveButton(videoElement) {
        let removeButton = document.createElement('button');
        removeButton.className = 'watch-later-remove-button';
        removeButton.textContent = 'Remove';
        removeButton.style.position = 'absolute';
        removeButton.style.top = '5px';
        removeButton.style.right = '5px';
        removeButton.style.zIndex = '1000';

        removeButton.onclick = removeButtonOnclick;
        videoElement.appendChild(removeButton);
    }

    const mouseenterHandler = function (e) {
        if (!e || !(e.target instanceof HTMLElement)) return;
        if (!scriptEnable) return;
        if (!e.target.classList.contains('ytd-playlist-video-renderer')) return;
        let videoElement = e.target.closest('ytd-thumbnail');
        if (!videoElement) return;
        let renderer = videoElement.closest('ytd-playlist-video-renderer.style-scope.ytd-playlist-video-list-renderer');
        if (!renderer || renderer.is !== 'ytd-playlist-video-renderer') return;
        let data = insp(renderer).data || 0;
        let itemData = getItemData(data.menu);
        if (!itemData) return;
        let button = videoElement.querySelector('button.watch-later-remove-button')
        if (!button) {
            createRemoveButton(videoElement);
        } else {
            button.style.display = '';
        }
    };

    const mouseleaveHandler = function (e) {
        if (!e || !(e.target instanceof HTMLElement)) return;
        if (!e.target.classList.contains('ytd-playlist-video-renderer')) return;
        let button = e.target.querySelector('button.watch-later-remove-button');
        if (button) {
            button.style.display = 'none';
        }
    };


    document.addEventListener('yt-navigate-finish', () => {

        const newEnable = location.pathname === '/playlist' && location.search.includes('list=WL');

        if (scriptEnable ^ newEnable) {

            if (scriptEnable) {
                scriptEnable = false;
                document.removeEventListener('mouseenter', mouseenterHandler, true);
                document.removeEventListener('mouseleave', mouseleaveHandler, true);
            } else if (newEnable) {
                scriptEnable = true;
                document.addEventListener('mouseenter', mouseenterHandler, true);
                document.addEventListener('mouseleave', mouseleaveHandler, true);
            }

        }

    }, false);

})();