// ==UserScript== // @name YouTubeEXT // @icon https://www.youtube.com/yt/brand/media/image/YouTube-icon-full_color.png // @namespace skoshy.com // @version 0.7.4 // @description Does cool things with YouTube // @author Stefan Koshy // @updateURL https://raw.githubusercontent.com/skoshy/YoutubeEXT/master/userscript.js // @match *://*.youtube.com/* // @exclude *://*.youtube.com/embed/* // @grant none // ==/UserScript== var scriptid = 'yt-ext'; var newElements = {}; // this object-array will contain all the new elements created for the page var timers = {}; // this object-array will contain various timers var cssTopBarHeightOffset = `0px`; var css = ` #masthead-container.ytd-app { transition: .2s ease-in-out; } html[`+scriptid+`-theater] #masthead-container.ytd-app { width: 75%; margin-left: 12.5%; opacity: 0; } html[`+scriptid+`-theater] #masthead-container.ytd-app:hover { opacity: 1; } html[`+scriptid+`-theater] ytd-watch #player.ytd-watch { z-index: 0; height: calc(100vh - `+cssTopBarHeightOffset+`); max-height: none; } html[`+scriptid+`-theater] ytd-watch #player.ytd-watch #player-container { position: fixed; top:0; box-sizing: border-box; padding-top: `+cssTopBarHeightOffset+`; } html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch { z-index: 1; position: relative; background-color: rgba(255,255,255,.55); opacity: .55; transition: .2s ease-in-out; } html[dark="true"][`+scriptid+`-theater] ytd-watch #top #container.ytd-watch { background-color: rgba(0,0,0,.55); } html[`+scriptid+`-theater] ytd-watch:hover #top #container.ytd-watch { opacity: 1; } html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch #author-thumbnail, html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch #avatar, html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch ytd-thumbnail { opacity: .55; transition: .2s ease-in-out; } html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch #author-thumbnail:hover, html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch #avatar:hover, html[`+scriptid+`-theater] ytd-watch #top #container.ytd-watch ytd-thumbnail:hover { opacity: 1; } /* Specifically used for small screen theater mode */ html[`+scriptid+`-theater] ytd-watch .ytp-iv-video-content { width: 100% !important; } html[`+scriptid+`-theater] ytd-watch #top, html[`+scriptid+`-theater] ytd-watch #player { width: 100%; } html[`+scriptid+`-theater] .html5-video-player .video-stream { padding: 0; } html[`+scriptid+`-theater] ytd-watch .ytp-chrome-bottom { left: 0 !important; margin: 0 auto; } /* GO TO TOP BUTTON */ #` + scriptid + `-goToTop { position: fixed; bottom: 20px; right: 20px; background-color: rgba(255,255,255,.8); padding: 10px; border-radius: 30px; box-shadow: #ccc 0px 0px 10px; cursor: pointer; color: #666; z-index: 2; transition: .2s ease-in-out; } #` + scriptid + `-goToTop:hover { color: #222; box-shadow: #aaa 0px 0px 10px; } html[`+scriptid+`-scroll-at-top] #` + scriptid + `-goToTop { display: none !important; } /* CUSTOM TOOLTIP */ .` + scriptid + `-tooltip { position: fixed; bottom: 5px; left: 5px; background: rgba(255, 255, 255, .8); padding: 3px; border-radius: 20px; z-index: 100; display: none; } `; document.addEventListener("keydown", function(e) { if (e.altKey === true && e.code == 'KeyO') { // toggle style if (isScriptEnabled()) turnOff(); else turnOn(); resizeCheck(); } }); function isScriptEnabled() { var cssEl = document.getElementById(scriptid); return !cssEl.disabled; } function turnOn() { var cssEl = document.getElementById(scriptid); cssEl.disabled = false; for (var key in newElements) { newElements[key].style.display = 'block'; } } function turnOff() { var cssEl = document.getElementById(scriptid); cssEl.disabled = true; for (var key in newElements) { newElements[key].style.display = 'none'; } } /* This function does a variety of checks and tweaks to the page on the resize and URL popstate */ function resizeCheck(e) { // set theat } // passed a target element, will check if it's an input box function isFocusOnInputBox(target) { if (target.getAttribute('role') == 'textbox' || target.tagName == 'INPUT' || target.tagName == 'TEXTAREA') return true; else return false; } function pausePlayVideoCheck(event) { if ( event.keyCode === 32 && !isFocusOnInputBox(event.target) && !event.target.classList.contains('html5-video-player') // don't pause/play if we're on the player itself. the player will handle it. ) { var videoId, status; event.preventDefault(); videoId = 'movie_player'; if (document.getElementById(videoId)) { status = document.getElementById(videoId).getPlayerState(); pausePlayVideo(videoId, status); } // if we're on a channel page, allow pausing/playing the main video on the channel homepage videoId = 'c4-player'; if (document.getElementById(videoId)) { status = document.getElementById(videoId).getPlayerState(); pausePlayVideo(videoId, status); } } } function pausePlayVideo(elId, status) { if (status === 1 || status === 3) { contentEval('document.querySelector("#' + elId + '").pauseVideo();'); } else if (status === -1 || status === 2 || status === 0) { contentEval('document.querySelector("#' + elId + '").playVideo();'); } // N/A (-4), unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5). // from https://greasyfork.org/scripts/8687-youtube-space-pause } function brightnessChangeCheck(event) { if (!isFocusOnInputBox(event.target)) { if (event.shiftKey) { var video = document.querySelector('video.html5-main-video'); var brightness = parseFloat(parseFromFilter('brightness', video.style.filter)); if (!brightness || isNaN(brightness)) { // no brightness has been specified yet video.style.filter = 'brightness(1.0)'; brightness = parseFloat(parseFromFilter('brightness', video.style.filter)); } if (event.keyCode === 33) { // shift+pgup var newBrightness = brightness + .1; video.style.filter = 'brightness(' + newBrightness + ')'; showTooltip('Brightness: ' + newBrightness.toFixed(2)); } else if (event.keyCode === 34) { // shift+pgdn var newBrightness = brightness - .1; video.style.filter = 'brightness(' + newBrightness + ')'; showTooltip('Brightness: ' + newBrightness.toFixed(2)); } } } } // will parse attribute from a filter string // ex: parseFromFilter('brightness', 'brightness(1.5)') => 1.5 // will return false if it can't parse it function parseFromFilter(name, string) { if (string == undefined) return false; var startLength = name.length + 1; var startPos = string.indexOf(name + '('); if (startPos == -1) return false; var endPos = string.indexOf(')', startLength + startPos); if (endPos == -1) return false; return string.substring(startLength + startPos, startLength + startPos + endPos); } function showTooltip(text) { newElements.tooltip.innerHTML = text; newElements.tooltip.style.display = 'block'; clearTimeout(timers.tooltip); timers.tooltip = setTimeout(function() { newElements.tooltip.style.display = 'none'; }, 1000); } /************ Initialize ************/ function initialize() { // create the tooltip newElements.tooltip = document.createElement('div'); newElements.tooltip.className = scriptid + '-tooltip'; setTimeout(function(){newElements.tooltip.style.display = 'none';}, 200); // there needs to be a delay to hide the brightness box for some reason insertAfter(newElements.tooltip, document.querySelector('body')); // initialize spacebar checking to pause video document.body.addEventListener('keydown', pausePlayVideoCheck); // initialize check for increasing/decreasing brightness document.body.addEventListener('keydown', brightnessChangeCheck); // Checks things on window resize window.addEventListener("resize", resizeCheck); // Check things when the page URL changes window.addEventListener('popstate', resizeCheck); addGlobalStyle(css, scriptid); // create the "Go To Top" button newElements.goToTop = document.createElement('div'); newElements.goToTop.id = scriptid + '-goToTop'; newElements.goToTop.onclick = function() { window.scrollTo(0, 0); }; newElements.goToTop.innerHTML = `