YouTube - whitelist channels in uBlock

Helps whitelist YouTube channels in uBlock

  1. // ==UserScript==
  2. // @name YouTube - whitelist channels in uBlock
  3. // @namespace https://github.com/SivaMachina
  4. // @author Siva Machina
  5. // @credits Alex Vallet, Gantt, Gingerbread Man
  6. // @description Helps whitelist YouTube channels in uBlock
  7. // @include http://*.youtube.com/*
  8. // @include https://*.youtube.com/*
  9. // @version 1.0
  10. // @grant none
  11. // @license http://creativecommons.org/licenses/by-sa/4.0/
  12. // @supportURL none
  13. // ==/UserScript==
  14.  
  15. // For static pages
  16. var uo = document.querySelector('#watch7-content link[href*="/user/"]');
  17. var uv = document.querySelector('.yt-user-info > a[href*="/channel/"]');
  18. if (uo) {
  19. addMenu();
  20. var ut = uo.href.slice(uo.href.lastIndexOf("/")+1);
  21. if (location.href.search("&user=") == -1) location.replace(location.href+"&user="+ut);
  22. }
  23. else if (uv) {
  24. addMenu();
  25. var ut = uv.textContent;
  26. if (location.href.search("&user=") == -1) location.replace(location.href+"&user="+ut);
  27. }
  28.  
  29. // For dynamic content changes, like when clicking a video on the main page.
  30. // This bit is based on Gantt's excellent Download YouTube Videos As MP4 script:
  31. // https://github.com/gantt/downloadyoutube
  32. var observer = new MutationObserver(function(mutations) {
  33. mutations.forEach(function(mutation) {
  34. if (mutation.addedNodes !== null) {
  35. for (i = 0; i < mutation.addedNodes.length; i++) {
  36. if (mutation.addedNodes[i].id == "watch7-container") {
  37. addMenu();
  38. var uo = document.querySelector('#watch7-content link[href*="/user/"]');
  39. var uv = document.querySelector('.yt-user-info > a[href*="/channel/"]');
  40. if (uo) {
  41. addMenu();
  42. var ut = uo.href.slice(uo.href.lastIndexOf("/")+1);
  43. if (location.href.search("&user=") == -1) location.replace(location.href+"&user="+ut);
  44. break;
  45. }
  46. else if (uv) {
  47. addMenu();
  48. var ut = uv.textContent;
  49. if (location.href.search("&user=") == -1) location.replace(location.href+"&user="+ut);
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. });
  56. });
  57. observer.observe(document.body, {childList: true, subtree: true});
  58.  
  59. // Add the context menu to the user name below the video
  60. // Only works in Firefox
  61. function addMenu() {
  62.  
  63. var uh = document.getElementById("watch7-user-header");
  64. var menu = document.createElement("menu");
  65. menu.setAttribute("id", "abpfilter");
  66. menu.setAttribute("type", "context");
  67. var mione = document.createElement("menuitem");
  68. // uBlock is registered under the GPLv3 license
  69. mione.setAttribute("label", "Ublock: toggle whitelist filter uBlock");
  70. mione.setAttribute("icon","data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgd2lkdGg9IjEyOCIKICAgaGVpZ2h0PSIxMjgiCiAgIGlkPSJzdmcyIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDguNCByOTkzOSIKICAgc29kaXBvZGk6ZG9jbmFtZT0idWJsb2NrLnN2ZyIKICAgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSIvaG9tZS9yaGlsbC9wZXJtYWhvbWUvd29ya3Nob3AvdWJsb2NrL3NyYy9pbWcvaWNvbl8xNi5wbmciCiAgIGlua3NjYXBlOmV4cG9ydC14ZHBpPSIxMS4yNSIKICAgaW5rc2NhcGU6ZXhwb3J0LXlkcGk9IjExLjI1Ij4KICA8ZGVmcwogICAgIGlkPSJkZWZzNCI+CiAgICA8bGluZWFyR3JhZGllbnQKICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgIGlkPSJsaW5lYXJHcmFkaWVudDM3NzAiPgogICAgICA8c3RvcAogICAgICAgICBzdHlsZT0ic3RvcC1jb2xvcjojMDAwMDAwO3N0b3Atb3BhY2l0eToxOyIKICAgICAgICAgb2Zmc2V0PSIwIgogICAgICAgICBpZD0ic3RvcDM3NzIiIC8+CiAgICAgIDxzdG9wCiAgICAgICAgIHN0eWxlPSJzdG9wLWNvbG9yOiMwMDAwMDA7c3RvcC1vcGFjaXR5OjA7IgogICAgICAgICBvZmZzZXQ9IjEiCiAgICAgICAgIGlkPSJzdG9wMzc3NCIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8aW5rc2NhcGU6cGF0aC1lZmZlY3QKICAgICAgIGlzX3Zpc2libGU9InRydWUiCiAgICAgICBpZD0icGF0aC1lZmZlY3QzOTk1IgogICAgICAgZWZmZWN0PSJzcGlybyIgLz4KICAgIDxyYWRpYWxHcmFkaWVudAogICAgICAgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIgogICAgICAgeGxpbms6aHJlZj0iI2xpbmVhckdyYWRpZW50Mzc3MCIKICAgICAgIGlkPSJyYWRpYWxHcmFkaWVudDM3NzYiCiAgICAgICBjeD0iODIuMTQ1NDIyIgogICAgICAgY3k9IjgxLjA1NTE5NyIKICAgICAgIGZ4PSI4Mi4xNDU0MjIiCiAgICAgICBmeT0iODEuMDU1MTk3IgogICAgICAgcj0iMjIuNTczMzIzIgogICAgICAgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLDAsMCwxLjI1ODQzMTgsMCwtMjAuOTQ3MjM4KSIKICAgICAgIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiAvPgogIDwvZGVmcz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjNDA0MDQwIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjIiCiAgICAgaW5rc2NhcGU6Y3g9Ijc1LjM4MjYyMyIKICAgICBpbmtzY2FwZTpjeT0iMTE1LjEwMjcxIgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJweCIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9InRydWUiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxODA0IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMzAiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjYiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjI1IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjAiCiAgICAgZml0LW1hcmdpbi10b3A9IjUiCiAgICAgZml0LW1hcmdpbi1sZWZ0PSI1IgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjUiCiAgICAgZml0LW1hcmdpbi1ib3R0b209IjUiCiAgICAgaW5rc2NhcGU6c25hcC1iYm94PSJ0cnVlIgogICAgIHNob3dndWlkZXM9InRydWUiCiAgICAgaW5rc2NhcGU6Z3VpZGUtYmJveD0idHJ1ZSIKICAgICBzaG93Ym9yZGVyPSJ0cnVlIgogICAgIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSJmYWxzZSIKICAgICBib3JkZXJsYXllcj0iZmFsc2UiPgogICAgPGlua3NjYXBlOmdyaWQKICAgICAgIHR5cGU9Inh5Z3JpZCIKICAgICAgIGlkPSJncmlkMzA1OSIKICAgICAgIGVtcHNwYWNpbmc9IjgiCiAgICAgICB2aXNpYmxlPSJ0cnVlIgogICAgICAgZW5hYmxlZD0idHJ1ZSIKICAgICAgIHNuYXB2aXNpYmxlZ3JpZGxpbmVzb25seT0idHJ1ZSIKICAgICAgIGRvdHRlZD0iZmFsc2UiIC8+CiAgPC9zb2RpcG9kaTpuYW1lZHZpZXc+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgICA8ZGM6ZGVzY3JpcHRpb24+VXNlIGdyYXkgNTAlIGZvciB0aGUgJnF1b3Q7b2ZmJnF1b3Q7IGNvbG9yPC9kYzpkZXNjcmlwdGlvbj4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0icG9seWdvbiIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgc3R5bGU9ImRpc3BsYXk6aW5saW5lIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNy44NzI1NDgsLTE3LjMyNTM1KSI+CiAgICA8cGF0aAogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIGlkPSJwYXRoMzc4OCIKICAgICAgIGQ9Im0gMTkuMzcyNTU0LDU0LjEwNzYxMiAwLDU0LjQzNTQ4OCAzNS4yODIyNTUsMzUuMjgyMjQgNTQuNDM1NDkxLDAgMzUuMjgyMjQsLTM1LjI4MjI0IDAsLTU0LjQzNTQ4OCAtMzUuMjgyMjQsLTM1LjI4MjI1NiAtNTQuNDM1NDkxLDAgeiIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjMuMDAwMDEyODY5OTk5OTk5OTQ7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46bWl0ZXI7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2Utb3BhY2l0eToxO3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtkaXNwbGF5OmlubGluZSIKICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2NjY2NjIgogICAgICAgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSIvaG9tZS9yaGlsbC9wZXJtYWhvbWUvd29ya3Nob3AvdWJsb2NrL3BsYXRmb3JtL2Nocm9taXVtL2ltZy9icm93c2VyaWNvbnMvaWNvbjM4LW9mZi5wbmciCiAgICAgICBpbmtzY2FwZTpleHBvcnQteGRwaT0iMjYuNzE5OTk5IgogICAgICAgaW5rc2NhcGU6ZXhwb3J0LXlkcGk9IjI2LjcxOTk5OSIgLz4KICAgIDxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuOTUwMjk1MzksMS4wNTIzMDQ0KSIKICAgICAgIHN0eWxlPSJmb250LXNpemU6MTAwLjIxOTQ1OTUzcHg7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDt0ZXh0LWFsaWduOmNlbnRlcjtsaW5lLWhlaWdodDoxMjUlO2xldHRlci1zcGFjaW5nOjBweDt3b3JkLXNwYWNpbmc6MHB4O3RleHQtYW5jaG9yOm1pZGRsZTtmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjEuOTk5OTk5NzY7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2Utb3BhY2l0eToxO2ZvbnQtZmFtaWx5OlVidW50dTstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOlVidW50dSIKICAgICAgIGlkPSJ0ZXh0MzgzMiI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Im0gMTEwLjM1Nzg0LDEwMi4yMzU4NiBjIC0yLjQ1NzUxLDAuNTM2MjUgLTUuNzAzNDUsMS4xMDQ2MiAtOS43Mzc4MiwxLjcwNTA5IC00LjAzNDQ2NSwwLjYwMDQ4IC04LjcwMjU5MywwLjkwMDcyIC0xNC4wMDQzOTgsMC45MDA3MiAtNC42MTAxMjUsMCAtOC40OTAzNjIsLTAuNTg0MTcgLTExLjY0MDcyNSwtMS43NTI1IC0zLjE1MDQwNywtMS4xNjgzMyAtNS42ODU4NCwtMi44MjE5MyAtNy42MDYzMDUsLTQuOTYwODA5IC0xLjkyMDQ5NCwtMi4xMzg4NzIgLTMuMzAzNDA2LC00LjY2MTA3NSAtNC4xNDg3MzUsLTcuNTY2NjE4IC0wLjg0NTM1LC0yLjkwNTUxNiAtMS4yNjgwMTksLTYuMTI5MTI1IC0xLjI2ODAxLC05LjY3MDgzNSBsIDAsLTI5LjI2MzI5OSAxMC43MTc0MTYsMCAwLDI3LjI2MDAxMSBjIC0xLjllLTUsNi4zNDUyOTMgMS4xNTI1MDQsMTAuODg3NjA0IDMuNDU3NTcyLDEzLjYyNjk0NyAyLjMwNTAyMiwyLjczOTM2NSA2LjE4NTg0Niw0LjEwOTA0MSAxMS42NDI0ODMsNC4xMDkwMzQgMS4xNTEzMTYsN2UtNiAyLjM0MTk0NCwtMC4wMzMxMyAzLjU3MTg4NiwtMC4wOTk0IDEuMjI5ODY3LC0wLjA2NjI2IDIuMzgyMzksLTAuMTQ5MzQ4IDMuNDU3NTcyLC0wLjI0OTI2NSAxLjA3NTA5OCwtMC4wOTk5IDIuMDU0Njg1LC0wLjIwMDMyMSAyLjkzODc2LC0wLjMwMTI1NyAwLjg4Mzk4NiwtMC4xMDA5MjIgMS41MTgyODQsLTAuMjE3NjUyIDEuOTAyODk2LC0wLjM1MDE5NCBsIDAsLTQzLjk5NTg3NyAxMC43MTc0MDgsMCB6IgogICAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoxLjk5OTk5OTc2O2ZvbnQtZmFtaWx5OlVidW50dTstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOlVidW50dSIKICAgICAgICAgaWQ9InBhdGgyOTkzIgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgICA8dGV4dAogICAgICAgICB4bWw6c3BhY2U9InByZXNlcnZlIgogICAgICAgICBzdHlsZT0iZm9udC1zaXplOjQwcHg7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2xpbmUtaGVpZ2h0OjEyNSU7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO2ZvbnQtZmFtaWx5OlNhbnMiCiAgICAgICAgIHg9Ijk1LjUiCiAgICAgICAgIHk9IjkwLjUiCiAgICAgICAgIGlkPSJ0ZXh0Mjk5MiIKICAgICAgICAgc29kaXBvZGk6bGluZXNwYWNpbmc9IjEyNSUiCiAgICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMDUyMzA0NCwwLDAsMC45NTAyOTUzNywxOC44MDczNjEsMTYuNDY0MikiPjx0c3BhbgogICAgICAgICAgIHNvZGlwb2RpOnJvbGU9ImxpbmUiCiAgICAgICAgICAgaWQ9InRzcGFuMjk5NCI+PC90c3Bhbj48L3RleHQ+CiAgICAgIDxwYXRoCiAgICAgICAgIHNvZGlwb2RpOnR5cGU9ImFyYyIKICAgICAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2ZmZmZmZjtzdHJva2Utd2lkdGg6NC4wNDUyMDA4MjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1vcGFjaXR5OjE7c3Ryb2tlLWRhc2hhcnJheTpub25lIgogICAgICAgICBpZD0icGF0aDI5OTYiCiAgICAgICAgIHNvZGlwb2RpOmN4PSI5OCIKICAgICAgICAgc29kaXBvZGk6Y3k9IjkwIgogICAgICAgICBzb2RpcG9kaTpyeD0iNi4wMDAwMDI0IgogICAgICAgICBzb2RpcG9kaTpyeT0iMTAiCiAgICAgICAgIGQ9Ik0gMTA0LDkwIEEgNi4wMDAwMDI0LDEwIDAgMSAxIDkxLjk5OTk5OCw5MCA2LjAwMDAwMjQsMTAgMCAxIDEgMTA0LDkwIHoiCiAgICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuOTY0NjExNTcsMCwwLDAuNTcwMTc3MjQsMjUuMjk2NjQ0LDQ5LjI0OTM4OCkiIC8+CiAgICA8L2c+CiAgPC9nPgogIDxnCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXI1IgogICAgIGlua3NjYXBlOmxhYmVsPSJ0ZXh0IgogICAgIHN0eWxlPSJkaXNwbGF5OmlubGluZSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTcuODcyNTQ4LC0xNy4zMjUzNSkiIC8+Cjwvc3ZnPgo=");
  71. menu.appendChild(mione);
  72. document.body.appendChild(menu);
  73. uh.setAttribute("contextmenu","abpfilter");
  74.  
  75. function abpShowFilter() {
  76. var fpo = "*youtube.com/*&user=";
  77. var fpt = "*";
  78. if (uo) var ut = uo.href.slice(uo.href.lastIndexOf("/")+1);
  79. else if (uv) var ut = uv.textContent;
  80. var ffl = fpo+ut+fpt;
  81. var wh = document.getElementById("watch8-action-buttons");
  82. var wlf = wh.parentNode.querySelector("#whitelistfilter");
  83. if (!wlf && ffl) {
  84. var div = document.createElement("div");
  85. div.setAttribute("id","whitelistfilter");
  86. div.innerHTML = "Add the following filter to uBlock:";
  87. var textarea = document.createElement("textarea");
  88. textarea.setAttribute("style", "display: block; font-family: monospace");
  89. textarea.setAttribute("spellcheck","false");
  90. textarea.setAttribute("rows","1");
  91. textarea.setAttribute("cols",ffl.length);
  92. textarea.innerHTML = ffl;
  93. div.appendChild(textarea);
  94. wh.parentNode.appendChild(div);
  95. textarea.focus();
  96. }
  97. else wh.parentNode.removeChild(wlf);
  98. }
  99.  
  100. mione.addEventListener("click",abpShowFilter,false);
  101.  
  102. }