User:Monster Domosed/common.js: Difference between revisions

Add support for HeroIcon for tooltips?
Scrapped HeroIcon hovers for now, added support for AbilityIcon for tooltips?
Line 303: Line 303:


/**
/**
  * Custom Item & Hero Tooltips — replaces Extension:Popups for .item-link-wrapper and .hero-link-wrapper links
  * Custom Tooltips — replaces Extension:Popups for .item-link-wrapper and .ability-link-wrapper links
  */
  */
( function () {
( function () {
Line 386: Line 386:
     }
     }


     /* ─── Show tooltip for item ─── */
     /* ─── Show tooltip ─── */
     function showItemTooltip( anchor, itemName ) {
     function showTooltip( anchor, name, type ) {
         clearTimeout( hideTimer );
         clearTimeout( hideTimer );
         clearTimeout( showTimer );
         clearTimeout( showTimer );
Line 394: Line 394:
             var tt = getTooltip();
             var tt = getTooltip();
             currentTarget = anchor;
             currentTarget = anchor;
            var cacheKey = type + ':' + name;


             // Already cached — show immediately
             // Already cached — show immediately
             if ( tooltipCache[ 'item_' + itemName ] ) {
             if ( tooltipCache[ cacheKey ] ) {
                 tt.html( tooltipCache[ 'item_' + itemName ] ).show();
                 tt.html( tooltipCache[ cacheKey ] ).show();
                 positionTooltip( anchor );
                 positionTooltip( anchor );
                 return;
                 return;
Line 406: Line 407:
             positionTooltip( anchor );
             positionTooltip( anchor );


             // Fetch rendered template
             // Build template text based on type
             new mw.Api().post( {
             var templateText;
                 action: 'parse',
            if ( type === 'item' ) {
                text: '{{Infobox item/auto|default=true|' + itemName + '}}',
                 templateText = '{{Infobox item/auto|default=true|' + name + '}}';
                title: mw.config.get( 'wgPageName' ),
            } else if ( type === 'ability' ) {
                 prop: 'text',
                 templateText = '{{Ability card v2' +
                disablelimitreport: true,
                    '|hero_name={{#invoke:Abilities/utils|find_hero_by_ability|' + name + '}}' +
                disableeditsection: true,
                    '|ability_num={{#invoke:Abilities|get_ability_number|{{#invoke:Abilities/utils|find_hero_by_ability|' + name + '}}|' + name + '}}' +
                wrapoutputclass: '',
                    '}}';
                format: 'json'
            } ).then( function ( data ) {
                var html = data.parse.text[ '*' ];
                tooltipCache[ 'item_' + itemName ] = html;
 
                // Only show if the mouse is still on this element
                if ( currentTarget === anchor ) {
                    tt.html( html ).show();
                    positionTooltip( anchor );
                }
            } ).catch( function () {
                if ( currentTarget === anchor ) {
                    tt.hide();
                }
            } );
 
        }, SHOW_DELAY );
    }
 
    /* ─── Show tooltip for hero ─── */
    function showHeroTooltip( anchor, heroKey ) {
        clearTimeout( hideTimer );
        clearTimeout( showTimer );
 
        showTimer = setTimeout( function () {
            var tt = getTooltip();
            currentTarget = anchor;
 
            // Already cached — show immediately
            if ( tooltipCache[ 'hero_' + heroKey ] ) {
                tt.html( tooltipCache[ 'hero_' + heroKey ] ).show();
                positionTooltip( anchor );
                return;
             }
             }


            // Loading indicator
             // Fetch rendered template
            tt.html( '<div class="custom-item-tooltip__loading">Loading…</div>' ).show();
            positionTooltip( anchor );
 
             // Fetch rendered hero infobox
             new mw.Api().post( {
             new mw.Api().post( {
                 action: 'parse',
                 action: 'parse',
                 text: '{{Infobox hero\n| key = ' + heroKey + '\n}}',
                 text: templateText,
                 title: mw.config.get( 'wgPageName' ),
                 title: mw.config.get( 'wgPageName' ),
                 prop: 'text',
                 prop: 'text',
Line 466: Line 430:
             } ).then( function ( data ) {
             } ).then( function ( data ) {
                 var html = data.parse.text[ '*' ];
                 var html = data.parse.text[ '*' ];
                 tooltipCache[ 'hero_' + heroKey ] = html;
                 tooltipCache[ cacheKey ] = html;


                 // Only show if the mouse is still on this element
                 // Only show if the mouse is still on this element
Line 491: Line 455:
             currentTarget = null;
             currentTarget = null;
         }, HIDE_DELAY );
         }, HIDE_DELAY );
    }
    /* ─── Attach handlers to wrapper ─── */
    function attachTooltipHandlers( $wrapper, name, type ) {
        // All links inside the wrapper, not just the first one
        var $links = $wrapper.find( 'a[href]' );
       
        // If no links found, attach to the wrapper itself (for icon-only mode)
        if ( !$links.length ) {
            $links = $wrapper;
        }
        $links.each( function () {
            var $link = $( this );
            // Remove native title from each link
            $link.removeAttr( 'title' );
            $link.on( 'mouseenter.customTooltip', function () {
                showTooltip( this, name, type );
            } ).on( 'mouseleave.customTooltip', function () {
                scheduleHide();
            } );
        } );
     }
     }


     /* ─── Initialization ─── */
     /* ─── Initialization ─── */
     mw.hook( 'wikipage.content' ).add( function ( $content ) {
     mw.hook( 'wikipage.content' ).add( function ( $content ) {
         // Handle item tooltips
         // Item tooltips
         $content.find( '.item-link-wrapper' ).each( function () {
         $content.find( '.item-link-wrapper' ).each( function () {
             var $wrapper = $( this );
             var $wrapper = $( this );
Line 501: Line 489:
             if ( !itemName ) return;
             if ( !itemName ) return;


             // All links inside the wrapper, not just the first one
             attachTooltipHandlers( $wrapper, itemName, 'item' );
            var $links = $wrapper.find( 'a[href]' );
            if ( !$links.length ) return;
 
            $links.each( function () {
                var $link = $( this );
 
                // Remove native title from each link
                $link.removeAttr( 'title' );
 
                $link.on( 'mouseenter.itemTooltip', function () {
                    showItemTooltip( this, itemName );
                } ).on( 'mouseleave.itemTooltip', function () {
                    scheduleHide();
                } );
            } );
         } );
         } );


         // Handle hero tooltips
         // Ability tooltips
         $content.find( '.hero-link-wrapper' ).each( function () {
         $content.find( '.ability-link-wrapper' ).each( function () {
             var $wrapper = $( this );
             var $wrapper = $( this );
             var heroKey = $wrapper.attr( 'data-hero-name' );
             var abilityName = $wrapper.attr( 'data-ability-name' );
             if ( !heroKey ) return;
             if ( !abilityName ) return;
 
            // All links inside the wrapper
            var $links = $wrapper.find( 'a[href]' );
            if ( !$links.length ) return;
 
            $links.each( function () {
                var $link = $( this );


                // Remove native title from each link
            attachTooltipHandlers( $wrapper, abilityName, 'ability' );
                $link.removeAttr( 'title' );
 
                $link.on( 'mouseenter.heroTooltip', function () {
                    showHeroTooltip( this, heroKey );
                } ).on( 'mouseleave.heroTooltip', function () {
                    scheduleHide();
                } );
            } );
         } );
         } );
     } );
     } );


} )();
} )();