hikakin remover

youtube hidden user

当前为 2014-09-28 提交的版本,查看 最新版本

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