nhentai Display and Highlight Tag with Thumbnail

nHentai 显示并高亮Tag在缩略图模式

اعتبارا من 22-01-2020. شاهد أحدث إصدار.

  1. // ==UserScript==
  2. // @name nhentai Display and Highlight Tag with Thumbnail
  3. // @namespace nhentai_display_and_highlight_tag_with_thumbnail
  4. // @supportURL https://github.com/zhuzemin
  5. // @description nHentai 显示并高亮Tag在缩略图模式
  6. // @include https://nhentai.net/*
  7. // @include https://en.nyahentai3.com/*
  8. // @include https://zh.nyahentai.co/*
  9. // @include https://ja.nyahentai.net/*
  10. // @include https://zh.nyahentai.pro/*
  11. // @version 1.4
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM_registerMenuCommand
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @run-at document-start
  17. // @author zhuzemin
  18. // @license Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
  19. // @license CC Attribution-ShareAlike 4.0 International; http://creativecommons.org/licenses/by-sa/4.0/
  20. // ==/UserScript==
  21. var config = {
  22. 'debug': false
  23. }
  24. var debug = config.debug ? console.log.bind(console) : function () {
  25. };
  26.  
  27. // setting User Preferences
  28. function setUserPref(varName, defaultVal, menuText, promtText, sep){
  29. GM_registerMenuCommand(menuText, function() {
  30. var val = prompt(promtText, GM_getValue(varName, defaultVal));
  31. if (val === null) { return; } // end execution if clicked CANCEL
  32. // prepare string of variables separated by the separator
  33. if (sep && val){
  34. var pat1 = new RegExp('\\s*' + sep + '+\\s*', 'g'); // trim space/s around separator & trim repeated separator
  35. var pat2 = new RegExp('(?:^' + sep + '+|' + sep + '+$)', 'g'); // trim starting & trailing separator
  36. //val = val.replace(pat1, sep).replace(pat2, '');
  37. }
  38. //val = val.replace(/\s{2,}/g, ' ').trim(); // remove multiple spaces and trim
  39. GM_setValue(varName, val);
  40. // Apply changes (immediately if there are no existing highlights, or upon reload to clear the old ones)
  41. //if(!document.body.querySelector(".THmo")) THmo_doHighlight(document.body);
  42. //else location.reload();
  43. });
  44. }
  45.  
  46. // prepare UserPrefs
  47. setUserPref(
  48. 'highlights',
  49. 'chinese;',
  50. 'Set Highlight Tags',
  51. `Set highlights, split with ";". Example: "mmf threesome; chinese"`,
  52. ','
  53. );
  54. setUserPref(
  55. 'BlackList',
  56. 'english;',
  57. 'Set BlackList',
  58. `Set BlackList, split with ";". Example: "chinese; yaoi"`,
  59. ','
  60. );
  61.  
  62.  
  63. CreateStyle=function(){
  64. debug("Start: CreateStyle");
  65. var style=document.createElement("style");
  66. style.setAttribute("type","text/css");
  67. style.innerHTML=`
  68. .glowbox {
  69. background: #4c4c4c;
  70. //width: 400px;
  71. //margin: 40px 0 0 40px;
  72. //padding: 10px;
  73. -moz-box-shadow: 0 0 5px 5px #FFFF00;
  74. -webkit-box-shadow: 0 0 5px 5px #FFFF00;
  75. box-shadow: 0 0 5px 5px #FFFF00;
  76. }
  77. `;
  78. debug("Processing: CreateStyle");
  79. var head=document.querySelector("head");
  80. head.insertBefore(style,null);
  81. debug("End: CreateStyle");
  82. }
  83. class Gallery{
  84. constructor(href,other=null) {
  85. this.method = 'GET';
  86. this.url = href;
  87. this.headers = {
  88. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  89. 'Accept': 'application/atom+xml,application/xml,text/xml',
  90. 'Referer': window.location.href,
  91. };
  92. this.charset = 'text/plain;charset=utf8';
  93. this.other=other;
  94. }
  95. }
  96. var BlackListLast=[];
  97. var highlightsLast=[];
  98. var DivCount;
  99. function HighlightTag(responseDetails,divs){
  100. //debug("HighlightTag");
  101. var dom;
  102. if(responseDetails!=null){
  103. var responseText=responseDetails.responseText;
  104. dom = new DOMParser().parseFromString(responseText, "text/html");
  105.  
  106. }
  107. var highlights;
  108. var BlackList;
  109. try{
  110. highlights=GM_getValue("highlights").trim().replace(/;$/,"").split(";");
  111. BlackList=GM_getValue("BlackList").trim().replace(/;$/,"").split(";");
  112. }catch(e){
  113. debug("Not set GM_Value.");
  114. }
  115. if (BlackList == undefined||BlackList.length ==0) {
  116. BlackList = [];
  117. }
  118. if (highlights == undefined||highlights.length ==0) {
  119. highlights = [];
  120. }
  121. debug("BlackList: " + BlackList);
  122. if(responseDetails!=null||JSON.stringify(BlackList)!=JSON.stringify(BlackListLast)||JSON.stringify(highlights)!=JSON.stringify(highlightsLast)){
  123.  
  124. var taglist;
  125. var NewDivs;
  126. if(responseDetails==null){
  127. NewDivs = divs;
  128. }
  129. else{
  130. NewDivs=[0];
  131. }
  132. //debug("NewDivs.length: "+NewDivs.length);
  133. for(var i=0;i<NewDivs.length;i++){
  134. var Break=false;
  135. var div;
  136. if(responseDetails!=null){
  137. div=divs[DivCount];
  138. taglist = dom.querySelector('#tags');
  139. }
  140. else{
  141. div=divs[i];
  142. taglist = div.querySelector('#tags');
  143.  
  144. }
  145. //debug(taglist);
  146. var links = taglist.querySelectorAll("a.tag");
  147. //debug(links);
  148. if(responseDetails!=null||JSON.stringify(BlackList)!=JSON.stringify(BlackListLast)){
  149. for (var link of links) {
  150. var tag = link.innerText.toLowerCase().match(/([\w\s]*)/)[1].trim();
  151. //debug("Tag: "+tag);
  152. for (var BlackWord of BlackList) {
  153. if (BlackWord.length > 1) {
  154. if (tag == BlackWord.trim()) {
  155. debug("BlackWord: " + link.innerText);
  156. div.className += " blacklisted";
  157. Break=true;
  158. break;
  159. }
  160. else if (link==links[links.length-1]&&BlackWord == BlackList[BlackList.length - 1]) {
  161. div.className = div.className.replace(" blacklisted", "");
  162. }
  163. }
  164. else{
  165. div.className = div.className.replace(" blacklisted", "");
  166.  
  167. }
  168. }
  169. if (Break) {
  170. break;
  171. }
  172. }
  173.  
  174. }
  175. if(responseDetails!=null||JSON.stringify(highlights)!=JSON.stringify(highlightsLast)){
  176. for (var link of links) {
  177. var tag = link.innerText.toLowerCase().match(/([\w\s]*)/)[1].trim();
  178. //debug("Tag: "+tag);
  179. for (var highlight of highlights) {
  180. if (highlight.length > 1) {
  181. //debug("Highlight: "+highlight);
  182. if (tag == highlight.trim()) {
  183. debug("highlight: " + link.innerText);
  184. link.className += " glowbox";
  185. break;
  186. }
  187. else if (highlight == highlights[highlights.length - 1]) {
  188. link.className = link.className.replace(" glowbox", "");
  189. }
  190. }
  191. else{
  192. link.className = link.className.replace(" glowbox", "");
  193.  
  194. }
  195. }
  196. }
  197.  
  198. }
  199.  
  200. if(responseDetails!=null) {
  201. var a = div.querySelector("a");
  202. a.replaceChild(taglist, a.querySelector("#tags"));
  203. DivCount++;
  204. }
  205. }
  206. if(responseDetails!=null) {
  207.  
  208. if (DivCount < divs.length) {
  209. MainWoker(divs);
  210. }
  211. }
  212. debug("BlackListLast: "+BlackListLast);
  213. debug("highlightsLast: "+highlightsLast);
  214. highlightsLast=highlights;
  215. BlackListLast=BlackList;
  216. }
  217.  
  218. }
  219.  
  220. function MainWoker(divs){
  221. debug("MainWoker");
  222. var div=divs[DivCount];
  223. div.style.maxHeight = "900px";
  224. div.style.height = "900px";
  225. var a = div.querySelector("a");
  226. var img = a.querySelector("img");
  227. var data_src=img.getAttribute("data-src");
  228. img.setAttribute("src",data_src);
  229. div.insertBefore(img, a);
  230. a.style.overflow = "auto";
  231. a.style.maxHeight = 900 - img.offsetHeight + "px";
  232. var caption = a.querySelector("div.caption");
  233. caption.style.position = "static";
  234. var taglist = document.createElement("section");
  235. taglist.setAttribute("id", "tags");
  236. a.insertBefore(taglist, null);
  237. var href = div.querySelector('a').href;
  238. //debug(href);
  239. var gallery = new Gallery(href);
  240. gallery.other=divs;
  241. request(gallery,HighlightTag);
  242.  
  243. }
  244. var init = function () {
  245. var LastDivNum=0;
  246. CreateStyle();
  247. DivCount=0;
  248. setInterval(function(){
  249. var divs = document.querySelectorAll('div.gallery');
  250. //debug("DivNum: "+divs.length);
  251. if(LastDivNum<divs.length) {
  252. MainWoker(divs);
  253. }
  254. LastDivNum=divs.length;
  255. HighlightTag(null,divs);
  256. }, 2000)
  257. }
  258. function request(object,func) {
  259. var retries = 10;
  260. GM_xmlhttpRequest({
  261. method: object.method,
  262. url: object.url,
  263. headers: object.headers,
  264. overrideMimeType: object.charset,
  265. //synchronous: true
  266. onload: function (responseDetails) {
  267. if (responseDetails.status != 200) {
  268. // retry
  269. if (retries--) { // *** Recurse if we still have retries
  270. setTimeout(request,2000);
  271. return;
  272. }
  273. }
  274. //debug(responseDetails);
  275. //Dowork
  276. func(responseDetails,object.other);
  277. }
  278. })
  279. }
  280.  
  281. window.addEventListener('DOMContentLoaded', init);