Auto pagination

Automatically reaches for "next" page when the bottom of a given page has been reached (where applicable)

  1. // ==UserScript==
  2. // @name Auto pagination
  3. // @description Automatically reaches for "next" page when the bottom of a given page has been reached (where applicable)
  4. // @include http://gamestorrent.co/page/*
  5. // @include /^https?://pcgamestorrents\.com/(|.*/)page/.*$/
  6. // @include /^https://fitgirl-repacks\.site/page/.*$/
  7. // @include /^https://(e-|ex)hentai\.org/(|\?.*|tag/.*)$/
  8. // @include https://www.skidrow-games.com/page/*
  9. // @author iceman94
  10. // @version 0.2
  11. // @grant none
  12. // @namespace https://greasyfork.org/users/148290
  13. // ==/UserScript==
  14.  
  15.  
  16. // Scroll back value in percent (see setScrollPos() function)
  17. var scrollBackInPct = 0.02
  18.  
  19. // Global flag variable
  20. var flag = false;
  21.  
  22. //=======================================================================================================
  23. // Setting up functions
  24. //=======================================================================================================
  25.  
  26. // Function to test if an URL is correctly formatted and reachable
  27. function isUrl(url)
  28. {
  29. var request;
  30.  
  31. if (window.XMLHttpRequest)
  32. {
  33. request = new XMLHttpRequest();
  34. }
  35. else
  36. {
  37. request = new ActiveXObject('Microsoft.XMLHTTP');
  38. };
  39.  
  40. try
  41. {
  42. request.open('GET', url, false);
  43. request.send();
  44.  
  45. if (request.status !== 200)
  46. {
  47. return false;
  48. };
  49. }
  50. catch(e)
  51. {
  52. return false;
  53. };
  54.  
  55. return true;
  56. };
  57.  
  58. // Function to test if a value is numerically valid (i.e. an integer/float...)
  59. // Source: https://stackoverflow.com/a/1830844
  60. function isNumeric(n)
  61. {
  62. return !isNaN(parseFloat(n)) && isFinite(n);
  63. }
  64.  
  65. // Detects which attribute work with the target browser
  66. function testAttr()
  67. {
  68. var method;
  69.  
  70. if(document.body.scrollTop)
  71. {
  72. method = 'chrome';
  73. } else if(document.documentElement.scrollTop)
  74. {
  75. method = 'firefox';
  76. } else {
  77. method = 'unsupported';
  78. };
  79.  
  80. return method;
  81. };
  82.  
  83. // Retrieves top scroll position (i.e. 0 = top)
  84. function getScrollPos()
  85. {
  86. var scrollP;
  87.  
  88. switch(testAttr())
  89. {
  90. case 'chrome':
  91. scrollP = document.body.scrollTop;
  92. break;
  93. case 'firefox':
  94. scrollP = document.documentElement.scrollTop;
  95. break;
  96. default:
  97. console.log('[getScrollPos] Only Firefox/Chrome based browsers are supported.');
  98. };
  99.  
  100. return scrollP;
  101. };
  102.  
  103. // Retrieves client (i.e. browser) height
  104. function getWinHeight()
  105. {
  106. var winH;
  107.  
  108. switch(testAttr())
  109. {
  110. case 'chrome':
  111. winH = document.body.clientHeight;
  112. break;
  113. case 'firefox':
  114. winH = document.documentElement.clientHeight;
  115. break;
  116. default:
  117. console.log('[getWinHeight] Only Firefox/Chrome based browsers are supported.');
  118. };
  119.  
  120. return winH;
  121. };
  122.  
  123. // Retrieves page height
  124. function getScrollHeight()
  125. {
  126. var scrollH;
  127.  
  128. switch(testAttr())
  129. {
  130. case 'chrome':
  131. scrollH = document.body.scrollHeight;
  132. break;
  133. case 'firefox':
  134. scrollH = document.documentElement.scrollHeight;
  135. break;
  136. default:
  137. console.log('[getScrollHeight] Only Firefox/Chrome based browsers are supported.');
  138. };
  139.  
  140. return scrollH;
  141. };
  142.  
  143. // Modify actual top scroll position to avoid triggering a script loop (i.e. scroll back up for x% where x=scrollBackInPct)
  144. function setScrollPos()
  145. {
  146. if (flag && flag == true)
  147. {
  148. return false;
  149. };
  150.  
  151. switch(testAttr())
  152. {
  153. case 'chrome':
  154. document.body.scrollTop = document.body.scrollTop - (document.body.scrollTop * scrollBackInPct);
  155. break;
  156. case 'firefox':
  157. document.documentElement.scrollTop = document.documentElement.scrollTop - (document.documentElement.scrollTop * scrollBackInPct);
  158. break;
  159. default:
  160. console.log('[setScrollPos] Only Firefox/Chrome based browsers are supported.');
  161. };
  162. };
  163.  
  164. // Tests if scroll position has reached the bottom of the page
  165. function isBottomReached()
  166. {
  167. //var result;
  168.  
  169. if(getScrollPos() + getWinHeight() == getScrollHeight())
  170. {
  171. //console.log('Bottom of the page reached!');
  172. return true;
  173. } else {
  174. return false;
  175. };
  176.  
  177. //return result;
  178. };
  179.  
  180. // Parses an URL to find a page number and, if true, returns an object w/ infos about it
  181. function getPageInfos(url)
  182. {
  183. var currUrl = new URL(url);
  184. var parsedPathname = currUrl.pathname.split("");
  185.  
  186. var numArr = new Array();
  187. var prevValue = undefined;
  188. var pageNb = "";
  189.  
  190. for (var i=parsedPathname.length -1; i>-1; i--)
  191. {
  192. if (isNumeric(parsedPathname[i]))
  193. {
  194. numArr.push({[i]: parsedPathname[i]});
  195. prevValue = parsedPathname[i];
  196. };
  197.  
  198. if (!isNumeric(parsedPathname[i]) && isNumeric(prevValue))
  199. {
  200. break;
  201. };
  202. };
  203.  
  204. for (var j=numArr.length -1; j>-1; j--)
  205. {
  206. for (var key in numArr[j])
  207. {
  208. pageNb = pageNb + numArr[j][key];
  209. };
  210. };
  211.  
  212. var pageObj = new Object();
  213. var pathnameBefore = "";
  214. var pathnameAfter = "";
  215. pageObj.current_page_nb = pageNb;
  216.  
  217. for (key in numArr[numArr.length -1])
  218. {
  219. pageObj.first_page_nb_pos = parseInt(key);
  220. };
  221.  
  222. for (key in numArr[0])
  223. {
  224. pageObj.last_page_nb_pos = parseInt(key) +1;
  225. };
  226.  
  227. for (i=0; i<pageObj.first_page_nb_pos; i++)
  228. {
  229. pathnameBefore = pathnameBefore + parsedPathname[i];
  230. };
  231. pageObj.pathname_before = pathnameBefore;
  232.  
  233. for (i=pageObj.last_page_nb_pos; i<parsedPathname.length; i++)
  234. {
  235. pathnameAfter = pathnameAfter + parsedPathname[i];
  236. };
  237. pageObj.pathname_after = pathnameAfter;
  238.  
  239. return pageObj;
  240. };
  241.  
  242. // Returns position of "Next" button in page
  243. function findNextPage()
  244. {
  245. var elmtObj = new Object();
  246.  
  247. //Is there an element w/ an Id called 'unext'?
  248. if(document.getElementById('unext'))
  249. {
  250. elmtObj.type = 'tag';
  251. elmtObj.content = document.getElementById('unext');
  252. //console.log('[findNextPage] ', document.getElementsByClassName('next')[0]);
  253. return elmtObj;
  254. };
  255.  
  256. //Is there an element w/ a ClassName called 'next'?
  257. if(document.getElementsByClassName('next')[0])
  258. {
  259. elmtObj.type = 'tag';
  260. elmtObj.content = document.getElementsByClassName('next')[0];
  261. //console.log('[findNextPage] ', document.getElementsByClassName('next')[0]);
  262. return elmtObj;
  263. };
  264.  
  265. //Is there a tag w/ an attribute called 'next-page-url'?
  266. var coll = document.getElementsByTagName('div');
  267. var l = coll.length;
  268. for (var i=0; i<l; i++)
  269. {
  270. if(coll[i] && coll[i].getAttribute('next-page-url'))
  271. {
  272. elmtObj.type = 'uri';
  273. elmtObj.content = coll[i].getAttribute('next-page-url');
  274. //console.log('[findNextPage] ', coll[i].getAttribute('next-page-url'));
  275. return elmtObj;
  276. };
  277. };
  278.  
  279. //Is there an element w/ a TagName containing ONLY a ">" (greater than) sign as textContent?
  280. coll = document.getElementsByTagName('a');
  281. var collL = coll.length;
  282. for (i=0; i<collL; i++)
  283. {
  284. if (coll[i].href && coll[i].textContent == ">")
  285. {
  286. elmtObj.type = 'uri';
  287. elmtObj.content = coll[i].href;
  288. //console.log('[findNextPage] ', coll[i].href);
  289. return elmtObj;
  290. };
  291. };
  292.  
  293. //Is there a page (i.e. URI) ending w/ a number that follows the actual one?
  294. var pageInfos = getPageInfos(window.location);
  295. var nextPageUrl = pageInfos.pathname_before + (parseInt(pageInfos.current_page_nb) +1) + pageInfos.pathname_after;
  296. //if (isUrl(nextPageUrl))
  297. if (nextPageUrl && nextPageUrl != "NaN" && isUrl(nextPageUrl))
  298. {
  299. elmtObj.type = 'uri';
  300. elmtObj.content = nextPageUrl;
  301. //console.log('[findNextPage] ', nextPageUrl);
  302. return elmtObj;
  303. };
  304. };
  305.  
  306. // Fetches next page based on target's element: tag (anchor, div, img...), attribute (src, class...), URI...
  307. function goNext(tgtObj)
  308. {
  309. // WIP - May change to handle a wide variety of element
  310. var type = tgtObj.type || undefined;
  311. var content = tgtObj.content || undefined;
  312.  
  313. window.onscroll = function()
  314. {
  315. if(isBottomReached() === true)
  316. {
  317. switch(type)
  318. {
  319. case 'tag':
  320. setScrollPos();
  321. flag = true;
  322. content.click();
  323. break;
  324. case 'attribute':
  325. console.log('[goNext] "attribute" method not yet implemented.');
  326. break;
  327. case 'uri':
  328. setScrollPos();
  329. flag = true;
  330. window.location = content;
  331. break;
  332. default:
  333. console.log('[goNext] This type of element is actually not (yet?) managed by this script.');
  334. };
  335. } else {
  336. //Do nothing for now
  337. }
  338.  
  339. //return false;
  340. };
  341. };
  342.  
  343.  
  344. //=======================================================================================================
  345. // Showtime !
  346. //=======================================================================================================
  347.  
  348. goNext(findNextPage());