Sleazy Fork is available in English.

Modal Image in rule

try to take over the world!

Ajankohdalta 15.12.2021. Katso uusin versio.

// ==UserScript==
// @name         Modal Image in rule
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  try to take over the world!
// @author       falaz
// @match        https://rule34.xxx/index.php?page=post*
// @icon         https://www.google.com/s2/favicons?domain=rule34.xxx
// @grant        none
// @license      MIT
// ==/UserScript==


// @ts-check

// @ts-check
/*jshint esversion: 8 */

class Modal{
    constructor(document, dp){
        this.pointer = 0;
        this.dp = dp;
        this.medias = this.populateMedias(document);
        this.createModalNode(document);
        this.nextSended = false;
    }
    createModalNode(document){
        const div = document.createElement('div');
        const css = document.createElement('style');
        div.innerHTML = '<div id="modal-container" style="display:none">'+
                        '<div id="modal">'+
                        '</div></div>';
        css.innerHTML = '#modal-container{background: #000000a8;width: 100%;height: 100%;position: fixed;z-index: 10;}'+
                        '#modal{height: 90%;width: 80%;background: transparent;padding: 0% 5%;margin: 2% 5% 2% 0;position: fixed}'+
                        '#modal img{width: auto%;border: none;vertical-align: middle;height: auto;}'+
                        '#modal video{width: 100%;heigth:100%}';
        document.body.prepend(div);
        document.head.prepend(css);
        this.modalContainer = document.querySelector('#modal-container');
        this.modal = document.querySelector('#modal');
        this.nextPage = document.querySelector('#paginator [alt="next"]').href;
    }
    /**
     * @param {Media} media
     */
    render(media){
        if(!this.modalContainer){
            this.createModalNode(document);
        }
        if(media.type== 'video'){
            this.modal.innerHTML = `<video src="${media.src}" autoplay controls loop></video>`;
        }else{
            this.modal.innerHTML = `<img src="${media.src}"/>`;
        }
        this.modalContainer.style.display = 'block';
    }
    close(){
        if(!this.modalContainer){
            this.createModalNode(document);
        }
        try{
            this.modal.querySelector('video').pause();
        }catch(e){

        }
        this.modalContainer.style.display = 'none';
    }
    nextMedia(){
        if(this.pointer < this.medias.length -1){
            this.pointer ++;
            this.render(this.medias[this.pointer]);
        }else{
            console.error('Reach the end of the medias');
        }
        if(this.pointer < this.medias.length -5 && this.nextSended){
            this.nextSended= true;
            this.getNextPage();
        }
    }
    prevMedia(){
        if(this.pointer > 0){
            this.pointer --;
            this.render(this.medias[this.pointer]);
        }else{
            console.error('Reach the end of the medias');
        }
    }
    async getNextPage(){
        if(!this.nextPage){
            this.nextPage = document.querySelector('#paginator [alt="next"]').href;
        }
        const response = await fetch(this.nextPage);
        const body = await response.text();
        const dp = new DOMParser();
        const pageDocument = dp.parseFromString(body,'text/html');
        const medias = this.populateMedias(pageDocument);
        this.addMedias(medias);
        this.nextSended = false;
    }
    addMedias(medias){
        const mediasTemp = [...this.medias, medias];
        this.medias = mediasTemp;
    }
    populateMedias(document){
        const thumbsNode = document.querySelectorAll('#content .thumb');
        const medias = [];
        for(const node of thumbsNode){
            const title = node.querySelector('img').title;
            const media = new Media(
                node.querySelector('a').href,
                /animated|video/.test(title)? 'video': 'image',
                node.querySelector('img').src,
                this.dp
            );
            medias.push(media);
        }
        return medias;
    }
}
class Media{
    /**
     * @param {string} _page This is the page of the media. Not the real src.
     * @param {string} _type
     * @param {string} _thumb
     */
    constructor(_page, _type, _thumb, dp){
        this.page = _page;
        this.type = _type;
        this.thumb = _thumb;
        this.dp = dp;
        this.getSrc().then(src=>{
            this.src = src;
        });
    }
    async getSrc (){
        const response = await fetch(this.page);
        const body = await response.text();
        const dp = new DOMParser();
        const pageDocument = dp.parseFromString(body,'text/html');
        const video = pageDocument.querySelector('video source');
        const image = pageDocument.querySelector('.flexi img');
        if(video){
            this.type ='video';
            return video.src;
        }else{
            this.type = 'image';
            return image.src;
        }
    }

}
const dp = new DOMParser();
let modalObj;
const loadingSVG = "https://samherbert.net/svg-loaders/svg-loaders/puff.svg";

(function() {
    'use strict';
    modalObj = new Modal(document, dp);
    document.querySelectorAll('.content .thumb').forEach(element=>{
        element.addEventListener('click',(e)=>{
            e.preventDefault();
            modalObj.render(modalObj.medias[modalObj.pointer]);
        });
    });
    document.addEventListener('keydown',(e)=>{
        if(e.key == 'ArrowRight'){
            modalObj.nextMedia();
        }else if(e.key == 'ArrowLeft'){
            modalObj.prevMedia();
        }else if(e.key == 'Escape'){
            modalObj.close();
        }
    });
})();