Greasy Fork

Greasy Fork is available in English.

Manga Enhancer

Enhances your manga reading experience with a set of features:

当前为 2023-12-25 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          Manga Enhancer
// @namespace     Moose
// @version       2.1
// @description   Enhances your manga reading experience with a set of features:
//                  1. Navigate between chapters using arrow keys. also works by 1+ -1 on chapters url to find new chapters
//                  2. Close tabs with a button press. Default "/" can be changed on line #101
//                  3. Remove Gaps between pages.
//                  4. Auto-reload on image loading errors. also tells user that some images are missing
//                  5. Image size as a percentage of screen width, also save preferences. found at the top right of screen
//
// If the script doesn't work on the site, add the site URL as shown below.
// @match 		  	https://manganelo.com/*
// @match			    https://mangakakalot.com/*
// @match         https://readmanganato.com/*
// @match         https://manganato.com/*
// @match         https://chapmanganato.com/*
// @match         https://chapmanganato.to/*
//
// @icon        https://manganato.com/favicon-96x96.png

// @author        Moose, ChatGPT
// @description   12/26/2023
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    // Counter for image loading attempts
    let attempts = 0;
    const maxAttempts = 4;
    const maxReloadPrompts = 2; // Maximum number of reload prompts

    // Function to close the error message
    function closeErrorMessage() {
        const errorContainer = document.getElementById('manga-enhancer-error-message');
        if (errorContainer) {
            errorContainer.remove();
        }}

    // Function to display an error prompt
    function displayErrorPrompt() {
        if (attempts <= maxReloadPrompts) {
            const reloadPrompt = prompt('Error loading images. Do you want to reload the page?');
            if (reloadPrompt && reloadPrompt.toLowerCase() === 'yes') {
                location.reload();
            } else {
                // If the user chooses not to reload, close the error message
                closeErrorMessage();
            }
        }
    }

    // Function to check image load status periodically
    function checkImageLoad() {
        attempts++;

        const images = document.querySelectorAll('img');
        for (const image of images) {
            if (!image.complete || !image.naturalWidth) {
                if (attempts >= maxAttempts) {
                    // Display an error message after maxAttempts
                    displayErrorPrompt();
                } else {
                    // Don't reload the page if the error is still active
                    return;
                }}}

        // If no error is found, reset attempts
        attempts = 0;
    }

    // Add event listener for arrow key presses
    window.addEventListener('keydown', function (event) {
        if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
           const isLeftArrow = event.key === 'ArrowLeft';

            const currentUrl = window.location.href;
            const match = currentUrl.match(/:\/\/([^/]+)\/([^/]+)\/chapter-(\d+)/);

            if (match) {
                const domain = match[1];
                const path = match[2];
                const currentChapter = parseInt(match[3], 10);

                // Increment or decrement the current chapter based on arrow key
                const newChapter = isLeftArrow ? currentChapter - 1 : currentChapter + 1;

                // Ensure the new chapter is non-negative
                if (newChapter >= 0) {
                    const newUrl = currentUrl.replace(`://${domain}/${path}/chapter-${currentChapter}`, `://${domain}/${path}/chapter-${newChapter}`);
                   window.location.href = newUrl;
                }
            }
           event.preventDefault(); // Prevent default behavior of arrow keys (e.g., scrolling)
       }
    });

// Add event listener for forward slash key press
    window.addEventListener('keydown', function (event) {
        // Forward slash key press
        if (event.key === '/' && event.code === 'Slash') {
            // Close the current tab
            window.close();
        }
    });

    // Check image load status periodically
    setInterval(checkImageLoad, 5000); // Adjust the interval as needed

    // Remove space between pages
    const targetDivs = document.querySelectorAll('div[style*="max-width: 620px; max-height: 310px; margin: 10px auto; overflow: hidden; display: block;"]');
    targetDivs.forEach(targetDiv => {
        // Change the margin property to "0" instead of "10px auto"
        targetDiv.style.margin = '0';
    });

    // Size Changer Section
    let isResizeEnabled = localStorage.getItem('isResizeEnabled') === 'true';

    // Function to set and save the image size as a percentage of screen width
    function setImageSize(percentage) {
        // Check if the current URL contains "chapter-#"
        if (window.location.href.includes('chapter-')) {
            // Set the image size for all images in your application logic
            const images = document.querySelectorAll('img');
            images.forEach(image => {
                image.style.width = isResizeEnabled ? percentage + '%' : ''; // Always set the size, even if resizing is enabled
            });

            // Save the user's preference in local storage
            localStorage.setItem('userImageSizePercentage', percentage);
        }}

    // Function to get the saved image size percentage
    function getSavedImageSizePercentage() {
        // Retrieve the user's saved preference from local storage
        const savedPercentage = localStorage.getItem('userImageSizePercentage');

        // Return the saved percentage or a default value if not found
        return savedPercentage ? parseFloat(savedPercentage) : 50; // Default percentage: 50%
    }

    // Function to toggle image resizing
    function toggleResize() {
        isResizeEnabled = !isResizeEnabled;
        const buttonText = isResizeEnabled ? 'Toggle Resize Enabled' : 'Toggle Resize Disabled';

        // Change the text on the "Toggle Resize" button
        toggleResizeButton.textContent = buttonText;

        // Save the current state of "Toggle Resize" in local storage
        localStorage.setItem('isResizeEnabled', isResizeEnabled);

        // Adjust the image size based on the current state of "Toggle Resize"
        setImageSize(getSavedImageSizePercentage());
    }

    // Function to handle button click and prompt the user for a new size percentage
    function handleButtonClick() {
        // Ask the user for a new image size percentage
        const newPercentage = prompt('Enter the new image size as a percentage of screen width:', getSavedImageSizePercentage());

        // Validate and set the new size percentage
        if (newPercentage !== null) {
            const validatedPercentage = parseFloat(newPercentage);
            if (!isNaN(validatedPercentage) && validatedPercentage > 0 && validatedPercentage <= 100) {
                setImageSize(validatedPercentage);
            } else {
                alert('Invalid input. Please enter a percentage between 1 and 100.');
            }}}

    // Create a button to trigger image size adjustment
    const resizeButton = document.createElement('button');
    resizeButton.textContent = 'Adjust Image Size';
    resizeButton.style.position = 'absolute';
    resizeButton.style.top = '10px';
    resizeButton.style.right = '10px';
    resizeButton.addEventListener('click', function () {
        handleButtonClick();
        setImageSize(getSavedImageSizePercentage()); // Adjust image size when resizing is toggled
    });

    // Append the button to the body
    document.body.appendChild(resizeButton);

    // Create a button to toggle image resizing
    const toggleResizeButton = document.createElement('button');
    toggleResizeButton.textContent = isResizeEnabled ? 'Toggle Resize Enabled' : 'Toggle Resize Disabled';
    toggleResizeButton.style.position = 'absolute';
    toggleResizeButton.style.top = '50px';
    toggleResizeButton.style.right = '10px';
    toggleResizeButton.addEventListener('click', toggleResize);

    // Append the button to the body
    document.body.appendChild(toggleResizeButton);

    // Initialize the image size percentage and "Toggle Resize" state on script load
    isResizeEnabled = localStorage.getItem('isResizeEnabled') === 'true';
    const buttonText = isResizeEnabled ? 'Toggle Resize Enabled' : 'Toggle Resize Disabled';
    toggleResizeButton.textContent = buttonText;
    setImageSize(getSavedImageSizePercentage());

})();