Wide Youtube

AKA: Wide video container - Uses the page space on youtube more efficiently (especially good for high resolutions)

As of 2020-01-11. See the latest version.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Wide Youtube
// @namespace   1N07
// @author      1N07
// @icon        https://i.imgur.com/VgEiyi3.png
// @description AKA: Wide video container - Uses the page space on youtube more efficiently (especially good for high resolutions)
// @include     https://www.youtube.com/*
// @version     1.7.9
// @grant       GM_registerMenuCommand
// @grant       GM_unregisterMenuCommand
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

(function() {

    var FPPHandle;
    var FPPCompOn = GM_getValue("FPPCompOn", false);
    SetFPPHandle();

	var ForceCSSHandle;
    var ForceCSSOn = GM_getValue("ForceCSSOn", false);
    SetForceCSSHandle();

    var MaxNumOfVideosPerRowHandle;
    var MaxNumOfVideosPerRow = GM_getValue("MaxNumOfVideosPerRow", 6);
    SetMaxNumOfVideosPerRowHandle();

    var TrendingVideoContainerWidthHandle;
    var TrendingVideoContainerWidth = GM_getValue("TrendingVideoContainerWidth", 600);
    SetTrendingVideoContainerWidthHandle();

    var ShowChannelIconNextToVideosOnHomePageHandle;
    var ShowChannelIconNextToVideosOnHomePage = GM_getValue("ShowChannelIconNextToVideosOnHomePage", true);
    SetShowChannelIconNextToVideosOnHomePageHandle();

    var LessenVideoTitleTopMarginOnHomePage = true;

    var screenWidth = screen.width;

    if(!!document.getElementById("early-body")) { //if old youtube
        document.getElementById("content").setAttribute("style", "width: 99%;");
    } else { //new youtube
        addGlobalStyle(`
			ytd-app #page-manager > ytd-browse:not([page-subtype="playlist"]):not([page-subtype="home"]) ytd-two-column-browse-results-renderer.ytd-browse
			{
				box-sizing: border-box`+(ForceCSSOn ? `!important`:``)+`;
				width: calc(100% - 25px) !important;
				margin: 10px`+(ForceCSSOn ? `!important`:``)+`;
			}

			/*channels page rules*/
			ytd-app #page-manager > ytd-browse[page-subtype="channels"] ytd-two-column-browse-results-renderer.ytd-browse ytd-item-section-renderer.ytd-section-list-renderer
			{
				width: calc(100% - 20px);
			}
			/*for some reason the arrows sometimes dont show up, so now forcing them to*/
			ytd-app #page-manager > ytd-browse[page-subtype="channels"] ytd-two-column-browse-results-renderer.ytd-browse ytd-item-section-renderer.ytd-section-list-renderer ytd-button-renderer.yt-horizontal-list-renderer.arrow
			{
				opacity: 1;
				display: flex;
			}

			/*trending page rules*/
			ytd-app #page-manager > ytd-browse:not([page-subtype]) #grid-container.ytd-expanded-shelf-contents-renderer > .ytd-expanded-shelf-contents-renderer,
			ytd-app #page-manager > ytd-browse:not([page-subtype]) #grid-container.ytd-expanded-shelf-contents-renderer > .ytd-expanded-shelf-contents-renderer > .ytd-video-renderer
			{
				max-width: `+TrendingVideoContainerWidth+`px;
			}
			ytd-app #page-manager > ytd-browse:not([page-subtype]) ytd-video-renderer.ytd-expanded-shelf-contents-renderer
			{
				padding-right: 15px;
			}
			ytd-app #page-manager > ytd-browse:not([page-subtype]) ytd-thumbnail.ytd-video-renderer
			{
				margin-right: 12px;
			}

			/*home page rules*/
			@media (min-width:` + (screenWidth - 300) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+MaxNumOfVideosPerRow+` !important;
					--ytd-rich-grid-posts-per-row:`+MaxNumOfVideosPerRow+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}

			@media (min-width:` + (screenWidth - 600) + `px) and (max-width:` + (screenWidth - 301) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+(((MaxNumOfVideosPerRow - 1) >= 3 ? (MaxNumOfVideosPerRow - 1) : 3))+` !important;
					--ytd-rich-grid-posts-per-row:`+(((MaxNumOfVideosPerRow - 1) >= 3 ? (MaxNumOfVideosPerRow - 1) : 3))+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}

			@media (min-width:` + (screenWidth - 900) + `px) and (max-width:` + (screenWidth - 601) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+(((MaxNumOfVideosPerRow - 2) >= 3 ? (MaxNumOfVideosPerRow - 2) : 3))+` !important;
					--ytd-rich-grid-posts-per-row:`+(((MaxNumOfVideosPerRow - 2) >= 3 ? (MaxNumOfVideosPerRow - 2) : 3))+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}

			@media (min-width:` + (screenWidth - 1200) + `px) and (max-width:` + (screenWidth - 901) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+(((MaxNumOfVideosPerRow - 3) >= 3 ? (MaxNumOfVideosPerRow - 3) : 3))+` !important;
					--ytd-rich-grid-posts-per-row:`+(((MaxNumOfVideosPerRow - 3) >= 3 ? (MaxNumOfVideosPerRow - 3) : 3))+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}

			@media (min-width:` + (screenWidth - 1500) + `px) and (max-width:` + (screenWidth - 1201) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+(((MaxNumOfVideosPerRow - 4) >= 3 ? (MaxNumOfVideosPerRow - 4) : 3))+` !important;
					--ytd-rich-grid-posts-per-row:`+(((MaxNumOfVideosPerRow - 4) >= 3 ? (MaxNumOfVideosPerRow - 4) : 3))+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}

			@media (max-width:` + (screenWidth - 1501) + `px) {
				ytd-app #page-manager > ytd-browse[page-subtype="home"] ytd-two-column-browse-results-renderer.ytd-browse ytd-rich-grid-renderer
				{
					--ytd-rich-grid-items-per-row:`+(((MaxNumOfVideosPerRow - 6) >= 3 ? (MaxNumOfVideosPerRow - 6) : 3))+` !important;
					--ytd-rich-grid-posts-per-row:`+(((MaxNumOfVideosPerRow - 6) >= 3 ? (MaxNumOfVideosPerRow - 6) : 3))+` !important;
					--ytd-rich-grid-movies-per-row:12 !important;
				}
			}
		`);
        console.log("Youtube Wide video container style added to DOM");

        if(!ShowChannelIconNextToVideosOnHomePage)
        {
            addGlobalStyle(`
				#avatar-link.ytd-rich-grid-video-renderer
				{
					display: none;
				}
			`);
        }

        if(LessenVideoTitleTopMarginOnHomePage)
        {
            addGlobalStyle(`
				h3.ytd-rich-grid-video-renderer
				{
					margin-top: 6px;
				}
			`);
        }

        if(FPPCompOn) {
			addGlobalStyle(`
				/*========== Fade++ Compatibility ==========*/
				ytd-app #page-manager > ytd-browse:not([page-subtype="playlist"]) {
					display: block;
				}
				ytd-app[guide-persistent-and-visible] #page-manager > ytd-browse:not([page-subtype="playlist"]) ytd-two-column-browse-results-renderer.ytd-browse
				{
					margin-left: 250px !important;
				}
			`);
            console.log("Youtube Wide video container Fade++ compatibilty style added to DOM");
        }
    }

    /*=== load more videos for channel sections (experimental) ===*/
    var lastCheckedURL = window.location.href;
    URLChanged();
    setInterval(function(){
        if(lastCheckedURL != window.location.href)
        {
            lastCheckedURL = window.location.href;
            URLChanged();
        }
    }, 200);

    var waitForArrows;
    function URLChanged()
    {
        //console.log("-urlchanged-");
        clearInterval(waitForArrows);
        let expandedEls = document.getElementsByClassName("expanded-wwc");
        //console.log("expanded els found: " + expandedEls.length);
        let numRemoved = 0;

        //seems to always remove exactly half of them only, for some reason. So I guess do this until all have been removed
        while(expandedEls.length > 0)
        {
            for(let x = 0; x < expandedEls.length; x++)
            {
                if(!!expandedEls[x])
                {
                    expandedEls[x].classList.remove("expanded-wwc");
                    //console.log(++numRemoved + " cleared");
                }
            }
            expandedEls = document.getElementsByClassName("expanded-wwc");
        }

        //console.log("-expandedclear-");
        if(lastCheckedURL.includes("/user/") || lastCheckedURL.includes("/channel/"))
        {
            waitForArrows = setInterval(function(){
                //console.log("-searching...-");
                let arrowsRight = document.querySelectorAll("yt-horizontal-list-renderer:not(.expanded-wwc) > #right-arrow > ytd-button-renderer.arrow");
                let arrowsLeft = document.querySelectorAll("yt-horizontal-list-renderer:not(.expanded-wwc) > #left-arrow > ytd-button-renderer.arrow");
                if(!!arrowsRight && arrowsRight.length > 0 && !!arrowsLeft && arrowsLeft.length > 0)
                {
                    //console.log("-found-");
                    for(let i = 0; i < arrowsRight.length; i++)
                    {
                        if(!!arrowsRight[i] && arrowsRight[i].offsetParent !== null && !!arrowsLeft[i] && arrowsLeft[i].offsetParent !== null)
                        {
                            arrowsRight[i].parentElement.parentElement.classList.add("expanded-wwc");
                            arrowsRight[i].click();
                            arrowsRight[i].classList.add("clicked");
                            arrowsLeft[i].click();
                            arrowsLeft[i].classList.add("clicked");
                        }
                    }
                }
            }, 200);
        }
    }
    /*============================================================*/

    function SetFPPHandle() {
        GM_unregisterMenuCommand(FPPHandle);

        FPPHandle = GM_registerMenuCommand("Fade++ Compatibility mode (" + (FPPCompOn ? "On" : "Off") + ") -click to change-", function(){
            FPPCompOn = !FPPCompOn;
            GM_setValue("FPPCompOn", FPPCompOn);
            SetFPPHandle();

            if(confirm('Press "OK" to refresh the page to apply new settings'))
                location.reload();
        });
    }
	function SetForceCSSHandle() {
        GM_unregisterMenuCommand(ForceCSSHandle);

        ForceCSSHandle = GM_registerMenuCommand("CSS important rule mode (" + (ForceCSSOn ? "On" : "Off") + ") -click to change-", function(){
            ForceCSSOn = !ForceCSSOn;
            GM_setValue("ForceCSSOn", ForceCSSOn);
            SetForceCSSHandle();

            if(confirm('Press "OK" to refresh the page to apply new settings'))
                location.reload();
        });
    }
    function SetMaxNumOfVideosPerRowHandle() {
        GM_unregisterMenuCommand(MaxNumOfVideosPerRowHandle);

        MaxNumOfVideosPerRowHandle = GM_registerMenuCommand("[homepage] Max number of videos per row (" + MaxNumOfVideosPerRow + ") -click to change-", function(){
            MaxNumOfVideosPerRow = prompt("Set the max number of videos per row on the home page. (Does not affect total number of videos shown, just the number on each ROW)");
            GM_setValue("MaxNumOfVideosPerRow", MaxNumOfVideosPerRow);
            SetMaxNumOfVideosPerRowHandle();

            if(confirm('Press "OK" to refresh the page to apply new settings'))
                location.reload();
        });
    }
    function SetTrendingVideoContainerWidthHandle() {
        GM_unregisterMenuCommand(TrendingVideoContainerWidthHandle);

        TrendingVideoContainerWidthHandle = GM_registerMenuCommand("[trendingpage] Video container width (" + TrendingVideoContainerWidth + ") -click to change-", function(){
            TrendingVideoContainerWidth = prompt("Set the width of the video container on trending pages. i.e. how much horizontal space does one video take");
            GM_setValue("TrendingVideoContainerWidth", TrendingVideoContainerWidth);
            SetTrendingVideoContainerWidthHandle();

            if(confirm('Press "OK" to refresh the page to apply new settings'))
                location.reload();
        });
    }
    function SetShowChannelIconNextToVideosOnHomePageHandle() {
        GM_unregisterMenuCommand(ShowChannelIconNextToVideosOnHomePageHandle);

        ShowChannelIconNextToVideosOnHomePageHandle = GM_registerMenuCommand("[homepage] Show channel icons next to videos (" + (ShowChannelIconNextToVideosOnHomePage ? "Yes" : "No") + ") -click to change-", function(){
            ShowChannelIconNextToVideosOnHomePage = !ShowChannelIconNextToVideosOnHomePage;
            GM_setValue("ShowChannelIconNextToVideosOnHomePage", ShowChannelIconNextToVideosOnHomePage);
            SetShowChannelIconNextToVideosOnHomePageHandle();

            if(confirm('Press "OK" to refresh the page to apply new settings'))
                location.reload();
        });
    }

    function addGlobalStyle(css) {
        var head, style;
        head = document.getElementsByTagName('head')[0];
        if (!head) { return; }
        style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = css;
        head.appendChild(style);
    }
})();