Sleazy Fork is available in English.

Auto pagination

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

// ==UserScript==
// @name            Auto pagination
// @description     Automatically reaches for "next" page when the bottom of a given page has been reached (where applicable)
// @include         http://gamestorrent.co/page/*
// @include         /^https?://pcgamestorrents\.com/(|.*/)page/.*$/
// @include         /^https://fitgirl-repacks\.site/page/.*$/
// @include         /^https://(e-|ex)hentai\.org/(|\?.*|tag/.*)$/
// @include         https://www.skidrow-games.com/page/*
// @author          iceman94
// @version         0.2
// @grant           none
// @namespace       https://greasyfork.org/users/148290
// ==/UserScript==


// Scroll back value in percent (see setScrollPos() function)
var scrollBackInPct = 0.02

// Global flag variable
var flag = false;

//=======================================================================================================
// Setting up functions
//=======================================================================================================

// Function to test if an URL is correctly formatted and reachable
function isUrl(url)
{
    var request;

    if (window.XMLHttpRequest)
    {
        request = new XMLHttpRequest();
    }
    else
    {
        request = new ActiveXObject('Microsoft.XMLHTTP');
    };

    try
    {
        request.open('GET', url, false);
        request.send();

        if (request.status !== 200)
        {
            return false;
        };
    }
    catch(e)
    {
        return false;
    };

    return true;
};

// Function to test if a value is numerically valid (i.e. an integer/float...)
// Source: https://stackoverflow.com/a/1830844
function isNumeric(n)
{
    return !isNaN(parseFloat(n)) && isFinite(n);
}

// Detects which attribute work with the target browser
function testAttr()
{
    var method;

    if(document.body.scrollTop)
    {
        method = 'chrome';
    } else if(document.documentElement.scrollTop)
    {
        method = 'firefox';
    } else {
        method = 'unsupported';
    };

    return method;
};

// Retrieves top scroll position (i.e. 0 = top)
function getScrollPos()
{
    var scrollP;

    switch(testAttr())
    {
        case 'chrome':
            scrollP = document.body.scrollTop;
            break;
        case 'firefox':
            scrollP = document.documentElement.scrollTop;
            break;
        default:
            console.log('[getScrollPos] Only Firefox/Chrome based browsers are supported.');
    };

    return scrollP;
};

// Retrieves client (i.e. browser) height
function getWinHeight()
{
    var winH;

    switch(testAttr())
    {
        case 'chrome':
            winH = document.body.clientHeight;
            break;
        case 'firefox':
            winH = document.documentElement.clientHeight;
            break;
        default:
            console.log('[getWinHeight] Only Firefox/Chrome based browsers are supported.');
    };

    return winH;
};

// Retrieves page height
function getScrollHeight()
{
    var scrollH;

    switch(testAttr())
    {
        case 'chrome':
            scrollH = document.body.scrollHeight;
            break;
        case 'firefox':
            scrollH = document.documentElement.scrollHeight;
            break;
        default:
            console.log('[getScrollHeight] Only Firefox/Chrome based browsers are supported.');
    };

    return scrollH;
};

// Modify actual top scroll position to avoid triggering a script loop (i.e. scroll back up for x% where x=scrollBackInPct)
function setScrollPos()
{
  if (flag && flag == true)
  {
      return false;
  };

    switch(testAttr())
    {
        case 'chrome':
            document.body.scrollTop = document.body.scrollTop - (document.body.scrollTop * scrollBackInPct);
            break;
        case 'firefox':
            document.documentElement.scrollTop = document.documentElement.scrollTop - (document.documentElement.scrollTop * scrollBackInPct);
            break;
        default:
            console.log('[setScrollPos] Only Firefox/Chrome based browsers are supported.');
    };
};

// Tests if scroll position has reached the bottom of the page
function isBottomReached()
{
    //var result;

    if(getScrollPos() + getWinHeight() == getScrollHeight())
    {
        //console.log('Bottom of the page reached!');
        return true;
    } else {
        return false;
    };

    //return result;
};

