您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Embeds a "Download" button before each file element and starts downloading and saving it to your computer.
当前为
// ==UserScript== // @name Kemono FIX+Download // @namespace GPT // @version 1.0.7 // @description Embeds a "Download" button before each file element and starts downloading and saving it to your computer. // @description:ru Встраивает кнопку Download перед каждым элементом с файлами и запускает скачивание с сохранением на компьютер // @author Wizzergod // @icon https://www.google.com/s2/favicons?sz=64&domain=kemono.su // @homepageURL https://greasyfork.org/ru/users/712283-wizzergod // @grant GM_download // @grant GM_xmlhttpRequest // @grant GM_info // @grant GM_addStyle // @match *://kemono.su/* // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; // Константа для включения/выключения замены изображений const ENABLE_IMAGE_REPLACEMENT = 1; // 1 - включено, 0 - выключено // Константа для включения/выключения замены URL для миниатюр const ENABLE_URL_REPLACEMENT = 1; // 1 - включено, 0 - выключено // Добавляем стиль для кнопки Download и контейнера GM_addStyle(` .download-container { margin-top: 10px; padding: 10px; border-radius: 5px; background-color: #0d0d0d52; background-position: center; background-repeat: no-repeat; text-align: center; border: none; width: 100%; display: inline-block; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease, background-color 0.3s ease; justify-content: center; font-size: 30px; opacity: 0.9; } .download-button { padding: 1px 7%; background-color: #4CAF50; background-position: center; background-repeat: no-repeat; color: white; border: none; cursor: pointer; font-size: 14px; display: inline-block; width: 100%; text-align: center; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease, background-color 0.3s ease; justify-content: center; font-size: 20px; opacity: 0.8; } .download-button:hover { background-color: #45a049; transform: scale(1.1); } .post__thumbnail { max-width: 10%; height: auto; cursor: pointer; padding: 5px; border: 5px; } .post__thumbnail img { cursor: pointer; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease, background-color 0.3s ease; } .post-card__image-container { max-width: 100%; height: auto; } .post__files { display: -webkit-inline-box; padding: 5px; border: 5px; } [data-testid='tracklist-row'] .newButtonClass { position: absolute; top: 50%; right: calc(100% + 10px); transform: translateY(-50%); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); } `); // Функция для скачивания изображения с использованием GM_xmlhttpRequest const downloadImage = (url) => { const originalFileName = url.split('/').pop().split('?')[0]; GM_xmlhttpRequest({ method: 'GET', url: url, responseType: 'blob', onload: (response) => { const link = document.createElement('a'); link.href = URL.createObjectURL(response.response); link.download = originalFileName; link.click(); URL.revokeObjectURL(link.href); }, onerror: (error) => { alert('Error fetching image: ' + error); } }); }; // Функция для замены атрибутов src и data-src изображений function replaceImageSources() { // Ищем все элементы с изображениями внутри ссылок const imageLinks = document.querySelectorAll('.post__files .post__thumbnail a.fileThumb.image-link'); imageLinks.forEach((link) => { const imgElement = link.querySelector('img'); if (imgElement) { const originalSrc = link.href; const dataSrc = imgElement.getAttribute('data-src'); // Если ENABLE_IMAGE_REPLACEMENT включен, заменяем src и data-src if (ENABLE_IMAGE_REPLACEMENT === 1) { imgElement.setAttribute('src', originalSrc); imgElement.setAttribute('data-src', originalSrc); } } }); } // Функция для замены URL для миниатюр function replaceThumbnailURLs() { const imageLinks = document.querySelectorAll('.post__files .post__thumbnail a.fileThumb.image-link, .post-card__image-container'); imageLinks.forEach((link) => { const imgElement = link.querySelector('img'); if (imgElement) { let src = imgElement.getAttribute('src'); let dataSrc = imgElement.getAttribute('data-src'); // Если ENABLE_URL_REPLACEMENT включен, заменяем URL if (ENABLE_URL_REPLACEMENT === 1) { if (src && src.includes('img.kemono.su/thumbnail/data/')) { src = src.replace('img.kemono.su/thumbnail/data/', 'n3.kemono.su/data/'); imgElement.setAttribute('src', src); } if (dataSrc && dataSrc.includes('img.kemono.su/thumbnail/data/')) { dataSrc = dataSrc.replace('img.kemono.su/thumbnail/data/', 'n3.kemono.su/data/'); imgElement.setAttribute('data-src', dataSrc); } } } }); } // Функция для добавления кнопок Download внутри контейнера function addDownloadButtons() { // Ищем все элементы с ссылками на файлы const fileElements = document.querySelectorAll('.post__files .post__thumbnail a.fileThumb.image-link'); fileElements.forEach((fileElement) => { // Проверяем, если кнопка уже добавлена, пропускаем этот элемент if (fileElement.parentElement.querySelector('.download-container')) { return; } // Создаем контейнер для кнопки Download const downloadContainer = document.createElement('div'); downloadContainer.classList.add('download-container'); // Создаем кнопку Download const downloadButton = document.createElement('button'); downloadButton.textContent = 'Download'; downloadButton.classList.add('download-button'); // Вставляем кнопку в контейнер downloadContainer.appendChild(downloadButton); // Вставляем контейнер под элементом с файлом fileElement.parentElement.appendChild(downloadContainer); // Слушаем клик по кнопке для скачивания файла downloadButton.addEventListener('click', (event) => { event.preventDefault(); // Предотвращаем стандартное действие ссылки const fileUrl = fileElement.href; // Вызываем функцию скачивания downloadImage(fileUrl); }); }); } // Двойная проверка добавления кнопок с таймаутом function checkAndAddButtons() { addDownloadButtons(); // Первая попытка добавить кнопки // Проверим через 500ms, если кнопки еще не добавлены setTimeout(() => { addDownloadButtons(); // Вторая попытка добавить кнопки, если они не появились }, 500); } // Вызываем проверку и добавление кнопок checkAndAddButtons(); // Используем MutationObserver для отслеживания изменений в DOM if (ENABLE_IMAGE_REPLACEMENT === 1 || ENABLE_URL_REPLACEMENT === 1) { const observer = new MutationObserver(() => { if (ENABLE_IMAGE_REPLACEMENT === 1) replaceImageSources(); if (ENABLE_URL_REPLACEMENT === 1) replaceThumbnailURLs(); }); // Начинаем отслеживание изменений в DOM observer.observe(document.body, { childList: true, subtree: true }); } // Если включены замены, выполняем их сразу после загрузки if (ENABLE_IMAGE_REPLACEMENT === 1) { replaceImageSources(); } if (ENABLE_URL_REPLACEMENT === 1) { replaceThumbnailURLs(); } })();