YouTube - Button Container (@require)

Creates a button container, under the video, onto which buttons can be added

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greatest.deepsurf.us/scripts/9004/44606/YouTube%20-%20Button%20Container%20%28%40require%29.js

  1. // ==UserScript==
  2. // @name YouTube - Button Container (@require)
  3. // @namespace https://greatest.deepsurf.us/en/users/10166-moriarty
  4. // @description Creates a button container, under the video, onto which buttons can be added
  5. // @include http://*.youtube.com/*
  6. // @include http://youtube.com/*
  7. // @include https://*.youtube.com/*
  8. // @include https://youtube.com/*
  9. // @copyright CodeFelony
  10. // @author Moriarty
  11. // @version 1.0.0
  12. // @license LGPL version 3 or any later version; http://www.gnu.org/copyleft/lgpl.html
  13. // @grant GM_addStyle
  14. // ==/UserScript==
  15.  
  16. var addButtonToContainer = (function () {
  17. 'use strict';
  18.  
  19. var rYoutubeWhitelistedUrls = /^https?:\/\/([^\.]+\.)?youtube\.com\/(watch|user\/|channel\/)/;
  20.  
  21. var TEST_MODE = false; // if true, will replace the current style with this one
  22.  
  23. // helper functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  24. function addStyle(contents) {
  25. var head = document.head || query('html > head'),
  26. style = document.createElement('style');
  27.  
  28. style.id = 'underMovieDivStyle';
  29. style.type = 'text/css';
  30. style.appendChild( document.createTextNode(contents) );
  31.  
  32. if (head) {
  33. head.appendChild(style);
  34. }
  35. }
  36. function id(name) {
  37. return document.getElementById(name);
  38. }
  39. function query(name) {
  40. return document.querySelector(name);
  41. }
  42. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  43.  
  44. function waitForHeadReady() {
  45. if ( document.head || query('html > head') ) {
  46. window.setTimeout(handleStyleCreation, TEST_MODE === true ? 3000 : 0);
  47. } else {
  48. window.setTimeout(waitForHeadReady, 200);
  49. }
  50. }
  51.  
  52. function handleStyleCreation() {
  53. var umdv = id('underMovieDivStyle'),
  54. obs = new MutationObserver(function (mutations) {
  55. mutations.forEach(function (mutation) {
  56. if (mutation.target.id === 'underMovieDivStyle') {
  57. handleStyleCreation();
  58. }
  59. });
  60. });
  61.  
  62. if (TEST_MODE === true || !umdv) {
  63. if (umdv) {
  64. umdv.parentNode.removeChild(umdv);
  65. }
  66.  
  67. addStyle('' +
  68. '#under-movie-div { ' +
  69. 'background: transparent !important; ' +
  70. 'display: block; ' +
  71. 'padding-top: 4px; ' +
  72. 'padding-bottom: 8px; ' +
  73. 'text-align: left; ' +
  74. 'z-index: 999999; ' +
  75. '}\n\n' +
  76. '.under-movie-div-button { ' +
  77. 'background-image: linear-gradient(to top, #F6F6F6 0px, #FCFCFC 100%) !important; ' +
  78. 'border: 1px solid #CCCCCC; ' +
  79. 'border-radius: 2px; ' +
  80. 'color: #666666 !important; ' +
  81. 'font-size: 12px !important; ' +
  82. 'font-family: arial, sans-serif !important; ' +
  83. 'font-weight: 400 !important; ' +
  84. 'height: auto !important; ' +
  85. 'line-height: 20px !important; ' +
  86. 'margin-right: 6px; ' +
  87. 'padding: 2px 10px !important; ' +
  88. '}\n\n' +
  89. // - - - - - - - - - - - - - - - - - - -
  90. '#watch7-headline { ' +
  91. 'padding: 4px 0 !important; ' +
  92. '}\n\n' +
  93. '#watch7-headline h1 { ' +
  94. 'text-align: center; ' +
  95. 'width: 100%; ' +
  96. '}\n\n' +
  97. '#upsell-video { ' +
  98. 'overflow: visible !important; ' + // allow the button container to show on non-video pages
  99. '}' +
  100. '');
  101.  
  102. // observe the style for changes if test mode enabled
  103. if (TEST_MODE === true) {
  104. obs.observe(id('underMovieDivStyle'), {
  105. childList : true,
  106. attributes : true,
  107. characterData : true
  108. });
  109. }
  110. }
  111. }
  112.  
  113. function handleContainerCreation() {
  114. var holder = query('#watch7-headline, #gh-overviewtab div.c4-spotlight-module-component'),
  115. container = id('under-movie-div');
  116.  
  117. if (container == null) {
  118. container = document.createElement('div');
  119. container.id = 'under-movie-div';
  120.  
  121. if (holder) {
  122. holder.appendChild(container);
  123. }
  124. }
  125.  
  126. return container;
  127. }
  128.  
  129. function add(text, onclick, ID) {
  130. var upsellVideo = id('upsell-video'),
  131. container = handleContainerCreation(),
  132. button = document.createElement('button'),
  133. span = document.createElement('span');
  134. ID = ID || text.replace(/[^a-zA-Z0-9-_]/, '');
  135.  
  136. if ( !location.href.match(rYoutubeWhitelistedUrls) || id(ID) ) { return; }
  137. if (typeof text !== 'string' || typeof onclick !== 'function') { return; }
  138.  
  139. span.setAttribute('class', 'yt-uix-button-content');
  140. span.appendChild( document.createTextNode(text) );
  141.  
  142. button.id = ID;
  143. button.addEventListener('click', function () {
  144. window.setTimeout(onclick, 0);
  145. }, false);
  146.  
  147. button.type = 'button';
  148. button.setAttribute('class', 'under-movie-div-button yt-uix-button yt-uix-button-text yt-uix-tooltip');
  149. button.appendChild(span);
  150.  
  151. return container.appendChild(button);
  152. }
  153.  
  154. waitForHeadReady();
  155.  
  156. return add;
  157. }());
  158.  
  159. /* EXAMPLE BUTTON
  160. addButtonToContainer('A Test Button', function () { alert('Test.'); }, 'test-button');
  161. */