Jegged-Tooltips

Adds tooltips to Jegged game gudies.

Verzia zo dňa 26.03.2025. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name        Jegged-Tooltips
// @description Adds tooltips to Jegged game gudies.
// @version 1.0
// @license GPL-3.0-or-later
// @include http://jegged.com/*
// @include https://jegged.com/*
// @run-at document-end
// @namespace https://greasyfork.org/users/115055
// ==/UserScript==

let HOLD_TOOLTIP = false;

function showCardTooltip(card, elem, x, y) {
    removeCardTooltip();
    
    let tooltip = document.createElement("div");
    const margin = 10;
    const maxWidth = 650;
    
    let left = x;
    let top = y + window.scrollY;
       
    tooltip.id = "JeggedTooltip";
    tooltip.style.position = "absolute";

    tooltip.style.maxWidth = `${maxWidth}px`;
    tooltip.style.marginTop = `${margin}px`;
    tooltip.style.marginBottom = `${margin}px`;
    tooltip.style.marginRight = `${margin}px`;
    tooltip.style.marginLeft = `${margin}px`;
            
    card.style.marginTop = 0;
    card.style.marginBottom = 0;
       
    tooltip.append(card); 
    document.body.append(tooltip);
  
    const elemRect = elem.getBoundingClientRect();
    const tooltipRect = tooltip.getBoundingClientRect();
    let headerHeight;
    
    const headerElem = document.getElementById("header");
    if (headerElem !== null) {
        headerHeight = headerElem.getBoundingClientRect().height;
    } else {
        headerHeight = 0;
    }
    
    // if destination position goes beyond viewport width, clamp position
    // within viewport or at 0
    if (x + tooltipRect.width + (margin*2) > window.innerWidth) {
        left = Math.max(window.innerWidth - tooltipRect.width - (margin*2), 0)
    }

    // never cover target element with tooltip
    if (y < elemRect.top + elemRect.height + window.scrollY) {
        top = elemRect.top + elemRect.height + window.scrollY;
    }
    
    tooltip.style.left = `${left}px`;
    tooltip.style.top = `${top}px`;
    
    // if destination position goes beyond viewport height, 
    // and tooltip fits above elem, display above elem
    if (top + tooltipRect.height + (margin*2) > window.scrollY + window.innerHeight) {
        if (elemRect.top - tooltipRect.height - (margin*2) - headerHeight >= 0) {
            top = window.scrollY + elemRect.top - tooltipRect.height - (margin*2);
        }    
    }
    
    tooltip.style.left = `${left}px`;
    tooltip.style.top = `${top}px`;
}

function removeCardTooltip() {
    const tooltip = document.getElementById("JeggedTooltip");
    if (tooltip) {
        tooltip.remove();        
    }
}

async function onMouseEnterLink(event) {
    const href = event.target.href;
    const url = URL.parse(href);
    
    if (url.origin !== window.location.origin) {
        // only follow same-origin links
        return;
    }
    
    if (url.hash === "") {
        // only follow anchor links 
        return;   
    }
    
    
    let x = event.x;
    let y = event.y;
    
    const onMouseMove = (e) => {
        x = e.x;
        y = e.y;
    }
    
    document.addEventListener("mousemove", onMouseMove);
    
    try {
        const r = await fetch(url)
        if (!r.ok) {
          throw new Error(`Response status: ${r.status}`);
        }

        const text = await r.text();

        const parser = new DOMParser();
        const page = parser.parseFromString(text, "text/html");

        const destination = page.getElementById(url.hash.slice(1));
        if (destination === null) {
            throw new Error(`Destination anchor not found on linked page.`)
        }

        let card; 
        if (destination.closest(".alert") !== null) {
            // if destination belongs to a card-style alert, use this
            card = destination.closest(".alert");
        } else if (destination.closest("tr") !== null) {
            // if destination belongs to a table, use nearest row
            card = document.createElement("div");
            card.innerHTML = destination.closest("tr").innerHTML;
            card.classList = "alert alert-secondary";
        } else {
            // element does not have associated card, do not display tooltip
            return;
        };
        
        showCardTooltip(card, event.target, x, y);
    } finally {
        document.removeEventListener("mousemove", onMouseMove);
    }
}

function onMouseLeaveLink() {
    if (HOLD_TOOLTIP === false) {
        removeCardTooltip();        
    }
}

function onKeyDown(e) {
    if (e.key === "Shift") {
        HOLD_TOOLTIP = !HOLD_TOOLTIP;
        
        if (!HOLD_TOOLTIP) {
            removeCardTooltip();
        }
    } else if (e.key === "Escape") {
        removeCardTooltip();
    }
}

function addEventListenersToLinks() {
    const links = document.getElementsByTagName("a");
    
    for (const l of links) {
        console.log(l);
        l.addEventListener("mouseenter", onMouseEnterLink);
        l.addEventListener("mouseleave", onMouseLeaveLink);
    }
    
    document.addEventListener("keydown", onKeyDown);
}

(() => {
    addEventListenersToLinks();
})();