Simple EHentai Viewer

Preload more images to help you fap online

  1. // ==UserScript==
  2. // @name Simple EHentai Viewer
  3. // @namespace http://hentaimore.net/
  4. // @version 1.0
  5. // @description Preload more images to help you fap online
  6. // @author Hentai More
  7. // @match https://e-hentai.org/s/*
  8. // @match https://exhentai.org/s/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (() => {
  13. 'use strict';
  14.  
  15. let reload = 0, preload = 0;
  16. let current = 1, count = 0;
  17. const maxcount = 10;
  18.  
  19. const srcarray = [];
  20. const nextarray = [];
  21. const failarray = [];
  22.  
  23. const image = document.createElement('img');
  24. const site = document.createElement('span');
  25. const tips = document.createElement('span');
  26. const link = document.createElement('a');
  27. const empty = 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=';
  28.  
  29. function style(css) {
  30. const style = document.createElement('style');
  31.  
  32. style.type = 'text/css';
  33. style.innerHTML = css;
  34.  
  35. return style;
  36. }
  37.  
  38. function loadManga() {
  39. const head = document.getElementsByTagName('head')[0];
  40.  
  41. head.appendChild(style('body {background: black; text-align: center}'));
  42. head.appendChild(style('@media screen and (min-width: 64em) {img {max-width: 1280px; margin: 0 auto; display: block}}'));
  43. head.appendChild(style('@media screen and (max-width: 64em) {img {width: 100%; margin: 0 auto; display: block}}'));
  44. head.appendChild(style('span {color: white; text-align: center; font-size: 15px; font-weight: bold; margin: 10px auto; display: block}'));
  45. head.appendChild(style('a {color: white; text-decoration: none; text-align: center; font-size:15px; font-weight: bold; margin: 10px auto; display: block} a:hover {color: white; text-decoration: underline}'));
  46.  
  47. image.id = 'img'; image.onload = () => window.scrollTo(0, 0); image.src = srcarray[current - 1]; link.href = failarray[current - 1];
  48. document.body.innerHTML = ''; document.body.appendChild(image); document.body.appendChild(site); document.body.appendChild(tips); document.body.appendChild(link);
  49. }
  50.  
  51. function loadStatus() {
  52. site.innerHTML = '<a href="http://hentaimore.net/" style="color: red">Promotion: Click Here to Download Hentai Games.</a>';
  53. tips.innerHTML = 'Press Ctrl or Drag Image Outside to Toggle View Mode. Preload Status: < ' + current + ' / ' + srcarray.length + ' >.';
  54. link.innerHTML = 'Press Enter or Click Here to Reload Current Image. Reload Status: ' + (reload ? 'True' : 'False') + '.';
  55. }
  56.  
  57. function loadImage(array, index, src) {
  58. const img = document.createElement('img'), callback = () => { array[index] = src; if (image.src === empty && index === current - 1) image.src = src; };
  59.  
  60. img.src = src; if (img.complete) { callback(); return; } img.onload = callback;
  61. }
  62.  
  63. function preloadImage() {
  64. const next = nextarray[nextarray.length - 1];
  65.  
  66. window.fetch(next, { method: 'GET', credentials: 'include' }).then(response => response.text()).then(text => {
  67. const doc = document.implementation.createHTMLDocument('doc'); doc.documentElement.innerHTML = text;
  68.  
  69. srcarray.push(empty); loadStatus(); loadImage(srcarray, srcarray.length - 1, doc.getElementById('img').src);
  70.  
  71. failarray.push(next + '?nl=' + doc.getElementById('loadfail').getAttribute('onclick').match(/[-0-9]+/)[0]);
  72.  
  73. if (next !== doc.getElementById('next').href) {
  74. nextarray.push(doc.getElementById('next').href); if (count < maxcount) preloadImage(); else count = 0;
  75. }
  76. });
  77.  
  78. ++count;
  79. }
  80.  
  81. function reloadImage() {
  82. if (!reload) {
  83. window.fetch(failarray[current - 1], { method: 'GET', credentials: 'include' }).then(response => response.text()).then(text => {
  84. const doc = document.implementation.createHTMLDocument('doc'); doc.documentElement.innerHTML = text;
  85.  
  86. image.src = empty; loadStatus(); loadImage(srcarray, current - 1, doc.getElementById('img').src);
  87.  
  88. link.href = failarray[current - 1] = failarray[current - 1] + '&nl=' + doc.getElementById('loadfail').getAttribute('onclick').match(/[-0-9]+/)[0];
  89.  
  90. reload = 0;
  91. });
  92.  
  93. reload = 1;
  94. }
  95. }
  96.  
  97. function prevImage() {
  98. if (current > 1) {
  99. --current; image.src = srcarray[current - 1]; link.href = failarray[current - 1]; loadStatus();
  100. }
  101. }
  102.  
  103. function nextImage() {
  104. if (current < srcarray.length) {
  105. ++current; image.src = srcarray[current - 1]; link.href = failarray[current - 1]; loadStatus();
  106. }
  107.  
  108. if (count === 0 && current >= srcarray.length - maxcount / 2) preloadImage();
  109. }
  110.  
  111. function startLoader() {
  112. nextarray.push(document.getElementById('next').href);
  113. srcarray.push(document.getElementById('img').src);
  114. failarray.push(document.location.href + '?nl=' + document.getElementById('loadfail').getAttribute('onclick').match(/[-0-9]+/)[0]);
  115.  
  116. loadManga(); loadStatus(); preloadImage();
  117.  
  118. image.onclick = event => {
  119. event.stopPropagation();
  120. event.preventDefault();
  121. if (event.clientX <= document.body.clientWidth / 2) prevImage(); else nextImage();
  122. };
  123.  
  124. link.onclick = event => {
  125. event.stopPropagation();
  126. event.preventDefault(); reloadImage();
  127. };
  128. }
  129.  
  130. function mapKey(event) {
  131. switch (event.which) {
  132. case 37:
  133. event.stopPropagation(); event.preventDefault(); if (preload) prevImage();
  134. break;
  135. case 38:
  136. event.stopPropagation(); event.preventDefault(); window.scrollBy(0, -100);
  137. break;
  138. case 39:
  139. event.stopPropagation(); event.preventDefault(); if (preload) nextImage();
  140. break;
  141. case 40:
  142. event.stopPropagation(); event.preventDefault(); window.scrollBy(0, +100);
  143. break;
  144. case 13:
  145. event.stopPropagation(); event.preventDefault(); if (preload) reloadImage();
  146. break;
  147. case 17:
  148. event.stopPropagation();
  149. event.preventDefault();
  150. if (!preload) {
  151. preload = 1; startLoader(); document.onkeydown = mapKey;
  152. window.removeEventListener('keydown', mapKey);
  153. } else {
  154. preload = 0; document.location.reload();
  155. }
  156. break;
  157. default:
  158. break;
  159. }
  160. }
  161.  
  162. window.addEventListener('keydown', mapKey);
  163.  
  164. window.addEventListener('dragstart', event => {
  165. if (event.target.id !== 'img') {
  166. event.stopPropagation();
  167. event.preventDefault();
  168. }
  169. });
  170.  
  171. window.addEventListener('drag', event => {
  172. });
  173.  
  174. window.addEventListener('dragover', event => {
  175. event.stopPropagation();
  176. event.preventDefault();
  177. });
  178.  
  179. window.addEventListener('drop', event => {
  180. event.stopPropagation();
  181. event.preventDefault();
  182. if (event.target.id !== 'img') {
  183. if (!preload) {
  184. preload = 1; startLoader(); document.onkeydown = mapKey;
  185. window.removeEventListener('keydown', mapKey);
  186. } else {
  187. preload = 0; document.location.reload();
  188. }
  189. }
  190. });
  191. })();