Gelbooru Visited and Type Highlighter

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

As of 15. 04. 2020. See the latest version.

// ==UserScript==
// @name         Gelbooru Visited and Type Highlighter
// @namespace    http://tampermonkey.net/
// @version      2.0.1
// @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   */
var imgUnvistedColor = '#E1F5FE'; // Color for unvisted images (Note: MUST BE A VALID, NON-TRANSPARENT COLOR FOR *VISITED* COLOR TO WORK)
var imgVisitedColor = '#2E7D32'; // Color for visited images
var webmUnvistedColor = '#1565C0'; // Color for unvisted WebMs
var webmVisitedColor = '#C62828'; // Color for visited WebMs
var gifUnvisitedColor = '#FFD600'; // Color for unvisited gifs/pngs
var gifVisitedColor = '#6A1B9A'; // Color for visited gifs/pngs

/*-------------------*/

(function() {
    'use strict';

    let searchParams = new URLSearchParams(window.location.search);
    var galleryLinks, css;

    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('.contain-push');
            if (!!galleryContainer) {
                // Get all image thumbnail links
                galleryLinks = galleryContainer.querySelectorAll('.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('onclick', 'window.location = "' + linkURL + '";return false;');
                    // Remove the "tags" attribute so the link being used for this
                    // is constant for the same image across all searches it is included in
                    var searchParams = new URLSearchParams(linkURL.search);
                    searchParams.delete('tags');
                    var newLinkURL = new URL(linkURL);
                    newLinkURL.search = searchParams.toString();
                    galleryLink.href = newLinkURL;
                });
            }
            // Apply borders
            css = document.createElement('style');
            css.innerHTML = `
			  .thumbnail-preview a .preview {
				  border: 3px solid ` + imgUnvistedColor + `;
				  margin: -3px;
			  }
			  .thumbnail-preview a:visited .preview {
				  border-color: ` + imgVisitedColor + `;
			  }
			  .thumbnail-preview a .preview.webm {
				  border-color: ` + webmUnvistedColor + ` !important;
			  }
			  .thumbnail-preview a:visited .preview.webm {
				  border-color: ` + webmVisitedColor + ` !important;
			  }
			  .thumbnail-preview a .preview[title*="animated_gif"],
			  .thumbnail-preview a .preview[title*="animated_png"],
			  .thumbnail-preview a .preview[title*="animated "]:not(.webm) {
				  border-color: ` + gifUnvisitedColor + `;
			  }
			  .thumbnail-preview a:visited .preview[title*="animated_gif"],
			  .thumbnail-preview a:visited .preview[title*="animated_png"],
			  .thumbnail-preview a:visited .preview[title*="animated "]:not(.webm) {
				  border-color: ` + gifVisitedColor + `;
			  }
			`;
            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)
            var 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
        galleryLinks = document.querySelectorAll('.thumb a');
        if (!!galleryLinks) {
            galleryLinks.forEach(galleryLink => {
                let linkURL = new URL(window.location.protocol + window.location.hostname + '/' + galleryLink.getAttribute('href'));
                // Set click to go to the original url to preserve next/previous feature
                galleryLink.setAttribute('onclick', 'window.location = "' + linkURL + '";return false;');
                // Remove the "pool" attribute so the link being used for this
                // is constant for the same image across all searches it is included in
                var searchParams = new URLSearchParams(linkURL.search);
                searchParams.delete('pool_id');
                var newLinkURL = new URL(linkURL);
                newLinkURL.search = searchParams.toString();
                galleryLink.href = newLinkURL;
            });
        }
        // Apply borders
        css = document.createElement('style');
        css.innerHTML = `
		  #content h3 + div *:not(:first-child) {
			  display: none !important;
		  }
		  #content h3 + div *:first-child {
			  margin-bottom: calc(-1 * (1em + 2px));
			  height: calc(1em + 2px);
			  background-color: currentColor;
			  display: block;
			  content: "";
			  border-radius: 6px;
		  }
		  .thumb a {
			  border: 1px solid #f0f0f0;
			  padding: 5px;
			  display: inline-block;
			  margin: -6px;
		  }
		  .thumb a .preview {
			  border: 3px solid ` + imgUnvistedColor + `;
			  margin: -3px;
		  }
		  .thumb a:visited .preview {
			  border-color: ` + imgVisitedColor + `;
		  }
		  .thumb a .preview[title*=" webm "] {
			  border: 5px solid ` + webmUnvistedColor + ` !important;
			  margin: -6px !important;
		  }
		  .thumb a:visited .preview[title*=" webm "] {
			  border-color: ` + webmVisitedColor + ` !important;
		  }
		  .thumb a .preview[title*="animated_gif"],
		  .thumb a .preview[title*="animated_png"],
		  .thumb a .preview[title*="animated "]:not([title*=" webm "]) {
			  border-color: ` + gifUnvisitedColor + `;
		  }
		  .thumb a:visited .preview[title*="animated_gif"],
		  .thumb a:visited .preview[title*="animated_png"],
		  .thumb a:visited .preview[title*="animated "]:not([title*=" webm "]) {
			  border-color: ` + gifVisitedColor + `;
		  }
		`;
        document.head.appendChild(css);
    }
})();