Youtube Scrolling Comments Layout 2017

Modern layout for 1080p res, lets you watch videos while being able to scroll and read the entire comments section, by pinning the YouTube video to the left-side page. Plus, a sleek 'More Videos by same user' playlist feed is auto-generated for the current channel and 2 very useful quicklinks are added: 'Most Popular' and 'Newest' sorted user videos. See screenshot for preview.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Youtube Scrolling Comments Layout 2017
// @namespace    YFVP3
// @website      https://greasyfork.org/en/users/10118-drhouse
// @version      16.0
// @description  Modern layout for 1080p res, lets you watch videos while being able to scroll and read the entire comments section, by pinning the YouTube video to the left-side page. Plus, a sleek 'More Videos by same user' playlist feed is auto-generated for the current channel and 2 very useful quicklinks are added: 'Most Popular' and 'Newest' sorted user videos. See screenshot for preview.
// @author       drhouse
// @contributor  Ronny John
// @include      http://www.youtube.com/*
// @include      https://www.youtube.com/*
// @exclude      http://www.youtube.com/embed/*
// @exclude      https://www.youtube.com/embed/*
// @require 	 http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require      https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @resource spfremove https://greasyfork.org/scripts/16935-disable-spf-youtube/code/Disable%20SPF%20Youtube.user.js
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @icon         https://s.ytimg.com/yts/img/favicon-vfldLzJxy.ico
// ==/UserScript==

var theurl = document.URL;
var links = document.getElementById('body-container').getElementsByTagName('a');

if (location.href.toString().indexOf("list") == -1 && parent.location.href.toString().indexOf("watch") != -1 && parent.location.href.toString().indexOf("feed") == -1 && parent.location.href.toString().indexOf("watch_") == -1)
	window.location.href = (theurl + "&list=UL&");

for(var i=0 ; i<links.length ; i++){
	if (links[i].href.toString().indexOf("watch") != -1 && links[i].href.toString().indexOf("list") <= -1 && links[i].href.toString().indexOf("feed") == -1 && links[i].href.toString().indexOf("watch_") == -1)
		links[i].setAttribute('href', links[i].getAttribute('href').split('&')[0] + '&list=UL&');
}

