hikakin remover

youtube hidden user

  1. // ==UserScript==
  2. // @name hikakin remover
  3. // @namespace http://kenmmn.5gbfree.com/
  4. // @include /^https?:\/\/(?:[\w\-]+\.)*youtube\.com\//
  5. // @version 1.1
  6. // @run-at document-start
  7. // @grant none
  8. // @description youtube hidden user
  9. // ==/UserScript==
  10.  
  11. // date 2014-09-28
  12.  
  13.  
  14. function Blocker(userSpecified) {
  15. this.makeSelector = function() {
  16. var selectors = [
  17. "li.channels-browse-content-list-item",
  18. "#pl-video-list .pl-video", // Popular in Japan
  19. "ol.item-section > li", // search
  20. ".video-list-item",
  21. "li.yt-shelf-grid-item",
  22. ".lohp-medium-shelf", // TOP
  23. ".lohp-large-shelf-container", // TOP
  24. ".branded-page-related-channels-item",
  25. "#guide li.guide-channel",
  26. ".branded-page-module-title"
  27. ];
  28. return selectors.join(", ");
  29. };
  30. this.user_specified = userSpecified;
  31. this.confirmHidden =
  32. "mozGetUserMedia" in navigator || "undefined" !== typeof InstallTrigger
  33. ? function(e) { // Firefox
  34. var v = window.getComputedStyle(e, "");
  35. return v.MozBinding.search(/\Wabout:abp-elemhidehit\W/) > -1;
  36. }
  37. : function(e) { // Chrome
  38. var v = window.getComputedStyle(e, "");
  39. return v.display === "none";
  40. };
  41. this.elem_selector = this.makeSelector();
  42. if(userSpecified){
  43. this.userInfo = {
  44. ytid: null,
  45. Name: null,
  46. count: 0
  47. };
  48. }
  49. }
  50.  
  51. Blocker.prototype = {
  52. ab_attr: "adblock-ytid",
  53. setYtid: function(e, ytid) {
  54. e.setAttribute(this.ab_attr, ytid);
  55. if(this.confirmHidden(e)){
  56. e.remove();
  57. }
  58. },
  59. observed: function(e) {
  60. var i, ytnode, ytid, elems = e.querySelectorAll(this.elem_selector);
  61. for (i = 0; i < elems.length; i++) {
  62. if (elems[i].hasAttribute(this.ab_attr)) {
  63. continue;
  64. }
  65. ytnode = elems[i].querySelector('[data-ytid]');
  66. if (ytnode) {
  67. ytid = ytnode.getAttribute('data-ytid');
  68. this.setYtid(elems[i], ytid);
  69. }
  70. else {
  71. var href_elems = elems[i].querySelectorAll('[href]');
  72. for (var j = 0; j < href_elems.length; j++){
  73. var href = href_elems[j].getAttribute('href');
  74. var m = href.match(/\/channel\/([\w\-]+)/);
  75. if (m) {
  76. var ytid = m[1];
  77. this.setYtid(elems[i], ytid);
  78. break;
  79. }
  80. }
  81. }
  82. }
  83.  
  84. if(this.user_specified && this.userInfo.count < 2){
  85. if(this.userInfo.ytid === null){
  86. if(!this.findUserYtid(e)){
  87. return;
  88. }
  89. }
  90. // ytid has found.
  91. if(this.userInfo.Name === null){
  92. this.findUserName(e);
  93. }
  94. this.setYtid4User(e);
  95. }
  96. },
  97. setYtid4User: function(e){
  98. var elems = document.querySelectorAll('#content, #player');
  99. for (var i = 0; i < elems.length; i++) {
  100. this.setYtid(elems[i], this.userInfo.ytid);
  101. this.userInfo.count++;
  102. }
  103. },
  104. findUserYtid: function(e){
  105. var meta = e.querySelector('meta[itemprop=channelId][content]');
  106. if (meta) {
  107. this.userInfo.ytid = meta.getAttribute('content');
  108. return true;
  109. }
  110. },
  111. findUserName: function(e){
  112. var elem = e.querySelector('#watch7-user-header a.yt-user-name');
  113. if (elem) {
  114. this.userInfo.Name = elem.textContent;
  115. return true;
  116. }
  117. else {
  118. elem = e.querySelector('meta[name=title][content]');
  119. if(elem){
  120. this.userInfo.Name = elem.getAttribute('content');
  121. return true;
  122. }
  123. }
  124. return false;
  125. },
  126. printUserRule: function(){
  127. if(typeof this.userInfo.ytid === "string"){
  128. var ul = document.querySelector("#guide ul");
  129. if(!ul) return false;
  130. var li = ul.querySelector("li");
  131. if(!li) return false;
  132. var input = document.createElement("textarea");
  133. input.textContent = this.makeRuleText();
  134. ul.insertBefore(input, li);
  135. return true;
  136. }
  137. return ture;
  138. },
  139. makeRuleText: function(){
  140. var rule = 'youtube.com##[' + this.ab_attr + '="' + this.userInfo.ytid + '"]';
  141. if (this.userInfo.Name === null){
  142. this.findUserName(document);
  143. }
  144. if (this.userInfo.Name) {
  145. rule += ' /' + '*' + this.userInfo.Name + '*' + '/';
  146. }
  147. console.log(rule);
  148. return rule;
  149. }
  150. };
  151.  
  152. (function () {
  153. var pa, obs, m = document.URL.match(/^https?:\/\/(?:[\w\-]+\.)*youtube\.com\/(\S*)$/);
  154.  
  155. if (!m) {return;}
  156. pa = m[1];
  157. if (pa.match(/^subscribe_embed\W/)) {
  158. return ;
  159. }
  160.  
  161. var blocker = new Blocker(pa.match(/^(?:user|channel|watch|playlist)\W/));
  162.  
  163. obs = new MutationObserver(function (mu) {
  164. mu.forEach(function (m) {
  165. blocker.observed(m.target);
  166. });
  167. });
  168. obs.observe(document, {attributes: false, subtree: true, childList: true, characterData: false});
  169.  
  170. window.addEventListener('DOMContentLoaded', function () {
  171. if(blocker.user_specified){
  172. blocker.observed(document.body);
  173. var try_print = function(d){
  174. setTimeout(function(){
  175. if(!blocker.printUserRule()){
  176. if(d < 10000)
  177. try_print(d * 1.3);
  178. }
  179. }, d);
  180. };
  181. try_print(1000);
  182. }
  183.  
  184. var i, items = document.querySelectorAll('.spf-link');
  185. for (i = 0; i < items.length; i++) {
  186. items[i].classList.remove('spf-link');
  187. }
  188. if(blocker.user_specified){
  189. var elems = document.querySelectorAll('#content, #player');
  190. if(elems.length == 0){
  191. document.location = "https://www.youtube.com/";
  192. }
  193. for (var i = 0; i < elems.length; i++) {
  194. var e = elems[i];
  195. if(this.confirmHidden( e ) ){
  196. document.location = "https://www.youtube.com/";
  197. }
  198. }
  199. }
  200. }, true);
  201.  
  202. }) ();