Use ResourceLoader modules for style loading

We want to be able to track what styles were added to be able to deliver
this information to MediaWiki's live preview functionality (in order
to solve bug 24134).

This required moving some code in SyntaxHighlight_GeSHi class around.

The old way still works and is used for MediaWiki 1.20 and lower.

Bug: 24134
Change-Id: Iafd91de8922be55688fedef4e43a8e7f54d4e1cc
This commit is contained in:
Bartosz Dziewoński 2014-04-16 22:23:12 +02:00
parent 49592712fe
commit b6d8b1a5b9
3 changed files with 115 additions and 20 deletions

View file

@ -0,0 +1,56 @@
<?php
class ResourceLoaderGeSHiModule extends ResourceLoaderModule {
/**
* @var string
*/
protected $lang;
/**
* @param array $info Module definition.
*/
function __construct( $info ) {
$this->lang = $info['lang'];
}
/**
* @param ResourceLoaderContext $context
* @return array
*/
public function getStyles( ResourceLoaderContext $context ) {
$geshi = SyntaxHighlight_GeSHi::prepare( '', $this->lang );
if ( !$geshi->error ) {
$css = SyntaxHighlight_GeSHi::getCSS( $geshi );
} else {
$css = ResourceLoader::makeComment( $geshi->error() );
}
return array( 'all' => $css );
}
/**
* @param ResourceLoaderContext $context
* @return int
*/
public function getModifiedTime( ResourceLoaderContext $context ) {
return max( array(
$this->getDefinitionMtime( $context ),
self::safeFilemtime( __FILE__ ),
self::safeFilemtime( __DIR__ . '/SyntaxHighlight_GeSHi.class.php' ),
self::safeFilemtime( __DIR__ . '/geshi/geshi.php' ),
self::safeFilemtime( GESHI_LANG_ROOT . "/{$this->lang}.php" ),
) );
}
/**
* @param $context ResourceLoaderContext
* @return array
*/
public function getDefinitionSummary( ResourceLoaderContext $context ) {
return array(
'class' => get_class( $this ),
'lang' => $this->lang,
);
}
}

View file

