Sleazy Fork is available in English.

Iwara Enhancement

Enhances UI for better experience

Mint 2020.11.12.. Lásd a legutóbbi verzió

// ==UserScript==
// @name         Iwara Enhancement
// @namespace    https://github.com/guansss/userscripts
// @version      0.1
// @description  Enhances UI for better experience
// @author       guansss
// @match        *://*.iwara.tv/*
// @require      https://cdn.jsdelivr.net/npm/video.js@7.10.1/dist/video.min.js#sha256=9HM07Of11yw3TL/m0BxP9pw08qXmG/xOTDc1d3sp2Wo=
// @resource     vjs-css https://cdn.jsdelivr.net/npm/video.js@7.10.1/dist/video-js.min.css#sha256=/fXfq3QrnWyMYmF0zX6ImdI1DTraNCAq1vPofa2rs2w=
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_download
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

const FILE_NAME = 'DATE TITLE - AUTHOR (ID)';

(() => {
    'use strict';

    const ready = new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve));

    // jQuery is available only when ready
    ready.then(() => window.$ = unsafeWindow.$ = unsafeWindow.jQuery);

    {
        general();
        enhanceList();

        const secondSlashIndex = location.pathname.indexOf('/', 1);
        const place = location.pathname.slice(1, secondSlashIndex !== -1 ? secondSlashIndex : undefined);

        if ((place === 'videos' || place === 'images') && secondSlashIndex !== -1) {
            prettifyContentPage();
        }
        if (place === 'videos' && secondSlashIndex !== -1) {
            enhanceVideo();
            setupAutoDownload();
        }
    }

    async function general() {
        // large screen mode
        GM_addStyle(`
@media (min-width: 2560px) {
    .container {
        width: 1984px;
    }

    .slick-slider {
        height: 920px !important;
    }

    .slick-list img {
        width: 1800px;
    }

    .comment .user-avatar {
        width: 8.33333333%;
    }
}
`);

        await ready;

        // remove R18 warning
        $('#r18-warning').remove();
    }

    async function enhanceList() {
        await ready;

        // display like rate and highlight
        $('.views-column').each(function() {
            const thiz = $(this);
            const children = $(this).find('.likes-icon');

            let likes = children.eq(0).contents().filter((i, e) => e.nodeType === 3).text().trim();
            let views = children.eq(1).contents().filter((i, e) => e.nodeType === 3).text().trim();

            views = views.includes('k') ? views.slice(0, -1) * 1000 : views;
            const likeRate = Math.round(1000 * likes / (+views || Infinity)) / 10;

            children.eq(1).text(likeRate + '%');

            if (likeRate >= 4) {
                thiz.css('background', '#79ecd6');
                thiz.find('.username').css('color', '#555');
            }
        });
    }

    async function enhanceVideo() {
        // remove old CSS of videojs
        for (const node of document.head.childNodes) {
            if (node && node.tagName === 'STYLE' && node.innerHTML.includes('video-js')) {
                node.innerHTML = node.innerHTML.replace(/.+?video-js\.min\.css.+/, '');
            }
        }

        // load newer CSS of videojs
        GM_addStyle(GM_getResourceText('vjs-css'));

        // patch the player.on() to return itself to support method chaining, which is no longer supported in the new version
        const Player = videojs.getComponent('Player');
        const readyFn = Player.prototype.ready;

        Player.prototype.ready = function() {
            const onFn = this.on;

            if (onFn && !onFn.patched) {
                this.on = function() {
                    onFn.apply(this, arguments);
                    return this;
                };
                this.on.patched = true;
            }
            return readyFn.apply(this, arguments);
        };

        // inject the videojs to page context
        unsafeWindow._videojs = videojs;

        // switch to newer version of videojs
        new MutationObserver((mutationsList, observer) => {
            mutationsList.forEach(mutation => {
                if (mutation.type === 'childList') {
                    for (const node of mutation.addedNodes) {
                        if (node && node.src && node.src.includes('video-js/video.js')) {
                            observer.disconnect();

                            const script = document.createElement('script');
                            script.innerHTML = 'window.videojs = window._videojs';
                            node.after(script);
                            node.remove();
                        }
                    }
                }
            });
        }).observe(document.head, { childList: true });

        // recover the volume in incognito mode
        if (localStorage['-volume'] === undefined) {
            localStorage['-volume'] = GM_getValue('volume', 0.5);
        }

        await ready;

        repeat(() => {
            const player = videojs.getPlayers()['video-player'];

            if (player) {
                player.ready(() => {
                    player.on('fullscreenchange', () => {
                            $('#video-player').focus();
                        })
                        .on('volumechange', () => {
                            // save volume when changed
                            GM_setValue('volume', player.volume() || 0.5);
                        });
                });

                return true;
            }
        }, 200);
    }

    async function prettifyContentPage() {
        await ready;

        // show full description
        $('.field-name-body a.show').click();

        // enlarge content area
        $('.node-full .col-sm-12:last-child').removeClass('col-sm-12').addClass('col-sm-9').parent().append($('.container .sidebar'));
        $('.container>.col-sm-9, .node-full').removeClass('col-sm-9').addClass('col-sm-12');
        $('.extra-content-block').remove();

        // move "liked by" block to the bottom
        $('#block-views-likes-block').appendTo('.sidebar .region-sidebar');
    }

    async function setupAutoDownload() {
        await ready;

        $('#download-button').off('click').click(e => {
            e.preventDefault();

            // like the video
            $('.flag-like a').click();

            const id = location.pathname.slice(location.pathname.lastIndexOf('/') + 1);

            const url = $('#download-options li:first-child a')[0].href;
            const ext = url.match(/Source(\.[^&]+)/)[1];

            const title = $('.node-info .title').text();
            const author = $('.node-info .username').text();
            const fileName = Object.entries({
                    ID: id,
                    TITLE: title,
                    AUTHOR: author,
                    DATE: new Date().toLocaleString('zh-cn', { hour12: false }).replace(/[\/ :]/g, ''),
                })
                .reduce((fileName, [key, value]) => fileName.replace(key, value), FILE_NAME)
                .replace(/[*/:<>?\\|]/g, '');

            GM_download({
                url,
                name: fileName + ext,
                saveAs: true,
            });
        });
    }

    function repeat(fn, interval = 500) {
        if (fn()) {
            return undefined;
        }

        const id = setInterval(() => {
            try {
                fn() && clearInterval(id);
            } catch (e) {
                clearInterval(id);
            }
        }, interval);

        return id;
    }
})();