Block Youtube Users / Channels

Prevent from seeing videos by certain users (from recommended, search, related channels...)

Versione datata 03/08/2015. Vedi la nuova versione l'ultima versione.

  1. // ==UserScript==
  2. // @name Block Youtube Users / Channels
  3. // @author Schegge
  4. // @namespace https://greatest.deepsurf.us/en/users/12632-schegge
  5. // @description Prevent from seeing videos by certain users (from recommended, search, related channels...)
  6. // @version 2.1.6
  7. // @match *://www.youtube.com/*
  8. // @exclude *://www.youtube.com/embed/*
  9. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkMzRDhDREZEMzVGMDExRTVBOUUzRDg5MDZENTJEMTA2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkMzRDhDREZFMzVGMDExRTVBOUUzRDg5MDZENTJEMTA2Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QzNEOENERkIzNUYwMTFFNUE5RTNEODkwNkQ1MkQxMDYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QzNEOENERkMzNUYwMTFFNUE5RTNEODkwNkQ1MkQxMDYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6dWQTHAAADwklEQVR42tRaTUwTQRR+u10q5WKTclOExASMwXT1aExoQpB4UHswajyVSDx40Caa6AmrJ000URI9EJP2ZOJJiBeh/oD4c6S9iScRDxyoQQ4USuk6s4wy2c7szP6Uti95TCAz3W9nvve996YohmFAM5oKTWpNC1wTTchOTibQ8Bj5Xh+fm0e+gvwH8WniQhsYHJQDjizhM2hsUTL2kfEOGSeQZ5CP+0GV3C4y4CzyV+SZuieqkCMFZbkAwedpT6gqh3qgcqADjd1gtLWJTmQO+RA5AVfAYRv4Mqjz370pAbV+66gO5ZP95svYWJqKgcZQlcBcDvY8eAQtL16KpmYaUg617DsRBTuJQLjjuC13O/YDIM7Sx46phePCShHm7n/+CgG0duvEcd6UpHXnNT9UZePeCP3rAut4tZnZU9qb7BFlaSnE+oyW8dd2wKOug5NnRiRSpfuhoSusZJIyf4Zap6C4PlAV/IUCqD8XTdXhWIwOUs8cN9ojzhYU189zVefbvP+1itHe7lc84piZYUruWrEWwCPQSFYfOVRV5i7Y8LtK3VTJo3ViYVvp7D18ESqVXnZJ0M1btmBVN1/k0KoexfSYTr009i6l8LtV+zh7LpB9f5C1qDzQb1e/pHyXQ5xcgqPPwNg55qhVd7FaKEjqlCI7+IxQCMrx07xHTDDzgl91B8y5q34x6NLtm7zd/sNK946Dk5FsvOUABBpnXZugjPNizBlwnyURUyc4+tTMmAybsWvn6l4dqou/IHj/IQt8HwEe9tRImLa2xvwzbgoMOw1G6zAwXpWId74FlbaWYo0GH7NSRnO6O1Xa29MNpWtXJbuogtk4BBiBjD878OkLq0KMEjlM1o0qOEbwS+ITYh7/1Fve0us4F/guh4wsN85RA4xYR5rdydt1BdGKI41JetdrATyD6vGUbWWbHsOc/cCkE4oFg91Ax2ngMlTR/X4zTqMhsk6aLjLAww4fkPO0Gfb3LV2Og5OTJNxWk3Fu9Whf2rpQFY6Gu6CWbpU2Wlp3r5GofqGwzTGnSEJhXqKW+V2+q8wZEyUlFGz/d0tZXR1mrNFBcOOLC7gtMfBp3+WQSuf7iDuy0nBCNCXfUEWWCfpyQnT5CWC5M9fqCRjX45uXLshQBMDFFVxNAFeO6bAZPyNb4z+B7etm58GJj3Lj1g1mwqC1V3gbZZkvYXnPzbIED6XmOLB/PedKw3VAgiozxishGhX4XaL9OS8JKAc7X+vV0vJEOTIy9Y4M8CQB3yWbTSVtmhpz4PCqT2nWf0L4K8AAGQEtCug+rd8AAAAASUVORK5CYII=
  13. // ==/UserScript==
  14.  
  15. /****************************************
  16.  
  17. → the program is case-insensitive
  18. → split the usernames with a comma
  19. → put a * in front of a word for wildcard (only in the blacklist!), it will find the word no matter its position in the username (example: *vevo)
  20. → it also hides videos from the playlists, but it doesn't prevent them from playing if the playlist is in autoplay (download another script that disables autoplay!)
  21. → on line 187 the channels' hovercards are disabled, comment it if you want them (they seem to cause a problem on the MutationObserver, but it does NOT broke this script anyway, so whatever)
  22. → on line 190 you can change the pages in which the search is excluded
  23. → VERSION 2:
  24. # blacklist editor changed
  25. # whitelist added
  26. # no need to refresh the page after changes in the blacklist/whitelist
  27. # added ☆ button to force a new search (in case of problems?)
  28. # added button for suspend temporarily the block (to reactivate it just click on the star/save or refresh the page)
  29.  
  30. <!> please report any bugs
  31.  
  32. ****************************************/
  33.  
  34. (function($) {
  35.  
  36. // get black/whitelist saved
  37. var sBL, sWL, ytblacklist, ytwhitelist;
  38. function getValues() {
  39. sBL = GM_getValue("savedblocks", "the program is case-insensitive, split the usernames with a comma, put a * in front of a word for wildcard, it will find the word no matter its position in the username, example, *vevo, delete all of this");
  40. sWL = GM_getValue("savedwhites", "put here whitelisted usernames, if for example you blacklist *vevo, but you want to see IndilaVEVO, write here:, indilavevo, delete all of this");
  41. ytblacklist = sBL.split(",");
  42. ytwhitelist = sWL.split(",");
  43. }
  44. getValues();
  45.  
  46. // where the usernames are
  47. var uClasses = [".g-hovercard", ".branded-page-related-channels-list", ".video-uploader-byline"];
  48.  
  49. // add blacklist button to masthead
  50. $buttonB = $("<span>", {
  51. id: "yt-blacklist",
  52. html: "B",
  53. css: {
  54. "cursor": "pointer",
  55. "margin-right": "2px",
  56. "font-size": "22px",
  57. "vertical-align": "middle"
  58. }
  59. });
  60. $buttonR = $("<span>", {
  61. id: "yt-blacklist-research",
  62. html: "&#9734;",
  63. css: {
  64. "cursor": "pointer",
  65. "font-size": "12px",
  66. "vertical-align": "top",
  67. "margin-right": "5px"
  68. }
  69. });
  70. $("<span></span>").insertAfter("#upload-btn")
  71. .append($buttonB)
  72. .append($buttonR);
  73.  
  74. // elements for user input
  75. var marginright = ( $(window).width() - $buttonB.offset().left - $buttonB.outerWidth() - $buttonR.outerWidth() - 20 );
  76. var margintop = $("#yt-masthead-container").height() + parseInt($("#yt-masthead-container").css("padding-top")) + parseInt($("#yt-masthead-container").css("padding-bottom"));
  77.  
  78. $divInput = $("<div>", {
  79. id: "yt-blacklist-options",
  80. css: {
  81. "display": "none",
  82. "position": "fixed",
  83. "right": marginright + "px",
  84. "top": margintop + "px",
  85. "padding": "0 20px 15px 20px",
  86. "text-align": "center",
  87. "background-color": "#fff",
  88. "box-shadow": "0 1px 1px 0 rgba(0,0,0,.1)",
  89. "border": "1px solid #e8e8e8",
  90. "border-top": "0",
  91. "z-index": "99999999999"
  92. }
  93. });
  94. $textareaBL = $('<div style="display:inline-block; width:350px; vertical-align:top; margin:0 5px; box-sizing:border-box">' +
  95. '<div style="text-align:center; font-weight:500; margin-bottom:5px"> Blacklist </div>' +
  96. '<textarea id="blacklist-words" style="resize:vertical; width:100%; height:80px; padding:4px; border:2px solid rgba(0,0,0,.13); box-sizing:border-box">' +
  97. sBL + '</textarea></div>');
  98. $textareaWL = $('<div style="display:inline-block; width:250px; vertical-align:top; margin:0 5px; box-sizing:border-box">' +
  99. '<div style="text-align:center; font-weight:500; margin-bottom:5px"> Whitelist </div>' +
  100. '<textarea id="whitelist-words" style="resize:vertical; width:100%; height:80px; padding:4px; border:2px solid rgba(0,0,0,.13); box-sizing:border-box">' +
  101. sWL + '</textarea></div>');
  102. $saveDiv = $('<div style="clear:both; padding-bottom: 10px; margin-top:1px; text-align:right">' +
  103. '<span id="saveblacklist" style="cursor:pointer; color:#cc181e; text-shadow: 1px 1px 1px rgba(0, 0, 0, .25); border-radius:2px">' +
  104. ' save </span></div>');
  105. $suspend = $("<div id='yt-blacklist-suspend' style='cursor: pointer; font-size: 70%; opacity: .5; text-align: right; padding-top: 5px'> suspend block </div>");
  106. $saved = $('<span style="margin-right: 7px; font-size: 80%"> saved and searched again </span>');
  107. $divInput
  108. .append($saveDiv)
  109. .append($textareaWL)
  110. .append($textareaBL)
  111. .append($suspend);
  112. $("body").append($divInput);
  113.  
  114. // open and close textareas
  115. $("#yt-blacklist").click(function() {
  116. $("#yt-blacklist-options").slideToggle();
  117. });
  118.  
  119. // check if a username is whitelisted
  120. function ifWhite(u) {
  121. var whitelisted = false;
  122. for(var z = 0; z < ytwhitelist.length; z++) {
  123. var w = ytwhitelist[z].trim().toLowerCase();
  124. if (w.length && u === w) {
  125. whitelisted = true;
  126. }
  127. }
  128. return whitelisted;
  129. }
  130.  
  131. // check if a username is blacklisted
  132. function ifMatch(u) {
  133. var match = false;
  134. if ( !ifWhite(u) ) { // if the username isn't whitelisted
  135. for (var j = 0; j < ytblacklist.length; j++) {
  136. var b = ytblacklist[j].trim().toLowerCase();
  137. if ( b.charAt(0) == "*" ) { // wildcards
  138. var part = b.split("*"),
  139. item = part[1];
  140. if ( item.length && u.indexOf(item) !== -1 ) {
  141. match = true;
  142. }
  143. } else { // exact match
  144. if ( b.length && u == b ) {
  145. match = true;
  146. }
  147. }
  148. }
  149. }
  150. return match;
  151. }
  152.  
  153. // delete blacklisted
  154. function suspend(s) {
  155. $(s).each(function() {
  156. if ( $(this).siblings(".span-is-black").length ) {
  157. $(this).siblings(".span-is-black").remove();
  158. } else if ( $(this).parents(".li-is-black").length ) {
  159. $(this).parents(".li-is-black").removeClass("li-is-black").show();
  160. }
  161. });
  162. }
  163.  
  164. // do the thing
  165. function findMatch(s) {
  166. $(s).each(function() {
  167. var username = $(this).text().trim().toLowerCase();
  168.  
  169. if ( ifMatch(username) ) { // if the username is blacklisted
  170. if ( $(this).parents("#watch-header").length ) { // WATCH VIDEO
  171. if ( !$(this).siblings(".span-is-black").length ) { // check if it wasn't already blacklisted
  172. $(".yt-user-info").append("<span class=\"span-is-black\" style=\"color:rgb(204, 24, 30);font-weight:500\">BLACKLISTED!</span>");
  173. }
  174. } else { // SEARCH, RECOMMENDED, etc...
  175. if ( !$(this).parents(".li-is-black").length ) { // check if it wasn't already blacklisted
  176. $(this).closest("li").addClass("li-is-black").hide();
  177. }
  178. }
  179. } else { // if a previous black/whitelist word is deleted/added
  180. suspend(this);
  181. }
  182. });
  183. }
  184.  
  185. // the final search function
  186. function search() {
  187. if ( yt.config_.UNIVERSAL_HOVERCARDS ) { yt.config_.UNIVERSAL_HOVERCARDS = false; }
  188.  
  189. var url = window.location.pathname;
  190. if ( url != ( "/feed/history" || "/playlist?list=WL" || "/feed/subscriptions" ) ) {
  191. for (var i = 0; i < uClasses.length; i++) {
  192. findMatch(uClasses[i]);
  193. }
  194. }
  195. }
  196.  
  197. // search when youtube is first opened
  198. search();
  199.  
  200. // save blacklist changes and research
  201. $("#saveblacklist").click(function() {
  202. GM_setValue("savedblocks", $('#blacklist-words').val());
  203. GM_setValue("savedwhites", $('#whitelist-words').val());
  204. getValues();
  205. search();
  206. $(this).before($saved);
  207. setTimeout(function() {
  208. $saved.remove();
  209. }, 2000);
  210. });
  211.  
  212. // research when $buttonR is clicked
  213. $("#yt-blacklist-research").click(function() {
  214. search();
  215. });
  216.  
  217. // suspend the block when $suspend is clicked
  218. $("#yt-blacklist-suspend").click(function() {
  219. for (var i = 0; i < uClasses.length; i++) {
  220. suspend(uClasses[i]);
  221. }
  222. });
  223.  
  224. // research after every change in #content
  225. var target = document.querySelector('#content');
  226. var observer = new MutationObserver(function(mutations) {
  227. mutations.forEach(function(mutation) {
  228. search();
  229. });
  230. });
  231. var config = { attributes: true, childList: true, characterData: true };
  232. observer.observe(target, config);
  233.  
  234. })(window.jQuery);