您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Pins the video player in its original position while you scroll the page.
- // ==UserScript==
- // @name Youtube floating player
- // @description Pins the video player in its original position while you scroll the page.
- // @version 3.2
- // @author REVerdi
- // @namespace https://openuserjs.org/users/REVerdi
- // @copyright 2014+, REVerdi (https://openuserjs.org/users/REVerdi)
- // @license (CC) Attribution Non-Commercial Share Alike; http://creativecommons.org/licenses/by-nc-sa/3.0/
- // Por causa do SPF (Structured Page Fragments), não posso usar // @include http*://www.youtube.com/watch?*
- // porque se o 1° link no YouTube não for do tipo acima, esse script nunca será executado.
- // @include http*://www.youtube.com/*
- // @grant none
- // ==/UserScript==
- /*
- TESTADO APENAS NO FIREFOX
- ONLY TESTED ON FIREFOX
- */
- /*
- O YouTube "quase" exatamente como eu queria!
- Eu não sou programador, então não joguem tomates podres em mim :)
- YouTube "almost" exactly as I wanted!
- I'm not a programmer, so don't throw rotten tomatoes at me :)
- */
- // Based on the ideia of drhouse (http://userscripts.org/scripts/show/186872)
- // and contains source code written by tforbus:
- // http://www.tristinforbus.com/
- // https://github.com/tforbus/youtube-fixed-video-bookmarklet
- // http://www.whattheforbus.com/youtube-bookmarklet [removed]
- // https://chrome.google.com/webstore/detail/video-pinner/egfhbaheiflmihggjcfmnmchkijkcdpl [removed]
- (function(){
- "use strict";
- var _window;
- if (typeof unsafeWindow !== undefined){
- _window = unsafeWindow;
- }
- else {
- _window = window;
- }
- /*
- * constants
- */
- const BODY_ID = 'body';
- const PLAYER_ID = 'player'; //why not 'movie_player'?
- const THEATER_ID = 'theater-background';
- const PLAYLIST_ID = 'watch-appbar-playlist';
- const CONTENT_ID = 'watch7-content';
- const SIDEBAR_ID = 'watch7-sidebar';
- const PLACEHOLDER_ID = 'placeholder-player'; //to detect if the user is or is not on a video page
- const BUTTON_CLASS = 'ytp-size-button ytp-button'; //player view toggle button class
- /*
- * flow control variables
- */
- var eventListenersAdded = 0;
- var bodyMutationObserverAdded = 0;
- /*
- * user is playing a...
- */
- const SINGLE_VIDEO = 1;
- const PLAYLIST = 2;
- /*
- * player view mode
- */
- var playerViewMode;
- const NOT_DETECTED = 0;
- const DEFAULT_VIEW = 1;
- const THEATER_MODE = 2;
- var playerViewToggleButton; //tem que ser pública para que se possa rodar o removeEventListener
- //http://www.w3schools.com/colors/colors_names.asp
- //if (document.getElementById( PLAYER_ID)) document.getElementById( PLAYER_ID).style.border = "thick solid cyan" ;
- //if (document.getElementById( THEATER_ID)) document.getElementById( THEATER_ID).style.border = "thick solid red" ;
- //if (document.getElementById( PLAYLIST_ID)) document.getElementById( PLAYLIST_ID).style.border = "thick solid pink" ;
- //if (document.getElementById( SIDEBAR_ID)) document.getElementById( SIDEBAR_ID).style.border = "thick solid yellow" ;
- //if (document.getElementById( PLACEHOLDER_ID)) document.getElementById( PLACEHOLDER_ID).style.border = "thick solid green" ;
- //if (document.getElementById( 'movie_player')) document.getElementById( 'movie_player').style.border = "thick solid blue" ;
- //if (document.getElementById('player-playlist')) document.getElementById('player-playlist').style.border = "thick solid fuchsia";
- function userIsOnAVideoPage() { //user is where?
- var playerPlaceHolder = document.getElementById(PLACEHOLDER_ID);
- if( playerPlaceHolder ) return 1; //user IS on a video page
- else return 0; //user is NOT on a video page
- }
- function userIsPlayingA() {
- if( /list/.test(document.location) === false ) return SINGLE_VIDEO;
- else return PLAYLIST;
- }
- function getPlayerViewToggleButton() {
- var player = document.getElementById(PLAYER_ID);
- var buttons = player.getElementsByTagName('BUTTON');
- for( var b = 0; b < buttons.length; b++ ) {
- if( buttons[b].className == BUTTON_CLASS) {
- var buttonTitle = buttons[b].getAttribute('title');
- if( buttonTitle != 'null' ) return buttons[b];
- }
- }
- }
- function resizePlayer() {
- var playerRect;
- var theaterRect;
- var sidebarRect;
- var playlist;
- var player = document.getElementById( PLAYER_ID);
- var theater = document.getElementById(THEATER_ID);
- var sidebar = document.getElementById(SIDEBAR_ID);
- var content = document.getElementById(CONTENT_ID);
- var contentRect = content.getBoundingClientRect();
- var playerPlaceHolder = document.getElementById(PLACEHOLDER_ID);
- playerPlaceHolder.firstElementChild.style.backgroundColor = 'transparent';
- player.style.top = '60px'; //determinado por tentativa e erro :S
- player.style.position = 'fixed';
- theater.style.position = 'fixed';
- sidebar.style.position = 'inherit'; //static|absolute|fixed|relative|initial|inherit
- switch( playerViewMode ) {
- case DEFAULT_VIEW:
- // var content = document.getElementById(CONTENT_ID);
- // var contentRect = content.getBoundingClientRect(); //bottom, height, left, right, top, width, x, y
- player.style.left = contentRect.left + 'px';
- switch( userIsPlayingA() ) {
- case SINGLE_VIDEO:
- player.style.zIndex = 998;
- sidebar.style.zIndex = 999;
- break;
- case PLAYLIST:
- player.style.zIndex = 999;
- sidebar.style.zIndex = 998;
- playlist = document.getElementById(PLAYLIST_ID); //para desfazer o que foi feito para playlist em modo teatro
- playlist.style.top = '';
- playlist.style.position = '';
- playlist.style.width = '';
- playlist.style.left = '';
- playerRect = player.getBoundingClientRect(); //to limit the
- sidebarRect = sidebar.getBoundingClientRect(); //width of
- player.style.width = sidebarRect.right - playerRect.left + 'px'; //the playlist
- break;
- }
- break;
- case THEATER_MODE:
- player.style.zIndex = 999;
- sidebar.style.zIndex = 998;
- playerRect = player.getBoundingClientRect();
- theaterRect = theater.getBoundingClientRect();
- player.style.left = (theaterRect.width / 2) - (playerRect.width / 2) + 'px';
- switch( userIsPlayingA() ) {
- case SINGLE_VIDEO:
- //nothing to do
- break;
- case PLAYLIST:
- sidebarRect = sidebar.getBoundingClientRect();
- playlist = document.getElementById(PLAYLIST_ID);
- playlist.style.top = '170px'; //determinado por tentativa e erro :S
- playlist.style.position = 'fixed';
- playlist.style.width = sidebarRect.right - contentRect.right + 'px';
- playlist.style.left = contentRect.right + 'px';
- //or
- //playlist.style.width = sidebarRect.width + 'px';
- //playlist.style.left = sidebarRect.left + 'px';
- break;
- }
- break;
- }
- }
- function pageResize() {
- resizePlayer();
- }
- function playerViewToggleButtonClick() {
- switch( playerViewMode ) {
- case DEFAULT_VIEW:
- playerViewMode = THEATER_MODE;
- break;
- case THEATER_MODE:
- playerViewMode = DEFAULT_VIEW;
- break;
- }
- resizePlayer();
- }
- function getPlayerViewMode() {
- var playerViewToggleButtonTitle = playerViewToggleButton.getAttribute('title');
- if( playerViewToggleButtonTitle != 'null' ) {
- playerViewToggleButtonTitle = playerViewToggleButtonTitle.toLowerCase();
- switch( playerViewToggleButtonTitle ) { //detecta o modo de visualização pelo título do botão (eu sei, depende do idioma :S)
- case 'theater mode': //'Theater mode'
- case 'modo teatro': //'Modo Teatro'
- playerViewMode = DEFAULT_VIEW;
- break;
- case 'default view': //'Default view'
- case 'visualização padrão': //'Visualização padrão'
- playerViewMode = THEATER_MODE;
- break;
- }
- }
- //else playerViewMode = NOT_DETECTED; //isso ocorre, mas daí é mantido o último valor válido detectado
- }
- /*
- function initElements() { //merged into resizePlayer()
- var player = document.getElementById( PLAYER_ID);
- var theater = document.getElementById(THEATER_ID);
- var sidebar = document.getElementById(SIDEBAR_ID);
- var playerPlaceHolder = document.getElementById(PLACEHOLDER_ID);
- playerPlaceHolder.firstElementChild.style.backgroundColor = 'transparent';
- player.style.top = '60px'; //determinado por tentativa e erro :S
- player.style.position = 'fixed';
- theater.style.position = 'fixed';
- sidebar.style.position = 'inherit'; //static|absolute|fixed|relative|initial|inherit
- }
- */
- //https://developer.mozilla.org/pt-BR/docs/Web/API/MutationObserver
- //http://www.w3schools.com/jsref/met_element_addeventlistener.asp
- var bodyMutationObserver = new MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- if( userIsOnAVideoPage() ) {
- if( eventListenersAdded === 0 ) { //só adiciona uma vez
- playerViewToggleButton = getPlayerViewToggleButton();
- playerViewToggleButton.addEventListener('click', playerViewToggleButtonClick, false);
- _window.addEventListener('resize', pageResize, false);
- eventListenersAdded = 1;
- getPlayerViewMode();
- //initElements();
- //resizePlayer(); //aqui não funciona 100%, portanto...
- }
- resizePlayer(); //...tem que ficar aqui e ser chamada várias vezes :S
- }
- else { //user is NOT on a video page
- if( eventListenersAdded ) { //só remove uma vez
- var player = document.getElementById(PLAYER_ID);
- player.style.top = '';
- player.style.position = '';
- player.style.zIndex = '';
- player.style.left = '';
- player.style.width = '';
- playerViewToggleButton.removeEventListener('click', playerViewToggleButtonClick, false);
- _window.removeEventListener('resize', pageResize, false);
- eventListenersAdded = 0;
- }
- }
- });
- });
- /*
- function remBodyMutationObserver();
- if( bodyMutationObserverAdded == 1 ) { //( bodyMutationObserverAdded == 1 ) ou apenas ( bodyMutationObserverAdded )
- bodyMutationObserver.disconnect();
- bodyMutationObserverAdded = 0;
- }
- }
- */
- function addBodyMutationObserver() {
- if( bodyMutationObserverAdded === 0 ) { //( bodyMutationObserverAdded === 0 ) ou apenas ( !bodyMutationObserverAdded )
- var config = { attributes: true, characterData: true, childList: true };
- var target = document.getElementById(BODY_ID); //tem que ser 'body', porque 'page' só funciona quando a 1ª página NÃO for uma de vídeo
- if( target !== null ) { //( target !== null ) ou apenas ( target )
- bodyMutationObserver.observe(target, config);
- bodyMutationObserverAdded = 1;
- }
- }
- }
- addBodyMutationObserver(); //initScript == entryPoint
- })();