// Parses an URL to find a page number and, if true, returns an object w/ infos about it
function getPageInfos(url)
{
    var currUrl = new URL(url);
    var parsedPathname = currUrl.pathname.split("");

    var numArr = new Array();
    var prevValue = undefined;
    var pageNb = "";

    for (var i=parsedPathname.length -1; i>-1; i--)
    {
        if (isNumeric(parsedPathname[i]))
        {
            numArr.push({[i]: parsedPathname[i]});
            prevValue = parsedPathname[i];
        };

        if (!isNumeric(parsedPathname[i]) && isNumeric(prevValue))
        {
            break;
        };
    };

    for (var j=numArr.length -1; j>-1; j--)
    {
        for (var key in numArr[j])
        {
            pageNb = pageNb + numArr[j][key];
        };
    };

    var pageObj = new Object();
    var pathnameBefore = "";
    var pathnameAfter = "";
    pageObj.current_page_nb = pageNb;

    for (key in numArr[numArr.length -1])
    {
        pageObj.first_page_nb_pos = parseInt(key);
    };

    for (key in numArr[0])
    {
        pageObj.last_page_nb_pos = parseInt(key) +1;
    };

    for (i=0; i<pageObj.first_page_nb_pos; i++)
    {
        pathnameBefore = pathnameBefore + parsedPathname[i];
    };
    pageObj.pathname_before = pathnameBefore;

    for (i=pageObj.last_page_nb_pos; i<parsedPathname.length; i++)
    {
        pathnameAfter = pathnameAfter + parsedPathname[i];
    };
    pageObj.pathname_after = pathnameAfter;

    return pageObj;
};

// Returns position of "Next" button in page
function findNextPage()
{
    var elmtObj = new Object();

    //Is there an element w/ an Id called 'unext'?
    if(document.getElementById('unext'))
    {
        elmtObj.type = 'tag';
        elmtObj.content = document.getElementById('unext');
        //console.log('[findNextPage] ', document.getElementsByClassName('next')[0]);
        return elmtObj;
    };

    //Is there an element w/ a ClassName called 'next'?
    if(document.getElementsByClassName('next')[0])
    {
        elmtObj.type = 'tag';
        elmtObj.content = document.getElementsByClassName('next')[0];
        //console.log('[findNextPage] ', document.getElementsByClassName('next')[0]);
        return elmtObj;
    };

    //Is there a tag w/ an attribute called 'next-page-url'?
    var coll = document.getElementsByTagName('div');
    var l = coll.length;
    for (var i=0; i<l; i++)
    {
        if(coll[i] && coll[i].getAttribute('next-page-url'))
        {
            elmtObj.type = 'uri';
            elmtObj.content = coll[i].getAttribute('next-page-url');
            //console.log('[findNextPage] ', coll[i].getAttribute('next-page-url'));
            return elmtObj;
        };
    };

    //Is there an element w/ a TagName containing ONLY a ">" (greater than) sign as textContent?
    coll = document.getElementsByTagName('a');
    var collL = coll.length;
    for (i=0; i<collL; i++)
    {
        if (coll[i].href && coll[i].textContent == ">")
        {
            elmtObj.type = 'uri';
            elmtObj.content = coll[i].href;
            //console.log('[findNextPage] ', coll[i].href);
            return elmtObj;
        };
    };

    //Is there a page (i.e. URI) ending w/ a number that follows the actual one?
    var pageInfos = getPageInfos(window.location);
    var nextPageUrl = pageInfos.pathname_before + (parseInt(pageInfos.current_page_nb) +1) + pageInfos.pathname_after;
    //if (isUrl(nextPageUrl))
    if (nextPageUrl && nextPageUrl != "NaN" && isUrl(nextPageUrl))
    {
        elmtObj.type = 'uri';
        elmtObj.content = nextPageUrl;
        //console.log('[findNextPage] ', nextPageUrl);
        return elmtObj;
    };
};

// Fetches next page based on target's element: tag (anchor, div, img...), attribute (src, class...), URI...
function goNext(tgtObj)
{
    // WIP - May change to handle a wide variety of element
    var type = tgtObj.type || undefined;
    var content = tgtObj.content || undefined;

    window.onscroll = function()
    {
        if(isBottomReached() === true)
        {
            switch(type)
            {
                case 'tag':
                    setScrollPos();
                    flag = true;
                    content.click();
                    break;
                case 'attribute':
                    console.log('[goNext] "attribute" method not yet implemented.');
                    break;
                case 'uri':
                    setScrollPos();
                    flag = true;
                    window.location = content;
                    break;
                default:
                    console.log('[goNext] This type of element is actually not (yet?) managed by this script.');
            };
        } else {
            //Do nothing for now
        }

        //return false;
    };
};


//=======================================================================================================
// Showtime !
//=======================================================================================================

goNext(findNextPage());