RARBG Show thumbnail & Bigger preview images (all site variants)

Show torrent's thumbnail directly on torrents list & Load bigger preview images. Run on all different variants of RARBG site (since they keep change site's URL). Lazy preload preview image for faster browsing.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         RARBG Show thumbnail & Bigger preview images (all site variants)
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  Show torrent's thumbnail directly on torrents list & Load bigger preview images. Run on all different variants of RARBG site (since they keep change site's URL). Lazy preload preview image for faster browsing.
// @author       Nobakab
// @icon         https://rarbg.com/favicon.ico
// @include      http*://*rarbg*/top10
// @include      http*://*rarbg*/top100.php*
// @include      http*://*rarbg*/torrents.php*
// @include      http*://*rarbg*/torrent/*
// @include      http*://*rarbg*/s/*
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// @grant        none
// ==/UserScript==

/* globals jQuery */

(function () {
    'use strict';
    // jQuery.noConflict();

    jQuery(function () {
        /* top10, top100.php, torrents.php, s/ */
        // Add one more table column for thumbnail
        // Use tr:first-child instead of eq(0) since we can have more than one table.lista2t when viewing top10 page
        jQuery('table.lista2t tr:first-child td:nth-child(2)').each(function () {
            jQuery(this).before('<td align="center" class="header6 header40" style="width:100px">Thumb.</td>');
        });

        /* Show thumbnail directly on torrents list */
        jQuery('table.lista2t tr.lista2 td.lista:nth-child(2)').each(function () {
            insertThumbnail(this);
        });

        /* torrent/ */
        // Some torrents don't have related table so check for it first
        if (jQuery('table.lista table.lista tr.lista_related td.lista a[onmouseover~=return]').length) {
            // Add one more table column for thumbnail
            jQuery('table.lista table.lista').eq(0).find('tr:first-child td:nth-child(1)').each(function () {
                jQuery(this).before('<td class="header2" style="width:100px">Thumb.</td>');
            });

            /* Show thumbnail directly on torrents list */
            jQuery('table.lista table.lista tr.lista_related td:first-child').each(function () {
                insertThumbnail(this);
            });
        }

        /* Move previewer following mouse */
        betterPreviewerMoving();

        var imagesCache = new Array();
        /* Recommended list: add bigger preivew */
        addBiggerPreviewer(imagesCache);

        /* Torrents list: Replace big preview */
        replaceBiggerPreviewer(imagesCache);

        lazyPreLoad(imagesCache);
    });

})();

function insertThumbnail(td) {
    var link = jQuery(td).find('a').eq(0);
    var onmouseover = jQuery(link).attr('onmouseover');

    /* https://regexr.com/ */
    // Must escape when using regex in script file but don't escape if you are going to test in Console
    // Use a parenthesis here to have match/exec return the captured group only (without the \' and '\) at 2nd element
    var regExp = /\\\'([^)]+)\\\'/;
    var matches = regExp.exec(onmouseover);
    if (matches && matches.length == 2) {
        // Keep link and hover so that we can also replace & show bigger preview later
        jQuery(td).before(jQuery('<td/>').attr('align', 'left').attr('class', 'lista').html(link.clone().html('<img src="' + matches[1] + '">')));
    } else {
        // Don't have thumbnail so replace by a "nocover" instead
        jQuery(td).before(jQuery('<td align="left" class="lista"><img src="https://dyncdn.me/20/img/nocover.gif" style="width:100px"></td>'));
    }
}

function addBiggerPreviewer(imagesCache) {
    jQuery('td.lista[valign=top] a[onmouseover~=return]').each(function () {
        var thumb = jQuery(this).find('img');
        if (thumb.length >= 1) {
            var thumbUrl = thumb[0].src;
            var biggerImageUrl = changeLink(thumbUrl);
            imagesCache.push(biggerImageUrl);

            var onmouseover = jQuery(this).attr("onmouseover");
            onmouseover = onmouseover.substr(0, onmouseover.length - 2) + "<br/><img src=\\\'" + biggerImageUrl + "\\\'/>')";
            jQuery(this).attr("onmouseover", onmouseover);
        }
    });
}

function replaceBiggerPreviewer(imagesCache) {
    jQuery('table.lista2t tr.lista2 td.lista:nth-child(2), table.lista table.lista tr.lista_related td.lista:nth-child(1)').find('a[onmouseover~=return]').each(function () {
    // jQuery('table.lista2t tr.lista2, table.lista table.lista tr.lista_related').find('td.lista a[onmouseover~=return]').each(function () {
        var onmouseover = jQuery(this).attr("onmouseover");

        var regExp = /\\\'([^)]+)\\\'/;
        var matches = regExp.exec(onmouseover);

        if (matches && matches.length == 2) {
            var link = matches[1];
            var newLink = changeLink(link);
            imagesCache.push(newLink);

            jQuery(this).attr("onmouseover", onmouseover.replace(link, newLink));
        }
    });
}

function changeLink(link) {
    var newLink = link;
    var path = link.split('/')

    switch (path[3]) {
        case 'static':
            switch (path[4]) {
                case 'over': //18+
                    // Images are further divided into sub-directories with name is first charater of image's file name (path[5].substr(0, 1))
                    newLink = link.replace('static/over', 'posters2/' + path[5].substr(0, 1));
                    break;
                case '20': //TVdb
                    newLink = link.replace('_small', '_banner_optimized');
                    break;
                default:
                    console.log("Unable to replace rarbg source:" + link);
                    break;
            }
            break;
        case 'mimages': //movie
            newLink = link.replace('over_opt', 'poster_opt');
            break;
        default:
            console.log("Unable to replace rarbg source:" + link);
            break;
    }

    return newLink;
}

function preLoad(imageURL) {
    (new Image()).src = imageURL;
    // jQuery('<img/>')[0].src = imageURL;
}

function lazyPreLoad(imagesCache) {
    // Timer to lazy load
    setTimeout(function () {
        if (imagesCache.length >= 1) {
            var imageURL = imagesCache[0];
            imagesCache.shift();
            lazyPreLoad(imagesCache);

            preLoad(imageURL);
        }
    }, 100);
}

function betterPreviewerMoving() {
    // var pop = document.getElementById("overlib");

    // Set popup image following mouse
    document.onmousemove = function (mouseEvent) {
        var e = mouseEvent || event || window.event;

        /**
         * xoffset & yoffset are already preset by default
         *     xoffset = 15;
         *     yoffset = 10;
         *
         * e.pageX & e.pageY are mouse positions in relative to page
         * e.clientX & e.clientY are mouse positions in relative to window
         *
         * scrollX & scrollY are scroll bar position, should also be provided automatically already
         *     var scrollX = document.scrollingElement.scrollLeft || document.documentElement.scrollLeft || document.body.scrollLeft;
         *     var scrollY = document.scrollingElement.scrollTop || document.documentElement.scrollTop || document.body.scrollTop;
         *
         * document.scrollingElement.clientHeight is height of the whole scrolling element, same as window's height if whole page is scrolling
         */
        var x = (e.pageX || e.clientX + scrollX) + xoffset;
        var y = (e.pageY || e.clientY + scrollY) + yoffset;

        // The element on which mouse is pointing to
        el = e.target || e.srcElement

        if (pop.children[0]) {
            // Avoid showing previewer outside of bottom window
            var r = scrollY + document.scrollingElement.clientHeight - pop.children[0].height - 10
            if (y > r) {
                y = r
            }
        }

        // Position of popup image, in relative to page (not window)
        pop.style.top = y + "px";
        pop.style.left = x + "px"
    };
}