[
  {
    "path": "153699.user.js",
    "content": "// ==UserScript==\n// @name            Resize YT To Window Size\n// @description     Moves the YouTube video to the top of the website and fill the window with the video player.\n// @author          Chris H (Zren / Shade)\n// @license         MIT\n// @icon            https://s.ytimg.com/yts/img/favicon_32-vflOogEID.png\n// @homepageURL     https://github.com/Zren/ResizeYoutubePlayerToWindowSize/\n// @namespace       http://xshade.ca\n// @version         139\n// @include         http*://*.youtube.com/*\n// @include         http*://youtube.com/*\n// @include         http*://*.youtu.be/*\n// @include         http*://youtu.be/*\n// @grant           none\n// ==/UserScript==\n\n// Github:          https://github.com/Zren/ResizeYoutubePlayerToWindowSize\n// GreasyFork:      https://greasyfork.org/scripts/811-resize-yt-to-window-size\n// OpenUserJS.org:  https://openuserjs.org/scripts/zren/Resize_YT_To_Window_Size\n// Userscripts.org: http://userscripts-mirror.org/scripts/show/153699\n\n(function (window) {\n    \"use strict\";\n\n    //--- Settings\n    var playerHeight = '100vh';\n    var enableOnLoad = true;\n    var scriptToggleKey = 'w';\n\n    //--- Imported Globals\n    // yt\n    // ytcenter\n    // html5Patched (Youtube+)\n    // ytplayer\n    var uw = window;\n\n    //--- Already Loaded?\n    // GreaseMonkey loads this script twice for some reason.\n    if (uw.ytwp) return;\n\n    //--- Is iframe?\n    function inIframe () {\n        try {\n            return window.self !== window.top;\n        } catch (e) {\n            return true;\n        }\n    }\n    if (inIframe()) return;\n\n    //--- Utils\n    function isStringType(obj) { return typeof obj === 'string'; }\n    function isArrayType(obj) { return obj instanceof Array; }\n    function isObjectType(obj) { return typeof obj === 'object'; }\n    function isUndefined(obj) { return typeof obj === 'undefined'; }\n    function buildVenderPropertyDict(propertyNames, value) {\n        var d = {};\n        for (var i in propertyNames)\n            d[propertyNames[i]] = value;\n        return d;\n    }\n    function observe(selector, config, callback) {\n        var observer = new MutationObserver(function(mutations) {\n            mutations.forEach(function(mutation){\n                callback(mutation);\n            });\n        });\n        var target = document.querySelector(selector);\n        if (!target) {\n            return null;\n        }\n        observer.observe(target, config);\n        return observer;\n    }\n\n    //--- Stylesheet\n    var JSStyleSheet = function(id) {\n        this.id = id;\n        this.stylesheet = '';\n    };\n\n    JSStyleSheet.prototype.buildRule = function(selector, styles) {\n        var s = \"\";\n        for (var key in styles) {\n            s += \"\\t\" + key + \": \" + styles[key] + \";\\n\";\n        }\n        return selector + \" {\\n\" + s + \"}\\n\";\n    };\n\n    JSStyleSheet.prototype.appendRule = function(selector, k, v) {\n        if (isArrayType(selector))\n            selector = selector.join(',\\n');\n        var newStyle;\n        if (!isUndefined(k) && !isUndefined(v) && isStringType(k)) { // v can be any type (as we stringify it).\n            var d = {};\n            d[k] = v;\n            newStyle = this.buildRule(selector, d);\n        } else if (!isUndefined(k) && isUndefined(v) && isObjectType(k)) {\n            newStyle = this.buildRule(selector, k);\n        } else {\n            // Invalid Arguments\n            console.log('Illegal arguments', arguments);\n            return;\n        }\n\n        this.stylesheet += newStyle;\n    };\n\n    JSStyleSheet.injectIntoHeader = function(injectedStyleId, stylesheet) {\n        var styleElement = document.getElementById(injectedStyleId);\n        if (!styleElement) {\n            styleElement = document.createElement('style');\n            styleElement.type = 'text/css';\n            styleElement.id = injectedStyleId;\n            document.getElementsByTagName('head')[0].appendChild(styleElement);\n        }\n        styleElement.appendChild(document.createTextNode(stylesheet));\n    };\n\n    JSStyleSheet.prototype.injectIntoHeader = function() {\n        JSStyleSheet.injectIntoHeader(this.id, this.stylesheet);\n    };\n\n    //--- History\n    var HistoryEvent = function() {}\n    HistoryEvent.listeners = []\n\n    HistoryEvent.dispatch = function(state, title, url) {\n      var stack = this.listeners\n      for (var i = 0, l = stack.length; i < l; i++) {\n        stack[i].call(this, state, title, url)\n      }\n    }\n    HistoryEvent.onPushState = function(state, title, url) {\n        HistoryEvent.dispatch(state, title, url)\n        return HistoryEvent.origPushState.apply(window.history, arguments)\n    }\n    HistoryEvent.onReplaceState = function(state, title, url) {\n        HistoryEvent.dispatch(state, title, url)\n        return HistoryEvent.origReplaceState.apply(window.history, arguments)\n    }\n    HistoryEvent.inject = function() {\n        if (!HistoryEvent.injected) {\n            HistoryEvent.origPushState = window.history.pushState\n            HistoryEvent.origReplaceState = window.history.replaceState\n\n            window.history.pushState = HistoryEvent.onPushState\n            window.history.replaceState = HistoryEvent.onReplaceState\n            HistoryEvent.injected = true\n        }\n    }\n\n    HistoryEvent.timerId = 0\n    HistoryEvent.onTick = function() {\n        var currentPage = window.location.pathname + window.location.search\n        if (HistoryEvent.lastPage != currentPage) {\n            HistoryEvent.dispatch({}, document.title, window.location.href)\n            HistoryEvent.lastPage = currentPage\n        }\n    }\n    HistoryEvent.startTimer = function() {\n        HistoryEvent.lastPage = window.location.pathname + window.location.search\n        HistoryEvent.timerId = setInterval(HistoryEvent.onTick, 500)\n    }\n    HistoryEvent.stopTimer = function() {\n        clearInterval(HistoryEvent.timerId)\n    }\n    window.ytwpHistoryEvent = HistoryEvent\n\n\n    //--- Constants\n    var scriptShortName = 'ytwp'; // YT Window Player\n    var scriptStyleId = scriptShortName + '-style'; // ytwp-style\n    var scriptBodyClassId = scriptShortName + '-window-player'; // .ytwp-window-player\n    var viewingVideoClassId = scriptShortName + '-viewing-video'; // .ytwp-viewing-video\n    var topOfPageClassId = scriptShortName + '-scrolltop'; // .ytwp-scrolltop\n\n    var scriptHtmlSelector = 'html:not([fullscreen=\"true\"])';\n    var scriptBodySelector = 'body.' + scriptBodyClassId; // body.ytwp-window-player\n    scriptBodySelector += ':not(.enhancer-for-youtube-pinned-player)'; // Support \"Enhancer for Youtube\" (Pull Request #51)\n    var scriptSelector = scriptHtmlSelector + ' ' + scriptBodySelector;\n\n    var videoContainerId = 'player';\n    var videoContainerPlacemarkerId = scriptShortName + '-placemarker'; // ytwp-placemarker\n\n    var transitionProperties = [\"transition\", \"-ms-transition\", \"-moz-transition\", \"-webkit-transition\", \"-o-transition\"];\n    var transformProperties = [\"transform\", \"-ms-transform\", \"-moz-transform\", \"-webkit-transform\", \"-o-transform\"];\n\n    //--- YTWP\n    var ytwp = uw.ytwp = {\n        scriptShortName: scriptShortName, // YT Window Player\n        log_: function(logger, args) { logger.apply(console, ['[' + this.scriptShortName + '] '].concat(Array.prototype.slice.call(args))); return 1; },\n        log: function() { return this.log_(console.log, arguments); },\n        error: function() { return this.log_(console.error, arguments); },\n\n        initialized: false,\n        pageReady: false,\n        isWatchPage: false,\n    };\n\n    ytwp.debugPage = function() {\n        function prettyHtml(el) {\n            var s = el.outerHTML\n            return s.substr(0, s.indexOf('>')+1)\n        }\n        var defStyle = {\n            'display':'block', 'position': 'static',\n            'left': 'auto', 'right': 'auto', 'top': 'auto', 'bottom': 'auto',\n            'padding-left':'0px', 'padding-right':'0px', 'padding-top':'0px', 'padding-bottom':'0px',\n            'margin-left':'0px', 'margin-right':'0px', 'margin-top':'0px', 'margin-bottom':'0px',\n            'width': 'auto', 'min-width': 'auto', 'max-width': 'auto',\n            'height': 'auto', 'min-height': 'auto', 'max-height': 'auto',\n        }\n        var keyFilter = Object.keys(defStyle)\n        var node = document.querySelector('#movie_player video')\n        var outStr = ''\n        while (node && node.parentNode) {\n            var style = getComputedStyle(node)\n            var styleDiff = {}\n            for (var key of style) {\n                if (keyFilter.includes(key) && style[key] != defStyle[key]) {\n                    styleDiff[key] = style[key]\n                }\n            }\n            outStr += prettyHtml(node) + ' ' + JSON.stringify(styleDiff) + '\\n'\n            node = node.parentNode\n        }\n        outStr = outStr.split('\\n').reverse().join('\\n')\n        ytwp.log('debugPage', outStr)\n    }\n\n    ytwp.hasYoutubeChanged = function() {\n        var tree = [\n            'html',\n            'body',\n            'ytd-app',\n            '#content.ytd-app',\n            'ytd-page-manager#page-manager.ytd-app',\n            'ytd-watch-flexy.ytd-page-manager',\n            '#full-bleed-container.ytd-watch-flexy',\n            '#player-full-bleed-container.ytd-watch-flexy',\n            '#player-container.ytd-watch-flexy',\n            'ytd-player#ytd-player.ytd-watch-flexy',\n            '#container.ytd-player',\n            '.html5-video-player',\n            '.html5-video-container',\n            'video.html5-main-video',\n        ]\n        tree = tree.reverse()\n        var node = document.querySelector(tree[0])\n        if (!node) {\n            ytwp.error('YT has changed!', tree[0], 'no longer exists!')\n            return true\n        }\n        for (var i = 1; i < tree.length; i++) {\n            var parent = node.parentNode\n            var selector = tree[i]\n            if (parent.matches(selector)) {\n                node = parent\n            } else {\n                ytwp.error('YT has changed!', selector, 'no longer exists!')\n            }\n        }\n        return false\n    }\n\n    ytwp.isWatchUrl = function (url) {\n        if (!url)\n            url = uw.location.href;\n        if (url.match(/https?:\\/\\/(www\\.)?youtube.com\\/(c|channel|user)\\/[^\\/]+\\/live/)) {\n            if (document.querySelector('ytd-browse')) {\n                return false\n            } else {\n                return true\n            }\n        }\n        return url.match(/https?:\\/\\/(www\\.)?youtube.com\\/watch\\?/);\n    };\n\n    ytwp.setTheaterMode = function(enable) {\n        // ytwp.log('setTheaterMode', enable)\n\n        var watchElement = document.querySelector('ytd-watch:not([hidden])') || document.querySelector('ytd-watch-flexy:not([hidden])') || document.querySelector('ytd-watch-grid:not([hidden])')\n        if (watchElement) {\n            var isTheater = watchElement.hasAttribute('theater')\n            if (enable != isTheater) {\n                // Note: (Issue #75) ytd-watch-flexy watchElement.querySelector() will find\n                // Nothing for some reason. We need to query from the document scope.\n                var sizeButton = document.querySelector(watchElement.tagName + ':not([hidden]) button.ytp-size-button')\n                if (!sizeButton) {\n                    var screenModeButtons = document.querySelectorAll(watchElement.tagName + ':not([hidden]) button.ytp-screen-mode-settings-button')\n                    sizeButton = screenModeButtons[1] // 2nd button is \"Theater mode (t)\"\n                }\n                if (sizeButton) {\n                    sizeButton.click()\n                }\n            }\n            watchElement.canFitTheater_ = true // When it's too small, it disables the theater mode.\n        } else if (watchElement = document.querySelector('#page.watch')) {\n            var isTheater = watchElement.classList.contains('watch-stage-mode')\n            if (enable != isTheater) {\n                var sizeButton = watchElement.querySelector('button.ytp-size-button')\n                if (sizeButton) {\n                    sizeButton.click()\n                }\n            }\n        }\n    }\n    ytwp.enterTheaterMode = function() {\n        // ytwp.log('enterTheaterMode')\n        if (!document.body.classList.contains(scriptBodyClassId)) {\n            return\n        }\n\n        ytwp.setTheaterMode(true)\n    }\n    ytwp.enterTheaterMode();\n    uw.addEventListener('resize', ytwp.enterTheaterMode);\n\n    ytwp.detectPlayerUnavailable = function() {\n        if (document.querySelector('[player-unavailable]')) {\n            ytwp.event.removeBodyClass()\n        }\n    }\n\n\n    ytwp.init = function() {\n        ytwp.log('init');\n        if (!ytwp.initialized) {\n            ytwp.isWatchPage = ytwp.isWatchUrl();\n            if (ytwp.isWatchPage) {\n                ytwp.removeSearchAutofocus();\n                if (!document.getElementById(scriptStyleId)) {\n                    ytwp.event.initStyle();\n                }\n                ytwp.initScroller();\n                ytwp.initialized = true;\n                ytwp.pageReady = false;\n            }\n        }\n        ytwp.event.onWatchInit();\n        if (ytwp.isWatchPage) {\n            ytwp.html5PlayerFix();\n        }\n    }\n\n    ytwp.initScroller = function() {\n        // Register listener & Call it now.\n        uw.addEventListener('scroll', ytwp.onScroll, false);\n        uw.addEventListener('resize', ytwp.onScroll, false);\n        ytwp.onScroll();\n    }\n\n    ytwp.onScroll = function() {\n        var viewportHeight = document.documentElement.clientHeight;\n\n        // topOfPageClassId\n        if (ytwp.isWatchPage && uw.scrollY == 0) {\n            document.body.classList.add(topOfPageClassId);\n            //var player = document.getElementById('movie_player');\n            //if (player)\n            //    player.focus();\n        } else {\n            document.body.classList.remove(topOfPageClassId);\n        }\n\n        // viewingVideoClassId\n        if (ytwp.isWatchPage && uw.scrollY <= viewportHeight) {\n            document.body.classList.add(viewingVideoClassId);\n        } else {\n            document.body.classList.remove(viewingVideoClassId);\n        }\n    }\n\n    ytwp.event = {\n        initStyle: function() {\n            ytwp.log('initStyle');\n            ytwp.style = new JSStyleSheet(scriptStyleId);\n            ytwp.event.buildStylesheet();\n            // Duplicate stylesheet targeting data-spf-name if enabled.\n            if (uw.spf) {\n                var temp = scriptBodySelector;\n                scriptBodySelector = 'body[data-spf-name=\"watch\"]';\n                scriptSelector = scriptHtmlSelector + ' ' + scriptBodySelector\n                ytwp.event.buildStylesheet();\n                ytwp.style.appendRule('body[data-spf-name=\"watch\"]:not(.ytwp-window-player) #masthead-positioner',  {\n                    'position': 'absolute',\n                    'top': playerHeight + ' !important'\n                });\n            }\n            ytwp.style.injectIntoHeader();\n        },\n        buildStylesheet: function() {\n            ytwp.log('buildStylesheet');\n            //--- Browser Scrollbar\n            // Chrome/Webkit\n            ytwp.style.appendRule(scriptBodySelector + '::-webkit-scrollbar', {\n                'width': '0 !important',\n                'height': '0 !important',\n            });\n            // Firefox/Gecko\n            // Requires about:config flag to be toggled as of FireFox v63\n            // https://github.com/Zren/ResizeYoutubePlayerToWindowSize/issues/42\n            ytwp.style.appendRule('html', {\n                'scrollbar-width': 'none',\n            });\n\n            //--- Video Player\n            var d;\n            d = buildVenderPropertyDict(transitionProperties, 'left 0s linear, padding-left 0s linear');\n            d['padding'] = '0 !important';\n            d['margin'] = '0 !important';\n            ytwp.style.appendRule([\n                scriptBodySelector + ' #player',\n                scriptBodySelector + '.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible #player',\n                scriptBodySelector + '.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #player',\n                scriptBodySelector + '.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #player-legacy',\n                scriptBodySelector + '.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #watch7-main-container',\n            ], d);\n            //\n            d = buildVenderPropertyDict(transitionProperties, 'width 0s linear, left 0s linear');\n\n            // Bugfix for Firefox\n            // Parts of the header (search box) are hidden under the player.\n            // Firefox doesn't seem to be using the fixed header+guide yet.\n            d['float'] = 'initial';\n\n            // Skinny mode\n            d['left'] = 0;\n            d['margin-left'] = 0;\n\n            ytwp.style.appendRule(scriptBodySelector + ' #player-api', d);\n\n            // Theater mode\n            ytwp.style.appendRule(scriptBodySelector + ' .watch-stage-mode #player .player-api', {\n                'left': 'initial !important',\n                'margin-left': 'initial !important',\n            });\n\n            // Hide the cinema/wide mode button since it's useless.\n            //ytwp.style.appendRule(scriptBodySelector + ' #movie_player .ytp-size-button', 'display', 'none');\n\n            // !important is mainly for simplicity, but is needed to override the !important styling when the Guide is open due to:\n            // .sidebar-collapsed #watch7-video, .sidebar-collapsed #watch7-main, .sidebar-collapsed .watch7-playlist { width: 945px!important; }\n            // Also, Youtube Center resizes #player at element level.\n            // Don't resize if Youtube+'s html.floater is detected.\n            // Dont' resize if Youtube+ (Iridium/Material)'s html.iri-always-visible is detected.\n            ytwp.style.appendRule(\n                [\n                    scriptSelector + ' #player',\n                    scriptSelector + ' #player-wrap',\n                    scriptSelector + ' #player-api',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' #movie_player',\n                    scriptSelector + ' #player-mole-container',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' .html5-video-container',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' .html5-main-video',\n                    scriptSelector + ' ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy',\n                    scriptSelector + ' ytd-watch-flexy[flexy] #player-container-outer.ytd-watch-flexy',\n                    scriptSelector + ' ytd-watch-flexy[flexy] #player-container-inner.ytd-watch-flexy',\n                    scriptSelector + ' ytd-watch-flexy[flexy] #player-container.ytd-watch-flexy',\n                    scriptSelector + ' ytd-watch-grid[theater] #player-theater-container.ytd-watch-grid',\n                    scriptSelector + ' ytd-watch-grid[flexy] #player-container-outer.ytd-watch-grid',\n                    scriptSelector + ' ytd-watch-grid[flexy] #player-container-inner.ytd-watch-grid',\n                    scriptSelector + ' ytd-watch-grid[flexy] #player-container.ytd-watch-grid',\n                ],\n                {\n                    'width': '100% !important',\n                    'min-width': '100% !important',\n                    'max-width': '100% !important',\n                    'height': playerHeight + ' !important',\n                    'min-height': playerHeight + ' !important',\n                    'max-height': playerHeight + ' !important',\n                }\n            );\n\n             ytwp.style.appendRule(\n                [\n                    scriptSelector + ' #player',\n                    scriptSelector + ' .html5-main-video',\n                ],\n                {\n                    'top': '0 !important',\n                    'right': '0 !important',\n                    'bottom': '0 !important',\n                    'left': '0 !important',\n                }\n            );\n            // Resize #player-unavailable, #player-api\n            // Using min/max width/height will keep\n            ytwp.style.appendRule(scriptSelector + ' #player .player-width', 'width', '100% !important');\n            ytwp.style.appendRule(scriptSelector + ' #player .player-height', 'height', '100% !important');\n\n            // Fix video overlays\n            ytwp.style.appendRule([\n                scriptSelector + ' .html5-video-player .ad-container-single-media-element-annotations', // Ad\n                scriptSelector + ' .html5-video-player .ytp-upnext', // Autoplay Next Video\n            ], 'top', '0');\n\n            // Fix video cropping (object-fit: cover) (Issue #70)\n            ytwp.style.appendRule(scriptSelector + ' .ytp-fit-cover-video .html5-main-video', 'object-fit', 'contain !important');\n            // Thumbnail cropping\n            ytwp.style.appendRule(scriptSelector + ' .ytp-cued-thumbnail-overlay-image', {\n                'background-size': 'contain !important',\n                '-moz-background-size': 'contain !important',\n                '-webkit-background-size': 'contain !important',\n            });\n\n            //--- Video Container Background\n            ytwp.style.appendRule(scriptSelector + ' #movie_player', 'background-color', '#000000');\n\n            //--- Move Video Player\n            ytwp.style.appendRule(scriptSelector + ' #player', {\n                'position': 'absolute',\n                // Already top:0; left: 0;\n            });\n            ytwp.style.appendRule(scriptSelector, { // body\n                'margin-top': playerHeight,\n            });\n\n            // Fix the top right avatar button\n            ytwp.style.appendRule(scriptSelector + ' button.ytp-button.ytp-cards-button', 'top', '0');\n\n\n            //--- Sidebar\n            // Remove the transition delay as you can see it moving on page load.\n            d = buildVenderPropertyDict(transitionProperties, 'margin-top 0s linear, padding-top 0s linear');\n            d['margin-top'] = '0 !important';\n            d['top'] = '0 !important';\n            ytwp.style.appendRule(scriptSelector + ' #watch7-sidebar', d);\n\n            ytwp.style.appendRule(scriptSelector + '.cardified-page #watch7-sidebar-contents', 'padding-top', '0');\n\n            //--- Absolutely position the fixed header.\n            // Masthead\n            ytwp.style.appendRule('#skip-navigation.ytd-masthead', 'top', '-150vh'); // Normally -1000px can be shorter than screen (Issue #77)\n            d = buildVenderPropertyDict(transitionProperties, 'top 0s linear !important');\n            ytwp.style.appendRule(scriptSelector + '.hide-header-transition #masthead-positioner', d);\n            ytwp.style.appendRule(scriptSelector + '.' + viewingVideoClassId + ' #masthead-positioner', {\n                'position': 'absolute',\n                'top': playerHeight + ' !important'\n            });\n            // Lower masthead below Youtube+'s html.floater\n            ytwp.style.appendRule('html.floater ' + scriptBodySelector + '.' + viewingVideoClassId + ' #masthead-positioner', {\n                'z-index': '5',\n            });\n            // Autocomplete popup\n            ytwp.style.appendRule(scriptSelector + ' .sbdd_a', {\n                'top': '56px',\n            });\n            ytwp.style.appendRule(scriptSelector + '.' + viewingVideoClassId + ' .sbdd_a', {\n                'top': 'calc(' + playerHeight + ' + 56px) !important',\n                'position': 'absolute !important',\n            });\n\n            // Guide\n            // When watching the video, we need to line it up with the masthead.\n            ytwp.style.appendRule(scriptSelector + '.' + viewingVideoClassId + ' #appbar-guide-menu', {\n                'display': 'initial',\n                'position': 'absolute',\n                'top': '100% !important' // Masthead height\n            });\n            ytwp.style.appendRule(scriptSelector + '.' + viewingVideoClassId + ' #page.watch #guide', {\n                'display': 'initial',\n                'margin': '0',\n                'position': 'initial'\n            });\n            // When the guide is open, it adds body{top:-1000px} which messes with the top position (Issue #77)\n            ytwp.style.appendRule(scriptSelector + '.lock-scrollbar', {\n                'top': '0 !important',\n                'position': 'static !important',\n            });\n\n\n            //---\n            // MiniPlayer-Bar\n            ytwp.style.appendRule(scriptSelector + ' #miniplayer-bar #player', {\n                'position': 'static',\n            });\n            ytwp.style.appendRule(\n                [\n                    scriptSelector + ' #miniplayer-bar #player',\n                    scriptSelector + ' #miniplayer-bar #player-api',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' #miniplayer-bar #movie_player',\n                    scriptSelector + ' #player-mole-container',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' #miniplayer-bar .html5-video-container',\n                    scriptHtmlSelector + ':not(.floater):not(.iri-always-visible) ' + scriptBodySelector + ' #miniplayer-bar .html5-main-video',\n                ],\n                {\n                    'width': '252px !important',\n                    'min-width': '252px !important',\n                    'max-width': '252px !important',\n                    'height': '142px !important',\n                    'min-height': '142px !important',\n                    'max-height': '142px !important',\n                }\n            );\n            // Override inline style (caused by a JS animation) that breaks the miniplayer video\n            // https://github.com/Zren/ResizeYoutubePlayerToWindowSize/issues/41#issuecomment-439710130\n            ytwp.style.appendRule('.video-stream.html5-main-video', {\n                'top': '0 !important',\n            });\n\n            //---\n            // Hide Scrollbars\n            ytwp.style.appendRule(scriptSelector + '.' + topOfPageClassId, 'overflow-x', 'hidden');\n\n\n            //--- Fix Other Possible Style Issues\n            ytwp.style.appendRule(scriptSelector + ' #placeholder-player', 'display', 'none');\n            ytwp.style.appendRule(scriptSelector + ' #watch-sidebar-spacer', 'display', 'none');\n            ytwp.style.appendRule(scriptSelector + ' .skip-nav', 'display', 'none');\n\n            //--- Whitespace Leftover From Moving The Video\n            ytwp.style.appendRule(scriptSelector + ' #page.watch', 'padding-top', '0');\n            ytwp.style.appendRule(scriptSelector + ' .player-branded-banner', 'height', '0');\n\n            //--- Youtube+ Compatiblity\n            ytwp.style.appendRule(scriptSelector + ' #body-container', 'position', 'static');\n            ytwp.style.appendRule(scriptHtmlSelector + '.part_static_size:not(.content-snap-width-skinny-mode) ' + scriptBodySelector + ' .watch-non-stage-mode #player-playlist', 'width', '1066px');\n\n            //--- Playlist Bar\n            ytwp.style.appendRule([\n                scriptSelector + ' #placeholder-playlist',\n                scriptSelector + ' #player .player-height#watch-appbar-playlist',\n            ], {\n                'height': '540px !important',\n                'max-height': '540px !important',\n            });\n\n            d = buildVenderPropertyDict(transitionProperties, 'transform 0s linear');\n            ytwp.style.appendRule(scriptSelector + ' #watch-appbar-playlist', d);\n            d = buildVenderPropertyDict(transformProperties, 'translateY(0px)');\n            d['margin-left'] = '0';\n            d['top'] = 'calc(' + playerHeight + ' + 60px)';\n            ytwp.style.appendRule(scriptSelector + ' #player .player-height#watch-appbar-playlist', d);\n            ytwp.style.appendRule(scriptSelector + ' .playlist-videos-list', {\n                'max-height': '470px !important',\n                'height': 'initial !important',\n            });\n\n            // Old layout `&disable_polymer=true`\n            ytwp.style.appendRule(scriptSelector + ' #player .player-height#watch-appbar-playlist', {\n                'left': 'calc((100vw - 1066px)/2 + 640px + 10px)',\n                'width': '416px',\n            });\n            ytwp.style.stylesheet += '@media screen and (min-height: 630px) and (min-width: 1294px) {\\n';\n            ytwp.style.appendRule(scriptSelector + ' #player .player-height#watch-appbar-playlist', {\n                'left': 'calc((100vw - 1280px)/2 + 854px + 10px)',\n            });\n            ytwp.style.stylesheet += '}\\n @media screen and (min-width: 1720px) and (min-height:980px) {\\n';\n            ytwp.style.appendRule(scriptSelector + ' #player .player-height#watch-appbar-playlist', {\n                'left': 'calc((100vw - 1706px)/2 + 1280px + 10px)',\n            });\n            ytwp.style.stylesheet += '}\\n';\n\n            //---\n            // Material UI\n            ytwp.style.appendRule(scriptSelector + '.ytwp-scrolltop #extra-buttons', 'display', 'none !important');\n            // ytwp.style.appendRule('body > #player:not(.ytd-watch)', 'display', 'none');\n            // ytwp.style.appendRule('body.ytwp-viewing-video #content:not(app-header-layout) ytd-page-manager', 'margin-top', '0 !important');\n            // ytwp.style.appendRule('.ytd-watch-0 #content-separator.ytd-watch', 'margin-top', '0');\n            ytwp.style.appendRule('ytd-app', 'position', 'static !important');\n            ytwp.style.appendRule('ytd-watch #top', 'margin-top', '71px !important'); // 56px (topnav height) + 15px (margin)\n            ytwp.style.appendRule('ytd-watch #container', 'margin-top', '0 !important');\n            ytwp.style.appendRule('ytd-watch #content-separator', 'margin-top', '0 !important');\n            // Note: Container is now relative since 2023 June (Issue #77)\n            // Note: Container is now a full-bleed-player (Issue #79)\n            ytwp.style.appendRule([\n                scriptSelector + ' ytd-watch-flexy[theater] #player-wide-container.ytd-watch-flexy',\n                scriptSelector + ' ytd-watch-flexy[fullscreen] #player-wide-container.ytd-watch-flexy',\n                scriptSelector + ' ytd-watch-flexy[full-bleed-player] #player-full-bleed-container.ytd-watch-flexy', // Issue #79 (2023-08-17)\n                scriptSelector + ' ytd-watch-flexy[full-bleed-player] #full-bleed-container.ytd-watch-flexy', // Issue #79 (2023-08-22)\n                scriptSelector + ' ytd-watch-grid[theater] #player-wide-container.ytd-watch-grid',\n                scriptSelector + ' ytd-watch-grid[fullscreen] #player-wide-container.ytd-watch-grid',\n                scriptSelector + ' ytd-watch-grid[full-bleed-player] #player-full-bleed-container.ytd-watch-grid', // Issue #81 (2023-08-30)\n                scriptSelector + ' ytd-watch-grid[full-bleed-player] #full-bleed-container.ytd-watch-grid', // Issue #81 (2023-08-30)\n            ], {\n                'position': 'static',\n                'height': 0,\n                'min-height': 0,\n            });\n\n            ytwp.style.appendRule(scriptSelector + '.ytwp-viewing-video ytd-app #masthead-container.ytd-app', {\n                'position': 'absolute',\n                'top': playerHeight,\n                'z-index': 0,\n            });\n            ytwp.style.appendRule(scriptSelector + '.ytwp-viewing-video ytd-watch #masthead-positioner', {\n                'top': playerHeight + ' !important',\n            });\n            ytwp.style.appendRule(scriptSelector + ' .ytp-cued-thumbnail-overlay', 'z-index', '10');\n\n            //---\n            // Flexy UI\n            ytwp.style.appendRule([\n                scriptSelector + ' ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy',\n                scriptSelector + ' ytd-watch-grid[theater] #player-theater-container.ytd-watch-grid',\n            ], {\n                'position': 'absolute',\n                'top': '0',\n            });\n            // Youtube seems to be ignoring the margin/padding top in certain elements for some reason (Issue #88)\n            // ytwp.style.appendRule([\n            //     scriptSelector + ' ytd-watch-flexy',\n            //     scriptSelector + ' ytd-watch-grid',\n            // ], 'padding-top', '71px'); // 56px (topnav height) + 15px (margin)\n            ytwp.style.appendRule('#page-manager.ytd-app', 'padding-top', 'var(--ytd-masthead-height,var(--ytd-toolbar-height))');\n            ytwp.style.appendRule(scriptSelector + ' #error-screen', 'z-index', '11');\n        },\n        onWatchInit: function() {\n            ytwp.log('onWatchInit');\n            if (!ytwp.initialized) return;\n            if (ytwp.pageReady) return;\n\n            if (enableOnLoad) {\n                ytwp.event.addBodyClass();\n            }\n            if (ytwp.hasYoutubeChanged()) {\n                ytwp.debugPage()\n            }\n            ytwp.pageReady = true;\n        },\n        onDispose: function() {\n            ytwp.log('onDispose');\n            ytwp.initialized = false;\n            ytwp.pageReady = false;\n            ytwp.isWatchPage = false;\n        },\n        addBodyClass: function() {\n            // Insert CSS Into the body so people can style around the effects of this script.\n            document.body.classList.add(scriptBodyClassId);\n            ytwp.log('Applied ' + scriptBodySelector);\n        },\n        removeBodyClass: function() {\n            document.body.classList.remove(scriptBodyClassId);\n            ytwp.log('Removed ' + scriptBodySelector);\n        },\n    };\n\n    ytwp.html5PlayerFix = function() {\n        ytwp.log('html5PlayerFix');\n        return;\n\n        try {\n            if (!uw.ytcenter // Youtube Center\n                && !uw.html5Patched // Youtube+\n                && (!ytwp.html5.app)\n                && (uw.ytplayer && uw.ytplayer.config)\n                && (uw.yt && uw.yt.player && uw.yt.player.Application && uw.yt.player.Application.create)\n            ) {\n                ytwp.html5.app = ytwp.html5.getPlayerInstance();\n            }\n\n            ytwp.html5.update();\n            ytwp.html5.autohideControls();\n        } catch (e) {\n            ytwp.error(e);\n        }\n    }\n\n    ytwp.fixMasthead = function() {\n        ytwp.log('fixMasthead');\n        var el = document.querySelector('#masthead-positioner-height-offset');\n        if (el) {\n            ytwp.fixMastheadElement(el);\n        }\n    }\n    ytwp.fixMastheadElement = function(el) {\n        ytwp.log('fixMastheadElement', el);\n        if (el.style.height) { // != \"\"\n            setTimeout(function(){\n                el.style.height = \"\"\n                document.querySelector('#appbar-guide-menu').style.marginTop = \"\";\n            }, 0);\n        }\n    }\n\n    JSStyleSheet.injectIntoHeader(scriptStyleId + '-focusfix', 'input#search[autofocus] { display: none; }');\n    ytwp.removeSearchAutofocus = function() {\n        var e = document.querySelector('input#search');\n        // ytwp.log('removeSearchAutofocus', e)\n        if (e) {\n            e.removeAttribute('autofocus')\n        }\n    }\n\n    ytwp.registerMastheadFix = function() {\n        ytwp.log('registerMastheadFix');\n        // Fix the offset when closing the Share widget (element.style.height = ~275px).\n\n        observe('#masthead-positioner-height-offset', {\n            attributes: true,\n        }, function(mutation) {\n            console.log(mutation.type, mutation)\n            if (mutation.attributeName === 'style') {\n                var el = mutation.target;\n                if (el.style.height) { // != \"\"\n                    setTimeout(function(){\n                        el.style.height = \"\"\n                        document.querySelector('#appbar-guide-menu').style.marginTop = \"\";\n                    }, 0);\n                }\n\n            }\n        });\n    }\n\n    //--- Material UI\n    ytwp.materialPageTransition = function() {\n        ytwp.log('materialPageTransition')\n        ytwp.init();\n\n        if (ytwp.isWatchUrl()) {\n            ytwp.removeSearchAutofocus();\n            if (enableOnLoad) {\n                ytwp.event.addBodyClass();\n            }\n            // if (!ytwp.html5.app) {\n            if (!ytwp.initialized) {\n                ytwp.log('materialPageTransition !ytwp.html5.app', ytwp.html5.app)\n                setTimeout(ytwp.materialPageTransition, 100);\n            }\n            // Focus player\n            // var moviePlayer = document.querySelector('#movie_player')\n            // if (moviePlayer) {\n            //     moviePlayer.click()\n            // }\n        } else {\n            ytwp.event.onDispose();\n            document.body.classList.remove(scriptBodyClassId);\n        }\n        ytwp.onScroll();\n        ytwp.fixMasthead();\n        ytwp.attemptToUpdatePlayer();\n    };\n\n    //--- Listeners\n    ytwp.registerListeners = function() {\n        ytwp.registerMaterialListeners();\n        ytwp.registerMastheadFix();\n    };\n\n    ytwp.registerMaterialListeners = function() {\n        // For Material UI\n        // HistoryEvent.listeners.push(ytwp.materialPageTransition);\n        // HistoryEvent.startTimer();\n        // HistoryEvent.inject();\n        // HistoryEvent.listeners.push(console.log.bind(console));\n        document.addEventListener('yt-page-data-fetched', ytwp.materialPageTransition)\n        document.addEventListener('yt-navigate-finish', ytwp.materialPageTransition)\n\n        // Debugging\n        // document.addEventListener('yt-navigate-start', function(e){ ytwp.log('document.yt-navigate-start', e)})\n        document.addEventListener('yt-page-data-fetched', function(e){ ytwp.log('document.yt-page-data-fetched', e)})\n        document.addEventListener('yt-navigate-finish', function(e){ ytwp.log('document.yt-navigate-finish', e)})\n        // document.addEventListener('yt-navigate-error', function(e){ ytwp.log('document.yt-navigate-error', e)})\n        // document.addEventListener('yt-navigate-cache', function(e){ ytwp.log('document.yt-navigate-cache', e)})\n        // document.addEventListener('yt-navigate-redirect', function(e){ ytwp.log('document.yt-navigate-redirect', e)})\n        // document.addEventListener('yt-navigate-action', function(e){ ytwp.log('document.yt-navigate-action', e)})\n        // document.addEventListener('yt-navigate-home-action', function(e){ ytwp.log('document.yt-navigate-home-action', e)})\n    };\n\n    ytwp.main = function() {\n        ytwp.registerListeners();\n        ytwp.init();\n        ytwp.fixMasthead();\n    };\n\n    ytwp.main();\n\n    // ytwp.updatePlayerTimerId = 0;\n    ytwp.updatePlayerAttempts = -1;\n    ytwp.updatePlayerMaxAttempts = 150; // 60fps = 2.5sec\n    ytwp.attemptToUpdatePlayer = function() {\n        // console.log('ytwp.attemptToUpdatePlayer')\n        if (0 <= ytwp.updatePlayerAttempts && ytwp.updatePlayerAttempts < ytwp.updatePlayerMaxAttempts) {\n            ytwp.updatePlayerAttempts = 0;\n        } else {\n            ytwp.updatePlayerAttempts = 0;\n            ytwp.attemptToUpdatePlayerTick();\n        }\n        // setTimeout(ytwp.updatePlayer, 10000); /// Just in case it's not caught\n    }\n    ytwp.attemptToUpdatePlayerTick = function() {\n        // console.log('ytwp.attemptToUpdatePlayerTick', ytwp.updatePlayerAttempts)\n        if (ytwp.updatePlayerAttempts < ytwp.updatePlayerMaxAttempts) {\n            ytwp.updatePlayerAttempts += 1;\n            ytwp.updatePlayer();\n            // ytwp.updatePlayerTimerId = setTimeout(ytwp.attemptToUpdatePlayerTick, 200);\n            requestAnimationFrame(ytwp.attemptToUpdatePlayerTick);\n        }\n    }\n\n    ytwp.updatePlayer = function() {\n        ytwp.removeSearchAutofocus();\n        ytwp.enterTheaterMode();\n        ytwp.detectPlayerUnavailable();\n    }\n\n    ytwp.toggleExtension = function() {\n        document.body.classList.toggle('ytwp-window-player')\n        ytwp.setTheaterMode(document.body.classList.contains('ytwp-window-player'))\n    }\n\n\n    //--- Main\n    ytwp.materialPageTransition()\n    setInterval(ytwp.updatePlayer, 2500);\n\n\n    //--- Keyboard Shortcut\n    function childOf(child, ancestor) {\n        var parent = child.parentNode\n        while (parent) {\n            if (parent == ancestor) {\n                return true\n            }\n            parent = parent.parentNode\n        }\n        return false\n    }\n    function cancelIfToggleKey(validKeyCallback, e) {\n        var isKey = e.key === scriptToggleKey\n        var validTarget = (\n            e.target === document.body\n            || e.target.id === 'player-api'\n            || e.target.id === 'movie_player'\n            || childOf(e.target, document.querySelector('#movie_player'))\n        )\n        if (validTarget && isKey) {\n            e.preventDefault()\n            e.stopPropagation()\n            console.log('cancelIfToggleKey.validKeyCallback', validKeyCallback, 'e', e)\n            if (validKeyCallback) {\n                validKeyCallback()\n            }\n        }\n    }\n    window.addEventListener('keydown', cancelIfToggleKey.bind(null, ytwp.toggleExtension), true)\n    window.addEventListener('keyup', cancelIfToggleKey.bind(null, null), true)\n    // Note: keypress is deprecated\n    // https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event\n    window.addEventListener('keypress', cancelIfToggleKey.bind(null, null), true)\n\n\n    //--- Browser Extension\n    if (typeof browser !== \"undefined\") {\n        browser.runtime.onMessage.addListener(request => {\n            if (request.id == \"toggle\") {\n                ytwp.toggleExtension()\n\n                return Promise.resolve({\n                    enabled: document.body.classList.contains('ytwp-window-player'),\n                })\n            } else {\n                return Promise.reject(new Error('Unreconized message.id'))\n            }\n        });\n    }\n\n})(window);\n"
  },
  {
    "path": "README.md",
    "content": "# Resize Youtube Player To Window Size\n\nMoves the video to the top of the website and resizes it to the screen size. A side effect is that the resolution will auto-select 480p/720p/1080p if it fits in the window due to the video player's default behaviour.\n\n## UserJS Hosts\n\n* **GreasyFork:** https://greasyfork.org/scripts/811-resize-yt-to-window-size\n* **OpenUserJS.org:** https://openuserjs.org/scripts/zren/Resize_YT_To_Window_Size\n* ~~**Userscripts.org:** http://userscripts-mirror.org/scripts/show/153699~~\n\n## License\n\nGPL\n"
  },
  {
    "path": "ResizeRedditToWindowSize.user.js",
    "content": "// ==UserScript==\n// @name            Resize Reddit To Window Size\n// @description     Resize the video player for various sites to the window size.\n// @author          Chris H (Zren / Shade)\n// @namespace       https://www.github.com/Zren\n// @icon            https://reddit.com/favicon.ico\n// @version         50\n// @include         https://*.reddit.com/*\n// @grant           GM_addStyle\n// ==/UserScript==\n\n(function() {\n    var movedTopPlayer = function(videoBoxElement) {\n        document.body.insertBefore(videoBoxElement, document.body.firstChild);\n        videoBoxElement.style.width = '100%'\n        videoBoxElement.style.height = '100vh'\n        videoBoxElement.style.backgroundColor = '#000'\n    }\n\n    var urlMatch = function(regexStr) {\n        regexStr = regexStr.replace(/\\//g, '\\\\/'); // Auto escape forward slashes to make url regexes more legible.\n        var regex = new RegExp(regexStr);\n        return regex.exec(window.location.href);\n    }\n\n    var addViewportHeight = function(selector) {\n        var el = document.querySelector(selector)\n        if (!el) { return }\n        var style = getComputedStyle(el)\n        if (style.position == \"absolute\") {\n            var top = style.top || \"0\"\n            el.style.top = \"calc(100vh + \" + top + \")\"\n        }\n    }\n\n    if (document.location.host.endsWith('reddit.com')) {\n        var commentsRegex = /^https:\\/\\/www\\.reddit\\.com\\/(r|user)\\/[^\\/]+\\/comments\\//\n        if (!window.location.href.match(commentsRegex)) { return }\n        var videoBoxElement = document.querySelector('.reddit-video-player-root')\n        if (!videoBoxElement) { return }\n        movedTopPlayer(videoBoxElement)\n        var css = '.reddit-video-player-root { width: 100vw !important; height: 100vh !important; position: relative !important; display: block !important; float: none; z-index: 1000000; }'\n        css += '.reddit-video-player-root .pinned-controls { display: none; }'\n        css += '.pinnable-content.pinned { background-color: transparent !important; box-shadow: none !important; }'\n        css += '.pinnable-content.pinned .dismiss-pinnable { display: none; }'\n        css += '.pinnable-content .expando { display: none; }'\n        css += '.pinnable-content .expando-button { visibility: hidden; }'\n        css += '.pinnable-content.pinned { position: static !important; }'\n        css += '.pinnable-content.pinned .top-matter { position: static !important; }'\n        css += '.pinnable-content.pinned .midcol { position: static !important; }'\n        css += 'html, body { padding-left: 0 !important; padding-right: 0 !important }'\n        GM_addStyle(css)\n\n        setTimeout(function(){\n            addViewportHeight('.side #search')\n            addViewportHeight('.side .submit-link')\n            addViewportHeight('.side .submit-text')\n            addViewportHeight('.linkinfo')\n        }, 2000)\n    }\n\n    GM_addStyle('html::-webkit-scrollbar { width: 0; height: 0; } body::-webkit-scrollbar { width: 0; height: 0; }')\n    GM_addStyle('html { scrollbar-width: none; } body { scrollbar-width: none; }')\n})();\n"
  },
  {
    "path": "ResizeVideoDescription.md",
    "content": "Resizes the following sites\n\n* https://www.crunchyroll.com/\n* https://docs.google.com/file/\n* https://drive.google.com/drive/\n* https://vimeo.com/ (Will also autoplay video)\n* http://www.onepieceofficial.com/\n* https://www.youpak.com/\n* http://olympics.cbc.ca/\n* ~~http://www.dailymotion.com/ (Will also hide control bar faster)~~\n* https://streamable.com/\n* https://www.globaltv.com/shows/the-late-show-with-stephen-colbert/\n* https://www.much.com/shows/south-park/episode/\n* https://www.ctvnews.ca/\n* https://watch.cbc.ca/live/\n* https://www.ctv.ca/ (Will also unmute, and reload the page to workaround uBlockOrigin bug)\n* https://www.funimation.com/\n* https://www.crave.ca/\n* https://tubitv.com/\n* https://tv.bell.ca/\n\n# Suggestions\n* Use [Resize YT To Window Size](https://greasyfork.org/en/scripts/811-resize-yt-to-window-size) for YouTube. It has it's own script since YouTube's website is much more complicated and has many edge cases.\n* Experimental support for hiding scrollbar in Firefox v63. Go to `about:config` and set `layout.css.scrollbar-width.enabled` to `true`, then restart Firefox.\n\n## Screenshots\n\n![](https://i.imgur.com/bdoXOQc.png)\n![](https://i.imgur.com/K7uvIhp.png)\n![](https://i.imgur.com/CmxBBdj.png)\n"
  },
  {
    "path": "ResizeVideoToWindowSize.user.js",
    "content": "// ==UserScript==\n// @name            Resize Video To Window Size\n// @description     Resize the video player for various sites to the window size.\n// @author          Chris H (Zren / Shade)\n// @namespace       http://xshade.ca\n// @version         67\n// @include         https://www.crunchyroll.com/*\n// @include         https://beta.crunchyroll.com/*\n// @include         https://static.crunchyroll.com/vilos-v2/web/vilos/player.html*\n// @include         https://docs.google.com/file/*\n// @include         https://drive.google.com/drive/*\n// @include         https://drive.google.com/file/*\n// @include         https://vimeo.com/*\n// @include         http://onepieceofficial.com/videos.aspx*\n// @include         http://www.onepieceofficial.com/videos.aspx*\n// @include         https://www.youpak.com/watch*\n// @include         https://olympics.cbc.ca/video/*\n// @include         https://olympics.cbc.ca/divaPlayer/*\n// @include         http://www.dailymotion.com/*\n// @include         https://www.dailymotion.com/*\n// @include         https://streamable.com/*\n// @include         https://www.globaltv.com/shows/*\n// @include         https://watch.globaltv.com/video/*\n// @include         https://www.much.com/shows/south-park/episode/*/*/\n// @include         http://*.ctvnews.ca/*\n// @include         https://watch.cbc.ca/live/channel/*\n// @include         https://watch.cbc.ca/live/*\n// @include         https://www.ctv.ca/shows/*\n// @include         https://www.ctv.ca/video/*\n// @include         https://www.ctv.ca/*/Video*\n// @include         https://www.ctv.ca/Movie/*\n// @include         https://www.funimation.com/shows/*\n// @include         https://www.funimation.com/player/*\n// @include         https://www.crave.ca/*\n// @include         https://tubitv.com/*\n// @include         https://tv.bell.ca/*\n// @grant           GM_addStyle\n// ==/UserScript==\n\n(function() {\n    var fixedOverlayPlayer = function(selector) {\n        var css = selector + \"{\";\n        css += \"position: fixed;\";\n        css += \"top: 0;\";\n        css += \"left: 0;\";\n        css += \"right: 0;\";\n        css += \"bottom: 0;\";\n        css += \"}\";\n        GM_addStyle(css);\n    };\n\n    var absoluteTopPlayer = function(selector, staticSelectors) {\n        var css = selector + \"{\";\n        css += \"position: absolute;\";\n        css += \"top: 0;\";\n        css += \"left: 0;\";\n        css += \"width: 100vw;\";\n        css += \"height: 100vh;\";\n        css += \"padding: 0;\";\n        css += \"margin: 0;\";\n        css += \"}\";\n        css += \"body {\";\n        css += \"margin-top: 100vh;\";\n        css += \"margin-top: 100vh;\";\n        css += \"padding-top: 0;\";\n        css += \"}\";\n        if (staticSelectors) {\n            css += staticSelectors + \"{\";\n            css += \"position: static\";\n            css += \"}\";\n        }\n        GM_addStyle(css);\n    };\n\n    var movedTopPlayer = function(videoBoxElement) {\n        document.body.insertBefore(videoBoxElement, document.body.firstChild);\n        videoBoxElement.style.width = '100%';\n        videoBoxElement.style.height = '100%';\n        videoBoxElement.style.backgroundColor = '#000';\n    };\n\n    var waitFor = function(selector, callback) {\n        var tick = function(){\n            var e = document.querySelector(selector);\n            if (e) {\n                callback(e);\n            } else {\n                setTimeout(tick, 100);\n            }\n        };\n        tick();\n    };\n\n    var bindJWPlayerSpacebar = function() {\n        window.addEventListener('keydown', function(e){\n            if (e.key == ' ' && e.target == document.body) {\n                var video = document.querySelector('.jwplayer video')\n                if (video) {\n                    e.preventDefault();\n                    if (video.paused) {\n                        video.play()\n                    } else {\n                        video.pause()\n                    }\n                }\n            }\n        });\n    };\n\n    var urlMatch = function(regexStr) {\n        regexStr = regexStr.replace(/\\//g, '\\\\/'); // Auto escape forward slashes to make url regexes more legible.\n        var regex = new RegExp(regexStr);\n        return regex.exec(window.location.href);\n    };\n\n    if (document.location.host.endsWith('crunchyroll.com')) {\n        // console.log('doc loc', document.location)\n        // console.log('win loc', window.location)\n        if (document.location.hostname == 'www.crunchyroll.com' || document.location.hostname == 'beta.crunchyroll.com') {\n            var rvtwsHeaderClass = 'rvtws-header-hidden'\n            var css = ''\n            css += '.erc-header.'+rvtwsHeaderClass+' { position: absolute; }'\n            css += '.erc-header.'+rvtwsHeaderClass+' .header-content { opacity: 0; transition: opacity: 0.1s; }'\n            css += '.erc-header.'+rvtwsHeaderClass+' .header-content:hover { opacity: 1; }'\n            css += '.erc-watch-episode-layout .video-player-wrapper { max-height: 100vh; height: 100vh; display: flex; }'\n            // css += '.erc-watch-episode-layout .video-player { height: 56.25vw; align-self: center; }'\n            GM_addStyle(css)\n            function updateHeader() {\n                var ercHeader = document.querySelector('.erc-header')\n                var ercWatchEpisode = document.querySelector('.erc-watch-episode')\n                if (ercHeader) {\n                    if (ercWatchEpisode) {\n                        ercHeader.classList.add(rvtwsHeaderClass)\n                    } else {\n                        ercHeader.classList.remove(rvtwsHeaderClass)\n                    }\n                }\n            }\n            window.addEventListener('popstate', updateHeader)\n            setInterval(updateHeader, 1000)\n            updateHeader()\n        } else if (document.location.hostname == 'static.crunchyroll.com' && document.location.pathname == '/vilos-v2/web/vilos/player.html') {\n            GM_addStyle('#vilosRoot { height: 100vh !important; }');\n            GM_addStyle('#vilosControlsContainer > div:first-child { margin-top: 3.75rem; }'); // Make room for header\n        }\n    } else if (document.location.href.startsWith('https://docs.google.com/file/')) {\n        fixedOverlayPlayer('#drive-viewer-video-player-object-0');\n        var css = 'body:not(:hover) .ytp-chrome-bottom { opacity: 0 !important; }';\n        css += 'body:not(:hover) .drive-viewer-toolstrip { opacity: 0 !important; }';\n        GM_addStyle(css);\n    } else if (document.location.href.startsWith('https://drive.google.com/')) {\n        fixedOverlayPlayer('.drive-viewer-video-player');\n        var css = '.drive-viewer-toolstrip { opacity: 0 !important; }';\n        css += '.drive-viewer-toolstrip:hover { opacity: 1 !important; }';\n        GM_addStyle(css);\n    } else if (document.location.href.startsWith('https://vimeo.com/')) {\n        if (! /\\/\\d+/.exec(document.location.pathname))\n            return;\n        var css = '.js-player_area-wrapper, .player_area-wrapper, .player_area, .player_container, .player, .video-wrapper, .video, .video * { width: 100vw !important; height: 100vh !important; max-height: 100vh !important; }';\n        css += '.vp-player-layout { left: 0 !important; top: 0 !important; width: 100vw !important; height: 100vh !important; }';\n        css += '.clip_main > *:not(.player_area-wrapper) { margin-top: 70px; }';\n        css += '.VimeoBrand_ColorRibbon, .body_ribbon, .topnav_desktop, .topnav_mobile { position: absolute; top: 100vh; width: 100%; }';\n        css += '.topnav_desktop { top: calc(100vh + 5px); }';\n        GM_addStyle(css);\n\n        // autoplay\n        function tick() {\n            var e = document.querySelector('button.play[aria-label=\"Play\"]');\n            if (e) {\n                e.click();\n            } else {\n                setTimeout(tick, 100);\n            }\n        }\n        setTimeout(tick, 100);\n    } else if (document.location.host.endsWith('onepieceofficial.com')) {\n        movedTopPlayer(document.querySelector('#FUNimationVideo'));\n    } else if (document.location.host.endsWith('youpak.com')) {\n        movedTopPlayer(document.querySelector('.videoWrapper'))\n        var css = 'body > .container { padding-top: 60px; }'\n        css += '.navbar-fixed-top { position: absolute; top: 100vh; }'\n        css += 'body { padding-top: 0; }'\n        GM_addStyle(css)\n    } else if (document.location.host == 'olympics.cbc.ca') {\n        console.log(document.location.pathname, document.location.pathname.match(/\\/video\\/([^\\/]+)\\/([^\\/]+)(\\/?)/))\n        if (document.location.pathname.match(/\\/video\\/([^\\/]+)\\/([^\\/]+)(\\/?)/)) {\n            var css = '.cbc-video--player-wrapper { position: static !important; }'\n            css += '.cbc-video {'\n            css += '    position: absolute !important;'\n            css += '    top: 0 !important;'\n            css += '    left: 0 !important;'\n            css += '    padding: 0px !important;'\n            css += '    margin: 0px !important;'\n            css += '    width: 100% !important;'\n            css += '    height: 100vh !important;'\n            css += '}'\n            css += 'figure.cbc-video--thumb-wrapper, a[data-js-hook=\"play-video\"] picture img { max-height: 100vh !important; }'\n            css += '.or-podium .or-box { position: static !important; }'\n            css += '.or-podium .col-xs-1, .or-podium .col-sm-1, .or-podium .col-md-1, .or-podium .col-lg-1, .or-podium .col-xs-2, .or-podium .col-sm-2, .or-podium .col-md-2, .or-podium .col-lg-2, .or-podium .col-xs-3, .or-podium .col-sm-3, .or-podium .col-md-3, .or-podium .col-lg-3, .or-podium .col-xs-4, .or-podium .col-sm-4, .or-podium .col-md-4, .or-podium .col-lg-4, .or-podium .col-xs-5, .or-podium .col-sm-5, .or-podium .col-md-5, .or-podium .col-lg-5, .or-podium .col-xs-6, .or-podium .col-sm-6, .or-podium .col-md-6, .or-podium .col-lg-6, .or-podium .col-xs-7, .or-podium .col-sm-7, .or-podium .col-md-7, .or-podium .col-lg-7, .or-podium .col-xs-8, .or-podium .col-sm-8, .or-podium .col-md-8, .or-podium .col-lg-8, .or-podium .col-xs-9, .or-podium .col-sm-9, .or-podium .col-md-9, .or-podium .col-lg-9, .or-podium .col-xs-10, .or-podium .col-sm-10, .or-podium .col-md-10, .or-podium .col-lg-10, .or-podium .col-xs-11, .or-podium .col-sm-11, .or-podium .col-md-11, .or-podium .col-lg-11, .or-podium .col-xs-12, .or-podium .col-sm-12, .or-podium .col-md-12, .or-podium .col-lg-12 { position: static; }'\n            css += 'body:not(.cbc-main-page) { padding-top: 100vh; }'\n            GM_addStyle(css);\n            var playVideoButton = document.querySelector('a[data-js-hook=\"play-video\"]')\n            if (playVideoButton) {\n                playVideoButton.click()\n            }\n        } else if (document.location.pathname.startsWith('/divaPlayer')) {\n            var css = '#videoContainer:not(:hover) > .caption { opacity: 0; }'\n            css += '#videoContainer:not(:hover) .controlbar-diva { opacity: 0 !important; }'\n            css += '#videoContainer:not(:hover) #icon-menu-diva { opacity: 0; }'\n            css += '#videoContainer:not(:hover) diva-simple-controls { opacity: 0 !important; }'\n            GM_addStyle(css);\n        } else {\n            return; // Keep scrollbars\n        }\n    } else if (false && document.location.host.endsWith('www.dailymotion.com')) {\n        var css = '#player:not(:hover) .dmp_will-transition.dmp_is-transitioned--fadeinslide { opacity: 0; }';\n        if (document.location.pathname.startsWith('/playlist')) {\n            css += '#player_container { height: 100vh!important; width: 100vw!important; }';\n            css += '#playerv5-iframe { width: 100% !important; height: 100% !important; }'; // playlists\n            css += '.sd_header.sd_header--fixed { top: 100vh; position: absolute; }';\n            css += '#content { margin-top: 60px; }';\n            movedTopPlayer(document.querySelector('#player_container'));\n            absoluteTopPlayer('#player_container');\n\n            GM_addStyle(css);\n\n        } else if (document.location.pathname.startsWith('/video')) {\n            //css +='.main-container-player { display: none; }';\n            //css += '#player { height: 100vh!important; width: 100vw!important; }';\n            css += '.Player { height: 100vh!important; width: 100vw!important; }';\n            css += '.Player { top: 0!important; left: 0!important; }';\n            css += 'header { position: absolute!important; top: 100vh !important; }';\n            css += 'footer { margin-top: 50px; }';\n            css += 'div[class^=\"Video__placeholder___\"] { margin-top: -180px; height: 100vh!important; }';\n            GM_addStyle(css);\n            document.addEventListener('load',function(){\n                movedTopPlayer(document.querySelector('.Player'));\n            });\n        }\n\n    } else if (document.location.host.endsWith('streamable.com')) {\n        if (document.location.pathname == '/') {\n            return;\n        }\n        var css = '#player-content, #player.container .media-container, #player.container #filler, #player.container .player { max-width: 100% !important; width:100%; }';\n        css += '#player.container #filler { padding-bottom: 100vh !important; }';\n        css += '.player { background: #000; }';\n        css += '#player.container .player { display: flex; }';\n        css += '.player, #player.container video { max-height: 100vh; object-fit: contain; }';\n        css += '#player > div[style=\"height:15px;\"] { display: none; }';\n        css += '#player.container .topbanner { display: none; }';\n        GM_addStyle(css);\n    } else if (document.location.host.endsWith('globaltv.com')) {\n        var css = 'html, body, #root, .App, .Video {'\n        css += 'min-height: 100%; height: 100%; max-height: 100%;'\n        css += 'min-width: 100%; width: 100%; max-width: 100%;'\n        css += '}'\n        css += 'body { overflow-y: auto; }'\n        GM_addStyle(css);\n        waitFor('.jwplayer', function(jwPlayerElement) {\n            waitFor('.jwplayer video', function(videoElement) {\n                setTimeout(function() {\n                    videoElement.muted = false;\n                }, 200)\n            });\n        });\n        bindJWPlayerSpacebar();\n    } else if (document.location.host.endsWith('much.com')) {\n        var css = '#TopVideoWidgetSection, #ShowNav, #MainHeader, #MastHeadTakeover { display: none; }';\n        css += '#ShowTop #PlayerWrapper, #ShowTop .container-fluid, #ShowTop #ShowInfo, #ShowTop {';\n        css += 'margin: 0 !important; padding: 0 !important;';\n        css += 'width: 100vw !important; height: 100vh !important; max-width: 100vw !important; max-height: 100vh !important;';\n        css += '}';\n        css += '#ShowTop #ShowInfo #EpisodeInfo { margin-top: 0 !important; }';\n        css += '.jwplayer { max-height: 100vh; }';\n        css += '#EpisodeInfo .new-episodes { display: none !important; }';\n        GM_addStyle(css);\n    } else if (document.location.host.endsWith('ctvnews.ca')) {\n        if (window.location.pathname == '/latest') {\n            // Redirect to latest video\n            document.body.style.opacity = \"0\"\n            document.documentElement.style.transition = \"background 0.4s\"\n            document.documentElement.style.background = \"#000\"\n            var latestVideoLink = document.querySelector('.mainnavigation + .drop_down + script + .drop_down > .drop_down_element_container > div > div > ul > li:first-child > a')\n            if (latestVideoLink) {\n                window.location.href = latestVideoLink.href\n            }\n        } else if (window.location.pathname == '/video') {\n            var contentWrapper = document.querySelector('body > .content > .video-header > .content-wrapper')\n            if (contentWrapper) {\n                var header = document.querySelector('body > header')\n                document.body.insertBefore(contentWrapper, header)\n                var mediaplayerdiv = document.querySelector('#mediaplayerdiv')\n\n                contentWrapper.querySelector('.topname').style.display = \"none\"\n                contentWrapper.style.width = \"100%\"\n                contentWrapper.style.height = \"100vh\"\n                contentWrapper.style.maxWidth = \"100vw\"\n                contentWrapper.style.maxHeight = \"100vh\"\n                contentWrapper.style.background=\"#000\"\n\n                function onWindowResize() {\n                    var viewportWidth = document.documentElement.clientWidth\n                    var viewportHeight = document.documentElement.clientHeight\n                    var translate = \"translate(\" + ((viewportWidth - 960)/2) + \"px, \" + ((viewportHeight - 540)/2) + \"px)\"\n                    var scale = \"scale(\" + Math.min(viewportWidth / 960, viewportHeight / 540) + \")\"\n                    mediaplayerdiv.style.transform = translate + \" \" + scale\n                }\n                window.addEventListener('resize', onWindowResize);\n                onWindowResize();\n                return; // Keep scrollbars\n            }\n        } else {\n            return; // Keep scrollbars\n        }\n    } else if (document.location.host.endsWith('watch.cbc.ca')) {\n        var css = '#masthead { position: absolute; z-index: 1; width: 100%; opacity: 0; transition: opacity 250ms ease-in-out; }';\n        css += '#masthead:hover { opacity: 1; }';\n        css += '.regional-channel .container { max-width: 100%; }';\n        css += '.player-container.live, .jwplayer.jw-flag-aspect-mode { max-height: 100vh; }';\n        css += '.jwplayer.jw-stretch-uniform video { object-fit: contain !important; }';\n        css += '.regional-channel footer.regional-channel-footer, section.content-article.live { padding: 10px 0; }';\n        css += 'section.content-article.live-premium { display: none; }';\n        css += '.upgrade-banner, .live-premium, iframe.zEWidget-launcher { display: none; }';\n        css += '.upgrade-banner + .app-container.with-banner-large { top: 0; }';\n        css += '.content-article { padding-top: 0; padding-bottom: 0; }';\n        css += '.content-section.live-detail-layout { max-width: 100%; }';\n        GM_addStyle(css);\n    } else if (document.location.host.endsWith('www.ctv.ca')) {\n        var css = ''\n        css += 'header.navigation { opacity: 0; position: fixed; }'\n        css += 'header.navigation:hover { opacity: 1; }'\n        css += '.main { padding-top: 0 !important; }'\n        css += '#vidi-player-standalone { margin: 0vw 0vw 0; }'\n        css += 'div[class*=\"VidiPlayerstyles__VidiPlayerStandAloneContainer\"] { margin: 0vw 0vw 0; }'\n        css += '.jwplayer.jw-flag-aspect-mode { min-height: 100vh !important; height: 100vh !important; max-height: 100vh !important; }'\n        css += 'div[class*=\"BrowserNotificationstyles\"] { display: none; }'\n        css += 'div[class^=\"ArrowBackstyles__ButtonContainer\"] { display: none; }'\n\n        css += 'div[class^=\"globalStyles__MainContainer\"] { padding-top: 0 !important; }'\n        css += 'div[class^=\"VidiPlayerstyles__VidiPlayerPageContainer\"] { margin: 0 !important; }'\n        GM_addStyle(css);\n        waitFor('.jwplayer', function(jwPlayerElement) {\n            waitFor('.jwplayer video', function(videoElement) {\n                setTimeout(function() {\n                    videoElement.muted = false;\n                }, 200)\n            });\n        });\n        bindJWPlayerSpacebar();\n        var reverseEpisodeOrder = [\n            '/shows/the-daily-show-with-trevor-noah',\n        ]\n        waitFor('ul[class*=\"Episodesstyles__EpisodeList\"]', function(ul) {\n            if (reverseEpisodeOrder.indexOf(document.location.pathname) >= 0) {\n                for (var i = 0; i < ul.children.length; i++) {\n                    ul.insertBefore(ul.children[i], ul.firstChild)\n                }\n            }\n        });\n        setInterval(function(){\n            var e = document.querySelector('#__next div:not(.App)')\n            if (e) {\n                var h2 = e.querySelector('h2')\n                if (h2 && h2.textContent == 'An unexpected error has occurred.') {\n                    // CTV doesn't like uBlockOrigin, so reload the page to workaround the AJAX React links breaking.\n                    window.location.reload()\n                }\n            }\n        }, 100);\n    } else if (document.location.host.endsWith('funimation.com')) {\n        console.log('funimation.com')\n        var videoBoxElement = document.querySelector('.video-player-section .video-player-container');\n        console.log('videoBoxElement', videoBoxElement)\n        if (videoBoxElement) {\n            movedTopPlayer(videoBoxElement);\n            videoBoxElement.classList.remove('col-md-10');\n\n            var css = 'html, body { width: 100%; height: 100%; }';\n            css += '.video-player-container { width: 100vw !important; height: 100vh !important; }';\n            css += '#funimation-main-site-header { position: absolute; top: 100vh; }';\n            GM_addStyle(css);\n        } else {\n            console.log('location', document.location)\n            waitFor('#brightcove-player', function(player){\n                console.log('player', player)\n                player.removeAttribute('muted')\n                waitFor('.vjs-mute-control.vjs-vol-0', function(muteButton){\n                    console.log('muteButton', muteButton)\n                    muteButton.click()\n                })\n            })\n        }\n    } else if (document.location.host.endsWith('crave.ca')) {\n        if (document.location.pathname.startsWith('/live')) return;\n        var videoBoxElement = document.querySelector('video-player');\n        if (!videoBoxElement) return;\n        var css = 'footer, .back-button-wrapper, #mega-menu { display: none !important; }';\n        css += '.container-site-margin { margin-left: 0; margin-right: 0; }';\n        css += '.web-videoplayer { margin: 0; }';\n        css += 'html .jwplayer.jw-flag-aspect-mode { height: 100vh !important; }';\n        GM_addStyle(css);\n    } else if (document.location.host.endsWith('tubitv.com')) {\n        var css = 'header { transition: transform .3s, opacity .3s !important; }';\n        css += 'header.hide-header { opacity: 0 !important }';\n        css += 'header.hide-header:hover { opacity: 1 !important; }';\n        css += 'header + div > div:first-child > div:first-child > div:nth-child(2) { top: 0 !important; left: 0 !important; width: 100% !important; height: 100vh !important; }';\n        css += 'header + div > div:first-child > div:first-child > div:nth-child(2) > div:first-child > section { padding-top: 0 !important; height: 100vh !important; }';\n        css += 'header + div > div:first-child > div:first-child > div:nth-child(2) > div:first-child > section > div > div:nth-child(2) > div:first-child { background-image: linear-gradient(0deg,rgba(0,0,0,0), rgba(0,0,0,0.25) 30%, rgba(0, 0, 0, 1) 90%); }';\n        css += 'header + div > div:first-child > div:first-child > div:nth-child(2) > div:first-child > section > div > div:nth-child(2) > div:nth-child(2) { background-image: linear-gradient(180deg,rgba(0,0,0,0), rgba(0,0,0,0.25) 30%, rgba(0, 0, 0, 1) 90%); }';\n        css += '#captionsComponent > span { background: none !important; font-size: 3rem !important;';\n        css += 'text-shadow: 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000, 0 0 0.5rem #000;';\n        css += '}';\n        GM_addStyle(css);\n        var updateHeader = function() {\n            var header = document.querySelector('header')\n            if (header) {\n                var video = document.querySelector('video')\n                if (video) {\n                    header.classList.add('hide-header')\n                } else {\n                    header.classList.remove('hide-header')\n                }\n            }\n        }\n        updateHeader()\n        setInterval(updateHeader, 1000)\n    } else if (document.location.host.endsWith('tv.bell.ca')) {\n        if (!document.location.pathname.startsWith('/watch/')) return;\n        //let videoBoxElement = document.querySelector('video[playsinline]');\n        //if (!videoBoxElement) return;\n        waitFor('video[playsinline]', function(videoBoxElement){\n            let css = ''\n            css += '.bg-greyscale-black.w-capped { position: absolute !important; top: calc((var(--headerHeight) + 100vh) * -1 ) !important; height: 100vh !important; }';\n            css += '.bg-greyscale-black.w-full { position: absolute !important; top: -100vh !important; height: 100vh !important; }';\n            css += 'body { padding-top: 100vh !important; }';\n            css += '[class*=\"&_.bmpui-ui-subtitle-label]:!bg-greyscale-black-70\"].h-full.w-full.justify-center { max-width: 100% !important; }'\n            css += 'header[class=\"bg-greyscale-03 virgin:bg-tertiary-medium flex\"][aria-label=\"Global\"] { display: none !important; }'\n            console.log('css', css)\n            GM_addStyle(css);\n        })\n    }\n\n    GM_addStyle('html::-webkit-scrollbar { width: 0; height: 0; } body::-webkit-scrollbar { width: 0; height: 0; }');\n    GM_addStyle('html { scrollbar-width: none; } body { scrollbar-width: none; }');\n})();\n"
  },
  {
    "path": "YTDocs.md",
    "content": "# Youtube Player Documentation\n\n## 2023 Oct 31\n\nhttps://www.youtube.com/s/desktop/9e7f5697/jsbin/desktop_polymer_enable_wil_icons.vflset/desktop_polymer_enable_wil_icons.js\n\nNote, `yt-navigate-start` does not fire on web browser Back button ([Issue #76](https://github.com/Zren/ResizeYoutubePlayerToWindowSize/issues/76)). `document` events fire before `window` events.\n\n```js\ndocument.addEventListener('yt-navigate-start', function(){ console.log('document.yt-navigate-start', arguments)})\ndocument.addEventListener('yt-navigate-finish', function(){ console.log('document.yt-navigate-finish', arguments)})\ndocument.addEventListener('yt-navigate-error', function(){ console.log('document.yt-navigate-error', arguments)})\ndocument.addEventListener('yt-navigate-redirect', function(){ console.log('document.yt-navigate-redirect', arguments)})\ndocument.addEventListener('yt-navigate-cache', function(){ console.log('document.yt-navigate-cache', arguments)})\ndocument.addEventListener('yt-navigate-action', function(){ console.log('document.yt-navigate-action', arguments)})\ndocument.addEventListener('yt-navigate-home-action', function(){ console.log('document.yt-navigate-home-action', arguments)})\ndocument.addEventListener('yt-page-data-fetched', function(){ console.log('document.yt-page-data-fetched', arguments)})\nwindow.addEventListener('yt-navigate-start', function(){ console.log('window.yt-navigate-start', arguments)})\nwindow.addEventListener('yt-navigate-finish', function(){ console.log('window.yt-navigate-finish', arguments)})\nwindow.addEventListener('yt-navigate-error', function(){ console.log('window.yt-navigate-error', arguments)})\nwindow.addEventListener('yt-navigate-redirect', function(){ console.log('window.yt-navigate-redirect', arguments)})\nwindow.addEventListener('yt-navigate-cache', function(){ console.log('window.yt-navigate-cache', arguments)})\nwindow.addEventListener('yt-navigate-action', function(){ console.log('window.yt-navigate-action', arguments)})\nwindow.addEventListener('yt-navigate-home-action', function(){ console.log('window.yt-navigate-home-action', arguments)})\nwindow.addEventListener('yt-page-data-fetched', function(){ console.log('window.yt-page-data-fetched', arguments)})\n```\n\n```js\n    T8c = function (a, b) {\n      a.listen(b, 'yt-navigate-start', 'onYtNavigateStart');\n      a.listen(b, 'yt-navigate-finish', 'onYtNavigateFinish');\n      a.listen(b, 'yt-navigate-error', 'onYtNavigateError');\n      a.listen(b, 'yt-page-data-fetched', 'onYtPageDataFetched');\n      a.listen(b, 'yt-navigate-redirect', 'onYtNavigateRedirect')\n    };\n    f = C6.prototype;\n    f.detached = function () {\n      var a = rp().resolve(BE);\n      this.unlisten(a, 'yt-navigate-start', 'onYtNavigateStart');\n      this.unlisten(a, 'yt-navigate-finish', 'onYtNavigateFinish');\n      this.unlisten(a, 'yt-navigate-error', 'onYtNavigateError');\n      this.unlisten(a, 'yt-page-data-fetched', 'onYtPageDataFetched');\n      this.unlisten(document, 'yt-navigate-cache', 'onYtNavigateCache');\n      this.unlisten(a, 'yt-navigate-redirect', 'onYtNavigateRedirect');\n      this.ytActionHandlerBehavior.unregisterActionMap(this.appBehaviorActionMap)\n    };\n```\n\n```js\na.actionMap = {\n'yt-command-executor-command': 'handleCommandWithCommandHandler',\n'yt-dark-mode-toggled-action': 'onDarkModeToggledAction',\n'yt-edu-dismiss-action': 'handleEduDismissAction',\n'yt-edu-impression-action': 'handleEduImpressionAction',\n'yt-navigate-action': 'onYtNavigateAction',\n'yt-navigate-home-action': 'onYtNavigateHomeAction',\n'yt-player-fullscreen': 'onPlayerFullscreen',\n'yt-register-create-family-dialog': 'onYtRegisterCreateFamilyDialog',\n'yt-select-country-command': 'handleSelectCountryCommand',\n'yt-select-language-command': 'handleSelectLanguageCommand',\n'yt-clear-url-param-command': 'handleClearUrlParamCommand',\n'yt-set-cookie-command': 'onSetCookieCommand',\n'yt-set-pref-storage-entry-command': 'onSetPrefStorageEntryCommand',\n'yt-set-local-storage-command': 'onSetLocalStorageCommand',\n'yt-set-push-notifications-enabled-command': 'onSetPushNotificationsEnabledCommand',\n'yt-signal-action-copy-debug-data': 'onYtSignalActionCopyDebugData',\n'yt-signal-action-enable-chrome-notifications': 'onYtSignalActionEnableChromeNotifications',\n'yt-signal-action-toggle-restricted-mode-on': 'onYtSignalActionToggleRestrictedModeOnAction',\n'yt-signal-action-toggle-restricted-mode-off': 'onYtSignalActionToggleRestrictedModeOffAction',\n'yt-signal-action-confirm-mentions-edu': 'onYtSignalActionConfirmMentionsEdu',\n'yt-signal-action-record-mentions-edu-impression': 'onYtSignalActionRecordMentionsEduImpression',\n'yt-signal-action-show-keyboard-shortcut-dialog': 'onYtSignalActionShowKeyboardShortcutDialog',\n'yt-signal-action-skip-navigation': 'onYtSignalActionSkipNavigation',\n'yt-signal-action-request-persistent-storage': 'onYtSignalActionRequestPersistentStorage',\n'yt-timed-command': 'onYtTimedCommand',\n'yt-window-resized': 'onWindowResized',\n'yt-window-scrolled': 'onWindowScrolled',\n'yt-persist-subscriptions-display-preferences-command': 'handlePersistSubscriptionsDisplayPreferencesCommand',\n'yt-invoke-instrument-manager-action': 'onInvokeInstrumentManagerAction',\n'yt-entity-update-command': 'handleEntityUpdateCommand',\n'yt-web-native-share-command': 'handleWebNativeShareCommand',\n'yt-confirm-dialog-endpoint': 'handleConfirmDialogEndpoint',\n'yt-ad-feedback-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-create-backstage-post-dialog-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-manage-purchase-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-modal-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-unlimited-family-flow-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-ypc-cancel-survey-endpoint': 'handleOpenPopupNavigationEndpoints',\n'yt-register-promo-command': 'handleYtRegisterPromoCommand',\n'yt-location-collection-command': 'onYtLocationCollectionCommand',\n'yt-get-location-command': 'onYtGetLocationCommand',\n'yt-log-flow-logging-event-command': 'logFlowLoggingEventCommand',\n'yt-save-command-to-session-storage-action': 'handleSaveCommandToSessionStorage',\n'yt-show-dma-consent-flow-command': 'handleShowDmaConsentFlow',\n'yt-signal-action-show-dma-consent-flow': 'handleShowDmaConsentFlow',\n'yt-signal-action-toggle-dark-theme-on': 'handleSignalActionToggleDarkThemeOn',\n'yt-signal-action-toggle-dark-theme-off': 'handleSignalActionToggleDarkThemeOff',\n'yt-signal-action-toggle-dark-theme-device': 'handleSignalActionToggleDarkThemeDevice',\n'yt-select-active-identity-endpoint': 'handleSelectActiveIdentityEndpointInternal',\n'yt-update-permission-role-command': 'handleUpdatePermissionRoleCommand',\n'yt-channel-creation-form-endpoint': 'handleYtChannelCreationFormEndpoints',\n'yt-google-payment-billing-command': 'handleCommandWithCommandHandler'\n}\n```\n\n\n## 2017 May 11\n\n`base.js` defines the classes and exposes them at `window._yt_player`\na watch page will add a script tag that sets `window.ytplayer.config`\nthen immeditately calls `Application.create()`, but doesn't expose the app instance.\n\n```js\nytplayer.load = function() {\n  yt.player.Application.create(\"player-api\", ytplayer.config);\n  ytplayer.config.loaded = true;\n};\n(function() {\n  if (!!window.yt && yt.player && yt.player.Application) {\n    ytplayer.load();\n  }\n}());\n```\n\n`Application.create` does store the app instance in a list, \nbut it's no longer accessible.\nReinitializing the player will work, but may cause a 2nd `#movie_player` element to be created.\n\n`Application.create()` will call\n\n```js\nO1 = function(a, b) {\n    g.M.call(this);\n    var c = this;\n    this.ca = Xia(b);\n    var d = this.ca.args || {};\n    this.Z = new zO(d);\n    g.N(this, this.Z);\n    this.Z.experiments.g(\"legacy_autoplay_flag\") || \"detailpage\" != this.Z.g || (d.autoplay = \"1\");\n    this.Bc = dO(\"detailpage\" == this.Z.g && \"blazer\" != this.Z.o, d.enablesizebutton);\n    this.oa = dO(!1, d.player_wide);\n    this.V = this.Z.Fb && dO(!1, d.external_list);\n    this.va = (this.qc = this.Z.Fb && dO(!1, d.external_play_video)) && this.Z.experiments.g(\"player_unified_fullscreen_transitions\");\n    this.P = new g.BL(this);\n    g.N(this, this.P);\n    Gc = function(a, b) {\n        g.kE(b, \"WARNING\")\n    }\n    ;\n    this.Oa = null;\n    this.K = new g.cD;\n    this.ba = new g.cD;\n    this.da = new N1(this.ba);\n    this.da.pause();\n    this.g = new PU(this);\n    g.N(this, this.g);\n    this.J = new PU(this,1);\n    g.N(this, this.J);\n    this.F = new bZ(this);\n    g.N(this, this.F);\n    this.O = 1;\n    this.Va = {};\n    this.M = this.Z.storeUserVolume ? Cja() : {\n        volume: 100,\n        muted: this.Z.mute\n    };\n    this.aa = this.Z.Fb ? new YJ(this,1) : new bJ(this,1);\n    g.N(this, this.aa);\n    this.D = null;\n    this.Ra = {};\n    d = {};\n    this.xb = (d.internalAbandon = this.RL,\n    d.internalvideodatachange = this.QL,\n    d.playbackready = this.SL,\n    d.playbackstarted = this.TL,\n    d.statechange = this.UL,\n    d.signatureexpired = this.YO,\n    d);\n    this.A = Lna(this);\n    g.N(this, this.A);\n    this.G = new zP(this.Z,\"\",this.A);\n    this.o = Mna(this);\n    d = {};\n    this.tc = (d.airplayactivechange = this.HL,\n    d.airplayavailabilitychange = this.IL,\n    d.beginseeking = this.cM,\n    d.endseeking = this.QM,\n    d.internalAbandon = this.iN,\n    d.internalaudioformatchange = this.WL,\n    d.internalvideodatachange = this.vr,\n    d.internalvideoformatchange = this.BP,\n    d.liveviewshift = this.oN,\n    d.playbackstalledatstart = this.eP,\n    d.progresssync = this.RI,\n    d.seekto = this.SI,\n    d.onLoadProgress = this.pN,\n    d.onVideoProgress = this.VI,\n    d.playbackready = this.lO,\n    d.statechange = this.cA,\n    d.connectionissue = this.AM,\n    d.newelementrequired = this.SN,\n    d.heartbeatparams = this.OI,\n    d.videoelementevent = this.TI,\n    d);\n    this.C = null;\n    this.ra = new zZ(5,function(a) {\n        a != g.WU(c, a.getPlayerType()) && a.dispose()\n    }\n    );\n    g.N(this, this.ra);\n    this.zb = this.Bb = -1;\n    this.sb = new g.nt(this.F.Zf,16,this.F);\n    g.N(this, this.sb);\n    this.tb = !1;\n    this.fa = !0;\n    this.sa = this.Na = this.B = null;\n    this.Hb = !1;\n    this.Tb = this.sc = null;\n    this.ob = this.ga = 0;\n    this.ka = this.Ja = !1;\n    this.Fa = this.ha = null;\n    this.P.T(this.g, \"crn_appapi\", this.OL);\n    this.P.T(this.g, \"crx_appapi\", this.PL);\n    this.P.T(this.g, \"crn_appad\", this.mz);\n    this.P.T(this.g, \"crx_appad\", this.mz);\n    this.P.T(this.g, \"presentingplayerstatechange\", this.QI);\n    this.P.T(this.g, \"resize\", this.IO);\n    this.F.Ia(g.ae(a));\n    this.Xb = this.Z.experiments.g(\"html5_enable_embedded_player_visibility_signals\") && this.Z.A ? new BZ(this.F.element) : null;\n    g.N(this, this.Xb);\n    g.ND = this.Z.ba;\n    Nna(this);\n    this.G.o(\"fs\");\n    Ona(this);\n    this.Fa = new L1(this.g);\n    this.A.C = this.Fa;\n    this.Fa.init();\n    g.dV(this.J, \"init\")\n}\n```\n\nThe `g` variable is an alias for `_yt_player`.\nWe can monkey patch `g.WU` since it's passed the \"c = this\" variable as it's first argument.\n\n```js\ng.WU=function(a,b){return b?1==b?a.o:a.Ra[b]||null:a.C}; // Chrome\ng.ZU=function(a,b){return b?1==b?a.o:a.Ra[b]||null:a.C}; // Firefox\n```\n\nWe then take that instance and patch `app[key1][key2]()`\nwhere the value of `key1` has a property called element that points to `#movie_player`\n\n```js\napp[key1].element = #movie_player`\n```\n\nThe value of `key2` is the function we need to patch.\nWe use regex detect if it's source looks like the following.\n\n```js\nfunction(){var a=this.app.Z,b=g.pF()==this.element;if(b&&IE())return new g.Vd(window.outerWidth,window.outerHeight);if(b||a.mi){if(window.matchMedia){a=\"(width: \"+window.innerWidth+\"px) and (height: \"+window.innerHeight+\"px)\";this.C&&this.C.media==a||(this.C=window.matchMedia(a));var c=this.C&&this.C.matches}if(c)return new g.Vd(window.innerWidth,window.innerHeight)}else if(this.P&&!this.app.oa)for(a=0;a<this.P.length;a++)if(b=this.P[a],b.query.matches)return new g.Vd(b.size.width,b.size.height);\nreturn new g.Vd(this.element.clientWidth,this.element.clientHeight)};\n```\n\nwe then call another function that'll update the DOM.\n\n\n## 2013 May 3\n\n`.watch-playlist-collapsed` and `.watch-medium` now attach to `#player`\n\n```\n#watch7-container .watch-playlist\n  #player .watch-playlist-collapsed .watch-medium (moved)\n    #playlist (Moved to inside #player)\n      #watch7-playlist-scrollfloater\n        #watch7-playlist-bar\n      #watch7-playlist-data\n        #watch7-playlist-bar\n#watch7-main-container\n  ...\n```\n\nThe following pubsub events fire when you scroll to see the comments since ~2017-02-14.\n\n```\npubsub1 yt-www-pageFrameCssNotifications-load\npubsub1 yt-www-comments-page-updated\n```\n\nSomething fires on scroll that needs to fire, otherwise the next button doesn't work,\nand autoplay doesn't work either.\n\n```\n/watch_fragments_ajax\n  ?v=9BJ3jDWlOHE\n  &list=WL\n  &index=15\n  &tr=scroll\n  &distiller=1\n  &ctoken=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%253D\n    decode this param with atob(decodeURIComponent(decodeURIComponent(\"...\")))\n  &frags=comments\n  &spf=load\n```\n\n\n## 2013  April 2\n\n`#watch7-playlist-container` --renamed--> `#playlist`\n\n\n## 2013 March 20\n\n`#watch7-video-container` --renamed--> `#watch7-container` (renamed back then?)\n\n```\n#player (#watch7-playlist-container is injected above this element)\n  #player-api\n    embed#movie_player\n  #watch7-creator-bar\n```\n\n\n## 2013 March ?\n\n```\n#watch7-video-container (#watch7-playlist-container is injected above this element)\n  #watch7-video\n    #watch-player ?\n      embed#movie_player ?\n```\n\n"
  },
  {
    "path": "changelog.md",
    "content": "<h3>Changelog</h3>\n\n## v139 - April 10, 2024\n\n* Fix page top margin as certain elements seem to ignore the CSS properties completely (Issue #88)\n\n## v138 - January 9, 2024\n\n* Bind toggle to `keydown` instead of `keyup` so that pressing `Ctrl+W` to close a tab does not trigger the YTWP toggle when you then focus on a Youtube tab.\n\n## v137 - November 1, 2023\n\n* Bind to `yt-page-data-fetched` and `yt-navigate-finish` to fix the back button not cleaning up the window view since `yt-navigate-start` does not always fire (Issue #72 and #76)\n* Bind `keyup` not `keypress` (which is deprecated). Also cancel event during `keydown`. This fixes the `w` key also changing the caption box style. It should also fix changing the toggle key to `Escape` (Issue #71)\n\n## v136 - August 30, 2023\n\n* Attempt to fix `ytd-watch-grid` papercuts (Issue #81)\n\n## v135 - August 30, 2023\n\n* Attempt to fix `ytd-watch-grid` (Issue #81)\n\n## v134 - August 22, 2023\n\n* Fix video container getting shifted again after YT update caused by new `full-bleed-player` layout. Thanks again @Vamael for the fix. (Issue #79)\n\n## v133 - August 18, 2023\n\n* Fix video container getting shifted after YT update caused by new `full-bleed-player` layout. Thanks @Vamael for the fix. (Issue #79)\n\n## v132 - June 29, 2023\n\n* Fix video container getting shifted after YT update (Issue #77)\n* Fix nav moving around when guide is open.\n* Added `background-color: black` to `#movie_player` so it looks better in light mode.\n\n## 131 - March 11, 2023\n\n* Fix theater mode toggle. `ytd-watch-flexy` DOM is weird. (Issue #75)\n* Listen for `yt-navigate-start` and `yt-navigate-finish` events.\n\n## 130 - April 19, 2022\n\n* Add quick boolean toggle for enableOnLoad (Issue #67 and #69)\n* Fix video cropping caused by object-fit:cover (Issue #70)\n* Make it easy to change script toggle keybinding as it'll need to change (Issue #71)\n\n## 129 - March 9, 2022\n\n* Fix toggling theater mode as YouTube moved the button into the settings cog menu (Issue #66)\n\n## 128 - December 25, 2021\n\n* Disable script when an unavailable video is detected\n* Remove some logging\n\n## 127 - April 5, 2021\n\n* Resize the video faster by styling the `#player-wrap` element.\n\n## 126 - April 5, 2021\n\n* Fix scrollbar not being hidden in Chrome.\n\n## 125 - May 5, 2020\n\n* Bind `w` key to toggle off script on current page.\n* Prep toggle code for firefox extension.\n\n## 124 - November 6, 2019\n\n* Fix autogenerated gaming channel \"live channels\" page like https://www.youtube.com/channel/UCZtmNrG53nmbq-Ww2VJrxEQ/live (Issue #46)\n\n## 123 - June 24, 2019\n\n* Support `/user/channelName/live` url paths like https://www.youtube.com/user/pokemon/live (Issue #29)\n\n## 122 - January 30, 2019\n\n* Fix hidden video bug when fullscreen (Issue #43)\n\n## 121 - November 18, 2018\n\n* Fix miniplayer video getting positioned offscreen.\n\n## 120 - November 13, 2018\n\n* Add experimental support for hiding scrollbar in Firefox v63. Go to `about:config` and set `layout.css.scrollbar-width.enabled` to `true`, then restart Firefox.\n\n## 119 - August 22, 2018\n\n* Fix the current video thumbnail not showing up when autoplay is disabled.\n* Fix the black bg showing a white section when the miniplayer is active.\n\n## 118 - May 19, 2018\n\n* Support (one of) the new \"flexy\" youtube interface.\n\n## 117 - April 21, 2018\n\n* Slightly fix the playlist area positioning in the old youtube layout.\n\n## 116 - April 19, 2018\n\n* Use a 32px icon so that it looks better in various browser extensions.\n* Support YouTube's experimental MiniPlayer Bar.\n* Fix onScroll event not triggering in firefox.\n\n## 115 - December 8, 2017\n\n* Fix script not loading error when the page has only loaded halfway.\n\n## 114 - December 8, 2017\n\n* Use !important to fix compatibility with Youtube+ on the old Youtube layout.\n\n## 113 - December 5, 2017\n\n* Fix the autocomplete popup when the video is still visible.\n\n## 112 - December 2, 2017\n\n* Fix the positioning of the search box's autocomplete popup (it was previously hidden).\n* Attempt to cleanup the player every 2.5sec instead of every 1sec, as well as the first 150 frames on page load.\n\n## 111 - November 10, 2017\n\n* Constantly attempt to enter Theater mode every second if we don't enter it right away.\n* Support entering theater mode in the old layout.\n\n## 110 - October 6, 2017\n\n* Focus on video on page load.\n* Support Youtube+'s successor script (Iridium)'s \"Video always visible\" feature.\n\n## 109 - September 19, 2017\n\n* Fix seekbar resizing when the window is less than ___px wide.\n* Fix scrolling jitter on load caused by the search box getting focus.\n\n## 108 - September 12, 2017\n\n* Toggle theater mode to fix the progressbar since it works consistently.\n\n## 107 - August 30, 2017\n\n* Fix videos on channel pages when first visiting a video page.\n\n## 106 - July 4, 2017\n\n* Enable script on `/c/ChannelName/live` and `/channel/ChannelId/live` pages.\n\n## 105 - June 28, 2017\n\n* Fix update loop not starting.\n\n## 104 - June 27, 2017\n\n* Don't start another fix loop when one is in progress.\n\n## 103 - June 27, 2017\n\n* Reattempt fix 10 more times on page load (shit solution but it works).\n\n## 102 - June 18, 2017\n\n* Fix regex checks in FF v54.\n* Attempt to fix resizing the progressbar after a few vidoes have played.\n* Fix detection for video -> video page changes.\n* Keep track of the player size instead of querying the element every time it's looked up (which is a lot).\n\n## 101 - May 11, 2017\n\n* Finish the last regex for applying the control bar fix on page load, control bar should now work in firefox.\n\n## 100 - May 11, 2017\n\n* Patch the player with a newer method to retrieve the app instance. Works for Chrome, but firefox needs one more regex update. Will push a final fix for firefox later today.\n\n## 99 - May 10, 2017\n\n* Undo the update for the control bar since it can cause a second instance of the player.\n\n## 98 - May 8, 2017\n\n* Quick update for the control bar monkey patch. We need to reinit the player so it's slightly slower than normal. Unfortunately the list of players isn't exposed anymore.\n\n## 97 - May 8, 2017\n\n* Fix the info card button in the top right. Example of button: https://www.youtube.com/watch?v=XGu-WCyiaEY\n* Make it easy to edit the script to set the player to a fixed height.\n\n## 96 - April 25, 2017\n\n* Fix Material UI bug. Don't use pubsub anymore since Material UI keeps fucking around with it's API. Just use a periodic timer.\n\n## 95 - April 16, 2017\n\n* TempFix for detecting page transition for the Material UI. Check the URL every 500ms and see if it's changed. A proper fix will come when I find a better solution.\n\n## 94 - April 15, 2017\n\n* Fix high CPU usage caused by binding listeners over and over due to an error (and my bad code).\n\n## 93 - April 4, 2017\n\n* Don't run on `/shared` pages anymore.\n\n## 92 - March 21, 2017\n\n* Fix content positioning in the Material Design css.\n* Fix some error spam caused by the pubsub/pubsub2 subscribe() function getting moved.\n\n## 91 - March 2, 2017\n\n* Update CSS to support new beta of the Material Design layout (tested by adding `&f6=4` to the `PREFS` cookie).\n\n## 90 - February 12, 2017\n\n* Support `/shared` pages.\n\n## 89 - January 24, 2017\n\n* Hide the scrollbar on video pages (webkit browsers).\n* No longer promote Stylish to hide scrollbars now that the extension spies on you by default.\n\n## 88 - October 25, 2016\n\n* Add support for the Material Design UI experiment.\n\n## 87 - September 3, 2016\n\n* Rewrite the previous fix since it caused problems.\n\n## 86 - September 3, 2016\n\n* Fix empty space when closing the share widget.\n\n## 85 - July 14, 2016\n\n* Fix seekbar fix regex.\n\n## 84 - July 7, 2016\n\n* Don't run script in youtube.com video iframes, or iframes on youtube.com. Now compatible with \"Simple YouTube MP3 Button\".\n* Fix videos on channel pages when first visiting a video url.\n\n## 83 - Mar 27, 2016\n\n* Force width to 100% on the `#player-api` element to fix compatibility with Youtube+.\n\n## 82 - Mar 1, 2016\n\n* Prevent script from running on channel pages.\n\n## 81 - Feb 20, 2016\n\n* Proper fix for the player ui not resizing before being clicked.\n\n## 80 - Feb 20, 2016\n\n* Tempfix the player ui not resizing before being clicked.\n\n## 79 - Feb 16, 2016\n\n* Tempfix the player ui not resizing before being clicked.\n* Stop duplicating the stylesheet every page.\n* Target `body[data-spf-name=\"watch\"]` if spf is enabled so the player remains the same size when changing video.\n\n## 78 - Jan 18, 2016\n\n* Fix a few errors.\n\n## 77 - Dec 24, 2015\n\n* Fix the autoplay UI not being shown.\n\n## 76 - Dec 24, 2015\n\n* Cleanup cached varibles when changing pages. Should fix the seekbar width breaking after a few videos.\n* Make compatible with Youtube+'s \"Player always visible when reading comments\" feature.\n\n## 75 - Dec 19, 2015\n\n* Trigger resizing the player controls after patching it's size function.\n\n## 74 - Dec 17, 2015\n\n* Fix the Skip Ad UI getting hidden.\n\n## 73 - Dec 13, 2015\n\n* Reenable the html5 seekbar fix since apparently the problem is unrelated to my script.\n\n## 72 - Dec 12, 2015\n\n* Disable the html5 seekbar fix (for now). My technique appears to break everything (comment loading/autoplay/buttons) on occasion.\n* Fix playlist widget overlaying sidebar.\n\n## 71 - Nov 24, 2015\n\n* Fix html5 seekbar.\n\n## 70 - Aug 19, 2015\n\n* Fix playlist overlaying the rest of the sidebar.\n* Fix playlist overlaying the video description when using Youtube+.\n\n## 69 - July 26, 2015\n\n* Make script slightly compatible with Youtube+ after clicking another video.\n\n## 68 - June 19, 2015\n\n* Update HTML5 fix for the old player. `Objects.keys(obj.constructor.prototype)` was skipping the property, so used `for (var k in obj){}`.\n\n## 67 - June 17, 2015\n\n* Make script slightly compatible with Youtube+\n\n## 66 - June 14, 2015\n\n* Fix player offset when the window is really small.\n\n## 65 - May 28, 2015\n\n* Update HTML5 fix for old player.\n\n## 64 - May 7, 2015\n\n* Fix removing transition on the masthead. YT Center has another rule with `!important`.\n* Fix the playlist widget getting hidden beneath the player.\n\n## 63 - May 6, 2015\n\n* Update HTML5 fix.\n* Remove transition on the masthead.\n\n## 62 - May 6, 2015\n\n* Fix the height on new `.html5-video-container` element.\n\n## 61 - Apr 30, 2015\n\n* Update HTML5 fix.\n\n## 60 - Apr 29, 2015\n\n* Prevent offset on `.player-api` when in theater mode.\n\n## 59 - Apr 29, 2015\n\n* Update HTML5 fix regexes.\n\n## 58 - Apr 29, 2015\n\n* Hide the `#placeholder-player` element.\n\n## 57 - Mar 16, 2015\n\n* Update HTML5 fix regexes.\n\n## 56 - Mar 2, 2015\n\n* Update HTML5 fix regexes.\n\n## 55 - Feb 24, 2015\n\n* Update HTML5 fix regexes.\n\n## 54 - Feb 23, 2015\n\n* Fix double audio bug after clicking a video on the homepage/search page.\n* No longer reloading the html5 player to get the `playerInstance`. We are instead creating an unused dummy `playerInstance` to get the reference to it's constructor, which has a static list of the list of active `playerInstances`.\n* Reattempt to subscribe to `pubsub` events 1 second later if we get an error.\n\n## 53 - Feb 12, 2015\n\n* Fix double audio due to not doing a null check.\n* Hide `Skip navigation` text that overlays the video.\n\n## 52 - Jan 28, 2015\n\n* Search with regex for function that need replacing in HTML5 player.\n\n## 1.51 - Jan 27, 2015\n\n* Update HTML5 fix variables and check in case things have changed.\n\n## 1.50 - Jan 24, 2015\n\n* New HTML5 player fix method which should fix any weird video => video navigation bugs.\n\n## 1.49 - Jan 9, 2015\n\n* Update to the new \"detailpage\" variable for the HTML5 fix.\n\n## 1.48 - Dec 20, 2014\n\n* Update to the new \"detailpage\" variable for the HTML5 fix.\n\n## 1.47 - Dec 11, 2014\n\n* Fix bug when visiting a non /watch page first before navigation to the watch video page.\n* Update to the new \"detailpage\" variable for the HTML5 fix.\n\n## 1.46 - Nov 15, 2014\n\n* Remote undoing the HTML5 player fix before navigating to a new video as it isn't needed.\n\n## 1.45 - Nov 12, 2014\n\n* Re fix the progress bar scaling issue.\n* Undo the HTML5 player fix before navigating to a new video in order to also load the video description / comments.\n\n## 1.44 - Oct 31, 2014\n\n* Fix a second video player getting loaded when running this script along Youtube Center, this reintroduces the progressbar bug for users with YT Center. Please use the [dev build of YT Center](https://github.com/YePpHa/YouTubeCenter/raw/master/dist/YouTubeCenter.user.js) until the author pushes the fix to the main build.\n\n## 1.43 - Oct 30, 2014\n\n* Fix HTML5 progress bar not resizing. Thanks to [YePpHa](https://github.com/YePpHa/) for re-solving this bug in YoutubeCenter [Issue #1083](https://github.com/YePpHa/YouTubeCenter/issues/1083).\n* Completely hide the Player controls on the HTML5 player since we're reloading the player anyways.\n\n## 1.42 - Aug 18, 2014\n\n* Fix HTML5 progress bar not resizing. Thanks to [YePpHa](https://github.com/YePpHa/) for solving this bug in YoutubeCenter. [[Screenshot](https://i.imgur.com/FcLISVq.png)]\n* Fix the player getting right aligned in some cases. [[Screenshot]](https://greasyfork.org/forum/uploads/FileUpload/95/4d455197513c65d1aa243a0d800133.jpg)\n* Prevent the script from running twice on the same page.\n\n## 1.41 - Aug 11, 2014\n\n* Remove poorly done HTML5 fix. The HTML5 progress bar will remain unfixed until a Youtube update provides the ability to resize it.\n* Use CSS absolutly positioning to move the player. This should fix playback restarting while moving the player.\n\n## 1.40 - July 23, 2014\n\n* Attempt to fix the html5 player. The seek bar & annotations might not scale properly.\n\n## 1.39 - July 12, 2014\n\n* Remove debugging code that broke the script due to a raise in javascript execution security.\n\n## 1.38 - June 17, 2014\n\n* Style `#watch7-sidebar {top: 0 !important; }` to fix the sidebar overlapping the player.\n* Fix the guide from being off position when viewing the video.\n\n<p>\n  <h4>1.37 - May 13, 2014</h4>\n  <ul>\n    <li>Style the new <code>#player-mole-container</code> element. It had a height of 0, which was hiding the player.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.36 - March 22, 2014</h4>\n  <ul>\n    <li>[<a href=\"https://github.com/YePpHa/YouTubeCenter/issues/349\">Link</a>] BugFix: On the HTML5 player, resizing it to a non standard width will cause the cursor in the seek bar to not line up. In order to fix this, the script now removes the <code>.watch-small</code>, <code>.watch-medium</code> or <code>.watch-large</code> from the <code>#player</code> element.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.35 - Febuary 12, 2014</h4>\n  <ul>\n    <li>Hook into the <code>appbar-guide-delay-load</code> event. It should be called on every single page however, unlike the other events...</li>\n    <li>Fix another regression from rewriting the script: check if the script is on a <code>/watch?</code> page before runnning.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.34 - Febuary 7, 2014</h4>\n  <ul>\n    <li>Re add code to move the playlist as not all users might have updated to the new UI.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.33 - Febuary 7, 2014</h4>\n  <ul>\n    <li>Check the previous player state before moving to decide to autoplay or not.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.32 - Febuary 7, 2014</h4>\n  <ul>\n    <li>Fix issue where video would bug when playing videoes in a row.</li>\n    <li>Refactored script.</li>\n    <li>Autoplay videos as moving the player pauses the video.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.31 - October 28, 2013</h4>\n  <ul>\n    <li>Automatically uncheck relevant YT Center settings for the user. This is done during the <code>player-added</code> event simply because it (should) be after YT Center is up and running.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.30 - October 28, 2013</h4>\n  <ul>\n    <li>Create a placeholder to mark where the player was, so we can move it back there during a SPF navigation.</li>\n    <li>Hook into the <code>init-watch</code> and <code>dispose-watch</code> events rather than the ones used before (<code>player-added</code> and <code>navigate</code>).</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.29 - October 26, 2013</h4>\n  <ul>\n    <li>Minor CSS update to fix padding below the playlist tray caused by todays update.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.28 - October 23, 2013</h4>\n  <ul>\n    <li>[<a href=\"https://userscripts.org/topics/132874\">Thread</a>] Update the fixed header so it doesn't overlay the video.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.27 - September 8, 2013</h4>\n  <ul>\n    <li>Go back to moving the #player element rather than #player-api as the playlist bar is no longer attached above it.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.26 - August 20, 2013</h4>\n  <ul>\n    <li>Remove references to <code>-legacy</code>.</li>\n    <li>Check the <code>window.location.href</code> for <code>/watch?</code> to run the script. The old way no longer works (checking for <code>#player-api</code>) as it's now pregenerated even on the homepage.</li>\n    <li>Add debugging ouput to the console.</li>\n    <li>Move the Video Manager bar into <code>#watch7-content</code> so that it fits in seemlessly [<a href=\"http://i.imgur.com/OqiVBkg.png\">Screenshot</a>].</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.25 - August 15, 2013</h4>\n  <ul>\n    <li>The script now moves the playlist bar and tray. The playlist tray is moved into the sidebar element.</li>\n    <li>General cleanup of unused styling.</li>\n    <li>Don't remove the script selector from the body element during AJAX navigation as it looks weird if you notice the removal of this scripts styling. Youtube will removes it later (at a proper time) anyways.</li>\n    <li>Only hide the horizontal scrollbar when fully scrolled to the top.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.24 - August 15, 2013</h4>\n  <ul>\n    <li>[<a href=\"https://userscripts.org/topics/129717\">Thread</a>] Update for today's Youtube update. <code>#player-api</code> → <code>#player-api-legacy</code>.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.23 - August 11, 2013</h4>\n  <ul>\n    <li>[<a href=\"https://userscripts.org/topics/129562\">Thread</a>] Bug Fix for users using Youtube Center. Had to override the height on the <code>#player</code> element.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.22 - August 10, 2013</h4>\n  <ul>\n    <li>[<a href=\"https://userscripts.org/topics/129495\">Thread</a>] Bug Fix for users using Firefox. The <code>#player-api</code> element had a <code>float: left;</code> on it. The UI in general doesn't seem to have had the update Chrome does (no fixed header + guide).</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.21 - August 1, 2013</h4>\n  <ul>\n    <li>[<a href=\"https://userscripts.org/topics/129111\">Thread</a>] Wrap an exception caused by the <code>window.yt</code> not yet existing when the script gets run in NinjaKit on Safari. Will possibly cause <a href=\"https://userscripts.org/topics/128760\">this bug</a> to resurface when using safari.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.20 - July 30, 2013</h4>\n  <ul>\n    <li>Fix <a href=\"http://userscripts.org/topics/129094\">bug</a> in Firefox/Greasemonkey where the script would break trying to get the <code>window.yt</code> object reference by changing all references to <code>window</code> to <code>unsafeWindow</code>.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.19 - July 30, 2013</h4>\n  <ul>\n    <li>Run the script slightly earlier at the <code>player-added</code> event.</li>\n    <li>The horizontal scrollbar is now hidden until the video is no longer visible.</li>\n    <li>Fix bug where the playlist tray was overlapping the video.</li>\n    <li>Fix bug where the script was run twice on page load.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.18 - July 28, 2013</h4>\n  <ul>\n    <li>\n      I managed to find a proper place to hook into Youtube's new AJAX technique. Wrapping <code>window.history.pushState</code> didn't seem to work. On a further look, it also seems like I should have tried wrapping <code>replaceState</code> as well. Instead of wrapping <code>ytspf.config</code> like Youtube Center, I've found <code>yt.pubsub.instance_.subscribe(eventName, callback)</code>. The bugs listed in 1.17 are fixed.\n      <ul>\n        <li>Listen to the <code>navigate</code> event which is triggered before the page loads through AJAX in order to perform a cleanup (delete the video player as it's out of position).</li>\n        <li>Listen to the <code>player-ready</code> event in order to move the player.</li>\n      </ul>\n    </li>\n  </ul>\n</p>\n\n\n<p>\n  <h4>1.17 - July 26, 2013</h4>\n  Youtube's latest update now loads new pages through ajax (and also when you click a Youtube link in Google).\n  <ul>\n    <li>Temporarily move the main selector used to identify the script <code>body.ytwp-window-player</code> to <code>html.ytwp-window-player body</code>. Navigating to a new page through ajax will clear all classes attached to the body element.</li>\n  </ul>\n\n  Until I've managed to hook into Youtube's new SPF/Ajax technique, the following bugs will be prevalent.\n  <ul>\n    <li>Visiting the homepage, then clicking a video won't cause the script to run.</li>\n    <li>Visiting the homepage (or any other url) will still show the last video above the page.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.16 - July 24, 2013</h4>\n  <ul>\n    <li>Use unsafeWindow.addEventListener(...) instead of window.onresize = function(){...}. window.addEventListener was broken in the recent version of Tampermonkey, but should work now.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.15 - July 19, 2013</h4>\n  <ul>\n    <li>Use absolute positioning on the guide until the user has scrolled past the video completely.</li>\n    <li>Do checks for if the video is in view (for switching to the fixed header) when the window is resized.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.14 - July 16, 2013</h4>\n  <ul>\n    <li>Minor refactor on the last update and removed a debugging <code>console.log()</code>.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.13 - July 16, 2013</h4>\n  <ul>\n    <li>Use absolute positioning on the fixed header until the user has scrolled past the video completely. It will add the class <code>ytwp-viewing-video</code> to the body element when doing so.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.12 - July 15, 2013</h4>\n  <ul>\n    <li>Remove some whitespace from some large areas of whitespace caused by branded pages (<a href=\"http://i.imgur.com/Re06imh.jpg\">Example</a>).</li>\n    <li>Resize the playlist tray to the same width as the sidebar.</li>\n    <li>Inject the completed stylesheet instead of updating as the script runs.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.11 - May 7, 2013</h4>\n  <ul>\n    <li>Fix edge case missed in the last version. There was another rule that affected the padding-left when the guide was collapsed and under the small page width media query.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.10 - May 7, 2013</h4>\n  <ul>\n    <li>Fix padding on the playlist bar when using 'Center Page' in YT Center.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.9 - May 3, 2013</h4>\n  <ul>\n    <li>Removed <code>padding</code> and <code>margin-top</code> override on <code>#player</code>.</li>\n    <li>Adjusted selectors for the sidebar due to the shifting of element/classes.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.8 - Apr 2, 2013</h4>\n  <ul>\n    <li>Change all occurance of <code>#playlist-main-container</code> to <code>#playlist</code>.</li>\n    <li>Use <code>!important</code> when settings <code>margin-top</code> on the sidebar due to it being set at element level (only on non-playlist pages).</li>\n    <li>Fix styling margins on the sidebar on pages with the playlist bar.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.7 - Mar 20, 2013</h4>\n  <ul>\n    <li>Updated for Youtube's new layout. <code>#watch7-video-container</code> became <code>#player</code>, <code>#watch7-video</code> became <code>#player-api</code>.</li>\n    <li>The fixed Feedback button code was removed (no longer there).</li>\n    <li>Raised the <code>z-index</code> of the <code>#watch7-creator-bar</code> due to the <code>#guide</code> overlaying it and making the buttons unclickable. This is most likely a side effect of the last patch because the <code>#watch7-creator-bar</code> was a child of <code>#watch7-video-container</code> and therafor was no longer moved with the video (speculation). The creator bar currently looks <a href=\"http://i.imgur.com/rMqaVpy.png\">like so</a>.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.6 - Feb 28, 2013</h4>\n  <ul>\n    <li>Script is now only run on the /watch page.</li>\n    <li>Removed whitespace margin leftover from moving the video.</li>\n    <li>The script now moves the <code>#watch7-video</code> instead of the <code>#watch7-video-container</code> element due to Youtube's new update which will move the <code>#watch7-playlist-container</code> element above the <code>#watch7-video-container</code> element. An example of this new bug can be seen <a href=\"http://i.imgur.com/pqyuduU.png\">here</a>.</li>\n    <li>Fixed typo in local variable name.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.5 - Feb 5, 2013</h4>\n  <ul>\n    <li>Refactored code to inject overriding CSS instead of applying styling to the elements themselves.</li>\n    <li>Deleted the Feedback element altogether.</li>\n    <li>Fixed compatibility with YT Center. (<a href=\"http://userscripts.org/topics/122305?page=1#posts-480909\">Forum Post</a>)</li>\n    <li>Fixed styling of the Video Manager bar when browsing your own videos. (<a href=\"http://userscripts.org/topics/122305?page=1#posts-481046\">Forum Post</a>) (<a href=\"http://i569.photobucket.com/albums/ss134/tom053/window-player-own-video-bug.jpg\">Example</a>)</li>\n    <li>Added css class to the <code>body</code> tag so people can style around this effects of this script. Use <code>body.ytwp-window-player</code> with your selector(s).</li>\n    <li>Overwrote the smooth resizing of the video player.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.4 - Jan 6, 2013</h4>\n  <ul>\n    <li>Fixed the video getting resized when opening the guide (<a href=\"http://i.imgur.com/V60lu.png\">Example</a>).</li>\n    <li>Moved the fixed Feedback element to the bottom of the page (<a href=\"http://i.imgur.com/z5pxM.png\">Example</a>).</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.3 - Dec 27, 2012</h4>\n  <ul>\n    <li>Fix styling on pages with a playlist bar by:\n      <ul>\n        <li>Moving down the related videos with the small video player</li>\n        <li>Fixing the width of the playlist bar and un-hiding the toggle playlist button in large video mode.</li>\n      </ul>\n    </li>\n    <li>Update script metadata.</li>\n  </ul>\n</p>\n\n<p>\n  <h4>1.2</h4>\n  <ul>\n    <li>Fixed styling to work in small video mode.</li>\n    <li>Fixed styling to work in FireFox. Examples: <a href=\"http://i.imgur.com/HmR0z.png\">[1]</a> | <a href=\"http://i.imgur.com/LrQR6.png\">[2]</a>. <i>Note that the feedback button was moved in later versions.</i></li>\n  </ul>\n</p>\n"
  },
  {
    "path": "description.md",
    "content": "# Suggestions\n\n* The `w` key will toggle the script in the current tab.\n* Use [Resize Video To Window Size](https://greasyfork.org/en/scripts/10815-resize-video-to-window-size) for Crunchyroll, Vimeo, and a few other sites.\n\n# Screenshots\n\n**After loading the video webpage you will see:**\n\n[![](https://i.imgur.com/GDeEDPA.png)](https://i.imgur.com/GDeEDPA.png)\n\n**It appears above the rest of the site, so you can scroll down for the description, related links, etc.**\n\n[![](https://i.imgur.com/uVDKPUp.jpg)](https://i.imgur.com/uVDKPUp.jpg)\n\n# Changelog\n\nhttps://github.com/Zren/ResizeYoutubePlayerToWindowSize/blob/master/changelog.md\n\n## v138 - January 9, 2024\n\n* Bind toggle to `keydown` instead of `keyup` so that pressing `Ctrl+W` to close a tab does not trigger the YTWP toggle when you focus on a Youtube tab.\n\n## v137 - November 1, 2023\n\n* Bind to `yt-page-data-fetched` and `yt-navigate-finish` to fix the back button not cleaning up the window view since `yt-navigate-start` does not always fire (Issue #72 and #76)\n* Bind `keyup` not `keypress` (which is deprecated). Also cancel event during `keydown`. This fixes the `w` key also changing the caption box style. It should also fix changing the toggle key to `Escape` (Issue #71)\n\n## v139 - April 10, 2024\n\n* Fix page top margin as certain elements seem to ignore the CSS properties completely (Issue #88)\n"
  },
  {
    "path": "ytwp.css",
    "content": "/*--- Browser Scrollbar */\n/* Chrome/Webkit */\nbody[data-spf-name=\"watch\"],\nbody.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t&::-webkit-scrollbar {\n\t\twidth: 0 !important;\n\t\theight: 0 !important;\n\t}\n}\n/* Firefox/Gecko */\n/* Requires about:config flag to be toggled as of FireFox v63 */\n/* https:/*github.com/Zren/ResizeYoutubePlayerToWindowSize/issues/42 */\nhtml {\n\tscrollbar-width: none;\n}\n\n/*--- Video Player */\nbody[data-spf-name=\"watch\"],\nbody.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t#player,\n\t&.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible #player,\n\t&.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #player,\n\t&.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #player-legacy,\n\t&.ltr.ytcenter-site-center.ytcenter-non-resize.ytcenter-guide-visible.guide-collapsed #watch7-main-container {\n\t\ttransition: left 0s linear, padding-left 0s linear;\n\t\tpadding: 0 !important;\n\t\tmargin: 0 !important;\n\t}\n\n\t#player-api {\n\t\ttransition: width 0s linear, left 0s linear;\n\t\t/* Bugfix for Firefox */\n\t\t/* Parts of the header (search box) are hidden under the player. */\n\t\t/* Firefox doesn't seem to be using the fixed header+guide yet. */\n\t\tfloat: initial;\n\t\t/* Skinny mode */\n\t\tleft: 0;\n\t\tmargin-left: 0;\n\t}\n\n\t/* Theater mode */\n\t.watch-stage-mode #player .player-api {\n\t\tleft: initial !important;\n\t\tmargin-left: initial !important;\n\t}\n\n\t/* Hide the cinema/wide mode button since it's useless. */\n\t/* #movie_player .ytp-size-button { display: none; } */\n}\n\n/* !important is mainly for simplicity, but is needed to override the !important styling when the Guide is open due to: */\n/* .sidebar-collapsed #watch7-video, .sidebar-collapsed #watch7-main, .sidebar-collapsed .watch7-playlist { width: 945px!important; } */\n/* Also, Youtube Center resizes #player at element level. */\n/* Don't resize if Youtube+'s html.floater is detected. */\n/* Dont' resize if Youtube+ (Iridium/Material)'s html.iri-always-visible is detected. */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #player,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #player-wrap,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #player-api,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body[data-spf-name=\"watch\"] #movie_player,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #player-mole-container,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body[data-spf-name=\"watch\"] .html5-video-container,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body[data-spf-name=\"watch\"] .html5-main-video,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-flexy[flexy] #player-container-outer.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-flexy[flexy] #player-container-inner.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-flexy[flexy] #player-container.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-grid[theater] #player-theater-container.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-grid[flexy] #player-container-outer.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-grid[flexy] #player-container-inner.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] ytd-watch-grid[flexy] #player-container.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #player,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #player-wrap,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #player-api,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #movie_player,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #player-mole-container,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) .html5-video-container,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) .html5-main-video,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-flexy[flexy] #player-container-outer.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-flexy[flexy] #player-container-inner.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-flexy[flexy] #player-container.ytd-watch-flexy,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-grid[theater] #player-theater-container.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-grid[flexy] #player-container-outer.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-grid[flexy] #player-container-inner.ytd-watch-grid,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) ytd-watch-grid[flexy] #player-container.ytd-watch-grid {\n\twidth: 100% !important;\n\tmin-width: 100% !important;\n\tmax-width: 100% !important;\n\theight: 100vh !important;\n\tmin-height: 100vh !important;\n\tmax-height: 100vh !important;\n}\n\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t#player,\n\t.html5-main-video {\n\t\ttop: 0 !important;\n\t\tright: 0 !important;\n\t\tbottom: 0 !important;\n\t\tleft: 0 !important;\n\t}\n\t/* Resize #player-unavailable, #player-api */\n\t/* Using min/max width/height will keep */\n\t#player .player-width { width: 100% !important; }\n\t#player .player-height { height: 100% !important; }\n\n\t/* Fix video overlays */\n\t.html5-video-player .ad-container-single-media-element-annotations, /* Ad */\n\t.html5-video-player .ytp-upnext { /* Autoplay Next Video */\n\t\ttop: 0;\n\t}\n\n\t/* Fix video cropping (object-fit: cover) (Issue #70) */\n\t.ytp-fit-cover-video .html5-main-video {\n\t\tobject-fit: contain !important;\n\t}\n\t/* Thumbnail cropping */\n\t.ytp-cued-thumbnail-overlay-image {\n\t\tbackground-size: contain !important;\n\t}\n\n\t/*--- Video Container Background */\n\t#movie_player {\n\t\tbackground-color: #000000;\n\t}\n\n\t/*--- Move Video Player */\n\t#player {\n\t\tposition: absolute;\n\t\t/* Already top:0; left: 0; */\n\t}\n\t& { /* body */\n\t\tmargin-top: 100vh;\n\t}\n\n\t/* Fix the top right avatar button */\n\tbutton.ytp-button.ytp-cards-button {\n\t\ttop: 0;\n\t}\n\n\n\t/*--- Sidebar */\n\t/* Remove the transition delay as you can see it moving on page load. */\n\t#watch7-sidebar {\n\t\ttransition: margin-top 0s linear, padding-top 0s linear;\n\t\tmargin-top: 0 !important;\n\t\ttop: 0 !important;\n\t}\n\n\t&.cardified-page #watch7-sidebar-contents {\n\t\tpadding-top: 0;\n\t}\n}\n\n/*--- Absolutely position the fixed header. */\n/* Masthead */\n#skip-navigation.ytd-masthead {\n\ttop: -150vh; /* Normally -1000px can be shorter than screen (Issue #77) */\n}\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t&.hide-header-transition #masthead-positioner {\n\t\ttransition: top 0s linear !important;\n\t}\n\t&.ytwp-viewing-video #masthead-positioner {\n\t\tposition: absolute;\n\t\ttop: 100vh !important;\n\t}\n}\n/* Lower masthead below Youtube+'s html.floater */\nhtml.floater body[data-spf-name=\"watch\"],\nhtml.floater body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t&.ytwp-viewing-video #masthead-positioner {\n\t\tz-index: 5;\n\t}\n}\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t/* Autocomplete popup */\n\t.sbdd_a {\n\t\ttop: 56px;\n\t}\n\t&.ytwp-viewing-video .sbdd_a {\n\t\ttop: calc(100vh + 56px) !important;\n\t\tposition: absolute !important;\n\t}\n\n\t/* Guide */\n\t/* When watching the video, we need to line it up with the masthead. */\n\t&.ytwp-viewing-video #appbar-guide-menu {\n\t\tdisplay: initial;\n\t\tposition: absolute;\n\t\ttop: 100% !important; /* Masthead height */\n\t}\n\t&.ytwp-viewing-video #page.watch #guide {\n\t\tdisplay: initial;\n\t\tmargin: 0;\n\t\tposition: initial;\n\t}\n\t/* When the guide is open, it adds body{top:-1000px} which messes with the top position (Issue #77) */\n\t&.lock-scrollbar {\n\t\ttop: 0 !important;\n\t\tposition: static !important;\n\t}\n}\n\n/*--- */\n/* MiniPlayer-Bar */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t#miniplayer-bar #player {\n\t\tposition: static;\n\t}\n\t/* Override inline style (caused by a JS animation) that breaks the miniplayer video */\n\t/* https://github.com/Zren/ResizeYoutubePlayerToWindowSize/issues/41#issuecomment-439710130 */\n\t.video-stream.html5-main-video {\n\t\ttop: 0 !important;\n\t}\n}\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #miniplayer-bar #player,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #miniplayer-bar #player-api,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body[data-spf-name=\"watch\"] #miniplayer-bar #movie_player,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"] #player-mole-container,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"]:not(.floater):not(.iri-always-visible) #miniplayer-bar .html5-video-container,\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"]:not(.floater):not(.iri-always-visible) #miniplayer-bar .html5-main-video,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #miniplayer-bar #player,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #miniplayer-bar #player-api,\nhtml:not([fullscreen=\"true\"]):not(.floater):not(.iri-always-visible) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #miniplayer-bar #movie_player,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) #player-mole-container,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player):not(.floater):not(.iri-always-visible) #miniplayer-bar .html5-video-container,\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player):not(.floater):not(.iri-always-visible) #miniplayer-bar .html5-main-video {\n\twidth: 252px !important;\n\tmin-width: 252px !important;\n\tmax-width: 252px !important;\n\theight: 142px !important;\n\tmin-height: 142px !important;\n\tmax-height: 142px !important;\n}\n\n/*--- */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t/* Hide Scrollbars */\n\t&.ytwp-scrolltop { overflow-x: hidden; }\n\n\t/*--- Fix Other Possible Style Issues */\n\t#placeholder-player { display: none; }\n\t#watch-sidebar-spacer { display: none; }\n\t.skip-nav { display: none; }\n\n\t/*--- Whitespace Leftover From Moving The Video */\n\t#page.watch { padding-top: 0; }\n\t.player-branded-banner { height: 0; }\n}\n\n/*--- Youtube+ Compatiblity */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t#body-container {\n\t\tposition: static;\n\t}\n}\nhtml:not([fullscreen=\"true\"]).part_static_size:not(.content-snap-width-skinny-mode) {\n\tbody[data-spf-name=\"watch\"],\n\tbody.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t\t.watch-non-stage-mode #player-playlist {\n\t\t\twidth: 1066px;\n\t\t}\n\t}\n}\n\n/*--- */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t/*--- Playlist Bar */\n\t#placeholder-playlist,\n\t#player .player-height#watch-appbar-playlist {\n\t\theight: 540px !important;\n\t\tmax-height: 540px !important;\n\t}\n\t#watch-appbar-playlist {\n\t\ttransition: transform 0s linear;\n\t}\n\t#player .player-height#watch-appbar-playlist {\n\t\ttransform: translateY(0px);\n\t\tmargin-left: 0;\n\t\ttop: calc(100vh + 60px);\n\t}\n\t.playlist-videos-list {\n\t\tmax-height: 470px !important;\n\t\theight: initial !important;\n\t}\n}\n\n\n/*--- */\n/* Material UI */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t&.ytwp-scrolltop #extra-buttons {\n\t\tdisplay: none !important;\n\t}\n}\n/* body > #player:not(.ytd-watch) { display: none; } */\n/* body.ytwp-viewing-video #content:not(app-header-layout) ytd-page-manager { margin-top: 0 !important; } */\n/* .ytd-watch-0 #content-separator.ytd-watch { margin-top: 0; } */\nytd-app { position: static !important; }\nytd-watch #top { margin-top: 71px !important; }\nytd-watch #container { margin-top: 0 !important; }\nytd-watch #content-separator { margin-top: 0 !important; }\n\n/* Note: Container is now relative since 2023 June (Issue #77) */\n/* Note: Container is now a full-bleed-player (Issue #79) */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\tytd-watch-flexy[theater] #player-wide-container.ytd-watch-flexy,\n\tytd-watch-flexy[fullscreen] #player-wide-container.ytd-watch-flexy,\n\tytd-watch-flexy[full-bleed-player] #player-full-bleed-container.ytd-watch-flexy, /* Issue #79 (2023-08-17) */\n\tytd-watch-flexy[full-bleed-player] #full-bleed-container.ytd-watch-flexy, /* Issue #79 (2023-08-22) */\n\tytd-watch-grid[theater] #player-wide-container.ytd-watch-grid,\n\tytd-watch-grid[fullscreen] #player-wide-container.ytd-watch-grid,\n\tytd-watch-grid[full-bleed-player] #player-full-bleed-container.ytd-watch-grid, /* Issue #81 (2023-08-30) */\n\tytd-watch-grid[full-bleed-player] #full-bleed-container.ytd-watch-grid { /* Issue #81 (2023-08-30) */\n\t\tposition: static;\n\t\theight: 0;\n\t\tmin-height: 0;\n\t}\n\t&.ytwp-viewing-video ytd-app #masthead-container.ytd-app {\n\t\tposition: absolute;\n\t\ttop: 100vh;\n\t\tz-index: 0;\n\t}\n\t&.ytwp-viewing-video ytd-watch #masthead-positioner {\n\t\ttop: 100vh !important;\n\t}\n\t.ytp-cued-thumbnail-overlay {\n\t\tz-index: 10;\n\t}\n}\n\n/*--- */\nhtml:not([fullscreen=\"true\"]) body[data-spf-name=\"watch\"],\nhtml:not([fullscreen=\"true\"]) body.ytwp-window-player:not(.enhancer-for-youtube-pinned-player) {\n\t/* Flexy UI */\n\tytd-watch-flexy[theater] #player-theater-container.ytd-watch-flexy,\n\tytd-watch-grid[theater] #player-theater-container.ytd-watch-grid {\n\t\tposition: absolute;\n\t\ttop: 0;\n\t}\n\t#error-screen {\n\t\tz-index: 11;\n\t}\n}\n/* Youtube seems to be ignoring the margin/padding top in certain elements for some reason (Issue #88) */\n/* NOT working: ytd-watch-flexy, ytd-watch-grid { padding-top: 71px; } 56px (topnav height) + 15px (margin) */\n#page-manager.ytd-app {\n\tpadding-top: var(--ytd-masthead-height,var(--ytd-toolbar-height));\n}\n"
  }
]