NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name YouTube Docking // @description Read the comments while watching the video // @author alike03 // @version 1.1.0 // @namespace youtubeDOCK // @icon https://cdn3.iconfinder.com/data/icons/free-social-icons/67/youtube_circle_color-128.png // @supportURL https://github.com/alike03/Userscripts/issues // @downloadURL https://raw.githubusercontent.com/alike03/Userscripts/master/src/YouTubeDocking.user.js // @updateURL https://raw.githubusercontent.com/alike03/Userscripts/master/meta/YouTubeDocking.user.js // @homepageURL http://alike.ml/UserScript.php // @match https://*.youtube.com/* // @require https://code.jquery.com/jquery-3.4.1.min.js // @copyright 2019, alike03 (https://openuserjs.org/users/alike03) // @license MIT // ==/UserScript== //window.addEventListener("yt-navigate-start", remove); // new youtube design window.addEventListener("yt-navigate-finish", start); // new youtube design window.addEventListener("load", start); // one-time early processing //window.addEventListener("unload", saveData); let miniplayer = null; let miniplayerStatus = false; let miniplayerEnable = false; let miniplayerBlock = false; let fullscreen = false; function start() { if (window.location.href.indexOf('youtube.com/watch?v=') > -1) { let targetNode = $('#movie_player'); observer.observe(targetNode[0], config); window.addEventListener('resize', fixVidSize); window.addEventListener("scroll", scrolling); } else { miniplayerEnable === false; //miniplayerStatus = false; disableMiniplayer(); observer.disconnect(); window.removeEventListener('resize', fixVidSize); window.removeEventListener("scroll", scrolling); } } function scrolling() { if (miniplayerBlock === false) { let limiter = $("#columns #alerts"); let top_of_element = $(limiter).offset().top; let bottom_of_element = $(limiter).offset().top + $(limiter).outerHeight(); let bottom_of_screen = $(window).scrollTop() + $(window).innerHeight(); let top_of_screen = $(window).scrollTop(); if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)) { miniplayerEnable = false; } else { miniplayerEnable = true; } check(); } } function check() { if (miniplayerEnable === true && miniplayerStatus === false && miniplayerBlock === false) { miniplayerStatus = true; enableMiniplayer(); movePlayer(); } if (miniplayerBlock === true || (miniplayerEnable === false && miniplayerStatus === true)) { miniplayerStatus = false; disableMiniplayer(); } } function enableMiniplayer() { if (miniplayer === null) { let checkExist = setInterval(function () { if ($("#primary #primary-inner").length) { $("ytd-miniplayer").attr("enabled", "alike"); $("ytd-miniplayer").attr("active", "alike"); $("ytd-miniplayer").css("height", "225px"); $("ytd-miniplayer").css("bottom", "310px"); $("ytd-miniplayer #card").css("height", "225px"); clearInterval(checkExist); } }, 100); } } function movePlayer() { let checkExist = setInterval(function () { if ($("ytd-player").length) { clearInterval(checkExist); //move player $("ytd-player").appendTo("#card #player-container"); //add right classes let attr = $("ytd-watch-flexy").attr("theater-requested_"); if (typeof attr !== typeof undefined && attr !== false) { $("#movie_player video").css("top", "0"); } $("#movie_player .ytp-chrome-bottom .ytp-progress-bar").on("mouseover", blockClick); $("#movie_player .ytp-chrome-bottom .ytp-progress-bar").on("mousedown", blockClick); $("#movie_player .ytp-chrome-bottom .ytp-scrubber-container").css("display", "none"); $("#movie_player .ytp-chrome-bottom .ytp-size-button").css("display", "none"); $("#movie_player").removeClass(".ytp-large-width-mode .ad-created"); $("#movie_player").addClass(".ytp-menu-shown .ytp-player-minimized .ytp-small-mode paused-mode"); fixVidSize(); } }, 100); } function blockClick(event) { event.stopPropagation(); event.preventDefault(); event.stopImmediatePropagation(); return false; } function disableMiniplayer() { //remove miniplayer $("ytd-miniplayer").removeAttr("enabled"); $("ytd-miniplayer").removeAttr("active"); $("ytd-miniplayer").removeAttr("style"); $("ytd-miniplayer #card").removeAttr("style"); //move player let attr = $("ytd-watch-flexy").attr("theater-requested_"); //let attr2 = $("ytd-watch-flexy").attr("fullscreen"); if (typeof attr !== typeof undefined && attr !== false && !$("#player-theater-container #player-container ytd-player").length) { $("ytd-player").appendTo("#player-theater-container #player-container"); } else { $("ytd-player").appendTo("#columns #player-container"); } //add right classes $("#movie_player .ytp-chrome-bottom .ytp-progress-bar").off("mouseover", blockClick); $("#movie_player .ytp-chrome-bottom .ytp-progress-bar").off("mousedown", blockClick); $("#movie_player .ytp-chrome-bottom .ytp-scrubber-container").css("display", ""); $("#movie_player .ytp-chrome-bottom .ytp-size-button").css("display", ""); $("#movie_player").removeClass(".ytp-menu-shown .ytp-player-minimized .ytp-small-mode paused-mode"); $("#movie_player").addClass(".ytp-large-width-mode .ad-created"); fixVidSize(); } function fixVidSize() { if (miniplayerStatus) { let sizeCheck = setInterval(function () { if (miniplayerStatus) { $("#movie_player video").css("width", "400px"); $("#movie_player video").css("height", "225px"); $("#movie_player video").css("left", "0"); $("#movie_player .ytp-chrome-bottom").css("width", "376px"); } }, 250); setTimeout(function () { clearInterval(sizeCheck); }, 5000); } else { $("#movie_player video").css("width", $("#movie_player").width()); $("#movie_player video").css("height", $("#movie_player").height()); $("#movie_player video").css("left", "0"); let spacing = 24; if (fullscreen) spacing *= 2; $("#movie_player .ytp-chrome-bottom").css("width", $("#movie_player").width() - spacing); } } // Options for the observer (which mutations to observe) const config = { attributes: true, childList: false, subtree: false, attributeFilter: ['class'] }; // Callback function to execute when mutations are observed const callback = function (mutationsList, observer) { for (let mutation of mutationsList) { if (mutation.attributeName === "class") { var classList = mutation.target.className; // Do something here with class you're expecting if (classList.includes("ended-mode") || classList.includes("ytp-fullscreen")) { miniplayerBlock = true; miniplayerEnable = false; fullscreen = true; check(); } else if (!classList.includes("ytp-fullscreen") && !classList.includes("ended-mode")) { miniplayerBlock = false; fullscreen = false; check(); } } } }; //document.addEventListener("fullscreenchange", function() { // if (document.fullscreenElement) //}, false); // Create an observer instance linked to the callback function const observer = new MutationObserver(callback); console.log("Youtube Docking");