Sleazy Fork is available in English.

EX封面图片替换

封面图片替换

// ==UserScript==
// @name         EX封面图片替换
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  封面图片替换
// @match        https://exhentai.org/*
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    const replacedImages = GM_getValue('replacedImages', {}); // 从存储加载已替换的图片
    const button = document.createElement('button');
    const dialog = document.createElement('div');
    const input = document.createElement('input');
    const confirmButton = document.createElement('button');
    const closeButton = document.createElement('button');
    const thumbnailContainer = document.createElement('div');

    // 设置按钮样式
    Object.assign(button.style, {
        position: 'fixed', top: '10px', right: '10px', width: '15px', height: '15px',
        borderRadius: '50%', backgroundColor: 'white', opacity: 0.5, border: 'none', cursor: 'pointer'
    });
    button.textContent = '⚙️';
    document.body.appendChild(button);

    // 设置对话框样式
    Object.assign(dialog.style, {
        display: 'none', position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
        backgroundColor: 'white', padding: '20px', border: '1px solid black', boxShadow: '0 0 10px rgba(0, 0, 0, 0.5)',
        width: '300px', boxSizing: 'border-box'
    });

    // 设置输入框样式
    Object.assign(input.style, {
        width: '100%', padding: '10px', marginBottom: '10px', border: '1px solid #ccc', borderRadius: '5px',
        boxSizing: 'border-box'
    });
    input.placeholder = '输入旧图片链接';
    dialog.appendChild(input);

    // 设置按钮样式
    Object.assign(confirmButton.style, {
        width: '48%', padding: '10px', border: 'none', borderRadius: '5px', backgroundColor: '#4CAF50', color: 'white',
        cursor: 'pointer', marginRight: '4%'
    });
    confirmButton.textContent = '确认';

    Object.assign(closeButton.style, {
        width: '48%', padding: '10px', border: 'none', borderRadius: '5px', backgroundColor: '#f44336', color: 'white',
        cursor: 'pointer'
    });
    closeButton.textContent = '关闭';

    // 将按钮加入对话框
    const buttonContainer = document.createElement('div');
    Object.assign(buttonContainer.style, {
        display: 'flex', justifyContent: 'space-between'
    });
    buttonContainer.appendChild(confirmButton);
    buttonContainer.appendChild(closeButton);
    dialog.appendChild(buttonContainer);

    document.body.appendChild(dialog);

    // 设置缩略图容器样式
    Object.assign(thumbnailContainer.style, {
        position: 'fixed', top: '50px', right: '10px', zIndex: 9999
    });
    document.body.appendChild(thumbnailContainer);

    // 点击按钮显示对话框
    button.addEventListener('click', () => {
        dialog.style.display = 'block';
        updateThumbnails(); // 更新缩略图
    });

    // 关闭对话框
    closeButton.addEventListener('click', () => {
        dialog.style.display = 'none';
        thumbnailContainer.style.display = 'none'; // 关闭对话框时隐藏缩略图
    });

    // 确认替换按钮
    confirmButton.addEventListener('click', () => {
        const oldUrl = input.value.trim();
        if (oldUrl) {
            const inputFile = document.createElement('input');
            inputFile.type = 'file';
            inputFile.accept = 'image/*';
            inputFile.addEventListener('change', (event) => {
                const file = event.target.files[0];
                if (file) {
                    const reader = new FileReader();
                    reader.onload = function(e) {
                        const newImageUrl = e.target.result;
                        replaceImages(oldUrl, newImageUrl);
                        replacedImages[oldUrl] = newImageUrl;
                        GM_setValue('replacedImages', replacedImages);
                        updateThumbnails();
                        location.reload();
                    };
                    reader.readAsDataURL(file);
                }
            });
            inputFile.click();
        }
    });

    // 替换页面中的图片
    function replaceImages(oldUrl, newImageUrl) {
        document.querySelectorAll('img[src="' + oldUrl + '"]').forEach(img => {
            img.src = newImageUrl;
        });
    }

    // 更新缩略图并显示删除按钮
    function updateThumbnails() {
        thumbnailContainer.innerHTML = ''; // 清空当前缩略图
        thumbnailContainer.style.display = 'block'; // 显示缩略图容器
        for (let [oldUrl, newImageUrl] of Object.entries(replacedImages)) {
            const thumbnailWrapper = document.createElement('div');
            const thumbnail = document.createElement('img');
            const deleteButton = document.createElement('button');

            thumbnail.src = newImageUrl;
            Object.assign(thumbnail.style, { width: '50px', height: '50px', margin: '5px', cursor: 'pointer' });

            // 设置删除按钮
            Object.assign(deleteButton.style, { position: 'absolute', top: '0', right: '0', fontSize: '12px', cursor: 'pointer', backgroundColor: 'transparent', border: 'none' });
            deleteButton.textContent = 'X';
            deleteButton.addEventListener('click', () => deleteReplacedImage(oldUrl));

            thumbnailWrapper.style.position = 'relative';
            thumbnailWrapper.appendChild(thumbnail);
            thumbnailWrapper.appendChild(deleteButton);
            thumbnailContainer.appendChild(thumbnailWrapper);
        }
    }

    // 删除已替换的图片
    function deleteReplacedImage(oldUrl) {
        delete replacedImages[oldUrl];
        GM_setValue('replacedImages', replacedImages);
        updateThumbnails(); // 更新缩略图
    }

    // 页面加载时应用替换的图片
    Object.entries(replacedImages).forEach(([oldUrl, newImageUrl]) => {
        replaceImages(oldUrl, newImageUrl);
    });
})();