Old Youtube Buttons

Changes various YouTube elements to resemble the old YouTube Design. (Green/Red Like/Dislike, Yellow Subscribe Button.)

Versión del día 17/12/2022. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name         Old Youtube Buttons
// @namespace    YellowSubButt
// @version      0.3.17
// @description  Changes various YouTube elements to resemble the old YouTube Design. (Green/Red Like/Dislike, Yellow Subscribe Button.)
// @author       SomeSchmuck
// @match        *://*.youtube.com/*
// @icon         https://th.bing.com/th/id/R.a12178dd72afd2470f0d2285602f2374?rik=%2fZTUzR2M%2fWKHUA&riu=http%3a%2f%2fsguru.org%2fwp-content%2fuploads%2f2018%2f02%2fYouTube_logo.png&ehk=kk7ZapiqeyJwuqO64Byiid8PbemJtRLsbmphetcvtcE%3d&risl=&pid=ImgRaw&r=0
// @grant        GM.xmlHttpRequest
// @run-at       document-end
// @connect      youtube.com
// @license      MIT
// ==/UserScript==

// TODOs:
//    make the above section a little cleaner and see if certain parts are actually needed or not
//    maybe make this not use esversion 6? technically better browser support that way, although
//        that might not even be an issue... Too bad!
/* jshint esversion: 6 */

//known issues:
//sub button sometimes has a thin white/really bright line at the very bottom;
//  this might be a browser issue, though adjusting css padding can hide it a little bit

// 0.3.17 changes:
// Adds support for Youtube's newest subscribe button format.
// Minor code revisions; let is used in place of var for variables now.

// 0.3.16 changes:
// removed unecessary evtListen function call via code comment; we already have an event listener
//    to trigger it, so it literally can only bog the script down. smh

// 0.3.15 changes:
// found a way to change the color of the animated like button; this will probably break compatibility
//    with any script replaces the new animated like button with the old, non animated one. Too Bad!

// 0.3.14 changes:
// tweaked code that applies styling to join button; this should if nothing else
//    reduce the frequency of random non-join buttons also gaining that styling.

// 0.3.13 change:
// Fixed a CSS typo.

