Greasy Fork

Manga Enhancer

Enhances your manga reading experience with a set of features:

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

// ==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());

})();