MediaWiki:Gadget-refTooltip.js

$( function { 'use strict';

var show, hide;

importStylesheet( 'User:Ultradude25/refTooltip.css' );

// Not really happy with this function; improvements wanted! function setPos { var $toolTip = $( '#ref-tooltip' ), $tooltipText, $tooltipArrow, tooltipHeight, $ref, offset = {}, refWidth, winWidth, pos = {}, posArr = {}; if ( $toolTip.length ) { $tooltipText = $( '#ref-tooltip-text' ); $tooltipArrow = $( '#ref-tooltip-arrow' ); $ref = $( '#' + $toolTip.prop( 'class' ).replace( /\./g, '\\.' ) ); tooltipHeight = Math.round( $tooltipText.height ) + 15; offset.x = Math.round( $ref.offset.left ) - 6; offset.y = Math.round( $ref.offset.top ) - 10; winWidth = $( window ).width; refWidth = $ref.width; // Get the tooltip's left pos, adjusting if it is offscreen if ( offset.x + 226 < winWidth ) { pos.x = offset.x;       } else { pos.x = offset.x - ( offset.x + 226 - winWidth ); // Clamp offset to end of ref tag if ( offset.x - pos.x > 197 - refWidth ) { pos.x = ( offset.x - 197 ) + refWidth; }       }        // Position the arrow's left pos posArr.x = offset.x + ( refWidth / 2 ) - 3; // Get the tooltip's top pos, moving it and the arrow under the ref if it is offscreen if ( offset.y - tooltipHeight - $( window ).scrollTop < 1 ) { pos.y = offset.y + 4; posArr.y = offset.y - 9; $tooltipArrow.addClass( 'ref-tooltip-flipped' ); } else { pos.y = offset.y - tooltipHeight - 25; posArr.y = offset.y - 29; $tooltipArrow.removeClass( 'ref-tooltip-flipped' ); }       // Set the positions $tooltipText.css( { 'left': pos.x + 'px', 'top': pos.y + 'px' } ); $tooltipArrow.css( { 'left': posArr.x + 'px', 'top': posArr.y + 'px' } ); } }

// When the window is resized or scrolled, check the pos again to make sure it hasn't moved off-screen // When anywhere but the tooltip is clicked, remove it immediately $( window ).resize( function { setPos; } ) .scroll( function { setPos; } ) .click( function( event ) {              if ( !$( '#ref-tooltip' ).has( event.target ).length ) {                   $( '#ref-tooltip' ).remove;               }           } );

// Jslinks need their own handler, as they don't allow propagation (due to sortable tables) $( '.jslink' ).click( function { $( '#ref-tooltip' ).remove; } );

$( '.reference' ).hover( function {       var ref = this, refID = $( this ).prop( 'id' ),            $refText = $( '#' + $( ref ).find( 'a' ).prop( 'href' ).split( '#' )[1].replace( /\./g, '\\.' ) );        clearTimeout( hide );        // Start the tooltip if timeout succeedes        show = setTimeout( function { // If we didn't hover over the current tooltip if ( !$( '#ref-tooltip' ).hasClass( refID ) ) { // Get rid of any existing tooltip/highlight $( '#ref-tooltip' ).remove; $( '.references' ).find( 'li' ).css( 'background-color', '' ); // If the ref is already on screen, just highlight it instead of bringing up the tooltip if ( Math.round( $refText.offset.top + $refText.height - $( window ).scrollTop + 20 ) < $( window ).height ) { $refText.css( 'background-color', '#C1DAF2' ); } else { // Otherwise create the tooltip near the end of the page $( '#netbar' ).after( '   ' ); // Add a class as a callback and fill with the ref's text $( '#ref-tooltip' ).addClass( refID ); $( '#ref-tooltip-text' ).html( $refText.find( '.cite-reference-text' ).html ); // Put it all in the right spot setPos; }           }        }, 200, show );    }, function {        clearTimeout( show );        // End the tooltip if timeout succeedes        hide = setTimeout( function { $( '#ref-tooltip' ).remove; $( '.references' ).find( 'li' ).css( 'background-color', '' ); }, 300, hide );   } );

// Callback to the ref's hover functions when the tooltip is hovered over $( '#ref-tooltip' ).live( {   mouseenter: function {        $( '#' + $( this ).prop( 'class' ) ).mouseenter;    },    mouseleave: function {        $( '#' + $( this ).prop( 'class' ) ).mouseleave;    } } );

} );