Youtube Hide Paused Gradient by Sapioit

Removes the annoying gradients visible when pausing a video.

  1. // ==UserScript==
  2. // @name Youtube Hide Paused Gradient by Sapioit
  3. // @namespace Sapioit
  4. // @copyright Sapioit, 2020 - Present
  5. // @author sapioitgmail.com
  6. // @license GPL-2.0-only; http://www.gnu.org/licenses/gpl-2.0.txt
  7. // @icon https://youtube.com/favicon.ico
  8. // @match https://www.youtube.com/*
  9. // @match http*://*.youtube.com/*
  10. // @match http*://youtube.com/*
  11. // @match https://youtu.be/*
  12. // @match http*://*.youtu.be/*
  13. // @description Removes the annoying gradients visible when pausing a video.
  14. // @version 1.6.0.1
  15. // @grant GM_addStyle
  16. // @grant GM_registerMenuCommand
  17. // @grant GM_setValue
  18. // @grant GM_getValue
  19. // ==/UserScript==
  20.  
  21. localStorage.setItem('currentWatchMetadataValued', 0);
  22. localStorage.setItem('consecutiveUnchangedCounted', 0);
  23. const isFocused = () => typeof document.hidden !== undefined ? !document.hidden : null;
  24.  
  25. function title_changed (count = 3) {
  26. console.info("%cYoutube Hide Paused Gradient by Sapioit: title_changed: %cChecking title.", "color: yellow; background-color: black;", "color: white");
  27.  
  28. // Check if the value of the title (the first "yt-formatted-string.style-scope.ytd-watch-metadata" element) has changed
  29. let firstWatchMetadataElement = document.querySelector('h1 yt-formatted-string.style-scope.ytd-watch-metadata');
  30.  
  31. if ( firstWatchMetadataElement === null || (typeof firstWatchMetadataElement) === 'undefined') {
  32. console.info("Youtube Hide Paused Gradient by Sapioit: title_changed: %cThe 'h1 yt-formatted-string.style-scope.ytd-watch-metadata' is either NULL or UNDEFINED.", "color: red");
  33. console.info("%cYoutube Hide Paused Gradient by Sapioit: title_changed: %c", "color: red", "color: default", firstWatchMetadataElement , (typeof firstWatchMetadataElement));
  34. return false;
  35. }
  36.  
  37. console.info("%cYoutube Hide Paused Gradient by Sapioit: title_changed:", "color: cyan", (firstWatchMetadataElement.textContent.trim()) );
  38. console.info("%cYoutube Hide Paused Gradient by Sapioit: title_changed:", "color: cyan", (firstWatchMetadataElement.textContent.trim() !== '') , ' ' , (firstWatchMetadataElement) );
  39.  
  40. if ( firstWatchMetadataElement.textContent.trim() !== '') {
  41. // Get the current value of the title
  42. let currentWatchMetadataValue = firstWatchMetadataElement.textContent.trim();
  43. console.info("%cYoutube Hide Paused Gradient by Sapioit: title_changed: %cTitle found.", "color: yellow; background-color: black;", "color: white");
  44.  
  45. // Get the consecutive unchanged count from localStorage, or set it to 0 if it's not available
  46. let consecutiveUnchangedCount = parseInt(localStorage.getItem('consecutiveUnchangedCounted')) || 0;
  47.  
  48. // Increment the consecutiveUnchangedCount if the value is the same
  49. consecutiveUnchangedCount++;
  50.  
  51. // Update the stored value and consecutiveUnchangedCount in localStorage
  52. localStorage.setItem('currentWatchMetadataValued', currentWatchMetadataValue);
  53. localStorage.setItem('consecutiveUnchangedCounted', consecutiveUnchangedCount.toString());
  54.  
  55. console.log("Youtube Hide Paused Gradient by Sapioit: title_changed: Try nr #" + (1+consecutiveUnchangedCount) );
  56.  
  57. // Check if the current value is the same as the previous one stored in localStorage
  58. if (localStorage.getItem('currentWatchMetadataValued') === currentWatchMetadataValue) {
  59.  
  60. // Stop the function if the title value hasn't changed for the last three checks (consecutiveUnchangedCount is less than 4)
  61. if ( consecutiveUnchangedCount < (count+1) ) {
  62. console.log("Youtube Hide Paused Gradient by Sapioit: title_changed: First 'yt-formatted-string.style-scope.ytd-watch-metadata' element has not changed for the last three checks. Stopping check.");
  63. return false; // Return that the title has not changed.
  64. } else {
  65. // Reset the consecutiveUnchangedCount if the value has changed
  66. consecutiveUnchangedCount = 0;
  67.  
  68. // Update the stored value and consecutiveUnchangedCount in localStorage
  69. localStorage.setItem('currentWatchMetadataValued', currentWatchMetadataValue);
  70. localStorage.setItem('consecutiveUnchangedCounted', consecutiveUnchangedCount.toString());
  71. return true; // Return that the title has changed.
  72. }
  73. } else {
  74. // Reset the consecutiveUnchangedCount if the value has changed
  75. consecutiveUnchangedCount = 0;
  76.  
  77. // Update the stored value and consecutiveUnchangedCount in localStorage
  78. localStorage.setItem('currentWatchMetadataValued', currentWatchMetadataValue);
  79. localStorage.setItem('consecutiveUnchangedCounted', consecutiveUnchangedCount.toString());
  80. return true; // Return that the title has changed.
  81. }
  82. } else {
  83. console.log("Youtube Hide Paused Gradient by Sapioit: title_changed: Checking title FAILED.");
  84. }
  85. return false; // Return that the title has changed.
  86. // Usage example:
  87. if ( title_changed() ){
  88. return;
  89. }
  90. if ( title_changed(8) ){
  91. return;
  92. }
  93. }
  94.  
  95.  
  96. function swapButtonsSaveShare(){
  97. if ( !isFocused() || title_changed(8) ){
  98. return;
  99. }
  100. console.log("Youtube Hide Paused Gradient by Sapioit: swapButtons:: Checking if 'Save' button is inside the top-level-buttons-computed element.");
  101.  
  102. let isSaveButtonInside = document.querySelector('div#top-level-buttons-computed.top-level-buttons.style-scope.ytd-menu-renderer button[aria-label="Save to playlist"]');
  103. console.info('%cYoutube Hide Paused Gradient by Sapioit: swapButtons: %c', "color: cyan", isSaveButtonInside, (typeof isSaveButtonInside));
  104.  
  105. if (isSaveButtonInside) {
  106. console.log("Youtube Hide Paused Gradient by Sapioit: swapButtons: 'Save' button is inside the top-level-buttons-computed element.");
  107. console.log("Youtube Hide Paused Gradient by Sapioit: swapButtons:: " + JSON.stringify(isSaveButtonInside));
  108. //GM_addStyle('div#top-level-buttons-computed.top-level-buttons.style-scope.ytd-menu-renderer button[aria-label="Save to playlist"] { background-color: red;}');
  109. return;
  110. }
  111.  
  112. console.log("Youtube Hide Paused Gradient by Sapioit: swapButtons: 'Save' button is NOT inside the top-level-buttons-computed element.");
  113. let saveButton = document.querySelector('ytd-button-renderer[button-renderer][button-next] button[aria-label="Save to playlist"]');
  114. let shareButton = document.querySelector('ytd-button-renderer[button-renderer][button-next] button[aria-label="Share"]');
  115.  
  116. if (saveButton && shareButton) {
  117. let saveButtonParent = saveButton.parentElement;
  118. let shareButtonParent = shareButton.parentElement;
  119.  
  120. // Create placeholder elements to hold the buttons temporarily
  121. const placeholder1 = document.createElement('div');
  122. const placeholder2 = document.createElement('div');
  123.  
  124. // Move the buttons to their respective placeholder positions
  125. saveButtonParent.insertBefore(placeholder1, saveButton);
  126. shareButtonParent.insertBefore(placeholder2, shareButton);
  127. shareButtonParent.insertBefore(saveButton, placeholder2);
  128. saveButtonParent.insertBefore(shareButton, placeholder1);
  129.  
  130. // Remove the placeholders
  131. saveButtonParent.removeChild(placeholder1);
  132. shareButtonParent.removeChild(placeholder2);
  133.  
  134. // Swap Save2 with a new Share2
  135. let save2Button = document.querySelector('tp-yt-paper-item[aria-disabled="false"] yt-formatted-string[role="option"][class="style-scope ytd-menu-service-item-renderer"]');
  136. if (save2Button) {
  137. let saveButtonParent = saveButton.parentElement;
  138.  
  139. // Swap the positions of saveButton and shareButton in their respective parents
  140. saveButtonParent.insertBefore(shareButton, saveButton.nextSibling);
  141.  
  142. // Create new HTML for the modified share2Button
  143. let newShare2ButtonHTML = '<ytd-menu-service-item-renderer class="style-scope ytd-menu-popup-renderer iron-selected" use-icons="" system-icons="" role="menuitem" tabindex="-1" aria-selected="true"><!--css-build:shady--><!--css-build:shady--><tp-yt-paper-item class="style-scope ytd-menu-service-item-renderer" style-target="host" role="option" tabindex="0" aria-disabled="false"><!--css-build:shady--><yt-icon class="style-scope ytd-menu-service-item-renderer"><!--css-build:shady--><!--css-build:shady--><yt-icon-shape class="style-scope yt-icon"><icon-shape class="yt-spec-icon-shape"><div style="width: 100%; height: 100%; fill: currentcolor;"><svg height="24" viewBox="0 0 24 24" width="24" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;"><path d="M15 5.63 20.66 12 15 18.37V14h-1c-3.96 0-7.14 1-9.75 3.09 1.84-4.07 5.11-6.4 9.89-7.1l.86-.13V5.63M14 3v6C6.22 10.13 3.11 15.33 2 21c2.78-3.97 6.44-6 12-6v6l8-9-8-9z"></path></svg></div></icon-shape></yt-icon-shape></yt-icon></div><yt-formatted-string class="style-scope ytd-menu-service-item-renderer">Share</yt-formatted-string><ytd-badge-supported-renderer class="style-scope ytd-menu-service-item-renderer" disable-upgrade="" hidden=""></ytd-badge-supported-renderer></tp-yt-paper-item></ytd-menu-service-item-renderer>';
  144.  
  145. // Create a new DOM element from the HTML string
  146. const parser = new DOMParser();
  147. const newShare2Button = parser.parseFromString(newShare2ButtonHTML, "text/html").body.firstChild;
  148.  
  149. // Add the newShare2Button after the saveButton
  150. saveButtonParent.insertBefore(newShare2Button, saveButton.nextSibling);
  151. }
  152.  
  153. /*let newShareButton = '<button class="yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-leading " aria-label="Share" style=""><div class="yt-spec-button-shape-next__icon" aria-hidden="true"><yt-icon style="width: 24px; height: 24px;"><!--css-build:shady--><!--css-build:shady--><yt-icon-shape class="style-scope yt-icon"><icon-shape class="yt-spec-icon-shape"><div style="width: 100%; height: 100%; fill: currentcolor;"><svg height="24" viewBox="0 0 24 24" width="24" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;"><path d="M15 5.63 20.66 12 15 18.37V14h-1c-3.96 0-7.14 1-9.75 3.09 1.84-4.07 5.11-6.4 9.89-7.1l.86-.13V5.63M14 3v6C6.22 10.13 3.11 15.33 2 21c2.78-3.97 6.44-6 12-6v6l8-9-8-9z"></path></svg></div></icon-shape></yt-icon-shape></yt-icon></div><div class="cbox yt-spec-button-shape-next__button-text-content"><span class="yt-core-attributed-string yt-core-attributed-string--white-space-no-wrap" role="text">Share</span></div><yt-touch-feedback-shape style="border-radius: inherit;"><div class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response" aria-hidden="true"><div class="yt-spec-touch-feedback-shape__stroke" style=""></div><div class="yt-spec-touch-feedback-shape__fill" style=""></div></div></yt-touch-feedback-shape></button>';
  154. let newSaveButton = '<button class="yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-leading " aria-label="Save to playlist" style=""><div class="yt-spec-button-shape-next__icon" aria-hidden="true"><yt-icon style="width: 24px; height: 24px;"><!--css-build:shady--><!--css-build:shady--><yt-icon-shape class="style-scope yt-icon"><icon-shape class="yt-spec-icon-shape"><div style="width: 100%; height: 100%; fill: currentcolor;"><svg height="24" viewBox="0 0 24 24" width="24" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;"><path d="M22 13h-4v4h-2v-4h-4v-2h4V7h2v4h4v2zm-8-6H2v1h12V7zM2 12h8v-1H2v1zm0 4h8v-1H2v1z"></path></svg></div></icon-shape></yt-icon-shape></yt-icon></div><div class="cbox yt-spec-button-shape-next__button-text-content"><span class="yt-core-attributed-string yt-core-attributed-string--white-space-no-wrap" role="text">Save</span></div><yt-touch-feedback-shape style="border-radius: inherit;"><div class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response" aria-hidden="true"><div class="yt-spec-touch-feedback-shape__stroke" style=""></div><div class="yt-spec-touch-feedback-shape__fill" style=""></div></div></yt-touch-feedback-shape></button>';
  155.  
  156. function createTrustedHTML(inputString) {
  157. const parser = new DOMParser();
  158. const doc = parser.parseFromString(inputString, "text/html");
  159. const fragment = doc.body;
  160. return fragment.outerHTML;
  161. }
  162.  
  163.  
  164. function escapeHTML(inputString) {
  165. return inputString.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  166. }
  167.  
  168.  
  169. newShareButton = createTrustedHTML(newShareButton);
  170. newSaveButton = createTrustedHTML(newSaveButton);
  171.  
  172.  
  173. shareButton.outerHTML = newSaveButton;
  174. saveButton.outerHTML = newShareButton;*/
  175.  
  176. // To remove the old "Save" and "Share" buttons, uncomment the lines below:
  177. // saveButtonParent.removeChild(saveButton);
  178. // shareButtonParent.removeChild(shareButton);
  179. }
  180. console.info("%cYoutube Hide Paused Gradient by Sapioit: swapButtons: Finishing swapping.", "color: cyan");
  181. }
  182.  
  183.  
  184. function add_hover_tooltips() {
  185. /*var video_titles = document.getElementsByTagName("h3").getElementsByClassName("ytd-compact-video-renderer").getElementsByTagName("span");*/
  186. /*var video_titles = document.querySelector("span.ytd-compact-video-renderer");*/
  187. //var video_titles = document.getElementsByTagName("span").getElementsByClassName("ytd-compact-video-renderer");
  188.  
  189. /*var video_titles = document.querySelectorAll("span.ytd-compact-video-renderer");*/
  190. var video_titles = document.querySelectorAll("span.ytd-compact-video-renderer, #video-title");
  191. for(var i=0; i<video_titles.length; i++){
  192. console.log(video_titles[i]);
  193. var current_title = video_titles[i].getAttribute("title");
  194. video_titles[i].setAttribute("alt", current_title);
  195. video_titles[i].setAttribute("data-title", current_title);
  196. video_titles[i].setAttribute("data-tooltip", current_title);
  197. }
  198. /*
  199. video_titles = document.querySelectorAll("#video-title");
  200. for(i=0; i<video_titles.length; i++){
  201. console.log(video_titles[i]);
  202. current_title = video_titles[i].getAttribute("title");
  203. video_titles[i].setAttribute("alt", current_title);
  204. video_titles[i].setAttribute("data-title", current_title);
  205. video_titles[i].setAttribute("data-tooltip", current_title);
  206. }
  207. */
  208. }
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215. window.onloadstart = function(){setTimeout(function () {
  216. add_hover_tooltips();
  217. }, 0.001*1000)}; //loads after 0.001 seconds
  218.  
  219.  
  220. window.addEventListener('keydown', function(e) {
  221. let play_button = document.querySelector('button.ytp-play-button');
  222. let valid_target = e.target === document.body || e.target === document.querySelector('#player-api');
  223. let pressed_space = e.keyCode === 32 || e.keyCode === 'Space'; // Space
  224. if (play_button && valid_target && pressed_space) {
  225. console.log("Youtube Hide Paused Gradient by Sapioit: Pressed pause or resume.");
  226. e.preventDefault();
  227. playButton.click();
  228. }
  229. });
  230.  
  231.  
  232.  
  233.  
  234. if (typeof document.getElementsByClassName("ytp-gradient-top")[0] != "undefined") {
  235. document.getElementsByClassName("ytp-gradient-top")[0].style.display = 'none';
  236. }
  237. if (typeof document.getElementsByClassName("ytp-gradient-top")[0] != "undefined") {
  238. document.getElementsByClassName("ytp-gradient-top")[0].style.opacity = '0';
  239. }
  240. if (typeof document.getElementsByClassName("ytp-gradient-bottom")[0] != "undefined") {
  241. document.getElementsByClassName("ytp-gradient-bottom")[0].style.display = 'none';
  242. }
  243. if (typeof document.getElementsByClassName("ytp-gradient-bottom")[0] != "undefined") {
  244. document.getElementsByClassName("ytp-gradient-bottom")[0].style.opacity = '0';
  245. }
  246.  
  247. /*
  248. document.getElementsByClassName("ytp-gradient-top")[0].style.display = 'none';
  249. document.getElementsByClassName("ytp-gradient-top")[0].style.opacity = '0';
  250. document.getElementsByClassName("ytp-gradient-bottom")[0].style.display = 'none';
  251. document.getElementsByClassName("ytp-gradient-bottom")[0].style.opacity = '0';
  252. */
  253.  
  254.  
  255.  
  256. GM_addStyle('.ytp-caption-window-container { top: 2% !important; }');
  257.  
  258. GM_addStyle('.ytp-gradient-top { display: none !important; opacity: 0 !important; }');
  259. GM_addStyle('.ytp-gradient-top { width: none !important; opacity: 0 !important; }');
  260.  
  261. GM_addStyle('button div.ytp-autonav-toggle-button-container { display: none !important;}');
  262. GM_addStyle('[data-tooltip-target-id="ytp-autonav-toggle-button"] { display: none !important;}');
  263. //GM_addStyle('.ytp-button[data-tooltip-target-id="ytp-autonav-toggle-button"] { display: none !important;}');
  264. GM_addStyle('--ytd-engagement-panel-section-list-rendere { display: none !important;}');
  265. GM_addStyle('.ytp-time-display > span { padding: 3px; background: rgba(0, 0, 0, 0.5); }');
  266. //GM_addStyle('.ytd-thumbnail-overlay-time-status-renderen { transition-duration: 0s; }');
  267.  
  268. window.onload = function(){setTimeout(function () {
  269. GM_addStyle('button div.ytp-autonav-toggle-button-container { display: none !important;}');
  270. GM_addStyle('[data-tooltip-target-id="ytp-autonav-toggle-button"] { display: none !important;}');
  271. GM_addStyle('--ytd-engagement-panel-section-list-rendere { display: none !important;}');
  272. GM_addStyle('#video-title.ytd-compact-video-renderer { overflow: none !important;}');
  273. GM_addStyle('ytd-button-renderer > yt-button-shape > button[aria-label="Thanks"] { display: none !important; }');
  274. //GM_addStyle('ytd-button-renderer > yt-button-shape > button[aria-label="Save to playlist"] { display: inline-block !important; }');
  275. add_hover_tooltips();
  276. swapButtonsSaveShare();
  277. setTimeout(function () {
  278. swapButtonsSaveShare();
  279. }, 5*1000) //loads after 5 seconds
  280. //GM_addStyle('.ytd-thumbnail-overlay-time-status-renderen { transition-duration: 0s; }');
  281. }, 5*1000)}; //loads after 5 seconds
  282.  
  283. function repeaterFunction(){
  284. if ( title_changed(8) ){
  285. return;
  286. }
  287. GM_addStyle('button div.ytp-autonav-toggle-button-container { display: none !important;}');
  288. GM_addStyle('[data-tooltip-target-id="ytp-autonav-toggle-button"] { display: none !important;}');
  289. GM_addStyle('--ytd-engagement-panel-section-list-rendere { display: none !important;}');
  290. add_hover_tooltips();
  291. swapButtonsSaveShare();
  292. setTimeout(repeaterFunction, 30*1000); //loads every 30 seconds
  293. }
  294. repeaterFunction();
  295.  
  296.  
  297. GM_addStyle("span[data-tooltip]:before { z-index:301; content: attr(data-tooltip); position: absolute; opacity: 0; padding: 10px; background: black; color: white;} span[data-tooltip]:hover:before { opacity: 1;} ");
  298. GM_addStyle(".yt-simple-endpoint[title]:before { z-index:301; content: attr(title); position: absolute; opacity: 0; padding: 10px; background: black; color: white;} .yt-simple-endpoint[title]:hover:before { opacity: 1 !important;} ");
  299.  
  300.  
  301. // <ytd-engagement-panel-section-list-renderer class="style-scope ytd-watch-flexy" visibility="ENGAGEMENT_PANEL_VISIBILITY_EXPANDED">GM_addStyle(a);
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.