MediaWiki:Gadget-refTooltip.js

$( function { 'use strict';

var show, hide;

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

// Not really happy with this function; improvements wanted! function setPos { var $tooltip = $( '#ref-tooltip' ), $tooltipText, $tooltipArrow, $ref, tooltipWidth, tooltipOuterWidth, tooltipOuterHeight, offset = {}, refWidth, winWidth, pos = {}, posArr = {}; if ( !$tooltip.length ) { return; }	$tooltipText = $tooltip.find( '#ref-tooltip-text' ); $tooltipArrow = $tooltip.find( '#ref-tooltip-arrow' ); $ref = $( '#' + $tooltip.data( 'ref' ).replace( /\./g, '\\.' ) ); tooltipWidth = Math.round( $tooltipText.width ); tooltipOuterWidth = Math.round( $tooltipText.outerWidth ); tooltipOuterHeight = Math.round( $tooltipText.outerHeight( true ) ); offset.x = Math.round( $ref.offset.left ); // 28 accounts for curse netbar, which throws off vertical offsets offset.y = Math.round( $ref.offset.top ) - 28; winWidth = $( window ).width; refWidth = $ref.width; // Get the tooltip's left pos, adjusting if it is offscreen if ( offset.x - 10 + tooltipOuterWidth < winWidth ) { pos.x = offset.x - 10; } else { pos.x = offset.x - ( offset.x + tooltipOuterWidth - winWidth ); // Clamp offset to end of ref tag if ( offset.x - pos.x > tooltipWidth - ( refWidth / 2 ) ) { pos.x = ( offset.x - tooltipWidth ) + ( refWidth / 2 ) + 10; }	}	// Position the arrow's left pos posArr.x = offset.x + ( refWidth / 2 ) - 10; // Get the tooltip's top pos, moving it and the arrow under the ref if it is off-screen if ( offset.y - tooltipOuterHeight - $( window ).scrollTop < 1 ) { $tooltip.addClass( 'flipped' ); // 13 is ref height pos.y = offset.y + 13; posArr.y = pos.y;	} else { $tooltip.removeClass( 'flipped' ); pos.y = offset.y - tooltipOuterHeight; // 11 is arrow height posArr.y = offset.y - 11; }	// Set the positions $tooltipText.css( { left: pos.x, top: pos.y } ); $tooltipArrow.css( { left: posArr.x, top: posArr.y } ); }

// When anywhere but the tooltip is clicked, remove it immediately $( window ).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 succeeds		show = setTimeout( function { // If we didn't hover over the current tooltip if ( $( '#ref-tooltip' ).data( 'ref' ) !== refID ) { // Get rid of any existing tooltip $( '#ref-tooltip' ).remove; // Create the tooltip $( 'body' ).append( '  ' ); // Save the ID as a callback $( '#ref-tooltip' ).data( 'ref', refID ); // Fill with the ref text $( '#ref-tooltip-text' ).html( $refText.find( '.cite-reference-text' ).html ); // Put it all in the right spot setPos; }		}, 200 );	}, function {		clearTimeout( show );		// Remove the tooltip if timeout succeeds		hide = setTimeout( function { $( '#ref-tooltip' ).remove; }, 300 );	} );

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

} );