Sleazy Fork is available in English.

Gelbooru Respect Tag Blacklist Everywhere

Properly hides image thumbnails that have user-blacklisted tags on Profile pages, Wiki entries, and other users' Favorites pages.

Від 02.12.2020. Дивіться остання версія.

// ==UserScript==
// @name         Gelbooru Respect Tag Blacklist Everywhere
// @namespace    http://tampermonkey.net/
// @version      5.0.0
// @description  Properly hides image thumbnails that have user-blacklisted tags on Profile pages, Wiki entries, and other users' Favorites pages.
// @author       Xerodusk
// @homepage     https://greasyfork.org/en/users/460331-xerodusk
// @include      https://gelbooru.com/index.php*page=account*s=profile*
// @include      https://gelbooru.com/index.php*page=favorites*
// @include      https://gelbooru.com/index.php*page=wiki*s=view*
// @include      https://gelbooru.com/index.php*page=comment*s=list*
// @grant        none
// @icon         https://gelbooru.com/favicon.png
// ==/UserScript==
/* jshint esversion: 6 */

/*   configuration   */

// Whether to hide blacklisted image placeholders on page
// If true:  Will blur out blacklisted images, but not remove them completely (like main gallery pages)
// If false: Will completely remove blacklisted image thumbnails from the page (like search pages)
const removeBlacklistedThumbnailsEntirely = false;

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

// Get cookie by name
// From https://www.w3schools.com/js/js_cookies.asp
// Modified by me to fix bugs
function getCookie(cname) {
    'use strict';

    var name = cname + "=";
    var cookie = document.cookie.split(';');
    var ca = cookie.map(item => decodeURIComponent(item));
    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 tag blacklist as list of strings
function GetBlockedTags() {
    'use strict';

    // Get blocked tags string from cookie
    let blockedTags = getCookie('tag_blacklist');
    blockedTags = htmlDecode(blockedTags).replace(/%20/g, ' ');

    // Split tags into list
    blockedTags = blockedTags.split(' ');

    return blockedTags;
}

// Get current user's user ID, if exists
function getUserID() {
    'use strict';

    // Get user ID from cookie
    const userID = window.Cookie.get('user_id');

    return userID ? parseInt(userID) : -1;
}

// Decode encoded characters in tags for proper matching
function htmlDecode(input) {
    'use strict';

    const tempElem = document.createElement('div');
    tempElem.innerHTML = input;
    return tempElem.childNodes.length === 0 ? '' : tempElem.childNodes[0].nodeValue;
}

// Get tags list for image thumbnail as list of strings
function GetImageTags(imageThumb) {
    'use strict';

    const tagsString = imageThumb.getElementsByTagName('img')[0].getAttribute('title') || imageThumb.getElementsByTagName('img')[0].getAttribute('alt') || [];
    const tagsList = htmlDecode(tagsString).trim().split(' ');

    return tagsList;
}

// Mark images as blacklisted for profile page
function MarkProfileBlacklistedImages(blockedTags) {
    'use strict';

    // Get all image thumbnails on page
    const imageThumbs = [...document.getElementsByClassName('profileThumbnailPadding')];

    // Apply blacklist to image thumbnails
    imageThumbs.forEach(imageThumb => {
        const tags = GetImageTags(imageThumb);
        if (tags.some(tag => blockedTags.includes(tag))) {
            if (removeBlacklistedThumbnailsEntirely) {
                imageThumb.remove();
            } else {
                imageThumb.classList.add('blacklisted');
            }
        }
    });
}

// Mark images as blacklisted for other users' favorites pages
function MarkFavoritesBlacklistedImages(blockedTags, searchParams) {
    'use strict';

    // Check if it is your own favorites before applying anything
    const userID = getUserID();
    if (searchParams.has('id') && parseInt(searchParams.get('id')) == userID) {
        return;
    }

    // Get all image thumbnails on page
    const imageThumbs = document.querySelectorAll('span.thumb');

    // Apply blacklist to image thumbnails
    imageThumbs.forEach(imageThumb => {
        const tags = GetImageTags(imageThumb);
        if (tags.some(tag => blockedTags.includes(tag))) {
            if (removeBlacklistedThumbnailsEntirely) {
                imageThumb.remove();
            } else {
                imageThumb.classList.add('blacklisted');
            }
        }
    });

    const css = document.createElement('style');

    css.appendChild(document.createTextNode(`
        .blacklisted {
            opacity: .2;
            filter: blur(10px);
        }
    `));

    document.head.appendChild(css);
}

// Mark images as blacklisted for wiki page
function MarkWikiBlacklistedImages(blockedTags) {
    'use strict';

    // Get all image thumbnails on page
    const imageThumbs = document.querySelectorAll('a[href^="index.php?page=post&s=view&id="]');

    // Apply blacklist to image thumbnails
    imageThumbs.forEach(imageThumb => {
        const tags = GetImageTags(imageThumb);
        if (tags.some(tag => blockedTags.includes(tag))) {
            if (removeBlacklistedThumbnailsEntirely) {
                imageThumb.remove();
            } else {
                imageThumb.classList.add('blacklisted');
            }
        }
    });
}


// Mark images as blacklisted for comments tab
function MarkCommentsBlacklistedImages(blockedTags) {
    'use strict';

    // Get all image thumbnails on page
    const imageThumbs = document.querySelectorAll('#comment-list .post .col1 a[href*="page=post&s=view"]');

    // Apply blacklist to image thumbnails
    imageThumbs.forEach(imageThumb => {
        const tags = GetImageTags(imageThumb);
        if (tags.some(tag => blockedTags.includes(tag))) {
            if (removeBlacklistedThumbnailsEntirely) {
                imageThumb.closest('div.post').remove();
            } else {
                imageThumb.classList.add('blacklisted');
            }
        }
    });

    const css = document.createElement('style');

    css.appendChild(document.createTextNode(`
        .blacklisted {
            opacity: .2;
            filter: blur(10px);
        }
    `));

    document.head.appendChild(css);
}

// Mark images as blacklisted
function MarkBlacklistedImages(blockedTags) {
    'use strict';

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

    if (!searchParams.has('s')) {
        return false;
    }
    if (searchParams.get('s') === 'profile') {
        MarkProfileBlacklistedImages(blockedTags);
    } else if (searchParams.get('page') === 'favorites') {
        MarkFavoritesBlacklistedImages(blockedTags, searchParams);
    } else if (searchParams.get('page') === 'wiki') {
        MarkWikiBlacklistedImages(blockedTags);
    } else if (searchParams.get('page') === 'comment') {
        MarkCommentsBlacklistedImages(blockedTags);
    }
}

(function() {
    'use strict';

    const blockedTags = GetBlockedTags();
    if (blockedTags) {
        MarkBlacklistedImages(blockedTags);
    }
})();