Youtube restore slim thumbnails

Restore slim thumbnails on home and subs pages. Disable autoplay on unsub channel's home.

目前为 2022-02-07 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube restore slim thumbnails
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.5
  5. // @description Restore slim thumbnails on home and subs pages. Disable autoplay on unsub channel's home.
  6. // @author me
  7. // @match https://www.youtube.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. //https://stackoverflow.com/a/52809105----
  15. history.pushState = ( f => function pushState(){
  16. var ret = f.apply(this, arguments);
  17. window.dispatchEvent(new Event('pushstate'));
  18. window.dispatchEvent(new Event('locationchange'));
  19. return ret;
  20. })(history.pushState);
  21.  
  22. history.replaceState = ( f => function replaceState(){
  23. var ret = f.apply(this, arguments);
  24. window.dispatchEvent(new Event('replacestate'));
  25. window.dispatchEvent(new Event('locationchange'));
  26. return ret;
  27. })(history.replaceState);
  28.  
  29. window.addEventListener('popstate',()=>{
  30. window.dispatchEvent(new Event('locationchange'))
  31. });
  32.  
  33. //https://stackoverflow.com/a/45956628----
  34. //youtube wtf events
  35. //new layout > 2017
  36. window.addEventListener("yt-navigate-finish", function(event) {
  37. window.dispatchEvent(new Event('locationchange'))
  38. });
  39.  
  40. //old layout < 2017
  41. window.addEventListener("spfdone", function(e) {
  42. window.dispatchEvent(new Event('locationchange'))
  43. });
  44.  
  45. //should made portable my settings
  46. const getRelative = () => {
  47. var p = document.createElement("p");
  48. p.innerHTML = "test";
  49. p.style.fontSize = "16px";
  50. document.body.appendChild(p);
  51. var relative = 19/p.offsetHeight;
  52. p.innerHTML = "";
  53. return relative;
  54. }
  55.  
  56. const disableAutoplayUnsubChannel = () => {
  57. if(interval != null){
  58. clearInterval(interval);
  59. }
  60. //(c|channel|user|u) wtf youtube!
  61. if(document.URL.match(/^(https:\/\/www\.youtube\.com)\/(c|channel|user|u)\/([a-z0-9_]*)(\/featured)?$/i) != null){
  62. var interval3 = setInterval(() => {
  63. var videos = document.getElementsByClassName("video-stream html5-main-video");
  64. if( videos != null){
  65. videos[videos.length-1].addEventListener("play", () => {
  66. videos[videos.length-1].pause();
  67. }, {once: true});
  68. videos[videos.length-1].pause();
  69. clearInterval(interval3);
  70. }
  71. },100);
  72. }
  73. }
  74.  
  75. const startObserve = () => {
  76. if(document.URL.match(/^(https:\/\/www\.youtube\.com)(\/|\/\?gl\=[a-z]+)?$/i) != null)
  77. var interval2 = setInterval(()=>{
  78. if(document.querySelectorAll("ytd-rich-grid-renderer>#contents")[0] !== undefined){
  79.  
  80. clearInterval(interval2);
  81.  
  82. var grid_renderer_contents = document.querySelectorAll("ytd-rich-grid-renderer>#contents")[0];
  83. const fixThubnails = function(){
  84. document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row > #contents > ytd-rich-item-renderer").forEach(
  85. function(element){element.parentNode.parentNode.insertAdjacentElement('beforebegin',element);}
  86. );
  87. document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row").forEach(
  88. function(element){element.remove()}
  89. );
  90. }
  91. fixThubnails();
  92. new MutationObserver(function (mutationList,observer){
  93. observer.disconnect();
  94. if(document.URL.match(/^(https:\/\/www\.youtube\.com)(\/|\/\?gl\=[a-z]+)?$/i) != null){
  95. fixThubnails();
  96. observer.observe(grid_renderer_contents,{childList: true});
  97. }
  98. }).observe(grid_renderer_contents,{childList: true});
  99. initObs = true;
  100.  
  101. }
  102. },5);
  103. }
  104.  
  105. const restoreSlimTubnails = () => {
  106. //work only on www.youtube.com and www.youtube.com/feed/subscriptions. If run on video's page it causes cpu load
  107. if(document.URL.match(/^(https:\/\/www\.youtube\.com)(\/|\/feed\/subscriptions|\/\?gl\=[a-z]+)?$/i) == null) return;
  108. if(!firstRun && !initObs){
  109. startObserve();
  110. return;
  111. }
  112.  
  113. if(!firstRun) return;
  114.  
  115. var relative = getRelative();
  116. var itemWidth = 240*relative;
  117. var postWidth = 350*relative;
  118. var subsWidth = 214;
  119. var padding = 48;
  120. var fontSize = 1.4*relative;
  121. var lineHeight = 1.8*relative;
  122. let parentSize = document.createElement("style");
  123. var parent = document.getElementById("page-manager");
  124. if(parent == null) return;
  125.  
  126. //fix
  127. var toResObs = document.querySelector("ytd-browse:not([hidden]) > #header");
  128. if(toResObs == null) return;
  129.  
  130.  
  131. const updateParentSize = () => {
  132. parentSize.innerHTML = ":root{--how-many-items:"+parseInt(parent.offsetWidth/itemWidth)+";"+
  133. "--how-many-posts:"+parseInt(parent.offsetWidth/postWidth)+";"+
  134. "--variable-columns-width:"+parseInt((parent.offsetWidth-padding)/subsWidth)*subsWidth+"px}";
  135. }
  136.  
  137. updateParentSize();
  138.  
  139. let style = document.createElement("style");
  140. style.innerHTML = "ytd-rich-grid-renderer.ytd-two-column-browse-results-renderer{"+
  141. "--ytd-rich-grid-items-per-row:var(--how-many-items) !important;"+
  142. "--ytd-rich-grid-posts-per-row:var(--how-many-posts) !important;"+
  143. "--ytd-rich-grid-movies-per-row:11 !important;}"+
  144.  
  145. "#metadata-line.ytd-video-meta-block,ytd-channel-name{"+
  146. "max-height: 7.1rem !important;"+
  147. "font-size:"+fontSize+"rem !important;"+
  148. "line-height:"+lineHeight+"rem !important}"+
  149.  
  150. "ytd-two-column-browse-results-renderer[page-subtype='subscriptions']{"+
  151. "width:var(--variable-columns-width) !important;"+
  152. "max-width:var(--variable-columns-width) !important}"+
  153.  
  154. "ytd-two-column-browse-results-renderer[page-subtype='home'] > #primary > ytd-rich-grid-renderer > #contents{"+
  155. "width:auto}"+
  156.  
  157. //new fix
  158. "ytd-rich-section-renderer[align-within-rich-grid] #content.ytd-rich-section-renderer{margin:0 8px !important}"+
  159. "ytd-rich-grid-renderer>#contents{max-width: calc( var(--ytd-rich-grid-items-per-row) * (var(--ytd-rich-grid-item-max-width) + var(--ytd-rich-grid-item-margin)) - var(--ytd-rich-grid-item-margin) );"+
  160. "padding: 0 24px;}";
  161. document.body.appendChild(parentSize);
  162. document.body.appendChild(style);
  163. new ResizeObserver(updateParentSize).observe(toResObs);
  164. firstRun = false;
  165. startObserve();
  166.  
  167. //new fix after some youtube changes
  168. /*var grid_renderer_contents = document.querySelectorAll("ytd-rich-grid-renderer>#contents")[0];
  169. const fixThubnails = function(){
  170. document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row > #contents > ytd-rich-item-renderer").forEach(
  171. function(element){element.parentNode.parentNode.insertAdjacentElement('beforebegin',element);}
  172. );
  173. document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row").forEach(
  174. function(element){element.remove()}
  175. );
  176. }
  177. fixThubnails();
  178. new MutationObserver(function (mutationList,observer){
  179. observer.disconnect();
  180. fixThubnails();
  181. observer.observe(grid_renderer_contents,{childList: true});
  182. }).observe(grid_renderer_contents,{childList: true});*/
  183. }
  184.  
  185.  
  186. var firstRun = true;
  187. var initObs = false;
  188. const run = () => {
  189. disableAutoplayUnsubChannel();
  190. restoreSlimTubnails();
  191. }
  192.  
  193. var interval = setInterval(()=>{
  194. if(document.body !== null){
  195. clearInterval(interval);
  196. run();
  197. }
  198. },5);
  199.  
  200. window.addEventListener('locationchange', run);
  201. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址