$(document).ready(function () {

	var bot = $('#page-container').css('height');
	$('#watch-appbar-playlist').css('height', bot);
	$('#watch-appbar-playlist').css('height', '-=1993px').css('top','60px').css('bottom','300px').css('right','0px').css('left','1605px').css('position','fixed');

	eval(GM_getResourceText("spfremove"));

	var dest = '#watch7-user-header > div > a';
	var channel = $(dest).attr('href');
	var link = 'https://www.youtube.com' + channel + '/videos?view=0&sort=p&flow=grid';
	var link2 = "'" + link + "'";
	var dest2 = $('#action-panel-overflow-button > span');
	var linkdd = 'https://www.youtube.com' + channel + '/videos?view=0&sort=dd&flow=grid';
	var linkdd2 = "'" + linkdd + "'";
	$('<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-has-icon no-icon-markup pause-resume-autoplay yt-uix-menu-triggerx yt-uix-tooltip addto-button" type="button" onclick="window.open(' + link2 + ')" title="More actions" aria-pressed="false" id="popular" role="button" aria-haspopup="false" data-tooltip-text="Popular videos" aria-labelledby="yt-uix-tooltip93-arialabel"><span class="yt-uix-button-content"><a href="' + link + '">Most popular videos</a></span></button>').insertAfter(dest2).css('color', '#666');
	$('<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-has-icon no-icon-markup pause-resume-autoplay yt-uix-menu-triggerx yt-uix-tooltip addto-button" type="button" onclick="window.open(' + linkdd2 + ')" title="More actions" aria-pressed="false" id="popular" role="button" aria-haspopup="false" data-tooltip-text="Newest videos" aria-labelledby="yt-uix-tooltip93-arialabel"><span class="yt-uix-button-content"><a href="' + linkdd + '">Newest videos</a></span></button>').insertAfter(dest2).css('color', '#666');


// code below created by Ronny John | http://ronnyjohn.work | Youtube Comments Sidebar | https://greasyfork.org/en/scripts/21391-youtube-comments-sidebar
	(function() {
		'use strict';

		var mutationObserver = window.MutationObserver || window.WebKitMutationObserver;
		var watchModeObserver, sidebarAdObserver, page, sidebar, ads, related, relatedParent, relatedWrapper, comments, footer;
		var onResizeFunc = function() { setPositions(); setHeights(); console.log('resize'); };
		var onScrollFunc = function() { setHeights(); };
		var modificationDone = false;

		if (typeof mutationObserver === 'undefined') return;

		// a little style adjustment
		if (typeof(GM_addStyle) === typeof(Function)) {
			GM_addStyle('#watch7-sidebar-contents.sidebar-comments { position: fixed; z-index: 1; } #watch-discussion.sidebar-comments { position: fixed; padding: 0 6px; overflow: hidden; overflow-y: auto; z-index: 2; } #watch-discussion.sidebar-comments .comment-section-renderer-paginator { margin: 0; } #watch7-sidebar { -moz-transition: all 0s !important; -webkit-transition: all 0s !important; -o-transition: all 0s !important; transition: all 0s !important; }');
		}

		initialize();

		var contentObserver = createContentObserver();
		contentObserver.observe(document.getElementById('content'), {childList: true, subtree: true});

		function initialize() {
			page = document.getElementById('page');
			sidebar = document.getElementById('watch7-sidebar-contents');
			related = document.getElementById('watch-related');
			comments = document.getElementById('watch-discussion');
			footer = document.getElementById('footer-container');

			// if modification is already done, stop initialization (can be cached on browser navigate back and forward)
			if (related && comments && related.parentNode.parentNode == comments.parentNode) {
				return;
			}

			removeListeners();
			if (watchModeObserver) watchModeObserver.disconnect();
			if (sidebarAdObserver) sidebarAdObserver.disconnect();

			// skip if no video is shown or playlist is open
			if (!sidebar || !comments || !related) {
				return;
			}

			relatedParent = related.parentNode;

			watchModeObserver = createWatchModeObserver();
			watchModeObserver.observe(page, {attributes: true});

			// if stage mode is active, do not run modifications
			if (page.classList.contains('watch-stage-mode')) {
				return;
			}

			runModifications();

			// if ads are inserted in the sidebar, the position of the comments must be updated
			ads = document.getElementById('google_companion_ad_div');
			if (ads) {
				sidebarAdObserver = createSidebarAdObserver();
				sidebarAdObserver.observe(ads, {childList: true});
			}
		}

		function runModifications() {
			// move ads and related
			relatedWrapper = document.createElement('div');
			relatedWrapper.className = comments.className;
			relatedWrapper.appendChild(related);
			comments.parentNode.insertBefore(relatedWrapper, comments);

			// comments node can't be moved, because loading of replies is not working properly then
			sidebar.classList.add('sidebar-comments');
			comments.className = 'sidebar-comments';

			window.addEventListener('resize', onResizeFunc);
			window.addEventListener('scroll', onScrollFunc);

			onResizeFunc();
			modificationDone = true;
		}

		function revertModifications() {
			sidebar.classList.remove('sidebar-comments');
			sidebar.style.width = 'auto';
			sidebar.style.height = 'auto';
			relatedParent.appendChild(related);
			comments.className = relatedWrapper.className;
			comments.style.width = 'auto';
			comments.style.height = 'auto';
			relatedWrapper.remove();

			removeListeners();

			modificationDone = false;
		}

		function removeListeners() {
			window.removeEventListener('resize', onResizeFunc);
			window.removeEventListener('scroll', onScrollFunc);
		}

		function setPositions() {        
			var sidebarParentRect = sidebar.parentNode.getBoundingClientRect();
			sidebar.style.top = (sidebarParentRect.top + scrollY) + 'px';
			sidebar.style.left = sidebarParentRect.left + 'px';
			sidebar.style.width = (sidebarParentRect.right - sidebarParentRect.left) + 'px';

			var containerRect = relatedParent.getBoundingClientRect();
			comments.style.top = containerRect.bottom + 'px';
			comments.style.left = containerRect.left + 'px';
			comments.style.width = (containerRect.right - containerRect.left) + 'px';

		}

		function setHeights() {
			var sidebarRect = sidebar.getBoundingClientRect();
			var containerRect = relatedParent.getBoundingClientRect();
			var footerRect = footer.getBoundingClientRect();
			var bottom = document.documentElement.clientHeight;

			if (footerRect.top < bottom) {
				bottom = footerRect.top;   
			}

			var commentsHeight = bottom - containerRect.bottom - 20;
			sidebar.style.height = (containerRect.bottom - sidebarRect.top + commentsHeight + 10) + 'px';
			comments.style.height = commentsHeight + 'px';
		}

		function createContentObserver() {
			return new mutationObserver(function(mutations) {
				mutations.forEach(function(mutation) {
					if (mutation.addedNodes !== null) {
						for (var i=0; i < mutation.addedNodes.length; i++) {
							var node = mutation.addedNodes[i];
							if (node.id == 'watch7-container' || node.id == 'watch7-main-container') {
								initialize();
								break;
							}
						}
					}
				});
			});
		}

		function createWatchModeObserver() {
			return new mutationObserver(function(mutations) {
				for (var i=0; i<mutations.length; i++) {
					if (mutations[i].attributeName === "class") {
						if (page.classList.contains('watch-stage-mode') && modificationDone) {
							revertModifications();
						} else if (!page.classList.contains('watch-stage-mode') && !modificationDone) {
							runModifications();   
						}
					}
				}
			});
		}

		function createSidebarAdObserver() {
			return new mutationObserver(function(mutations) {
				mutations.forEach(function(mutation) {
					if (mutation.addedNodes !== null) {
						onResizeFunc();
					}
				});
			});
		}
	})();
});