Highlight OCH links

Link Checker. Hit escape to check whether one-click hoster links are online or offline.

目前为 2016-04-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Highlight OCH links
  3. // @namespace cuzi
  4. // @oujs:author cuzi
  5. // @description Link Checker. Hit escape to check whether one-click hoster links are online or offline.
  6. // @icon https://greasyfork.org/system/screenshots/screenshots/000/003/868/original/och.png
  7. // @homepageURL https://openuserjs.org/scripts/cuzi/Highlight_OCH_links
  8. // @require http://openuserjs.org/src/libs/cuzi/RequestQueue.js
  9. // @require http://openuserjs.org/src/libs/cuzi/OCH_List.js
  10. // @grant GM_xmlhttpRequest
  11. // @version 4
  12. // @include *
  13. // @exclude *.yahoo.*
  14. // @exclude *.google.*
  15. // @exclude *.youtube.*
  16. // @exclude *.bing.com*
  17. // @exclude *duckduckgo.com*
  18. // ==/UserScript==
  19. "use strict";
  20.  
  21.  
  22. // Maximal number of links that are checked (per website)
  23. const MAXREQUESTS = 1000;
  24.  
  25. // Maximal number of links that are checked in parallel (per website)
  26. const MAXPARALLELCONNECTIONS = 16;
  27.  
  28. // Maximal number of DOM nodes that are examined. Decrease this number on slow machines.
  29. const MAXTEXTNODES = 10000;
  30.  
  31.  
  32. /*
  33. // Export
  34. var mypatterns = [];
  35. var mynames = [];
  36. var myurls = [];
  37. for(var key in OCH) {
  38. var o = OCH[key];
  39. if(o.multi.length > 0) {
  40. mypatterns.push(o.pattern.toString());
  41. mynames.push("'"+key+"'");
  42. myurls.push(" - ["+o.title+"]("+o.homepage+")");
  43. }
  44. }
  45.  
  46. alert(mypatterns.join(",\n"));
  47. alert(mynames.join(",\n"));
  48. alert(myurls.join("\n"));
  49.  
  50. */
  51.  
  52.  
  53. var links = []; // [ { hoster: "", url: "", element: DOMNode} , ... ]
  54. var rq = new RequestQueue(MAXPARALLELCONNECTIONS,MAXREQUESTS);
  55.  
  56.  
  57. function linkOffline(link) {
  58. link.element.style.backgroundColor = "rgba(255, 0, 20, 0.5)";
  59. link.element.dataset.linkValidatedAs = "offline";
  60. }
  61. function linkOnline(link) {
  62. link.element.style.backgroundColor = "rgba(70, 255 ,0, 0.5)";
  63. link.element.dataset.linkValidatedAs = "online";
  64. }
  65. function linkWaiting(link) {
  66. link.element.style.backgroundColor = "rgba(255, 150, 80, 0.4)";
  67. }
  68.  
  69. function handleResult(link,result,errorstring) {
  70. if(result === 1) {
  71. linkOnline(link);
  72. } else if(result === 0) {
  73. linkOffline(link);
  74. } else if(result == -1) {
  75. link.element.style.backgroundColor = "blue";
  76. link.element.title = errorstring;
  77. console.log(errorstring);
  78. } else {
  79. console.log("handleResult(link,result,errorstring) wrong resultcode: "+result);
  80. }
  81. }
  82.  
  83. function matchHoster(str) {
  84. // Return name of first hoster that matches, otherwise return false
  85. for(var name in OCH) {
  86. for(var i = 0; i < OCH[name].pattern.length; i++) {
  87. if(OCH[name].pattern[i].test(str)) {
  88. return name
  89. }
  90. }
  91. }
  92. return false;
  93. }
  94.  
  95. function findLinks() {
  96. links = [];
  97. // Normalize hoster object: Replace single patterns with arrays [RegExp]
  98. for(var name in OCH) {
  99. if(!Array.isArray(OCH[name].pattern)) {
  100. OCH[name].pattern = [ OCH[name].pattern ];
  101. }
  102. }
  103. // Find all text nodes that contain "http://"
  104. var nodes = [];
  105. var walk = document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,{ acceptNode: function(node) {
  106. if(node.parentNode.href || node.parentNode.parentNode.href || node.parentNode.parentNode.parentNode.href)
  107. return NodeFilter.FILTER_REJECT;
  108. if(node.parentNode.tagName == "TEXTAREA" || node.parentNode.parentNode.tagName == "TEXTAREA")
  109. return NodeFilter.FILTER_REJECT;
  110. if(node.data.match(/(\s|^)https?:\/\/\w+/))
  111. return NodeFilter.FILTER_ACCEPT;
  112. } },false);
  113. var node = walk.nextNode();
  114. while(node) {
  115. nodes.push(node);
  116. node = walk.nextNode();
  117. }
  118. // For each found text nodes check whether the URL is a valid OCH URL
  119. for(var i = 0; i < nodes.length && i < MAXTEXTNODES; i++) {
  120. if("" === nodes[i].data) {
  121. continue;
  122. }
  123. var httpPosition = nodes[i].data.indexOf("http");
  124. if(httpPosition == -1) {
  125. continue;
  126. }
  127. var urlnode;
  128. if(httpPosition > 0) {
  129. urlnode = nodes[i].splitText(httpPosition); // Split leading text
  130. } else {
  131. urlnode = nodes[i];
  132. }
  133. var stop = urlnode.data.match(/$|\s/)[0]; // Find end of URL
  134. if("" !== stop) { // If empty string, we found $ end of string
  135. var nextnode = urlnode.splitText(urlnode.data.indexOf(stop)); // Split trailing text
  136. if("" !== nextnode.data && nextnode.data.indexOf("http") != -1) {// The trailing text might contain another URL
  137. nodes.push(nextnode);
  138. }
  139. }
  140.  
  141. // Check whether the URL is a OCH. If so, create an <a> element
  142. var url = urlnode.data;
  143. var mh = matchHoster(url);
  144. if(mh !== false) {
  145. var a = document.createElement("a");
  146. a.href = url;
  147. a.appendChild(urlnode.parentNode.replaceChild(a, urlnode));
  148. links.push( {
  149. 'hoster' : mh,
  150. 'url' : url,
  151. 'element' : a
  152. });
  153. }
  154. }
  155.  
  156. // Find actual <a> links
  157. var al = document.getElementsByTagName('a');
  158. for(var i = 0; i < al.length; i++) {
  159. if(al[i].dataset.linkValidatedAs) {
  160. continue; // Link was already checked
  161. }
  162. var mH = matchHoster(al[i].href);
  163. if(mH !== false) {
  164. links.push( {
  165. 'hoster' : mH,
  166. 'url' : al[i].href,
  167. 'element' : al[i]
  168. });
  169. }
  170. }
  171.  
  172. return links.length;
  173. }
  174.  
  175. function checkLinks() {
  176. // Check all links by calling the hoster's check function
  177. for(var i = 0; i < links.length; i++) {
  178. if(links[i] && OCH[links[i].hoster].check && typeof(OCH[links[i].hoster].check) === 'function') {
  179. linkWaiting(links[i]);
  180. OCH[links[i].hoster].check(links[i],handleResult);
  181. }
  182. }
  183. }
  184.  
  185. (function() {
  186. var doit = true;
  187. document.addEventListener('keydown',function(ev) {
  188. if (ev.keyCode == 27) {
  189. if(doit) {
  190. // Highlight links and check them
  191. var n = findLinks();
  192. if(n > 0 )
  193. checkLinks();
  194. } else {
  195. // Abort all requests
  196. rq.abort();
  197. }
  198. doit = !doit;
  199. }
  200. },false);
  201. })();