Greasy Fork is available in English.
Enhances your manga reading experience with a set of features:
当前为
// ==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());
})();