您需要先安装一个扩展,例如 篡改猴、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 10.1.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 // @include https://gelbooru.com/index.php*page=post*s=list* // @include https://gelbooru.com/index.php*page=post*s=view* // @include https://gelbooru.com/index.php*page=pool*s=show* // @include https://gelbooru.com/index.php*page=favorites*s=view* // @include https://gelbooru.com/index.php*page=tags*s=saved_search* // @include https://gelbooru.com/index.php*page=wiki*s=view* // @include https://gelbooru.com/index.php*page=account*s=profile* // @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; /*-------------------*/ function binarySearch(items, value, first, last) { if (items.length === 0) { return -1; } const middle = (last + first) >> 1; if (last - first <= 1) { return (value < items[middle]) ? middle - 1 : middle; } if (value === items[middle]) { return middle; } if (value < items[middle]) { return binarySearch(items, value, first, middle); } return binarySearch(items, value, middle, last); } // Tests whether value is in items function truthyBinarySearch(items, value) { if (items.length === 0 || value > items[items.length - 1] || value < items[0]) { return false; } if (value === items[0] || value === items[items.length - 1]) { return true; } const index = binarySearch(items, value, 0, items.length - 1); return (items[index] === value); } // Inserts value in items if not already present, returns whether insertion took place function binaryInsertion(items, value) { if (items.length === 0 || value > items[items.length - 1]) { items.push(value); return true; } if (value < items[0]) { items.unshift(value); return true; } const index = binarySearch(items, value, 0, items.length - 1); if (items[index] !== value) { items.splice(index + 1, 0, value); return true; } return false; } // Check if link is in visited list function markIfVisited(galleryLink, visitedIDs) { const linkURL = new URL(galleryLink.getAttribute('href'), window.location.href); const linkSearchParams = new URLSearchParams(linkURL.search); const id = parseInt(linkSearchParams.get('id')); if (truthyBinarySearch(visitedIDs, id)) { galleryLink.classList.add('visited'); } } // Get cookie by name // From https://www.w3schools.com/js/js_cookies.asp function getCookie(cname) { 'use strict'; const name = cname + "="; const decodedCookie = decodeURIComponent(document.cookie); const ca = decodedCookie.split(';'); for (let i = 0; i < ca.length; i++) { let 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 const userID = getCookie('user_id'); return userID ? parseInt(userID) : -1; } (function() { 'use strict'; // Find out what kind of page we're on const searchParams = new URLSearchParams(window.location.search); if (!searchParams.has('page') || !searchParams.has('s')) { return false; } const page = searchParams.get('page'); const s = searchParams.get('s'); if (page === 'post') { if (s === 'view') { // Image page // Get id of current image const url = new URL(window.location); const currentURLSearchParams = new URLSearchParams(url.search); const id = parseInt(currentURLSearchParams.get('id')); // Get list of visited images let visitedIDs; function updateVisitedIDs(event) { visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; if (binaryInsertion(visitedIDs, id)) { localStorage.setItem('visitedIDs', JSON.stringify(visitedIDs)); } else { window.removeEventListener('storage', updateVisitedIDs); } } window.addEventListener('storage', updateVisitedIDs); // Update changes if another image being loaded in a different window changes the list before this one updateVisitedIDs(); // "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 const mltContainer = document.getElementsByClassName('contain-push')[0]; // Get all image thumbnail links const mltLinks = mltContainer.querySelectorAll('#right-col > div > div > a'); if (!!mltLinks) { mltLinks.forEach(mltLink => markIfVisited(mltLink, visitedIDs)); } const css = document.createElement('style'); css.innerHTML = css.innerHTML + ` a img.mltThumbs { padding: 5px; margin: 5px !important; outline: 3px solid ` + imgUnvistedColor + `; } a:visited img.mltThumbs, a.visited img.mltThumbs { outline-color: ` + imgVisitedColor + `; } `; document.head.appendChild(css); } else if (s === 'list') { // Search page // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; if (visitedIDs.length > 0) { // Get search results area const galleryContainer = document.querySelector('.thumbnail-container'); if (!!galleryContainer) { // Get all image thumbnail links const galleryLinks = galleryContainer.querySelectorAll('div.thumbnail-preview a'); if (!!galleryLinks) { galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } } } // Apply borders const 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, 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, 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), 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 (page === 'pool' && s === 'show') { // Pool page // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; if (visitedIDs.length > 0) { // Get image thumbnails area const galleryContainer = document.querySelector('.thumbnail-container'); if (!!galleryContainer) { // Get all image thumbnail links const galleryLinks = galleryContainer.querySelectorAll('span a'); if (!!galleryLinks) { galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } } } // Apply borders const css = document.createElement('style'); css.innerHTML = ` div.thumbnail-container a img { outline: 3px solid ` + imgUnvistedColor + `; } div.thumbnail-container a:visited img, 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 "], 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 "]), 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 (page === 'favorites' && s === 'view') { // Favorites page // Apply borders const 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 + `; } `; const userID = displayCurrentUserFavoritesVisited ? -1 : getUserID(); if (searchParams.has('id') && parseInt(searchParams.get('id')) != userID) { // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; // Mark visited links if (visitedIDs.length > 0) { const galleryLinks = document.querySelectorAll('.thumb a[href*="page=post"]'); galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } css.innerHTML += ` .thumb a img { outline: 3px solid ` + imgUnvistedColor + `; } .thumb a:visited img, .thumb a.visited img { outline-color: ` + imgVisitedColor + `; } .thumb a:visited img[title*=" webm"], .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"]), .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 (page === 'tags' && s === 'saved_search') { // Saved Searches page // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; // Mark visited links if (visitedIDs.length > 0) { const galleryLinks = document.querySelectorAll('.container-fluid > .thumb a'); galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } // Apply borders const css = document.createElement('style'); css.innerHTML = ` .container-fluid > .thumb a .thumbnail-preview { outline: 3px solid ` + imgUnvistedColor + `; } .container-fluid > .thumb a:visited .thumbnail-preview, .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"], .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"]), .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); } else if (page === 'wiki' && s === 'view') { // Wiki entry page // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; // Mark visited links if (visitedIDs.length > 0) { const galleryLinks = document.querySelectorAll('tr > td:nth-child(2) a[href*="s=view"]'); galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } // Apply borders const css = document.createElement('style'); css.innerHTML = ` a .thumbnail-preview img { padding: 5px; outline: 3px solid ` + imgUnvistedColor + `; } a:visited .thumbnail-preview img, a.visited .thumbnail-preview img { outline-color: ` + imgVisitedColor + `; } a .thumbnail-preview img[alt*="animated_gif"], a .thumbnail-preview img[alt*="animated_png"], a .thumbnail-preview img[alt*="animated "]:not([alt*=" webm"]) { outline: 3px solid ` + gifUnvisitedColor + `; } a .thumbnail-preview img[alt*=" webm"] { outline: 5px solid ` + webmUnvistedColor + `; margin: 5px 7px; } a:visited .thumbnail-preview img[alt*=" webm"], a.visited .thumbnail-preview img[alt*=" webm"] { outline-color: ` + webmVisitedColor + `; } a:visited .thumbnail-preview img[alt*="animated_gif"], a:visited .thumbnail-preview img[alt*="animated_png"], a:visited .thumbnail-preview img[alt*="animated "]:not([alt*=" webm"]), a.visited .thumbnail-preview img[alt*="animated_gif"], a.visited .thumbnail-preview img[alt*="animated_png"], a.visited .thumbnail-preview img[alt*="animated "]:not([alt*=" webm"]) { outline-color: ` + gifVisitedColor + `; } `; document.head.appendChild(css); } else if (page === 'account' && s === 'profile') { // Profile page // Get list of visited images const visitedIDs = JSON.parse(localStorage.getItem('visitedIDs')) || []; // Mark visited links if (visitedIDs.length > 0) { const galleryLinks = document.querySelectorAll('a[href*="s=view"]'); galleryLinks.forEach(galleryLink => markIfVisited(galleryLink, visitedIDs)); } // Apply borders const css = document.createElement('style'); css.innerHTML = ` .profileThumbnailPadding { max-width: none !important; } #statistics > span:last-child { display: none; } a[href*="s=view"] img { padding: 5px; outline: 3px solid ` + imgUnvistedColor + `; max-height: 190px; object-fit: scale-down; } a[href*="s=view"]:visited img, a[href*="s=view"].visited img { outline-color: ` + imgVisitedColor + `; } a[href*="s=view"] img[alt*="animated_gif"], a[href*="s=view"] img[alt*="animated_png"], a[href*="s=view"] img[alt*="animated "]:not([alt*=" webm"]) { outline: 3px solid ` + gifUnvisitedColor + `; } a[href*="s=view"] img[alt*=" webm"] { outline: 5px solid ` + webmUnvistedColor + `; margin: 5px 7px; } a[href*="s=view"]:visited img[alt*=" webm"], a[href*="s=view"].visited img[alt*=" webm"] { outline-color: ` + webmVisitedColor + `; } a[href*="s=view"]:visited img[alt*="animated_gif"], a[href*="s=view"]:visited img[alt*="animated_png"], a[href*="s=view"]:visited img[alt*="animated "]:not([alt*=" webm"]), a[href*="s=view"].visited img[alt*="animated_gif"], a[href*="s=view"].visited img[alt*="animated_png"], a[href*="s=view"].visited img[alt*="animated "]:not([alt*=" webm"]) { outline-color: ` + gifVisitedColor + `; } `; document.head.appendChild(css); } })();