nhentai_endless

nhentai automate next page

  1. // ==UserScript==
  2. // @name nhentai_endless
  3. // @name:ja nhentai_endless
  4. // @name:zh-TW nhentai_endless
  5. // @name:zh-CN nhentai_endless
  6. // @namespace nhentai_endless
  7. // @supportURL https://github.com/zhuzemin
  8. // @description:zh-CN nhentai automate next page
  9. // @description:zh-TW nhentai automate next page
  10. // @description:ja nhentai automate next page
  11. // @description nhentai automate next page
  12. // @include https://nhentai.net/*
  13. // @include https://en.nyahentai3.com/*
  14. // @include https://zh.nyahentai.co/*
  15. // @include https://ja.nyahentai.net/*
  16. // @include https://zh.nyahentai.pro/*
  17. // @include https://ja.nyahentai.org/*
  18. // @include https://zh.nyahentai4.com/*
  19. // @version 1.15
  20. // @grant GM_xmlhttpRequest
  21. // @grant GM_registerMenuCommand
  22. // @grant GM_setValue
  23. // @grant GM_getValue
  24. // @run-at document-start
  25. // @author zhuzemin
  26. // @license Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
  27. // @license CC Attribution-ShareAlike 4.0 International; http://creativecommons.org/licenses/by-sa/4.0/
  28. // @connect-src zh.nyahentai4.com
  29. // @connect-src ja.nyahentai.org
  30. // @connect-src zh.nyahentai.pro
  31. // @connect-src ja.nyahentai.net
  32. // @connect-src zh.nyahentai.co
  33. // @connect-src en.nyahentai3.com
  34. // @connect-src nhentai.net
  35. // @connect-src nyahentai.org
  36. // ==/UserScript==
  37. var config = {
  38. 'debug': false
  39. }
  40. var debug = config.debug ? console.log.bind(console) : function () {
  41. };
  42.  
  43. var interval;
  44. var lastUrl;
  45. var old_scrollY = 0;
  46. var request_pct = 0.05; // percentage of window height left on document to request next page, value must be between 0-1
  47.  
  48. var scroll_events = 0;
  49. var event_type = "scroll"; // or "wheel"
  50.  
  51. function onScroll(e) {
  52. var y = window.scrollY;
  53. // if (scroll_events === 0) old_scrollY = y; // stops only if scroll position was on 2. page
  54. var delta = e.deltaY || y - old_scrollY; // NOTE: e.deltaY for "wheel" event
  55. if (delta > 0 && (window.innerHeight + y) >= (document.body.clientHeight - (window.innerHeight * request_pct))) {
  56. debug("scroll end");
  57. window.removeEventListener(event_type, onScroll, false);
  58.  
  59. try {
  60. requestNextPage();
  61. } catch (err) {
  62. debug(err.name + ": " + err.message);
  63. // NOTE: recovery unnecessary, input event handles it with reset on new search
  64. }
  65. }
  66. old_scrollY = y;
  67. scroll_events += 1;
  68. }
  69.  
  70.  
  71. class Content{
  72. constructor(href) {
  73. this.method = 'GET';
  74. this.url = href;
  75. this.headers = {
  76. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  77. 'Accept': 'application/atom+xml,application/xml,text/xml',
  78. 'Referer': window.location.href,
  79. };
  80. this.charset = 'text/plain;charset=utf8';
  81. }
  82. }
  83.  
  84.  
  85. function requestNextPage() {
  86. var nextUrl;
  87. var parentNode;
  88. if(/nhentai\.net/.test(window.location.href)){
  89.  
  90. var nexts = document.querySelectorAll("a.next");
  91. var a = nexts[nexts.length - 1];
  92. debug("href: " + a.href);
  93. nextUrl=a.href;
  94. parentNode=document.body;
  95. }
  96. else{
  97. //in main page or search page
  98. if(!/https:\/\/[^\/]*\/g\/\d*\/list\/\d*\//.test(window.location.href)) {
  99.  
  100. var nexts = document.querySelectorAll("span.next");
  101. var next = nexts[nexts.length - 1];
  102. var a = next.querySelector("a");
  103. debug("href: " + a.href);
  104. nextUrl=a.href;
  105. parentNode=document.body;
  106. }
  107. //in content page
  108. else
  109. {
  110. var nextBtnList = document.querySelectorAll('a.changeSrc.next');
  111. nextUrl = nextBtnList[nextBtnList.length - 1].href;
  112. parentNode=document.querySelector('#content');
  113. }
  114.  
  115. }
  116. debug('lastUrl: '+lastUrl)
  117. debug('nextUrl: '+nextUrl)
  118. if(lastUrl!=nextUrl){
  119. var content = new Content(nextUrl);
  120. request(content,parentNode);
  121. lastUrl=nextUrl;
  122. }
  123. else {
  124. //clearInterval(interval);
  125. }
  126.  
  127. }
  128.  
  129. var init = function () {
  130. interval=setInterval(function(){
  131. window.addEventListener(event_type, onScroll, false);
  132. window.addEventListener("beforeunload", function () {
  133. window.scrollTo(0, 0);
  134. }, false);
  135. }, 3000);
  136. }
  137.  
  138.  
  139. function request(object,parentNode) {
  140. GM_xmlhttpRequest({
  141. method: object.method,
  142. url: object.url,
  143. headers: object.headers,
  144. overrideMimeType: object.charset,
  145. //synchronous: true
  146. onload: function (responseDetails) {
  147. debug(responseDetails);
  148. var html = new DOMParser().parseFromString(responseDetails.responseText, "text/html");
  149. //debug(galleryHtml);
  150. //Dowork
  151. var content;
  152. var nextElement=null;
  153. if(!/\/g\/\d*\/list\/\d*\//.test(responseDetails.finalUrl)){
  154. content = html.querySelector('#content');
  155. nextElement=parentNode.querySelector('#footer');
  156.  
  157. }
  158. else{
  159. content=html.querySelector('#page-container');
  160. }
  161. parentNode.insertBefore(content,nextElement);
  162. }
  163. });
  164. }
  165.  
  166.  
  167. window.addEventListener('DOMContentLoaded', init);