您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a styled download button below thumbnails on safebooru.org and downloads in background.
// ==UserScript== // @name Safebooru Auto Downloader // @namespace http://tampermonkey.net/ // @version 2.1 // @description Adds a styled download button below thumbnails on safebooru.org and downloads in background. // @match https://safebooru.org/* // @grant GM_download // @grant GM_xmlhttpRequest // @connect safebooru.org // @author Kyura // ==/UserScript== (function () { "use strict"; function addButtons() { document.querySelectorAll(".image-list span.thumb").forEach(span => { let link = span.querySelector("a"); if (!link || link.querySelector(".tm-download-btn")) return; // Flex layout link.style.display = "flex"; link.style.flexDirection = "column"; link.style.alignItems = "stretch"; span.style.marginBottom = "28px"; let btn = document.createElement("button"); btn.innerText = "Download"; btn.className = "tm-download-btn"; btn.style.width = "100%"; btn.style.height = "22px"; btn.style.marginTop = "6px"; btn.style.background = "#e0e0e0"; btn.style.border = "1px solid #aaa"; btn.style.borderRadius = "4px"; btn.style.cursor = "pointer"; btn.style.fontSize = "12px"; btn.style.transition = "background 0.2s"; btn.style.position = "relative"; btn.style.zIndex = "10"; btn.addEventListener("mouseenter", () => btn.style.background = "#d0d0d0"); btn.addEventListener("mouseleave", () => btn.style.background = "#e0e0e0"); btn.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // Fetch post page in background GM_xmlhttpRequest({ method: "GET", url: link.href, onload: function (res) { if (res.status === 200) { // Parse HTML let parser = new DOMParser(); let doc = parser.parseFromString(res.responseText, "text/html"); let img = doc.querySelector("#image"); if (img && img.src) { // Clean filename let filename = img.src.split("/").pop().split("?")[0]; console.log("[TM] Downloading:", img.src, "→", filename); GM_download(img.src, filename); } else { console.log("[TM] No image found on post page."); } } else { console.error("[TM] Failed to fetch post page:", res.status); } }, onerror: function (err) { console.error("[TM] GM_xmlhttpRequest error:", err); } }); }); link.appendChild(btn); }); } // Observe page for thumbnails const rootObserver = new MutationObserver(() => { if (document.querySelector(".image-list")) { addButtons(); const list = document.querySelector(".image-list"); if (list) { const innerObserver = new MutationObserver(addButtons); innerObserver.observe(list, { childList: true, subtree: true }); } rootObserver.disconnect(); } }); rootObserver.observe(document.documentElement || document, { childList: true, subtree: true }); // Try adding immediately if DOM is already ready if (document.readyState !== "loading") addButtons(); })();