Youtube New UI Fix

Fixes the new UI to one that resembles old one

目前为 2015-08-19 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube New UI Fix
  3. // @namespace YtNewUIFix
  4. // @description Fixes the new UI to one that resembles old one
  5. // @author Roy Scheerens
  6. // @include https://www.youtube.com/*
  7. // @version 1.8.6
  8. // @grant none
  9. // ==/UserScript==
  10. /* Original typescript code: https://copy.com/TzRldsobyPt8XcKA */
  11. var YtNewUIFix = (function () {
  12. function YtNewUIFix() {
  13. this.watchLaterAdded = false;
  14. this.playButtonReplaced = false;
  15. this.moviePlayer = document.querySelector("div.html5-video-player");
  16. var api = document.querySelector(".player-api");
  17. this.mouseMoveEvent = document.createEvent('Events');
  18. this.mouseMoveEvent.initEvent("mousemove", true, false);
  19. this.addWatchLater = this.getStorage("addWatchLater", true);
  20. this.autoHideFullScreen = this.getStorage("autoHideFullScreen", false);
  21. this.removeAllAnimations = this.getStorage("removeAllAnimations", false);
  22. }
  23. YtNewUIFix.prototype.applyFix = function () {
  24. var _this = this;
  25. this.addCSS();
  26. if (localStorage) {
  27. this.addOptions();
  28. }
  29. setInterval(function () {
  30. _this.checkMoviePlayer();
  31. _this.checkWatchLater();
  32. _this.removePlayAnim();
  33. }, 1000);
  34. };
  35. YtNewUIFix.prototype.removeSearchPlaceHolder = function () {
  36. var search = document.querySelector("input#masthead-search-term");
  37. if (search) {
  38. search.placeholder = "";
  39. }
  40. };
  41. YtNewUIFix.prototype.getStorage = function (key, defaultVal) {
  42. if (!localStorage) {
  43. return defaultVal;
  44. }
  45. var result = localStorage.getItem(key);
  46. if (result) {
  47. return result == "true";
  48. }
  49. else {
  50. return defaultVal;
  51. }
  52. };
  53. YtNewUIFix.prototype.addCSS = function () {
  54. var css = document.createElement("style");
  55. css.id = "YoutubeNewUIFix-Style";
  56. css.textContent = "/* fixing the colors */\n .ytp-chrome-bottom { background-color: #1B1B1B!important; }\n .ytp-svg-fill { fill: #8E8E8E!important; }\n #movie_player { height: calc(100% + 35px)!important; }\n .html5-video-content { background-color: black!important; }\n .ytp-panelpopup { background: rgb(28, 28, 28) none repeat scroll 0% 0%!important; }\n\n /* moving the content below down, but not when the 'Resize YT To Window Size' script is active (.ytwp-window-player) */\n body:not(.ytwp-window-player) #watch7-content, body:not(.ytwp-window-player) div.watch-stage-mode #watch7-sidebar { transform: translateY(35px)!important; }\n\n /* controls always visible */\n " + (this.autoHideFullScreen ? ".html5-video-player:not(.ytp-big-mode) " : "") + ".ytp-chrome-bottom { opacity: 1!important; }\n\n /* move controls to the right place */\n #movie_player { height: calc(100% + 35px)!important; }\n .ytp-gradient-bottom, .ytp-gradient-top, .ytp-chrome-top { display: none!important; }\n .ytp-chrome-controls { width: calc(100% + 24px)!important; transform: translateX(-12px)!important; }\n\n /* Fix the theater black bars */\n .watch-stage-mode #theater-background::after { content: ''; height: 35px; bottom: -35px; left: 0px; position: absolute; background-color: black; width: 100%; }\n\n /* scale down the controls */\n .ytp-chrome-bottom { transform: translateY(5px)!important; }\n .ytp-chrome-bottom::before {content: ''; bottom: 0px; top: -1px; left: -12px; right: -12px; position: absolute; background-color: #1B1B1B; z-index: -1000; }\n .ytp-chrome-controls { height: 31px!important; line-height: 31px!important; font-size: 11px!important; }\n .ytp-chrome-controls .ytp-button:not(.ytp-play-button):not(.ytp-watch-later-button) { width: 32px!important; }\n .ytp-play-button { width: 41px!important; }\n .ytp-progress-bar-container:not(.ytp-pulling) { height: 5px!important; }\n\n /* scale down the controls big mode */\n .ytp-big-mode .ytp-chrome-bottom { transform: translateY(24px)!important; }\n .html5-video-container { height: 100%!important; }\n .ytp-cards-button { top: 0!important } /* needed or else focusing the card will move it under the controls */\n " + (this.autoHideFullScreen ? "" : ".html5-main-video { max-height: calc(100vh - 35px)!important; }") + " /* vh instead of % because chrome is weird */\n .ytp-big-mode .ytp-progress-bar-container { transform: translateY(-1px)!important; }\n\n /* Fix the quality badge (red HD rectangle) */\n .ytp-settings-button.ytp-hd-quality-badge::after,.ytp-settings-button.ytp-4k-quality-badge::after,.ytp-settings-button.ytp-5k-quality-badge::after,.ytp-settings-button.ytp-8k-quality-badge::after\n {\n \t content:''!important;\n \t position:absolute!important;\n \t top:6px!important;\n \t right:4px!important;\n \t height:9px!important;\n \t width:13px!important;\n \t background-color:#f12b24!important;\n \t border-radius:1px!important;\n \t line-height:normal!important;\n \t background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMTMgOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCiAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBmaWxsLW9wYWNpdHk9IjAuNjQ3MSIgZmlsbD0iIzAwMDAwMCIgZD0iTTUsNyBMNiw3IEw2LDggTDUsOCBMNSw3IFogTTEwLDMgTDEwLDQgTDgsNCBMOCwzIEwxMCwzIFogTTMsNiBMMyw1IEw1LDUgTDUsNiBMMyw2IFogTTIsNyBMMyw3IEwzLDggTDIsOCBMMiw3IFogTTcsNyBMMTAsNyBMMTAsOCBMNyw4IEw3LDcgWiBNMTAsNiBMMTEsNiBMMTEsNyBMMTAsNyBMMTAsNiBaIj48L3BhdGg+DQogIDxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGRkZGRiIgZD0iTTUsNyBMNSw2IEw1LDUgTDMsNSBMMyw2IEwzLDcgTDIsNyBMMiwyIEwzLDIgTDMsNCBMNSw0IEw1LDIgTDYsMiBMNiw3IEw1LDcgWiBNMTEsNiBMMTAsNiBMMTAsNyBMNyw3IEw3LDIgTDEwLDIgTDEwLDMgTDExLDMgTDExLDYgWiBNMTAsNCBMMTAsMyBMOCwzIEw4LDQgTDgsNiBMMTAsNiBMMTAsNCBaIj48L3BhdGg+DQo8L3N2Zz4NCg==')!important;\n \t padding: 0!important;\n }\n\n /* Fix the red line under the subtitle icon */\n .ytp-chrome-controls .ytp-button[aria-pressed=\"true\"]::after\n {\n width: 17px!important;\n height: 2px!important;\n left: 8px!important;\n bottom: 7px!important;\n }\n\n /* Makes sure the captions/subtitles are at the correct height and don't move up and down */\n .ytp-player-content, .ytp-subtitles-player-content { bottom: 49px!important; }\n\n /* rules for the watch later button */\n .ytp-watch-later-button { width: 24px!important; float: right!important; margin-right: 2px!important; }\n .ytp-tooltip-image-enabled { bottom: 49px!important; top: auto!important; }\n\n /* rules for the options */\n h3.optionChanged::after { content: 'Refresh page to save changes'; color: red; position: relative; left: 15px; }\n\n /* no animations */\n " + (this.removeAllAnimations ? ".ytp-bezel { display: none!important; }" : "") + "\n " + (this.removeAllAnimations ? ".html5-video-player div { transition-property: none !important; animation: none !important; }" : "");
  57. document.head.appendChild(css);
  58. };
  59. YtNewUIFix.prototype.addOptions = function () {
  60. var content = document.querySelector("div.account-content");
  61. var footer = document.querySelector("div.account-footer");
  62. if (content && footer) {
  63. var accSection = document.createElement("div");
  64. accSection.classList.add("account-section");
  65. var header = document.createElement("h3");
  66. header.classList.add("account-section-header");
  67. header.textContent = "Youtube New UI Fix Options";
  68. accSection.appendChild(header);
  69. accSection.appendChild(this.createOption(this.addWatchLater, "addWatchLater", "Add the watch later button to the controls", header));
  70. accSection.appendChild(this.createOption(this.autoHideFullScreen, "autoHideFullScreen", "Have the controls automatically hide in full-screen mode", header));
  71. accSection.appendChild(this.createOption(this.removeAllAnimations, "removeAllAnimations", "Remove all animations", header));
  72. content.insertBefore(accSection, footer);
  73. }
  74. };
  75. YtNewUIFix.prototype.createOption = function (optionValue, name, description, changeNotifier) {
  76. var accDiv = document.createElement("div");
  77. accDiv.classList.add("account-section-setting");
  78. accDiv.innerHTML = "\n\t\t <label>\n\t\t\t <span class='yt-uix-form-input-checkbox-container " + (optionValue ? "checked" : "") + "'>\n <input class='yt-uix-form-input-checkbox' name='" + name + "' " + (optionValue ? "checked='checked'" : "") + " type='checkbox'>\n <span class='yt-uix-form-input-checkbox-element'></span>\n </span>\n\t\t\t " + description + "\n\t\t </label>";
  79. var accInput = accDiv.querySelector("input[name='" + name + "']");
  80. accInput.onclick = function () {
  81. localStorage.setItem(name, String(accInput.checked));
  82. changeNotifier.classList.add("optionChanged");
  83. };
  84. return accDiv;
  85. };
  86. YtNewUIFix.prototype.checkWatchLater = function () {
  87. if (this.addWatchLater && !this.watchLaterAdded && this.moviePlayer) {
  88. var watchLater = document.querySelector("button.ytp-watch-later-button");
  89. if (watchLater) {
  90. var qaulitybutton = (document.querySelector("button.ytp-subtitles-button") || document.querySelector("button.ytp-settings-button"));
  91. if (qaulitybutton) {
  92. qaulitybutton.parentNode.insertBefore(watchLater, qaulitybutton.nextSibling);
  93. this.watchLaterAdded = true;
  94. }
  95. }
  96. }
  97. };
  98. YtNewUIFix.prototype.checkMoviePlayer = function () {
  99. if (!this.moviePlayer || !this.moviePlayer.parentNode) {
  100. this.moviePlayer = document.querySelector("div.html5-video-player");
  101. }
  102. else if (!this.moviePlayer.classList.contains("seeking-mode") && (!this.autoHideFullScreen || !this.moviePlayer.classList.contains("ytp-fullscreen"))) {
  103. this.moviePlayer.dispatchEvent(this.mouseMoveEvent);
  104. }
  105. };
  106. YtNewUIFix.prototype.removePlayAnim = function () {
  107. if (this.removeAllAnimations && !this.playButtonReplaced) {
  108. var button = document.querySelector('button.ytp-play-button');
  109. var buttonClone = button.cloneNode(false);
  110. var video = document.querySelector("video.html5-main-video");
  111. if (button && buttonClone && video) {
  112. var svgPlay = " <svg width='100%' height='100%' viewBox='0 0 36 36' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>\n\t <defs>\n\t\t <path id='ytp-19' d='M11,10 L18,13.74 18,22.28 11,26 M18,13.74 L26,18 26,18 18,22.28'></path>\n\t </defs>\n\t <use xlink:href='#ytp-19' class='ytp-svg-shadow'></use>\n\t <use xlink:href='#ytp-19' class='ytp-svg-fill'></use>\n </svg>";
  113. var svgPause = "<svg width='100%' height='100%' viewBox='0 0 36 36' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>\n\t <defs>\n\t\t <path id='ytp-19' d='M11,10 L17,10 17,26 11,26 M20,10 L26,10 26,26 20,26'></path>\n\t </defs>\n\t <use xlink:href='#ytp-19' class='ytp-svg-shadow'></use>\n\t <use xlink:href='#ytp-19' class='ytp-svg-fill'></use>\n </svg>";
  114. var svgReplay = "<svg width='100%' height='100%' viewBox='0 0 36 36' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>\n\t <defs>\n\t\t <path id='ytp-19' d='M26.466,21.04 L30.966,16 L27.8,16 C26.873,11.435 22.841,8 18.001,8 C12.474,8 8,12.477 8,18 C8,23.523 12.474,28 18.001,28 C21.181,28 24.009,26.511 25.841,24.197 L24.005,22.361 C22.652,24.217 20.471,25.427 18.001,25.427 C13.899,25.427 10.569,22.101 10.569,18 C10.569,13.898 13.899,10.572 18.001,10.572 C21.407,10.572 24.268,12.871 25.142,16 L21.966,16 L26.466,21.04'></path>\n\t </defs>\n\t <use xlink:href='#ytp-19' class='ytp-svg-shadow'></use>\n\t <use xlink:href='#ytp-19' class='ytp-svg-fill'></use>\n </svg>";
  115. if (video.paused) {
  116. buttonClone.innerHTML = svgPlay;
  117. }
  118. else if (video.ended) {
  119. buttonClone.innerHTML = svgReplay;
  120. }
  121. else {
  122. buttonClone.innerHTML = svgPause;
  123. }
  124. video.onplay = function () { return buttonClone.innerHTML = svgPause; };
  125. video.onpause = function () { return buttonClone.innerHTML = svgPlay; };
  126. video.onended = function () { return buttonClone.innerHTML = svgReplay; };
  127. buttonClone.onclick = function () {
  128. if (video.paused) {
  129. video.play();
  130. }
  131. else {
  132. video.pause();
  133. }
  134. };
  135. button.parentElement.replaceChild(buttonClone, button);
  136. this.playButtonReplaced = true;
  137. }
  138. }
  139. };
  140. return YtNewUIFix;
  141. })();
  142. new YtNewUIFix().applyFix();
  143. //# sourceMappingURL=Youtube_New_UI_Fix.user.js.map