FurAffinity - Tags on Hover

Shows tags as tooltip when hovering over submissions

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         FurAffinity - Tags on Hover
// @namespace    Tampermonkey
// @version      2025-11-25
// @description  Shows tags as tooltip when hovering over submissions
// @author       CameronsAccount
// @match        *://*.furaffinity.net/*
// @icon         https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let useNewlines = GM_getValue('useNewlines', false);
    let menuCommandId = null;

    function updateTags() {
        const images = document.querySelectorAll('img[data-tags]');
        images.forEach(img => {
            const tags = img.getAttribute('data-tags');
            if (tags) {
                const formattedTags = tags.replace(/\s+/g, useNewlines ? '\n' : ', ');
                const existingTitle = img.getAttribute('title');

                if (!img.hasAttribute('data-original-title')) {
                    img.setAttribute('data-original-title', existingTitle || '');
                }

                const originalTitle = img.getAttribute('data-original-title');

                if (originalTitle) {
                    img.setAttribute('title', originalTitle + '\n\n' + formattedTags);
                } else {
                    img.setAttribute('title', formattedTags);
                }
            }
        });
    }

    function registerMenu() {
        if (menuCommandId !== null) {
            GM_unregisterMenuCommand(menuCommandId);
        }
        menuCommandId = GM_registerMenuCommand(
            useNewlines ? 'Switch to comma-separated' : 'Switch to newline-separated',
            () => {
                useNewlines = !useNewlines;
                GM_setValue('useNewlines', useNewlines);
                updateTags();
                registerMenu();
            }
        );
    }

    window.addEventListener('storage', (e) => {
        if (e.key === 'useNewlines') {
            useNewlines = GM_getValue('useNewlines', false);
            updateTags();
            registerMenu();
        }
    });

    registerMenu();
    updateTags();
})();