您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
AKA: "Wide Youtube", AKA: "Wide video container" - Uses the page space on youtube more efficiently (especially good for high resolutions)
当前为
// ==UserScript== // @name Space-efficient Youtube // @namespace 1N07 // @author 1N07 // @icon https://i.imgur.com/VgEiyi3.png // @description AKA: "Wide Youtube", AKA: "Wide video container" - Uses the page space on youtube more efficiently (especially good for high resolutions) // @include https://www.youtube.com/* // @version 1.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 HQTNHandle; //var HQTN = GM_getValue("HQTN", false); var HomeVideoContainerWidthHandle; var HomeVideoContainerWidth = GM_getValue("HomeVideoContainerWidth", "360px"); SetHomeVideoContainerWidthHandle(); var SubVideoContainerWidthHandle; var SubVideoContainerWidth = GM_getValue("SubVideoContainerWidth", "210px"); //SetHQTNHandle(); SetSubVideoContainerWidthHandle(); var TrendingVideoContainerWidthHandle; var TrendingVideoContainerWidth = GM_getValue("TrendingVideoContainerWidth", "600px"); SetTrendingVideoContainerWidthHandle(); var VideoContainerHorMarginHandle; var VideoContainerHorMargin = GM_getValue("VideoContainerHorMargin", "4px"); SetVideoContainerHorMarginHandle(); var VideoContainerVerMarginHandle; var VideoContainerVerMargin = GM_getValue("VideoContainerVerMargin", "24px"); SetVideoContainerVerMarginHandle(); 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`:``)+`; max-width: none; } #items.ytd-grid-renderer > ytd-grid-video-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-radio-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-channel-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-playlist-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-movie-playlist-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-movie-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-grid-show-renderer.ytd-grid-renderer, #items.ytd-grid-renderer > ytd-game-card-renderer.ytd-grid-renderer, ytd-grid-video-renderer { width: `+SubVideoContainerWidth+`; margin-left: 0; margin-top: 0; margin-right: `+VideoContainerHorMargin+`; margin-bottom: `+VideoContainerVerMargin+`; } ytd-thumbnail.ytd-grid-video-renderer { width: `+SubVideoContainerWidth+`; height: calc(`+SubVideoContainerWidth+` * 0.5625); } ytd-thumbnail #thumbnail.ytd-thumbnail yt-img-shadow.ytd-thumbnail { width: 100%; height: 100%; } img.yt-img-shadow { max-width: 100%; max-height: 100%; margin-left: 0; margin-right: 0; width: 100%; height: 100%; } /*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); max-width: none; } /*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+`; } ytd-app #page-manager > ytd-browse:not([page-subtype]) ytd-video-renderer.ytd-expanded-shelf-contents-renderer, ytd-app #page-manager > ytd-browse:not([page-subtype]) ytd-video-renderer.ytd-expanded-shelf-contents-renderer:not(:last-child) { padding-right: 3px; margin-left: 0; margin-top: 0; margin-right: `+VideoContainerHorMargin+`; margin-bottom: `+VideoContainerVerMargin+`; } ytd-app #page-manager > ytd-browse:not([page-subtype]) ytd-thumbnail.ytd-video-renderer { margin-right: 10px; } /*Playlist page rules*/ ytd-browse[page-subtype="playlist"] ytd-two-column-browse-results-renderer.ytd-browse { max-width: none; } /*home page rules*/ ytd-rich-item-renderer { width: `+HomeVideoContainerWidth+`; margin-left: 0; margin-top: 0; margin-right: `+VideoContainerHorMargin+`; margin-bottom: `+VideoContainerVerMargin+`; } `); 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; //lol why am I doing this 3 times at different times here??? Should have probably commented this better huh? //leaving it as is for now. Should probably figure out something better, this is a mess... setTimeout(URLChanged, 500); setTimeout(URLChanged, 2000); setTimeout(URLChanged, 5000); } }, 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"); } numRemoved = 0; let clickedArrows = document.getElementsByClassName("clicked"); //console.log("clicked found: " + clickedArrows.length); while(clickedArrows.length > 0) { for(let x = 0; x < clickedArrows.length; x++) { if(!!clickedArrows[x]) { clickedArrows[x].classList.remove("clicked"); //console.log(++numRemoved + " cleared"); } } clickedArrows = document.getElementsByClassName("clicked"); } //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(); //console.log("simulated click on right arrow"); arrowsRight[i].classList.add("clicked"); arrowsLeft[i].click(); //console.log("simulated click on left arrow"); arrowsLeft[i].classList.add("clicked"); } } } }, 250); } } /*============================================================*/ 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 SetHomeVideoContainerWidthHandle() { GM_unregisterMenuCommand(HomeVideoContainerWidthHandle); HomeVideoContainerWidthHandle = GM_registerMenuCommand("[home-page] Video-renderer width (" + HomeVideoContainerWidth + ") -click to change-", function(){ HomeVideoContainerWidth = CleanCSSValue(prompt("Set the width of a single video renderer on the page (use CSS units)\nThe current value is: '" + HomeVideoContainerWidth + "'")); GM_setValue("HomeVideoContainerWidth", HomeVideoContainerWidth); SetHomeVideoContainerWidthHandle(); if(confirm('Press "OK" to refresh the page to apply new settings')) location.reload(); }); } /*function SetHQTNHandle() { GM_unregisterMenuCommand(HQTNHandle); HQTNHandle = GM_registerMenuCommand("[subs-page] Load HQ thumbnails (" + (HQTN ? "On" : "Off") + ") -click to change-", function(){ HQTN = !HQTN; GM_setValue("HQTN", HQTN); SetHQTNHandle(); if(confirm('Press "OK" to refresh the page to apply new settings')) location.reload(); }); }*/ function SetSubVideoContainerWidthHandle() { GM_unregisterMenuCommand(SubVideoContainerWidthHandle); SubVideoContainerWidthHandle = GM_registerMenuCommand("[subs-page] Video-renderer width (" + SubVideoContainerWidth + ") -click to change-", function(){ SubVideoContainerWidth = CleanCSSValue(prompt("Set the width of a single video renderer on the page (use CSS units)\nNote: Currently values larger than the default (210px) make the thumbnails blurry, as youtube only loads 210px resolution images. I might make a workaround for this later.\nThe current value is: '" + SubVideoContainerWidth + "'")); GM_setValue("SubVideoContainerWidth", SubVideoContainerWidth); SetSubVideoContainerWidthHandle(); if(confirm('Press "OK" to refresh the page to apply new settings')) location.reload(); }); } function SetTrendingVideoContainerWidthHandle() { GM_unregisterMenuCommand(TrendingVideoContainerWidthHandle); TrendingVideoContainerWidthHandle = GM_registerMenuCommand("[trending-page] Video-renderer width (" + TrendingVideoContainerWidth + ") -click to change-", function(){ TrendingVideoContainerWidth = CleanCSSValue(prompt("Set the width of a single video renderer on the page (use CSS units)\nThe current value is: '" + TrendingVideoContainerWidth + "'")); GM_setValue("TrendingVideoContainerWidth", TrendingVideoContainerWidth); SetTrendingVideoContainerWidthHandle(); if(confirm('Press "OK" to refresh the page to apply new settings')) location.reload(); }); } function SetVideoContainerHorMarginHandle() { GM_unregisterMenuCommand(VideoContainerHorMarginHandle); VideoContainerHorMarginHandle = GM_registerMenuCommand("[all pages] Video-renderer horizontal margin (" + VideoContainerHorMargin + ") -click to change-", function(){ VideoContainerHorMargin = CleanCSSValue(prompt("Set the horizontal margin of a single video renderer on the page. i.e. the space between videos (use CSS units)\nThe current value is: '" + VideoContainerHorMargin + "'")); GM_setValue("VideoContainerHorMargin", VideoContainerHorMargin); SetVideoContainerHorMarginHandle(); if(confirm('Press "OK" to refresh the page to apply new settings')) location.reload(); }); } function SetVideoContainerVerMarginHandle() { GM_unregisterMenuCommand(VideoContainerVerMarginHandle); VideoContainerVerMarginHandle = GM_registerMenuCommand("[all pages] Video-renderer vertical margin (" + VideoContainerVerMargin + ") -click to change-", function(){ VideoContainerVerMargin = CleanCSSValue(prompt("Set the vertical margin of a single video renderer on the page. i.e. the space between videos (use CSS units)\nThe current value is: '" + VideoContainerVerMargin + "'")); GM_setValue("VideoContainerVerMargin", VideoContainerVerMargin); SetVideoContainerVerMarginHandle(); 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 CleanCSSValue(val) { val = val.trim(); //if only numbers... if(/^\d+$/.test(val)) val += "px"; //...add px return val; } 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); } })();