您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Marks previously visited images on Gelbooru search pages, and extends animation highlighting from webm to also include gifs.
当前为
// ==UserScript== // @name Gelbooru Visited and Type Highlighter // @namespace http://tampermonkey.net/ // @version 7.0.0 // @description Marks previously visited images on Gelbooru search pages, and extends animation highlighting from webm to also include gifs. // @author Xerodusk // @homepage https://greasyfork.org/en/users/460331-xerodusk // @match https://gelbooru.com/index.php* // @grant none // @icon https://gelbooru.com/favicon.png // ==/UserScript== /* jshint esversion: 6 */ /* configuration */ // Highlight colors // Values can be hexadecimal, rgb, rgba, hsl, hsla, color name, or whatever CSS color definitions your browser supports const imgUnvistedColor = '#E1F5FE'; // Color for unvisted images const imgVisitedColor = '#2E7D32'; // Color for visited images const webmUnvistedColor = '#1565C0'; // Color for unvisted WebMs const webmVisitedColor = '#C62828'; // Color for visited WebMs const gifUnvisitedColor = '#FFD600'; // Color for unvisited animated gifs/pngs const gifVisitedColor = '#6A1B9A'; // Color for visited animated gifs/pngs // Whether to display visited/unvisited highlighting for your own favorites // If false: Will only show visited/unvisited on other users' favorites pages // Animated GIF/WebM type highlighting will always be shown on all favorites // If true: Will also show visited/unvisited on your own favorites page const displayCurrentUserFavoritesVisited = true; /*-------------------*/ // Convert any image link URL to a single, standard form function normalizeURL(linkURL) { 'use strict'; // Remove "tags" and "pool" attributes so the link being used for this // is constant for the same image across all searches it is included in let searchParams = new URLSearchParams(linkURL.search); searchParams.forEach((value, key) => { if (!['page', 's', 'id'].includes(key)) { searchParams.delete(key); } }); let newLinkURL = new URL(linkURL); newLinkURL.search = searchParams.toString(); return newLinkURL; } // Convert link formation so it is consistent across all pages function normalizeLink(galleryLink) { 'use strict'; // Convert to absolute URL from whichever random form of relative URL they decided to use on this specific page with no real consistency let linkURL = new URL(galleryLink.getAttribute('href'), window.location.href); // Fix for Gelbooru's broken implementation of tags containing apostrophes under many navigational situations if (linkURL.href.includes(''')) { linkURL.href = linkURL.href.replace(''', '%27'); } // Set click to go to the original url to preserve next/previous feature galleryLink.setAttribute('onmousedown', 'this.setAttribute("href", "' + linkURL + '")'); galleryLink.setAttribute('onmouseup', 'this.setAttribute("href", "' + linkURL + '")'); galleryLink.setAttribute('onkeydown', 'if(event.keyCode == 13) { this.setAttribute("href", "' + linkURL + '") }'); // Convert URL to be the one URL for one image let newLinkURL = normalizeURL(linkURL); galleryLink.setAttribute('href', newLinkURL); galleryLink.setAttribute('onfocusout', 'this.setAttribute("href", "' + newLinkURL + '")'); } // Get cookie by name // From https://www.w3schools.com/js/js_cookies.asp function getCookie(cname) { 'use strict'; var name = cname + "="; var decodedCookie = decodeURIComponent(document.cookie); var ca = decodedCookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } // Get current user's user ID, if exists function getUserID() { 'use strict'; // Get user ID from cookie let userID = getCookie('user_id'); return userID ? userID : -1; } (function() { 'use strict'; let searchParams = new URLSearchParams(window.location.search); if (!searchParams.has('page') || !searchParams.has('s')) { return false; } if (searchParams.get('page') === 'post') { if (searchParams.get('s') == 'list') { // Search page // Get search results area let galleryContainer = document.querySelector('.thumbnail-container'); if (!!galleryContainer) { // Get all image thumbnail links let galleryLinks = galleryContainer.querySelectorAll('div.thumbnail-preview a'); if (!!galleryLinks) { galleryLinks.forEach(galleryLink => normalizeLink(galleryLink)); } } // Apply borders let css = document.createElement('style'); css.innerHTML = ` div.thumbnail-preview { background-color: transparent; } div.thumbnail-preview a img.thumbnail-preview:not(.webm) { outline: 3px solid ` + imgUnvistedColor + `; } div.thumbnail-preview a:visited img.thumbnail-preview { outline-color: ` + imgVisitedColor + `; } div.thumbnail-preview a img.thumbnail-preview.webm { border-color: ` + webmUnvistedColor + ` !important; } div.thumbnail-preview a:visited img.thumbnail-preview.webm { border-color: ` + webmVisitedColor + ` !important; } div.thumbnail-preview a img.thumbnail-preview[title*="animated_gif"], div.thumbnail-preview a img.thumbnail-preview[title*="animated_png"], div.thumbnail-preview a img.thumbnail-preview[title*="animated "]:not(.webm) { outline-color: ` + gifUnvisitedColor + `; } div.thumbnail-preview a:visited img.thumbnail-preview[title*="animated_gif"], div.thumbnail-preview a:visited img.thumbnail-preview[title*="animated_png"], div.thumbnail-preview a:visited img.thumbnail-preview[title*="animated "]:not(.webm) { outline-color: ` + gifVisitedColor + `; } div.thumbnail-preview a:focus img.thumbnail-preview:not(.webm) { outline-color: #FFA726 !important; } div.thumbnail-preview a:focus img.thumbnail-preview.webm { border-color: #FFA726 !important; } `; document.head.appendChild(css); } else if (searchParams.get('s') === 'view') { // Image page // Add URL without the "tags" attribute to the history // so as to make it match what the search results pages are modified for // (and avoid breaking back button functionality while we're at it) let url = new URL(window.location); url = normalizeURL(url); window.history.replaceState({}, '', '/' + url.href.substring(url.href.indexOf('/') + 1)); // "More Like This" results, currently in beta, could break, but this code should hypothetically never break the page from this end // Unfortunately, type highlighting is impossible with their current implementation, but visited highlighting is still possible /*let mltContainer = document.getElementById('post-view'); // Get all image thumbnail links let mltLinks = mltContainer.querySelectorAll('#right-col > div > div > a'); if (!!mltLinks) { mltLinks.forEach(mltLink => normalizeLink(mltLink)); }*/ // In case this becomes necessary later, what with this being a beta feature that could change rapidly and all let css = document.createElement('style'); css.innerHTML = css.innerHTML + ` a img.mltThumbs { padding: 5px; margin: 5px !important; outline: 3px solid ` + imgUnvistedColor + `; } a:visited img.mltThumbs { outline-color: ` + imgVisitedColor + `; } `; document.head.appendChild(css); } } else if (searchParams.get('s') === 'show' && searchParams.get('page') === 'pool') { // Pool page // Get image thumbnails area let galleryContainer = document.querySelector('.thumbnail-container'); if (!!galleryContainer) { // Get all image thumbnail links let galleryLinks = galleryContainer.querySelectorAll('span a'); if (!!galleryLinks) { galleryLinks.forEach(galleryLink => normalizeLink(galleryLink)); } } // Apply borders let css = document.createElement('style'); css.innerHTML = ` div.thumbnail-container a img { outline: 3px solid ` + imgUnvistedColor + `; } div.thumbnail-container a:visited img { outline-color: ` + imgVisitedColor + `; } div.thumbnail-container a img[title*=" webm "] { outline: 5px solid ` + webmUnvistedColor + ` !important; } div.thumbnail-container a:visited img[title*=" webm "] { outline-color: ` + webmVisitedColor + ` !important; } div.thumbnail-container a img[title*="animated_gif"], div.thumbnail-container a img[title*="animated_png"], div.thumbnail-container a img[title*="animated "]:not([title*=" webm "]) { outline-color: ` + gifUnvisitedColor + `; } div.thumbnail-container a:visited img[title*="animated_gif"], div.thumbnail-container a:visited img[title*="animated_png"], div.thumbnail-container a:visited img[title*="animated "]:not([title*=" webm "]) { outline-color: ` + gifVisitedColor + `; } div.thumbnail-container a:focus img { outline-color: #FFA726 !important; } `; document.head.appendChild(css); } else if (searchParams.get('s') === 'view' && searchParams.get('page') === 'favorites') { // Favorites page // Apply borders let css = document.createElement('style'); css.innerHTML = ` .thumb { margin: 5px; } .thumb a img { padding: 5px; margin: 5px; } .thumb a img[title*="animated_gif"], .thumb a img[title*="animated_png"], .thumb a img[title*="animated "]:not([title*=" webm"]) { outline: 3px solid ` + gifUnvisitedColor + `; } .thumb a img[title*=" webm"] { outline: 5px solid ` + webmUnvistedColor + `; } `; let userID = displayCurrentUserFavoritesVisited ? -1 : getUserID(); if (searchParams.has('id') && searchParams.get('id') != userID) { css.innerHTML = css.innerHTML + ` .thumb a img { outline: 3px solid ` + imgUnvistedColor + `; } .thumb a:visited img { outline-color: ` + imgVisitedColor + `; } .thumb a:visited img[title*=" webm"] { outline-color: ` + webmVisitedColor + `; } .thumb a:visited img[title*="animated_gif"], .thumb a:visited img[title*="animated_png"], .thumb a:visited img[title*="animated "]:not([title*=" webm"]) { outline-color: ` + gifVisitedColor + `; } `; } document.head.appendChild(css); } else if (searchParams.get('s') === 'saved_search' && searchParams.get('page') === 'tags') { // Saved Searches page // Apply borders let css = document.createElement('style'); css.innerHTML = ` .container-fluid > .thumb a .thumbnail-preview { outline: 3px solid ` + imgUnvistedColor + `; } .container-fluid > .thumb a:visited .thumbnail-preview { outline-color: ` + imgVisitedColor + `; } .container-fluid > .thumb a .thumbnail-preview[alt*="animated_gif"], .container-fluid > .thumb a .thumbnail-preview[alt*="animated_png"], .container-fluid > .thumb a .thumbnail-preview[alt*="animated "]:not([alt*=" webm"]) { outline: 3px solid ` + gifUnvisitedColor + `; } .container-fluid > .thumb a .thumbnail-preview[alt*=" webm"] { outline: 5px solid ` + webmUnvistedColor + `; margin: 5px 7px; } .container-fluid > .thumb a:visited .thumbnail-preview[alt*=" webm"] { outline-color: ` + webmVisitedColor + `; } .container-fluid > .thumb a:visited .thumbnail-preview[alt*="animated_gif"], .container-fluid > .thumb a:visited .thumbnail-preview[alt*="animated_png"], .container-fluid > .thumb a:visited .thumbnail-preview[alt*="animated "]:not([alt*=" webm"]) { outline-color: ` + gifVisitedColor + `; } `; document.head.appendChild(css); } })();