YouTube - Non-Rounded Design

This script disables YouTube's new rounded corners (reverts back to the layout from 2021.)

目前为 2022-12-08 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube - Non-Rounded Design
  3. // @version 2.1.5.1
  4. // @description This script disables YouTube's new rounded corners (reverts back to the layout from 2021.)
  5. // @author Magma_Craft
  6. // @license MIT
  7. // @match *://*.youtube.com/*
  8. // @namespace https://greasyfork.org/en/users/933798
  9. // @icon https://www.youtube.com/favicon.ico
  10. // @run-at document-start
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. // Attributes to remove from <html>
  15. const ATTRS = [
  16. ];
  17.  
  18. // Regular config keys.
  19. const CONFIGS = {
  20. BUTTON_REWORK: false
  21. }
  22.  
  23. // Experiment flags.
  24. const EXPFLAGS = {
  25. kevlar_watch_metadata_refresh: false,
  26. kevlar_watch_modern_metapanel: false,
  27. kevlar_watch_modern_panels: false,
  28. web_rounded_containers: false,
  29. web_rounded_thumbnails: false,
  30. web_modern_dialogs: false,
  31. web_modern_chips: false,
  32. web_modern_subscribe: false,
  33. web_modern_buttons: false,
  34. web_modern_playlists: false,
  35. enable_programmed_playlist_redesign: false,
  36. web_amsterdam_playlists: false,
  37. web_searchbar_style: "default",
  38. web_button_rework: false,
  39. web_darker_dark_theme: false,
  40. kevlar_watch_cinematics: false,
  41. kevlar_refresh_on_theme_change: false,
  42. web_guide_ui_refresh: false,
  43. web_sheets_ui_refresh: false,
  44. web_snackbar_ui_refresh: false,
  45. web_segmented_like_dislike_button: false,
  46. web_animated_like: false,
  47. web_animated_like_lazy_load: false,
  48. kevlar_use_ytd_player: false
  49. }
  50.  
  51. // Player flags
  52. // !!! USE STRINGS FOR VALUES !!!
  53. // For example: "true" instead of true
  54. const PLYRFLAGS = {
  55. web_player_move_autonav_toggle: "true"
  56. }
  57.  
  58. class YTP {
  59. static observer = new MutationObserver(this.onNewScript);
  60.  
  61. static _config = {};
  62.  
  63. static isObject(item) {
  64. return (item && typeof item === "object" && !Array.isArray(item));
  65. }
  66.  
  67. static mergeDeep(target, ...sources) {
  68. if (!sources.length) return target;
  69. const source = sources.shift();
  70.  
  71. if (this.isObject(target) && this.isObject(source)) {
  72. for (const key in source) {
  73. if (this.isObject(source[key])) {
  74. if (!target[key]) Object.assign(target, { [key]: {} });
  75. this.mergeDeep(target[key], source[key]);
  76. } else {
  77. Object.assign(target, { [key]: source[key] });
  78. }
  79. }
  80. }
  81.  
  82. return this.mergeDeep(target, ...sources);
  83. }
  84.  
  85.  
  86. static onNewScript(mutations) {
  87. for (var mut of mutations) {
  88. for (var node of mut.addedNodes) {
  89. YTP.bruteforce();
  90. }
  91. }
  92. }
  93.  
  94. static start() {
  95. this.observer.observe(document, {childList: true, subtree: true});
  96. }
  97.  
  98. static stop() {
  99. this.observer.disconnect();
  100. }
  101.  
  102. static bruteforce() {
  103. if (!window.yt) return;
  104. if (!window.yt.config_) return;
  105.  
  106. this.mergeDeep(window.yt.config_, this._config);
  107. }
  108.  
  109. static setCfg(name, value) {
  110. this._config[name] = value;
  111. }
  112.  
  113. static setCfgMulti(configs) {
  114. this.mergeDeep(this._config, configs);
  115. }
  116.  
  117. static setExp(name, value) {
  118. if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {};
  119.  
  120. this._config.EXPERIMENT_FLAGS[name] = value;
  121. }
  122.  
  123. static setExpMulti(exps) {
  124. if (!("EXPERIMENT_FLAGS" in this._config)) this._config.EXPERIMENT_FLAGS = {};
  125.  
  126. this.mergeDeep(this._config.EXPERIMENT_FLAGS, exps);
  127. }
  128.  
  129. static decodePlyrFlags(flags) {
  130. var obj = {},
  131. dflags = flags.split("&");
  132.  
  133. for (var i = 0; i < dflags.length; i++) {
  134. var dflag = dflags[i].split("=");
  135. obj[dflag[0]] = dflag[1];
  136. }
  137.  
  138. return obj;
  139. }
  140.  
  141. static encodePlyrFlags(flags) {
  142. var keys = Object.keys(flags),
  143. response = "";
  144.  
  145. for (var i = 0; i < keys.length; i++) {
  146. if (i > 0) {
  147. response += "&";
  148. }
  149. response += keys[i] + "=" + flags[keys[i]];
  150. }
  151.  
  152. return response;
  153. }
  154.  
  155. static setPlyrFlags(flags) {
  156. if (!window.yt) return;
  157. if (!window.yt.config_) return;
  158. if (!window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS) return;
  159. var conCfgs = window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS;
  160. if (!("WEB_PLAYER_CONTEXT_CONFIGS" in this._config)) this._config.WEB_PLAYER_CONTEXT_CONFIGS = {};
  161.  
  162. for (var cfg in conCfgs) {
  163. var dflags = this.decodePlyrFlags(conCfgs[cfg].serializedExperimentFlags);
  164. this.mergeDeep(dflags, flags);
  165. this._config.WEB_PLAYER_CONTEXT_CONFIGS[cfg] = {
  166. serializedExperimentFlags: this.encodePlyrFlags(dflags)
  167. }
  168. }
  169. }
  170. }
  171.  
  172. window.addEventListener("yt-page-data-updated", function tmp() {
  173. YTP.stop();
  174. for (i = 0; i < ATTRS.length; i++) {
  175. document.getElementsByTagName("html")[0].removeAttribute(ATTRS[i]);
  176. }
  177. window.removeEventListener("yt-page-date-updated", tmp);
  178. });
  179.  
  180. YTP.start();
  181.  
  182. YTP.setCfgMulti(CONFIGS);
  183. YTP.setExpMulti(EXPFLAGS);
  184. YTP.setPlyrFlags(PLYRFLAGS);
  185.  
  186. function $(q) {
  187. return document.querySelector(q);
  188. }
  189.  
  190. // Fix for Return YouTube Dislike
  191. addEventListener('yt-page-data-updated', function() {
  192. if(!location.pathname.startsWith('/watch')) return;
  193.  
  194. var lds = $('ytd-video-primary-info-renderer div#top-level-buttons-computed');
  195. var like = $('ytd-video-primary-info-renderer div#segmented-like-button > ytd-toggle-button-renderer');
  196. var share = $('ytd-video-primary-info-renderer div#top-level-buttons-computed > ytd-segmented-like-dislike-button-renderer + ytd-button-renderer');
  197.  
  198. lds.insertBefore(like, share);
  199.  
  200. like.setAttribute('class', like.getAttribute('class').replace('ytd-segmented-like-dislike-button-renderer', 'ytd-menu-renderer force-icon-button'));
  201. like.removeAttribute('is-paper-button-with-icon');
  202. like.removeAttribute('is-paper-button');
  203. like.setAttribute('style-action-button', '');
  204. like.setAttribute('is-icon-button', '');
  205. like.querySelector('a').insertBefore(like.querySelector('yt-formatted-string'), like.querySelector('tp-yt-paper-tooltip'));
  206. try { like.querySelector('paper-ripple').remove(); } catch(e) {}
  207. var paper = like.querySelector('tp-yt-paper-button');
  208. paper.removeAttribute('style-target');
  209. paper.removeAttribute('animated');
  210. paper.removeAttribute('elevation');
  211. like.querySelector('a').insertBefore(paper.querySelector('yt-icon'), like.querySelector('yt-formatted-string'));
  212. paper.outerHTML = paper.outerHTML.replace('<tp-yt-paper-button ', '<yt-icon-button ').replace('</tp-yt-paper-button>', '</yt-icon-button>');
  213. paper = like.querySelector('yt-icon-button');
  214. paper.querySelector('button#button').appendChild(like.querySelector('yt-icon'));
  215.  
  216. var dislike = $('ytd-video-primary-info-renderer div#segmented-dislike-button > ytd-toggle-button-renderer');
  217. lds.insertBefore(dislike, share);
  218. $('ytd-video-primary-info-renderer ytd-segmented-like-dislike-button-renderer').remove();
  219. dislike.setAttribute('class', dislike.getAttribute('class').replace('ytd-segmented-like-dislike-button-renderer', 'ytd-menu-renderer force-icon-button'));
  220. dislike.removeAttribute('has-no-text');
  221. dislike.setAttribute('style-action-button', '');
  222. var dlabel = document.createElement('yt-formatted-stringx');
  223. dlabel.setAttribute('id', 'text');
  224. if(dislike.getAttribute('class').includes('style-default-active'))
  225. dlabel.setAttribute('class', dlabel.getAttribute('class').replace('style-default', 'style-default-active'));
  226. dislike.querySelector('a').insertBefore(dlabel, dislike.querySelector('tp-yt-paper-tooltip'));
  227.  
  228. $('ytd-video-primary-info-renderer').removeAttribute('flex-menu-enabled');
  229. });
  230.  
  231. // CSS adjustments and UI fixes
  232. (function() {
  233. ApplyCSS();
  234. function ApplyCSS() {
  235. var styles = document.createElement("style");
  236. styles.innerHTML=`
  237. #cinematics.ytd-watch-flexy {
  238. display: none;
  239. }
  240.  
  241. div#clarify-box.attached-message.style-scope.ytd-watch-flexy {
  242. margin-top: 0px;
  243. }
  244.  
  245. ytd-clarification-renderer.style-scope.ytd-item-section-renderer {
  246. border: 1px solid;
  247. border-color: #0000001a;
  248. border-radius: 0px;
  249. }
  250.  
  251. ytd-clarification-renderer.style-scope.ytd-watch-flexy {
  252. border: 1px solid;
  253. border-color: #0000001a;
  254. border-radius: 0px;
  255. }
  256.  
  257. yt-formatted-string.description.style-scope.ytd-clarification-renderer {
  258. font-size: 1.4rem;
  259. }
  260.  
  261. div.content-title.style-scope.ytd-clarification-renderer {
  262. padding-bottom: 4px;
  263. }
  264.  
  265. div.ytp-sb-subscribe.ytp-sb-rounded, .ytp-sb-unsubscribe.ytp-sb-rounded {
  266. border-radius: 2px;
  267. }
  268.  
  269. .yt-spec-button-shape-next--size-m {
  270. background-color: transparent;
  271. padding-right: 6px;
  272. }
  273.  
  274. .yt-spec-button-shape-next--mono.yt-spec-button-shape-next--tonal {
  275. background-color: transparent;
  276. }
  277.  
  278. div.cbox.yt-spec-button-shape-next--button-text-content {
  279. display: none;
  280. }
  281.  
  282. div.yt-spec-button-shape-next__secondary-icon {
  283. display: none;
  284. }
  285.  
  286. div#ytp-id-18.ytp-popup,ytp-settings-menu.ytp-rounded-menu {
  287. border-radius: 2px;
  288. }
  289.  
  290. div.branding-context-container-inner.ytp-rounded-branding-context {
  291. border-radius: 2px;
  292. }
  293.  
  294. div.iv-card.iv-card-video.ytp-rounded-info {
  295. border-radius: 0px;
  296. }
  297.  
  298. div.iv-card.iv-card-playlist.ytp-rounded-info {
  299. border-radius: 0px;
  300. }
  301.  
  302. div.iv-card.iv-card-channel.ytp-rounded-info {
  303. border-radius: 0px;
  304. }
  305.  
  306. div.iv-card.ytp-rounded-info {
  307. border-radius: 0px;
  308. }
  309.  
  310. .ytp-tooltip.ytp-rounded-tooltip.ytp-text-detail.ytp-preview, .ytp-tooltip.ytp-rounded-tooltip.ytp-text-detail.ytp-preview .ytp-tooltip-bg {
  311. border-radius: 0px;
  312. }
  313.  
  314. .ytp-ce-video.ytp-ce-medium-round, .ytp-ce-playlist.ytp-ce-medium-round, .ytp-ce-medium-round .ytp-ce-expanding-overlay-background {
  315. border-radius: 0px;
  316. }`
  317. document.head.appendChild(styles);
  318. }
  319. })();