userscripts 只显示中文

在 userscripts、greasyfork 脚本页面只显示中文脚本,支持 AutoPager 和其它翻页脚本。

  1. // ==UserScript==
  2. // @name userscripts 只显示中文
  3. // @namespace https://github.com/ywzhaiqi
  4. // @version 1.7.3
  5. // @author ywzhaiqi@gmail.com
  6. // @description 在 userscripts、greasyfork 脚本页面只显示中文脚本,支持 AutoPager 和其它翻页脚本。
  7. // @homepageURL https://greasyfork.org/scripts/305
  8.  
  9. // @include http*://greasyfork.org/scripts*
  10. // @include http*://greasyfork.org/*/scripts*
  11. // @include http*://userscripts.org*/scripts*
  12. // @include http*://userscripts-mirror.org*/scripts*
  13. // @include http*://www.webextender.net*/scripts*
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @run-at document-end
  17. // ==/UserScript==
  18.  
  19. (function(){
  20.  
  21. var Config = {
  22. debug: false,
  23. buttonID: 'gm-userscript-show-chinese-button',
  24. hiddenStyleID: 'gm-userscript-show-chinese-style',
  25. // 需要?稍微减少 MutationObserver 的触发?
  26. igoreAddedNodeName: ['script', 'hr', 'p', 'button'],
  27.  
  28. chineseRegExp: /[\u4E00-\u9Fa5]/,
  29. // 日文包含:1、片假名(Katakana) 2、平假名(Hiragana) 3、汉字
  30. // 下面正则检测的是 片假名 和 平假名
  31. japaneseRegexp: /[\u30A0-\u30FF]|[\u3040-\u309F]/,
  32. };
  33.  
  34.  
  35. var Sites = {
  36. // 兼容了 "Greasy Fork (Firefox)"、"GreasyFork 中文" 脚本
  37. 'greasyfork.org': {
  38. button: '#script-list-filter', // 按钮插入的位置
  39. line: '.script-list > li, #script-table > tr[id]', // 要隐藏的行(css 选择器)
  40. test: 'h2, td', // 要检测的对象(css 选择器)
  41. },
  42.  
  43. 'userscripts.org': {
  44. button: '#content th.la',
  45. line: 'tr[id^="scripts-"]',
  46. test: '.title, .desc',
  47. },
  48. };
  49.  
  50. Sites['userscripts-mirror.org'] = Sites['userscripts.org'];
  51. Sites['www.webextender.net'] = Sites['userscripts.org'];
  52.  
  53.  
  54. var debug = Config.debug ? console.log.bind(console) : function() {};
  55.  
  56. var onlyChinese,
  57. info;
  58.  
  59. function init() {
  60. var hostname = location.hostname;
  61.  
  62. info = Sites[hostname];
  63. if (!info) {
  64. return;
  65. }
  66.  
  67. var buttonParent = document.querySelector(info.button);
  68. if (!buttonParent) {
  69. return;
  70. }
  71.  
  72. // load setting
  73. onlyChinese = GM_getValue('onlyChinese', false);
  74.  
  75. if (onlyChinese) {
  76. addHiddenStyle();
  77. }
  78.  
  79. addButton(buttonParent);
  80.  
  81. checkScriptNode();
  82.  
  83. // 增加对 翻页脚本的支持
  84. addMutationObserver('body', checkScriptNode);
  85. }
  86.  
  87. function addHiddenStyle() {
  88. if (document.getElementById(Config.hiddenStyleID)) {
  89. return;
  90. }
  91.  
  92. var cssArr = info.line.split(',').map(function(selector) {
  93. return selector + ':not([gm-script-lan="zh"]) {display:none !important}';
  94. });
  95.  
  96. var style = document.createElement('style');
  97. style.id = Config.hiddenStyleID;
  98. style.textContent = cssArr.join('\n');
  99. document.head.appendChild(style);
  100. }
  101.  
  102. function removeHiddenStyle() {
  103. var style = document.getElementById(Config.hiddenStyleID);
  104. if (style) {
  105. document.head.removeChild(style);
  106. }
  107. }
  108.  
  109. function checkScriptNode() {
  110. var scripts = document.querySelectorAll(info.line);
  111. var script,
  112. nodes;
  113. for (var i = scripts.length - 1; i >= 0; i--) {
  114. script = scripts[i];
  115.  
  116. if (script.hasAttribute('gm-script-lan')) {
  117. continue;
  118. }
  119.  
  120. nodes = script.querySelectorAll(info.test);
  121. if (nodes.length === 0) {
  122. nodes = [script];
  123. }
  124. script.setAttribute('gm-script-lan', getScriptLan(nodes));
  125. }
  126. }
  127.  
  128. function getScriptLan(nodes) {
  129. for (var i = nodes.length - 1, text; i >= 0; i--) {
  130. text = nodes[i].textContent;
  131.  
  132. if (text.match(Config.japaneseRegexp)) {
  133. return 'jp';
  134. }
  135.  
  136. if (text.match(Config.chineseRegExp)) {
  137. return 'zh';
  138. }
  139. }
  140.  
  141. return '';
  142. }
  143.  
  144. function addButton(parent) {
  145. var button = document.createElement('button');
  146. button.type = "button";
  147. button.id = Config.buttonID;
  148. button.innerHTML = onlyChinese ? "显示全部" : "只显示中文";
  149. button.onclick = function(){
  150. if (onlyChinese) {
  151. removeHiddenStyle();
  152. button.innerHTML = "只显示中文";
  153. } else {
  154. addHiddenStyle();
  155. button.innerHTML = "显示全部";
  156. }
  157.  
  158. onlyChinese = !onlyChinese;
  159. GM_setValue('onlyChinese', onlyChinese);
  160. };
  161.  
  162. return parent.appendChild(button);
  163. }
  164.  
  165. function addMutationObserver(selector, callback) {
  166. var watch = document.querySelector(selector);
  167. if (!watch) return;
  168.  
  169. var observer = new MutationObserver(function(mutations){
  170. // 排除设定里的插入对象
  171. var nodeAdded = mutations.some(function(x){
  172. return [].some.call(x.addedNodes, function(node) {
  173. return node.localName && Config.igoreAddedNodeName.indexOf(node.localName) == -1;
  174. });
  175. });
  176. if (nodeAdded) {
  177. // console.log(mutations)
  178. // observer.disconnect();
  179. callback(mutations);
  180. }
  181. });
  182. observer.observe(watch, {childList: true, subtree: true});
  183. }
  184.  
  185.  
  186. // function showAll () {
  187. // var trs = document.querySelectorAll(".gm-mhide");
  188. // for (var i = trs.length - 1; i >= 0; i--) {
  189. // trs[i].classList.remove("gm-mhide");
  190. // }
  191.  
  192. // onlyChinese = false;
  193. // }
  194.  
  195. // // 隐藏其它,只显示中文
  196. // function hideOthers(){
  197. // var scripts = document.querySelectorAll(info.line + ':not(.gm-mhide)'),
  198. // script, checkElems;
  199.  
  200. // debug('要检查的行是:', scripts, '选择器是:' + info.line + ':not(.gm-mhide)');
  201.  
  202. // var hasChinese = function (elems) {
  203. // for (var i = elems.length - 1, text; i >= 0; i--) {
  204. // text = elems[i].textContent;
  205.  
  206. // if (text.match(Config.japaneseRegexp)) {
  207. // continue;
  208. // }
  209.  
  210. // if (text.match(Config.chineseRegExp)) {
  211. // return true;
  212. // }
  213. // }
  214.  
  215. // return false;
  216. // };
  217.  
  218. // for (var i = scripts.length - 1; i >= 0; i--) {
  219. // script = scripts[i];
  220.  
  221. // checkElems = script.querySelectorAll(info.test);
  222. // if (!hasChinese(checkElems)) {
  223. // script.classList.add('gm-mhide');
  224. // }
  225. // }
  226.  
  227. // onlyChinese = true;
  228. // }
  229.  
  230.  
  231. init();
  232.  
  233.  
  234. })();
  235.