(function() {
    "use strict";
    window.addEventListener('yt-navigate-finish', evtListen, true);
    // evtListen();
    // locationChange();
    function set_video_buttons(){
        let new_video_info = document.getElementsByClassName('item style-scope ytd-watch-metadata');
        if (new_video_info.length >= 1){
            // console.warn("new youtube layout detected!")
            // console.log(new_video_info);
            if (new_video_info[1] != undefined){
                let new_buttons = new_video_info[1].getElementsByClassName('style-scope ytd-segmented-like-dislike-button-renderer');
                //ez check for actually on a video
                if (new_buttons[1] != undefined){
                    let likeSVG = new_buttons[1].getElementsByTagName('yt-icon')[0].getElementsByTagName('svg')[0];
                    //check that it's not undefined so js console doesn't scream at you
                    if (likeSVG != undefined){
                        if (likeSVG.children[1] != undefined){
                            let likePaths = likeSVG.children[1].children[1];
                            //set stroke & fill colors when like button is NOT animated
                            //g1 (liked)
                            likePaths.children[0].children[0].setAttribute('style', 'fill: green;');
                            likePaths.children[0].children[1].setAttribute('style', 'stroke: green;');
                            //g2 (not yet liked)
                            likePaths.children[1].children[0].setAttribute('style', 'stroke: green;');
                            //g3 (liked)
                            likePaths.children[2].children[0].setAttribute('style', 'fill: green;');
                            likePaths.children[2].children[1].setAttribute('style', 'stroke: green;');
                            //g4 (not yet liked)
                            likePaths.children[3].children[0].setAttribute('style', 'stroke: green;');
                        }
                    }
                    // reset likeSVG element here so we can ensure that being signed out
                    // still allows the like button to be green. TODO: implement this better.
                    likeSVG = new_buttons[1].getElementsByTagName('yt-icon')[0];
                    // console.log(likeButt.getElementsByTagName('svg'));
                    likeSVG.setAttribute('style', 'color: green;');
                    let dislikeButt = new_buttons[3].getElementsByTagName('yt-icon')[0];
                    dislikeButt.setAttribute('style', 'color: red;');
                }
                return;
            }
        }
    }
    function set_join_buttons(){
        // remove any existing buttons with the 'oytJoin' id; this removes random
        // buttons that also get to look like the join button.
        let existJoins = document.querySelectorAll('#oytJoin');
        for (let i = 0; i < existJoins.length; i++){
            // console.log(existJoins[fj]);
            existJoins[i].removeAttribute('id');
        }
        let joinDivs = document.querySelectorAll('#sponsor-button');
        // console.log(joinDivs);
        for (let i = 0; i < joinDivs.length; i++){
            // console.log(joinDivs[jb].children.length);
            if (joinDivs[i].children.length > 0){
                let joinButton = joinDivs[i].getElementsByTagName('button')[0];
                // console.log(subButton);
                if (joinButton != undefined){
                    joinButton.setAttribute('id', 'oytJoin');
                    //TODO: implement support for having joined a channel.
                }
            }
        }
        //this might accidentally override a button we don't want to... Too bad!
        joinDivs = document.querySelectorAll('#purchase-button');
        for (let i = 0; i < joinDivs.length; i++){
            let purchaseButton = joinDivs[i].getElementsByTagName('button')[0];
            if (purchaseButton != undefined){
                purchaseButton.setAttribute('id', 'oytJoin');
                //TODO: implement support for having joined a channel.
            }
        }
    }
    //TODO: Fix comments text formatting
    function set_buttons_text(){
        let reply_info = document.getElementsByTagName('yt-formatted-string');
        //console.log(reply_info.length);
        if (reply_info.length != 0){
            for(let r = 0; r < reply_info.length; r++){
                let reply_str = reply_info[r].innerText.toLowerCase();
                const reply_style = 'border-bottom: 1px dotted #0140FF; color: #0140FF; text-transform: capitalize; font-weight: normal;';
                const join_text_style = 'color: #039';
                if (reply_str != null){
                    if (reply_str === 'reply'){
                        reply_info[r].setAttribute('style', reply_style);
                    } else if (reply_str === 'join' || reply_str === 'customize channel' || reply_str === 'manage videos'){
                        reply_info[r].setAttribute('style', join_text_style);
                    } else {
                        //if we don't pass above checks, remove styling. Youtube shouldn't have anything
                        // important formatted like this anyway, so we're... fine i think
                        reply_info[r].removeAttribute('style');
                    }
                }
            }
        }
    }
    function set_video_inf(){
        set_video_buttons();
        // set_buttons_text();
        // setSubJoin();
        set_join_buttons();
    }
    function addGlobalStyle(css) {
        let head, style, styles;
        //console.log(document.getElementsByTagName('head'))
        head = document.getElementsByTagName('head')[0];
        if (!head) { return; }
        styles = head.getElementsByClassName('yt_style');
        if (styles.length >= 1){ return; }
        style = document.createElement('style');
        style.type = 'text/css';
        style.setAttribute('class', "yt_style");
        style.innerHTML = css;
        head.appendChild(style);
        // console.log(head);
    }
    function createStyle() {
        let style = '';
        // var style = '';
        //sub button; new YT ver
        style += '#subscribe-button > .style-scope.ytd-watch-metadata > yt-button-shape > button{background: linear-gradient(180deg, #fff9c1 0%, #fed81c 100%) !important; border: 1px solid #ecc101 !important; border-radius: 4px !important; color: #994800 !important; text-transform: capitalize !important; font-weight: bold !important; padding: 2px 9px 0 10px; height: 27px; font-family: Arial, sans-serif; font-size: 12px;}';
        style += '#subscribe-button > .style-scope.ytd-watch-metadata > yt-button-shape > button:hover{background: linear-gradient(180deg, #fffffa 0%, #fed925 100%) !important; text-decoration: underline;}';
        //unsub button
        style += '#notification-preference-button > ytd-subscription-notification-toggle-button-renderer-next > yt-button-shape > button{background: linear-gradient(180deg, #fefefe 0%, #c2c2c2 100%) !important; color: #333 !important; border: 1px solid #ccc !important; border-radius: 4px !important; text-transform: capitalize !important; font-weight: bold !important; padding: 2px 9px 0 10px; height: 27px; font-family: Arial, sans-serif; font-size: 12px;}';
        style += '#notification-preference-button > ytd-subscription-notification-toggle-button-renderer-next > yt-button-shape > button:hover { background: linear-gradient(180deg, #fefefe 0%, #a8a6a6 100%) !important; }';
        //remove notif bell and dropdown arrow (maybe change arrow to something old style later?)
        style += '#notification-preference-button > ytd-subscription-notification-toggle-button-renderer-next > yt-button-shape > button > div.yt-spec-button-shape-next__icon{display: none;}';
        style += '#notification-preference-button > ytd-subscription-notification-toggle-button-renderer-next > yt-button-shape > button > div.yt-spec-button-shape-next__secondary-icon{display: none;}';
        //join button(s)
        style += '#oytJoin{background-image: linear-gradient(180deg, #fbfcff 0%, #93b2ff 100%) !important; color: #1c1b16 !important; font-size: 14px; text-transform: capitalize !important; font-weight: bold; font-family: Arial, sans-serif; height: 25px !important; border-radius: 4px !important; border-color: #8aa1d5 !important;}';
        //Likes-dislikes
        style += '#like-button{--yt-spec-text-primary: green !important;}';
        style += '#dislike-button{--yt-spec-text-primary: red !important;}';
        return style;
    }
    //trick to make buttons that don't originally have hover css have hover css part 2 :)
    //addGlobalStyle('ytd-button-renderer #button.ytd-button-renderer[join]:hover { border-color: green !important;}')
    // addGlobalStyle(style);
    addGlobalStyle(createStyle());
    //we don't use the event that gets passed here since we don't need it for this script
    function evtListen(event){
        locationChange();
    }
    //this bit of script was taken and modified from the script "Youtube: Download Video" by HayaoGai
    //link to that script: https://greasyfork.org/en/scripts/404304-youtube-download-video
    function locationChange() {
        //console.log('Switched page!');
        const observer = new MutationObserver(mutations => {
            set_video_inf();
        });
        const target = document.body;
        const config = { childList: true, subtree: true };
        observer.observe(target, config);
    }
})();