User:Ilmari Karonen/FancyTooltips

From mediawiki.org

This is a proof-of-concept extension for a JS-less fix to bug 26587. You probably don't want to use it yet — the tooltips in this version just show the raw wikitext and generally look ugly. Give me a few more minutes to improve it... ;)

<?php

if ( !defined( 'MEDIAWIKI' ) ) {
	die( 'This file is a MediaWiki extension, it is not a valid entry point' );
}

// Credits:
$wgExtensionCredits['other'][] = array(
       'name'		=> 'FancyTooltips',
       'version'	=> '0.1',
       'author'		=> 'Ilmari Karonen', 
       'url'		=> 'http://www.mediawiki.org/wiki/User:Ilmari_Karonen/FancyTooltips', 
       'description'	=> 'Replaces link tooltips with extracts of page text',
);

// Config variables:
$wgFancyTooltipsMaxLength = 100;

// Hooks:
$wgHooks['LinkBegin'][] = 'fancyTooltipsLinkBegin';

function fancyTooltipsLinkBegin ( $skin, $target, &$text, &$attribs, &$query, &$options, &$ret ) {
	global $wgFancyTooltipsMaxLength;
	static $ellipsis;
	static $cache = array();

	if ( array_key_exists( 'title', $attribs ) ) {
		return true;  // don't override explicit titles
	}
	
	// first check the cache
	$key = $target->getPrefixedDBkey();
	if ( array_key_exists( $key, $cache ) ) {
		$title = $cache[$key];
		if ( $title !== false ) {
			$attribs['title'] = $title;
		}
		return true;
	}

	$rev = Revision::newFromTitle( $target );
	if ( !$rev ) {
		// redlink? special? whatever it is, ignore it
		$cache[$key] = false;  // cache negative result
		return true;
	}

	// TODO: This is a test implementation.  For the final
	// implementation we should fetch the parsed page and extract
	// the text from it.

	$content = $rev->getText();
	if ( $content ) {
		$title = mb_substr( $content, 0, $wgFancyTooltipsMaxLength );
		if ( strlen( $title ) < strlen( $content ) ) {
			if ( !isset( $ellipsis ) ) {
				$ellipsis = wfMsgForContent( 'ellipsis' );
			}
			$title .= $ellipsis;
		}
		$cache[$key] = $attribs['title'] = $title; 
	}
	else {
		$cache[$key] = false;  // cache negative result
	}
	return true;
}