YouTube Playlist Mod

A script I wrote for TamperMonkey to add some checkboxes to the YouTube playlist editor for bulk removing items.

// ==UserScript==
// @name         YouTube Playlist Mod
// @namespace    https://tampermonkey.net/
// @version      Rob
// @description  Add checkboxes to playlist editors
// @author       You
// @match        http*://www.youtube.com/playlist*
// @grant        none
// @run-at       document-end
// ==/UserScript==


(function() {
    if (!document.querySelector('.pl-video-edit-remove')) return;

    var mod_controls = document.createElement('div');
    mod_controls.setAttribute('class', 'branded-page-box clearfix');

    var base_button = document.createElement('button');
    base_button.setAttribute('class', 'yt-uix-button yt-uix-button-size-default yt-uix-button-default');
    base_button.setAttribute('style', 'margin-left: 5px;');

    var rem_button = base_button.cloneNode();
    rem_button.innerText = 'Remove Checked';
    rem_button.setAttribute('style', 'background: #faa;');
    rem_button.addEventListener('click', function () {
        if (document.querySelector('.del_chbox:checked') && confirm('Are you sure you want to remove ' + document.querySelectorAll('.del_chbox:checked').length + ' items?')) {
            rem_func();
        }
    });

    var rem_func = function () {
        if (checked = document.querySelector('.del_chbox:checked')) {
            checked.parentNode.parentNode.querySelector('.pl-video-edit-remove').click();

            status_span.innerText = ' Removing items... ' + document.querySelectorAll('.del_chbox:checked').length + ' remaining...';
            status_span.style.opacity = 1;
            setTimeout(rem_func, 1000);
        } else {
        status_span.innerText = ' Complete.';
        status_span.style.opacity = 0;
        }
    };

    var check_all = base_button.cloneNode();
    check_all.innerText = 'Toggle All';
    check_all.addEventListener('click', function () {
        if (document.querySelector('.del_chbox').checked === true) {
            for (let checkbox of document.querySelectorAll('.del_chbox')) {
                checkbox.checked = true;
                checkbox.click();
            }
        } else {
            for (let checkbox of document.querySelectorAll('.del_chbox')) {
                checkbox.checked = false;
                checkbox.click();
            }
        }
    });

    var status_span = document.createElement('span');
    status_span.setAttribute('style', 'opacity: 0; transition: opacity 1s; background: rgba(255, 255, 0, 0.7); padding: 5px; border: dashed 1px #000');

    var channel_box = document.createElement('span');
    channel_box.setAttribute('style', 'position: relative;');

    var case_label = document.createElement('label');
    case_label.setAttribute('style', 'position: absolute; left: 15px; top: 20px; font-size: 0.8em; white-space: nowrap;');

    var case_check = document.createElement('input');
    case_check.setAttribute('type', 'checkbox');
    case_check.setAttribute('style', 'vertical-align: middle;');

    case_label.appendChild(case_check);
    case_label.appendChild(document.createTextNode('Case-sensitive'));

    var check_channel = base_button.cloneNode();
    check_channel.innerText = 'Toggle By Channel';
    check_channel.addEventListener('click', function () {
        var channel_check = prompt('Enter partial or full channel name to select:', '');
        if (!channel_check) return false;
        var count = 0;
        for (let owners of document.querySelectorAll('.pl-video-owner')) {
            if (case_check.checked) {
                if (owners.children[0].innerText.indexOf(channel_check) !== -1) {
                    count++;
                    owners.parentNode.parentNode.querySelector('.del_chbox').click();
                }
            } else {
                if (owners.children[0].innerText.toLowerCase().indexOf(channel_check.toLowerCase()) !== -1) {
                    count++;
                    owners.parentNode.parentNode.querySelector('.del_chbox').click();
                }
            }
        }
        status_span.innerText = ' ' + count + ' items toggled for "' + channel_check + '"';
        status_span.style.opacity = 1;
    });



    channel_box.appendChild(case_label);
    channel_box.appendChild(check_channel);

    mod_controls.appendChild(rem_button);
    mod_controls.appendChild(check_all);
    mod_controls.appendChild(channel_box);
    mod_controls.appendChild(status_span);

    var item_list = document.querySelector('#browse-items-primary');
    item_list.parentNode.insertBefore(mod_controls, item_list);


    var checkbox = document.createElement('input');
    checkbox.setAttribute('type', 'checkbox');
    checkbox.setAttribute('class', 'del_chbox');

    setInterval(function() {
        for (var vid_item of document.querySelectorAll('.pl-video:not(.modified)')) {
            vid_item.classList.add('modified');
            vid_item.classList.remove('yt-uix-tile');
            var checkbox_copy = checkbox.cloneNode(true);
            checkbox_copy.addEventListener('click', function () {
                if (this.checked) {
                    this.parentNode.parentNode.setAttribute('style', 'background: #f88;');
                } else {
                    this.parentNode.parentNode.removeAttribute('style');
                }
            });
            vid_item.children[1].appendChild(checkbox_copy);
            vid_item.children[1].addEventListener('click', function () {
                if (event.target.tagName != 'INPUT') this.children[0].click();
            });
        }
    }, 500);
})();
This entry was posted in Coding and tagged , , . Bookmark the permalink.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.