@ -102,7 +102,7 @@ class SyntaxHighlight_GeSHi {
$out = str_replace( "\t", '&#9;', $out );
}
// Register CSS
$parser->getOutput()->addHeadItem( self::buildHeadItem( $geshi ), "source-{$lang}" );
$parser->getOutput()->addModuleStyles( "ext.geshi.language.$lang" );
if ( $wgUseSiteCss ) {
$parser->getOutput()->addModuleStyles( 'ext.geshi.local' );
@ -302,7 +302,7 @@ class SyntaxHighlight_GeSHi {
$out = $geshi->parse_code();
if( !$geshi->error() ) {
// Done
$output->addHeadItem( self::buildHeadItem( $geshi ), "source-$lang" );
$output->addModuleStyles( "ext.geshi.language.$lang" );
$output->setText( "<div dir=\"ltr\">{$out}</div>" );
if( $wgUseSiteCss ) {
@ -320,8 +320,6 @@ class SyntaxHighlight_GeSHi {
* Initialise a GeSHi object to format some code, performing
* common setup for all our uses of it
*
* @note Used only until MW 1.20
*
* @param string $text
* @param string $lang
* @return GeSHi
@ -350,17 +348,6 @@ class SyntaxHighlight_GeSHi {
}
}
return $geshi;
}
/**
* Prepare a CSS snippet suitable for use as a ParserOutput/OutputPage
* head item
*
* @param GeSHi $geshi
* @return string
*/
public static function buildHeadItem( $geshi ) {
/**
* Geshi comes by default with a font-family set to monospace which
* ends ultimately ends up causing the font-size to be smaller than
@ -374,16 +361,40 @@ class SyntaxHighlight_GeSHi {
$geshi->set_code_style( 'font-family: monospace, monospace;',
/** preserve defaults */ true );
$lang = $geshi->language;
return $geshi;
}
/**
* Prepare a CSS snippet suitable for use as a ParserOutput/OutputPage
* head item.
*
* @deprecated
* @param GeSHi $geshi
* @return string
*/
public static function buildHeadItem( $geshi ) {
$css = array();
$css[] = '<style type="text/css">/*<![CDATA[*/';
$css[] = self::getCSS( $geshi );
$css[] = '/*]]>*/';
$css[] = '</style>';
return implode( "\n", $css );
}
/**
* Get the complete CSS code necessary to display styles for given GeSHi instance.
*
* @param GeSHi $geshi
* @return string
*/
public static function getCSS( $geshi ) {
$lang = $geshi->language;
$css = array();
$css[] = ".source-$lang {line-height: normal;}";
$css[] = ".source-$lang li, .source-$lang pre {";
$css[] = "\tline-height: normal; border: 0px none white;";
$css[] = "}";
$css[] = $geshi->get_stylesheet( false );
$css[] = '/*]]>*/';
$css[] = '</style>';
$css[] = $geshi->get_stylesheet( /*$economy_mode*/ false );
return implode( "\n", $css );
}
@ -488,4 +499,25 @@ class SyntaxHighlight_GeSHi {
public static function hOldSpecialVersion_GeSHi( &$sp, &$extensionTypes ) {
return self::hSpecialVersion_GeSHi( $extensionTypes );
}
/**
* Register a ResourceLoader module providing styles for each supported language.
*
* @param ResourceLoader $resourceLoader
* @return bool true
*/
public static function resourceLoaderRegisterModules( &$resourceLoader ) {
$modules = array();
foreach ( self::getSupportedLanguages() as $lang ) {
$modules["ext.geshi.language.$lang" ] = array(
'class' => 'ResourceLoaderGeSHiModule',
'lang' => $lang,
);
}
$resourceLoader->register( $modules );
return true;
}
}

View file

@ -55,9 +55,14 @@ $wgSyntaxHighlightKeywordLinks = false;
$dir = __DIR__ . '/';
$wgMessagesDirs['SyntaxHighlight_GeSHi'] = __DIR__ . '/i18n';
$wgExtensionMessagesFiles['SyntaxHighlight_GeSHi'] = $dir . 'SyntaxHighlight_GeSHi.i18n.php';
$wgAutoloadClasses['SyntaxHighlight_GeSHi'] = $dir . 'SyntaxHighlight_GeSHi.class.php';
$wgAutoloadClasses['ResourceLoaderGeSHiModule'] = $dir . 'ResourceLoaderGeSHiModule.php';
$wgAutoloadClasses['HighlightGeSHilocal'] = $dir . 'SyntaxHighlight_GeSHi.local.php';
$wgHooks['ParserFirstCallInit'][] = 'efSyntaxHighlight_GeSHiSetup';
$wgHooks['ExtensionTypes'][] = 'SyntaxHighlight_GeSHi::hSpecialVersion_GeSHi';
$wgHooks['ResourceLoaderRegisterModules'][] = 'SyntaxHighlight_GeSHi::resourceLoaderRegisterModules';
//if ( defined( 'MW_SUPPORTS_CONTENTHANDLER' ) ) {
// since MW 1.21
@ -68,8 +73,10 @@ $wgHooks['ExtensionTypes'][] = 'SyntaxHighlight_GeSHi::hSpecialVersion_GeSHi';
//}
$wgAutoloadClasses['HighlightGeSHilocal'] = $dir . 'SyntaxHighlight_GeSHi.local.php';
// Module to load MediaWiki:Geshi.css.
$wgResourceModules['ext.geshi.local'] = array( 'class' => 'HighlightGeSHilocal' );
// More modules are defined by SyntaxHighlight_GeSHi::resourceLoaderRegisterModules,
// one for each supported language. The general name template is 'ext.geshi.language.<lang>'.
/**
* Map content models to the corresponding language names to be used with the highlighter.