Youtube Centered

Center aligns the Youtube page

  1. // ==UserScript==
  2. // @name Youtube Centered
  3. // @namespace http://userscripts.org/users/zackton
  4. // @description Center aligns the Youtube page
  5. // @include *.youtube.com/*
  6. // @include *.youtube.com/
  7. // @run-at document-start
  8. // @grant none
  9. // @version 2.5
  10. // ==/UserScript==
  11.  
  12. // My precious...
  13. var YC = {};
  14.  
  15. /**
  16. * Show two columns for subscriptions, history, social {true, false}
  17. * Will make those pages wider.
  18. **/
  19. YC.doublecolumn = false;
  20. YC.doublecolumn_pages = ['watchlater', 'history', 'subscriptions', 'social', 'whattowatch'];
  21.  
  22. /**
  23. * Shift the video page if it doesn't look centered to you {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
  24. * watchshift = 1: 100px left shifted
  25. * watchshift = 2: 80px left shifted
  26. * watchshift = 3: 60px left shifted
  27. * watchshift = 4: 40px left shifted
  28. * watchshift = 5: 20px left shifted
  29. * watchshift = 6: Standard
  30. * watchshift = 7: 20px right shifted
  31. * watchshift = 8: 40px right shifted
  32. * watchshift = 9: 60px right shifted
  33. * watchshift = 10: 80px right shifted
  34. * watchshift = 11: 100px right shifted
  35. **/
  36. YC.watchshift = 6;
  37.  
  38. /**
  39. * Watch page size {1, 2, 3, 4}
  40. * watchsize = 1: 1003px, same as homepage.
  41. * watchsize = 2: 1203px, test size.
  42. * watchsize = 3: 1403px, test size.
  43. * watchsize = 4: 1485px, default size when left aligned on 1920x1280 resolution.
  44. * Note: Even if you pick options 1 or 2, the video page elements will still push the content width to around 1305px.
  45. **/
  46. YC.watchsize = 4;
  47.  
  48. /**
  49. * Flex-width page size {1, 2, 3, 4, 5}
  50. * flexsize = 1: Page width fixed to 1003px, default Youtube homepage size
  51. * flexsize = 2: Page width fixed to 1203px, test size
  52. * flexsize = 3: Page width fixed to 1403px, test size
  53. * flexsize = 4: Page width fixed to 1485px, default size when left aligned on 1920x1280 resolution.
  54. * flexsize = 5: Page width allowed to expand based on browser width
  55. **/
  56. YC.flexsize = 5;
  57.  
  58. /**
  59. * Default page size {1, 2, 3, 4}
  60. * defaultsize = 1: 1003px, default homepage.
  61. * defaultsize = 2: 1203px, test size.
  62. * defaultsize = 3: 1403px, test size.
  63. * defaultsize = 4: 1485px, video watch page size when left aligned on 1920x1280 resolution.
  64. * If YC.doublecolumn is set to TRUE, this will default to 3.
  65. **/
  66. YC.defaultsize = 1;
  67.  
  68. /**
  69. * Parameters for monitoring content width change after page load for flex-width pages
  70. * Checks once every YC.cmonitor_delay, YC.cmonitor_max times.
  71. **/
  72. YC.cmonitor_max = 30;
  73. YC.cmonitor_delay = 100;
  74. YC.cmonitor_count = 0;
  75. YC.cmonitor_width = 0;
  76.  
  77. /**
  78. * Makes the dislike bar red like it used to be.
  79. * Why? Because red bars are easier to see.
  80. **/
  81. YC.showdislikebar = true;
  82.  
  83. // Player width used for monitoring player size changes
  84. YC.playerwidth = 0;
  85.  
  86. // Size options (0 is just a placeholder to allow human-friendly option choices)
  87. YC.sizeoptions = [0, 1003, 1203, 1403, 1485];
  88.  
  89. // Shift options for video watch pages
  90. YC.shiftoptions = [0, -100, -80, -60, -40, -20, 0, 20, 40, 60, 80, 100];
  91.  
  92. // Initialize
  93. YC.init = function() {
  94. // Make sure we're not embedded
  95. if (window.top !== window.self) {
  96. return false;
  97. }
  98. // Determine page type
  99. if (window.location.pathname == '/watch') {
  100. this.pagetype = 'watch';
  101. }
  102. else if (window.location.pathname == '/feed/watch_later') {
  103. this.pagetype = 'watchlater';
  104. }
  105. else if (window.location.pathname == '/feed/history') {
  106. this.pagetype = 'history';
  107. }
  108. else if (window.location.pathname == '/feed/subscriptions') {
  109. this.pagetype = 'subscriptions';
  110. }
  111. else if (window.location.pathname == '/feed/what_to_watch') {
  112. this.pagetype = 'whattowatch';
  113. }
  114. else if (window.location.pathname == '/feed/social') {
  115. this.pagetype = 'social';
  116. }
  117. else if (window.location.pathname == '/my_subscriptions') {
  118. this.pagetype = 'mysubscriptions';
  119. }
  120. else {
  121. this.pagetype = 'default';
  122. }
  123. // Check for main elements
  124. this.params = {}
  125. this.params.flexwidth = document.body.className.indexOf('flex-width-enabled') > -1 ? true : false;
  126. this.params.guideenabled = document.body.className.indexOf('guide-enabled') > -1 ? true : false;
  127. this.params.guideexpanded = document.body.className.indexOf('guide-expanded') > -1 ? true : false;
  128. this.params.sidebarexpanded = document.body.className.indexOf('sidebar-expanded') > -1 ? true : false; // Video pages (exclusive?)
  129.  
  130. this.params.pagecontainer = document.getElementById('page-container') ? true : false;
  131. this.params.page = document.getElementById('page') ? true : false;
  132. this.params.guide = document.getElementById('guide') ? true : false;
  133. this.params.content = document.getElementById('content') ? true : false;
  134. this.params.masthead = document.getElementById('yt-masthead') ? true : false;
  135. this.params.subnav = document.getElementById('masthead-subnav') ? true : false; // Inbox
  136. this.params.alerts = document.getElementById('alerts') ? true : false;
  137. this.params.footer = document.getElementById('footer') ? true : false;
  138. //console.log(this.pagetype);
  139. //console.log(this.params);
  140. return true;
  141. }
  142.  
  143. // Center page elements
  144. YC.centerPage = function() {
  145. // Guide
  146. if (this.params.guide) {
  147. document.getElementById('guide').style.width = '175px';
  148. }
  149. // Footer
  150. if (this.params.footer) {
  151. document.getElementById('footer').style.textAlign = 'center';
  152. }
  153. // Add styles to head
  154. var styles = [{'elem': '#yt-masthead', 'css': '{margin-left:auto !important; margin-right:auto !important; position:relative;}'},
  155. {'elem': '#yt-masthead-content', 'css': '{max-width:none;}'},
  156. {'elem': '#masthead-subnav', 'css': '{margin-left:auto !important; margin-right:auto !important;}'},
  157. {'elem': '#alerts', 'css': '{margin-left:auto !important; margin-right:auto !important;}'},
  158. {'elem': '#page', 'css': '{margin-left:auto !important; margin-right:auto !important; position:relative;}'},
  159. {'elem': '#baseDiv', 'css': '{margin-left:auto !important; margin-right:auto !important;}'}
  160. ];
  161. var selectors = ['', '.guide-enabled', '.guide-expanded', '.guide-collapsed', '.sidebar-expanded', '.flex-width-enabled'];
  162. for (var i = 0; i < styles.length; i++) {
  163. for (var j = 0; j < selectors.length; j++) {
  164. this.addNewStyle('.site-left-aligned' + selectors[j] + ' ' + styles[i].elem + styles[i].css);
  165. }
  166. }
  167. }
  168.  
  169. // Set widths for page elements
  170. YC.setWidths = function() {
  171. // If flex-width, wait for page to settle on a size
  172. if (this.params.flexwidth && this.flexsize == 5) {
  173. var content_width = parseInt(window.getComputedStyle(document.getElementById('content')).getPropertyValue('width'));
  174. if ( (this.cmonitor_width !== content_width) && (this.cmonitor_count++ < this.cmonitor_max) ) {
  175. this.cmonitor_width = content_width;
  176. setTimeout(function() {
  177. YC.setWidths();
  178. }, YC.cmonitor_delay);
  179. return true;
  180. }
  181. }
  182. // Set content width
  183. if (this.params.flexwidth) {
  184. if (this.flexsize < 5) {
  185. // Fixed flex-width
  186. var content_width = this.params.guide ? this.sizeoptions[this.flexsize] - 180 : this.sizeoptions[this.flexsize];
  187. document.getElementById('content').style.width = content_width + 'px';
  188. }
  189. else {
  190. // Variable flex-width, do nothing
  191. }
  192. }
  193. else if (this.params.content) {
  194. if (this.params.sidebarexpanded) {
  195. // Watch page content width
  196. var content_width = this.params.guide ? this.sizeoptions[this.watchsize] - 180 : this.sizeoptions[this.watchsize];
  197. }
  198. else {
  199. if (this.doublecolumn && this.doublecolumn_pages.indexOf(this.pagetype) > -1) {
  200. // Double column width
  201. var content_width = this.params.guide ? this.sizeoptions[3] - 180 : this.sizeoptions[3];
  202. }
  203. else {
  204. // Standard page content width
  205. var content_width = this.params.guide ? this.sizeoptions[this.defaultsize] - 180 : this.sizeoptions[this.defaultsize];
  206. }
  207. }
  208. document.getElementById('content').style.width = content_width + 'px';
  209. }
  210.  
  211. // Set page and masthead width based on content and guide widths
  212. var pagewidth = 0;
  213. pagewidth = this.params.guide ? parseInt(window.getComputedStyle(document.getElementById('guide')).getPropertyValue('width')) : 0;
  214. pagewidth += this.params.content ? parseInt(window.getComputedStyle(document.getElementById('content')).getPropertyValue('width')) : 0;
  215. pagewidth += this.pagetype == 'mysubscriptions' ? 1003 : '';
  216. this.params.page ? document.getElementById('page').style.width = pagewidth + 'px' : '';
  217. this.params.masthead ? document.getElementById('yt-masthead').style.width = pagewidth + 'px' : '';
  218.  
  219. // Fix minor offsets based on page type
  220. this.fixOffsets();
  221. }
  222.  
  223. // Fix minor offsets based on page type
  224. YC.fixOffsets = function() {
  225. switch (this.pagetype) {
  226. case 'watch':
  227. // User defined offset
  228. var usershift = this.shiftoptions[this.watchshift];
  229. // Page required offset, corresponding to video watch size
  230. var offsets = [0, -152, -52, 48, 89];
  231. // Page offset
  232. document.getElementById('page').style.left = (usershift + offsets[this.watchsize]) + 'px';
  233. // Masthead size and offset (specifically for video pages)
  234. document.getElementById('yt-masthead').style.width = '1185px';
  235. document.getElementById('yt-masthead').style.left = (usershift - 13) + 'px';
  236. break;
  237. case 'subscriptions':
  238. case 'history':
  239. case 'watchlater':
  240. if (this.doublecolumn) {
  241. // Double column
  242. this.addNewStyle('.feed-list li.feed-list-item {float:left; display:block; width:475px; padding-top:10px;}');
  243. this.addNewStyle('.feed-list li.feed-list-item:first-child {padding-top:10px !important;}');
  244. this.addNewStyle('.feed-list li.feed-list-item:hover {background-color:#f8f8f8;}');
  245. this.addNewStyle('.feed-list .feed-item-content {height:116px;}');
  246. this.addNewStyle('.feed-load-more-container {clear:both;}');
  247. }
  248. break;
  249. case 'social':
  250. if (this.doublecolumn) {
  251. // Double column
  252. this.addNewStyle('.feed-list li.feed-list-item {float:left; display:block; width:475px; padding-top:10px;}');
  253. this.addNewStyle('.feed-list li.feed-list-item:first-child {padding-top:10px !important;}');
  254. this.addNewStyle('.feed-list li.feed-list-item:hover {background-color:#f8f8f8;}');
  255. this.addNewStyle('.feed-list .feed-item-main-content {height:84px;}');
  256. this.addNewStyle('.feed-load-more-container {clear:both;}');
  257. }
  258. break;
  259. case 'whattowatch':
  260. if (this.doublecolumn) {
  261. // Double column
  262. this.addNewStyle('.feed-list li.feed-list-item {float:left; display:block; width:475px; padding-top:10px;}');
  263. this.addNewStyle('.feed-list li.feed-list-item:first-child {padding-top:10px !important;}');
  264. this.addNewStyle('.feed-list li.feed-list-item:hover {background-color:#f8f8f8;}');
  265. this.addNewStyle('.feed-list .feed-item-main {height:155px;}');
  266. this.addNewStyle('.feed-load-more-container {clear:both;}');
  267. }
  268. var els = document.getElementsByClassName('feed-list-item');
  269. //console.log(els.length);
  270. for (var i = 0; i < els.length; i++) {
  271. if (els[i].getElementsByClassName('shelf-wrapper').length) {
  272. els[i].style.width = '950px';
  273. els[i].getElementsByClassName('feed-item-main') ? els[i].getElementsByClassName('feed-item-main')[0].style.height = 'auto' : '';
  274. }
  275. }
  276. break;
  277. case 'default':
  278. // Nothing for now
  279. break;
  280. }
  281. }
  282.  
  283. // Make the dislike bar red like it used to be
  284. YC.showDislikes = function() {
  285. var els = document.getElementsByClassName('video-extras-sparkbar-dislikes');
  286. for (var i = 0; i < els.length; i++) {
  287. els[i].style.backgroundColor = '#bc281c';
  288. }
  289. }
  290.  
  291. // Add css style to head
  292. YC.addNewStyle = function(newStyle) {
  293. var styleElement = document.getElementById('styles_js');
  294. if (!styleElement) {
  295. styleElement = document.createElement('style');
  296. styleElement.type = 'text/css';
  297. styleElement.id = 'styles_js';
  298. document.getElementsByTagName('head')[0].appendChild(styleElement);
  299. }
  300. styleElement.appendChild(document.createTextNode(newStyle));
  301. }
  302.  
  303. // Main
  304. function main() {
  305. if (YC.init()) {
  306. YC.centerPage();
  307. YC.setWidths();
  308. if (YC.pagetype == 'watch' && YC.showdislikebar) {
  309. YC.showDislikes();
  310. }
  311. }
  312. }
  313.  
  314. if (window.opera) {
  315. // Opera's greasemonkey version of addEventListener() breaks try-catch on error, so it must be called first.
  316. try {
  317. document.addEventListener('DOMContentLoaded', main(), false)
  318. }
  319. catch(err) {
  320. document.addEventListener('DOMContentLoaded', main, false)
  321. }
  322. }
  323. else {
  324. // FF, Chrome
  325. document.addEventListener('DOMContentLoaded', main, false);
  326. }