Gelbooru Visited and Type Highlighter

Marks previously visited images on Gelbooru search pages, and extends animation highlighting from webm to also include gifs.

Fra 15.05.2020. Se den seneste versjonen.

// ==UserScript==
// @name         Gelbooru Visited and Type Highlighter
// @namespace    http://tampermonkey.net/
// @version      4.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   */
const imgUnvistedColor = '#E1F5FE'; // Color for unvisted images (Note: MUST BE A VALID, NON-TRANSPARENT COLOR FOR *VISITED* COLOR TO WORK)
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 gifs/pngs
const gifVisitedColor = '#6A1B9A'; // Color for visited gifs/pngs
// Values can be hexadecimal, rgb, rgba, hsl, hsla, color name, or whatever CSS color definitions your browser supports
/*-------------------*/

(function() {
    'use strict';

    let searchParams = new URLSearchParams(window.location.search);

    if (searchParams.has('page') && searchParams.has('s') && 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 => {
                        let linkURL = new URL('https:' + galleryLink.getAttribute('href'));
                        // 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 || event.keyCode == 32) { this.setAttribute("href", "' + linkURL + '") }');
                        // Remove the "tags" attribute 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.delete('tags');
                        let newLinkURL = new URL(linkURL);
                        newLinkURL.search = searchParams.toString();
                        galleryLink.setAttribute("href", newLinkURL);
                        galleryLink.setAttribute('onfocusout', 'this.setAttribute("href", "' + newLinkURL + '")');
                    });
                }
            }
            // 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 {
				  outline-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);
            searchParams.delete('tags');
            searchParams.delete('pool_id');
            url.search = searchParams.toString();
            window.history.replaceState({}, '', '/' + url.href.substring(url.href.indexOf('/') + 1));
        }
    } else if (searchParams.has('page') && searchParams.has('s') && searchParams.get('s') === 'show' && searchParams.get('page') === 'pool') { // Pool page
        // Get all image thumbnail links
        let galleryContainer = document.querySelector('.thumbnail-container');
        if (!!galleryContainer) {
            // Get all image thumbnail links
            let galleryLinks = galleryContainer.querySelectorAll('span a');
            if (!!galleryLinks) {
                galleryLinks.forEach(galleryLink => {
                    let linkURL = new URL(window.location.protocol + window.location.hostname + '/' + galleryLink.getAttribute('href'));
                    // Get original onclick to preserve delete
                    // Set click when not in delete mode 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 + '") }');
                    // Remove the "pool" attribute 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.delete('pool_id');
                    let newLinkURL = new URL(linkURL);
                    newLinkURL.search = searchParams.toString();
                    galleryLink.setAttribute("href", newLinkURL);
                    galleryLink.setAttribute('onfocusout', 'this.setAttribute("href", "' + newLinkURL + '")');
                });
            }
        }
        // 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);
    }
})();