E-Hentai / nHentai highlight thumb when open Anthology gallery

highlight and navigate to artist work first thumb when open "Anthology gallery" from search page with tag "artist"

Pada tanggal 27 Desember 2020. Lihat %(latest_version_link).

  1. // ==UserScript==
  2. // @name E-Hentai / nHentai highlight thumb when open Anthology gallery
  3. // @name:zh-CN E-Hentai / nHentai highlight thumb when open Anthology gallery
  4. // @name:zh-TW E-Hentai / nHentai highlight thumb when open Anthology gallery
  5. // @name:ja E-Hentai / nHentai highlight thumb when open Anthology gallery
  6. // @namespace E-Hentai_highlight_thumb_when_open_Anthology_gallery_from_tag_artist
  7. // @supportURL https://github.com/zhuzemin
  8. // @description highlight and navigate to artist work first thumb when open "Anthology gallery" from search page with tag "artist"
  9. // @description:zh-CN highlight and navigate to artist work first thumb when open "Anthology gallery" from search page with tag "artist"
  10. // @description:zh-TW highlight and navigate to artist work first thumb when open "Anthology gallery" from search page with tag "artist"
  11. // @description:ja highlight and navigate to artist work first thumb when open "Anthology gallery" from search page with tag "artist"
  12. // @include https://exhentai.org/g/*
  13. // @include https://e-hentai.org/g/*
  14. // @include https://nhentai.net/g/*
  15. // @include https://en.nyahentai3.com/g/*
  16. // @include https://zh.nyahentai.co/g/*
  17. // @include https://ja.nyahentai.net/g/*
  18. // @include https://zh.nyahentai.pro/g/*
  19. // @include https://ja.nyahentai.org/g/*
  20. // @include https://zh.nyahentai4.com/g/*
  21. // @version 1.43
  22. // @run-at document-start
  23. // @author zhuzemin
  24. // @license Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
  25. // @license CC Attribution-ShareAlike 4.0 International; http://creativecommons.org/licenses/by-sa/4.0/
  26. // @grant GM_xmlhttpRequest
  27. // @grant GM_registerMenuCommand
  28. // @grant GM_setValue
  29. // @grant GM_getValue
  30. // @connect-src e-hentai.org
  31. // @connect-src exhentai.org
  32. // @connect-src proud-surf-e590.zhuzemin.workers.dev
  33. // ==/UserScript==
  34. var config = {
  35. 'debug': false
  36. }
  37. var debug = config.debug ? console.log.bind(console) : function () {
  38. };
  39.  
  40. //for avoid exhentai login require
  41. var cloudFlareUrl = 'https://proud-surf-e590.zhuzemin.workers.dev/ajax/';
  42.  
  43. var searchStatus = 0;
  44. class E_hentai {
  45. constructor(keyword) {
  46. this.method = 'GET';
  47. this.url = "https://e-hentai.org/?f_search=" + keyword;
  48. this.headers = {
  49. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  50. 'Accept': 'application/atom+xml,application/xml,text/xml',
  51. 'Referer': window.location.href,
  52. };
  53. this.charset = 'text/plain;charset=utf8';
  54. }
  55. }
  56. class Exhentai {
  57. constructor(keyword) {
  58. this.method = 'GET';
  59. this.url = "https://exhentai.org/?f_search=" + keyword;
  60. this.headers = {
  61. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  62. 'Accept': 'application/atom+xml,application/xml,text/xml',
  63. 'Referer': window.location.href,
  64. };
  65. this.charset = 'text/plain;charset=utf8';
  66. }
  67. }
  68. class CloudFlare {
  69. constructor(keyword) {
  70. this.method = 'GET';
  71. this.url = "https://proud-surf-e590.zhuzemin.workers.dev/ajax/https://exhentai.org/?f_search=" + keyword;
  72. this.headers = {
  73. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  74. 'Accept': 'application/atom+xml,application/xml,text/xml',
  75. 'Referer': window.location.href,
  76. };
  77. this.charset = 'text/plain;charset=utf8';
  78. }
  79. }
  80.  
  81. class Gallery {
  82. constructor(href) {
  83. this.method = 'GET';
  84. this.url = href;
  85. this.headers = {
  86. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  87. 'Accept': 'application/atom+xml,application/xml,text/xml',
  88. 'Referer': window.location.href,
  89. };
  90. this.charset = 'text/plain;charset=utf8';
  91. }
  92. }
  93. var exhentai;
  94. var e_hentai;
  95.  
  96. var GetArtistStartImg = function () {
  97. debug("Start: GetArtistStartImg");
  98. let object=null;
  99. if (document.referrer.includes("/tag/artist:") || window.location.href.includes("#/tag/artist:") || document.referrer.includes("/artist/")) {
  100. var taglist;
  101. var links;
  102. if (document.referrer.includes("/artist/")) {
  103.  
  104. taglist = document.querySelector('#tags');
  105. links = taglist.querySelectorAll("a.tag");
  106. }
  107. else {
  108. taglist = document.querySelector('#taglist');
  109. links = taglist.querySelectorAll("a");
  110.  
  111. }
  112. for (var link of links) {
  113. var tag = link.innerText;
  114. if (tag.includes('anthology')) {
  115. debug(tag);
  116. /*var title=document.querySelector("#gn").textContent;
  117. debug("Title: "+title);
  118. if(title.toLowerCase().includes("anthology")||(title.toLowerCase().match(/^comic/)!=null)){*/
  119. var artist;
  120. if (document.referrer.includes("/artist/")) {
  121. artist = document.referrer.match(/\/artist\/([\d\w\-]*)/)[1].replace("-", " ");
  122. }
  123. else {
  124. try {
  125. artist = document.referrer.match(/\/tag\/artist:([\d\w\+]*)/)[1].replace("+", " ");
  126. } catch (e) {
  127. artist = window.location.href.match(/\/tag\/artist:([\d\w\+]*)/)[1].replace("+", " ");
  128. }
  129. }
  130. debug("Artist: " + artist);
  131. var divs = document.querySelectorAll("div.c1");
  132. for (var div of divs) {
  133. var comment = div.querySelector("div.c6");
  134. debug(comment);
  135. if (comment.innerHTML.toLowerCase().includes(artist)) {
  136. /*var links=comment.querySelectorAll("a");
  137. debug(links);
  138. for(var a of links){
  139. var textContent=a.textContent.toLowerCase();
  140. if(textContent.includes(artist)){
  141. var array=textContent.match(/(\d{1,4})/);
  142. debug(array);
  143. if(array!=null){
  144. var ArtistStartImg=parseInt(array[1]);
  145. debug("ArtistStartImg: "+ArtistStartImg);
  146. var object={
  147. "ArtistStartImg":ArtistStartImg,
  148. "artist":artist
  149. }
  150. return object;
  151. }
  152. }
  153. }*/
  154. let ArtistStartImg=null;
  155. if (comment.innerHTML.toLowerCase().includes('https://')){
  156. let names=comment.innerText.split("…");
  157. let count=0;
  158. for(let name of names){
  159. if(name.match(/\w+/)!=null){
  160. debug('name: '+name);
  161. if(name.toLowerCase().includes(artist)){
  162. debug('count: '+count);
  163. break;
  164. }
  165. count++;
  166. }
  167. }
  168. let urls=comment.querySelectorAll('a');
  169. let artistUrl=urls[count];
  170. debug('artistUrl: '+artistUrl);
  171. ArtistStartImg = artistUrl.href.match(/\d*-(\d{1,4})/)[1];
  172. }
  173. else{
  174. var lines = comment.innerText.split("\n");
  175. debug(lines);
  176. for (var line of lines) {
  177. var line = line.toLowerCase();
  178. if (line.includes(artist)) {
  179. var array = line.match(/(\d{1,4})/);
  180. debug(array);
  181. if (array != null) {
  182. ArtistStartImg = parseInt(array[1]);
  183. }
  184. }
  185. }
  186. }
  187. debug("ArtistStartImg: " + ArtistStartImg);
  188. object = {
  189. "ArtistStartImg": ArtistStartImg,
  190. "artist": artist
  191. }
  192. break;
  193. }
  194. }
  195. break;
  196. }
  197. else if (link == links[links.length - 1]) {
  198. debug("End: GetArtistStartImg");
  199. break;
  200. }
  201. }
  202. }
  203. return object;
  204. }
  205.  
  206.  
  207. GetCurrentPageTotalImg = function () {
  208. debug("Start: GetCurrentPageTotalImg");
  209. var divs;
  210. if (document.referrer.includes("/artist/")) {
  211. divs = document.querySelectorAll("div.thumb-container");
  212. }
  213. else {
  214.  
  215. divs = document.querySelectorAll("div.gdtl");
  216. }
  217. debug(divs);
  218. if (divs != null) {
  219. var CurrentPageTotalImg = divs.length;
  220. debug("CurrentPageTotalImg: " + CurrentPageTotalImg);
  221. var object = {
  222. "CurrentPageTotalImg": CurrentPageTotalImg,
  223. "divs": divs
  224. }
  225. return object;
  226. }
  227. debug("End: GetCurrentPageTotalImg");
  228. return null;
  229. }
  230.  
  231. CreateStyle = function () {
  232. debug("Start: CreateStyle");
  233. var style = document.createElement("style");
  234. style.setAttribute("type", "text/css");
  235. style.innerHTML = `
  236. .glowbox {
  237. background: #4c4c4c;
  238. //width: 400px;
  239. margin: 40px 0 0 40px;
  240. padding: 10px;
  241. -moz-box-shadow: 0 0 5px 5px #FFFF00;
  242. -webkit-box-shadow: 0 0 5px 5px #FFFF00;
  243. box-shadow: 0 0 5px 5px #FFFF00;
  244. }
  245. `;
  246. debug("Processing: CreateStyle");
  247. var head = document.querySelector("head");
  248. head.insertBefore(style, null);
  249. debug("End: CreateStyle");
  250. }
  251.  
  252. init = function () {
  253. debug("init");
  254. //nhentai
  255. if (!/(https:\/\/e(-|x)hentai\.org\/g\/[\d\w]*\/[\d\w]*\/)/.test(window.location.href)) {
  256. debug("nhentai");
  257. var info = document.querySelector('#info');
  258. var title;
  259. try {
  260. title = info.querySelector("h2").innerText;
  261.  
  262. }
  263. catch (e) {
  264. title = info.querySelector("h1").innerText;
  265. }
  266. title = encodeURIComponent('"' + title.replace(' ', '+') + '"');
  267. exhentai = new Exhentai(title);
  268. e_hentai = new E_hentai(title);
  269. cloudflare = new CloudFlare(title);
  270. request(exhentai, SearchGallery);
  271. }
  272. var interval = setInterval(function () {
  273. var cdiv = document.querySelector('#cdiv');
  274. if (cdiv != null || searchStatus != 0) {
  275. clearInterval(interval);
  276. if (cdiv != null) {
  277. var ObjectArtistStartImg = GetArtistStartImg();
  278. var ArtistStartImg = ObjectArtistStartImg.ArtistStartImg;
  279. if (ArtistStartImg != null) {
  280. var ObjectCurrentPageTotalImg = GetCurrentPageTotalImg();
  281. var CurrentPageTotalImg = ObjectCurrentPageTotalImg.CurrentPageTotalImg;
  282. var ArtistStartImgInCurrentPage = ArtistStartImg % CurrentPageTotalImg;
  283. if (ArtistStartImgInCurrentPage == 0) {
  284. ArtistStartImgInCurrentPage = CurrentPageTotalImg - 1;
  285. }
  286. else {
  287. ArtistStartImgInCurrentPage -= 1;
  288. }
  289. debug("ArtistStartImgInCurrentPage: " + ArtistStartImgInCurrentPage);
  290. //e-hentai
  291. if (!document.referrer.includes("/artist/")) {
  292. if (window.location.href.includes("#/tag/artist:")) {
  293. ArtistStartImg = ArtistStartImgInCurrentPage;
  294. }
  295. var CorrectPage;
  296. if (ArtistStartImg == 0) {
  297. CorrectPage = 0;
  298. }
  299. else {
  300. CorrectPage = Math.ceil(ArtistStartImg / CurrentPageTotalImg) - 1;
  301. }
  302. debug("CorrectPage: " + CorrectPage);
  303. if (CorrectPage != 0) {
  304. window.location.href += "?p=" + CorrectPage + "#/tag/artist:" + ObjectArtistStartImg.artist;
  305.  
  306. }
  307.  
  308. }
  309. CreateStyle();
  310. var div = ObjectCurrentPageTotalImg.divs[ArtistStartImgInCurrentPage];
  311. var img = div.querySelector("img");
  312. img.className += " glowbox";
  313. debug(div);
  314. div.scrollIntoView();
  315.  
  316. }
  317.  
  318. }
  319.  
  320. }
  321. }, 2000);
  322. }
  323.  
  324. window.addEventListener('DOMContentLoaded', init);
  325.  
  326.  
  327. function SearchGallery(responseDetails) {
  328. var responseText = responseDetails.responseText;
  329. if (responseText != null && responseText.length < 200 || !responseDetails.finalUrl.includes('.workers.dev')) {
  330. request(cloudflare, SearchGallery);
  331. return;
  332. }
  333. else if (responseText != null && responseText.length < 200 && responseDetails.finalUrl.includes('.workers.dev')) {
  334. request(e_hentai, SearchGallery);
  335. return;
  336.  
  337. }
  338. var href = responseText.match(/(https:\/\/e(-|x)hentai\.org\/g\/[\d\w]*\/[\d\w]*\/)/)[1];
  339. debug("href: " + href);
  340. if (href != null) {
  341. /*var dom = new DOMParser().parseFromString(responseText, "text/html");
  342. var div = dom.getElementsByClassName('itg')[0];
  343. var href = div.querySelector('a').href;*/
  344. var url;
  345. if (responseDetails.finalUrl.includes('.workers.dev')) {
  346. url = cloudFlareUrl + href;
  347. }
  348. else {
  349. url = href;
  350. }
  351. var gallery = new Gallery(url);
  352. debug("SearchGallery");
  353. request(gallery, GetComments);
  354. }
  355. else {
  356. searchStatus = 2;
  357. }
  358. }
  359.  
  360. function GetComments(responseDetails) {
  361. var responseText = responseDetails.responseText;
  362. var dom = new DOMParser().parseFromString(responseText, "text/html");
  363. var comments = dom.querySelector("#cdiv");
  364. comments.style.color = "#34495e";
  365. var content = document.querySelector("#content");
  366. var related = content.querySelector("#related-container");
  367. debug("GetComments");
  368. content.insertBefore(comments, related);
  369. var link = document.createElement("link");
  370. link.innerHTML = `<link rel="stylesheet" type="text/css" href="https://e-hentai.org/z/0347/g.css">`;
  371. var head = document.querySelector("head");
  372. head.insertBefore(link, null);
  373. searchStatus = 1;
  374. }
  375. function request(object, func) {
  376. GM_xmlhttpRequest({
  377. method: object.method,
  378. url: object.url,
  379. headers: object.headers,
  380. overrideMimeType: object.charset,
  381. timeout: 60000,
  382. //synchronous: true
  383. onload: function (responseDetails) {
  384. debug(responseDetails);
  385. //Dowork
  386. func(responseDetails);
  387. },
  388. ontimeout: function (responseDetails) {
  389. debug(responseDetails);
  390. //Dowork
  391. func(responseDetails);
  392.  
  393. },
  394. ononerror: function (responseDetails) {
  395. debug(responseDetails);
  396. //Dowork
  397. func(responseDetails);
  398.  
  399. }
  400. });
  401. }