mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateStyles
synced 2024-11-24 08:14:23 +00:00
dfa7e27b5a
- add a tweak to the parser (keep the value tokens in a declaration separate in the parsed tree to ease matching at render time - add error checking to encoding/decoding the templatestyles property - pick some lint suggested by Brion and Bryan Change-Id: If60b91e119102c0f0f559fe7e5a4c421c94b7ff4
121 lines
3 KiB
PHP
121 lines
3 KiB
PHP
<?php
|
|
/**
|
|
* TemplateStyles extension hooks
|
|
*
|
|
* @file
|
|
* @ingroup Extensions
|
|
* @license LGPL-2.0+
|
|
*/
|
|
class TemplateStylesHooks {
|
|
/**
|
|
* Register parser hooks
|
|
*/
|
|
public static function onParserFirstCallInit( &$parser ) {
|
|
$parser->setHook( 'templatestyles', 'TemplateStylesHooks::render' );
|
|
return true;
|
|
}
|
|
|
|
private static function decodeFromBlob( $blob ) {
|
|
$tree = gzdecode( $blob );
|
|
if ( $tree ) {
|
|
$tree = unserialize( $tree );
|
|
}
|
|
return $tree;
|
|
}
|
|
|
|
private static function encodeToBlob( $tree ) {
|
|
return gzencode( serialize( $tree ) );
|
|
}
|
|
|
|
public static function onOutputPageParserOutput( &$out, $parseroutput ) {
|
|
global $wgTemplateStylesNamespaces;
|
|
if ( $wgTemplateStylesNamespaces ) {
|
|
$namespaces = $wgTemplateStylesNamespaces;
|
|
} else {
|
|
$namespaces = [ NS_TEMPLATE ];
|
|
}
|
|
|
|
$renderer = new CSSRenderer();
|
|
$pages = [];
|
|
|
|
foreach ( $namespaces as $ns ) {
|
|
if ( array_key_exists( $ns, $parseroutput->getTemplates() ) ) {
|
|
foreach ( $parseroutput->getTemplates()[$ns] as $title => $pageid ) {
|
|
$pages[$pageid] = $title;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( count( $pages ) ) {
|
|
$db = wfGetDB( DB_SLAVE );
|
|
$res = $db->select( 'page_props', [ 'pp_page', 'pp_value' ], [
|
|
'pp_page' => array_keys( $pages ),
|
|
'pp_propname' => 'templatestyles'
|
|
],
|
|
__METHOD__,
|
|
[ 'ORDER BY', 'pp_page' ]
|
|
);
|
|
foreach ( $res as $row ) {
|
|
$css = self::decodeFromBlob( $row->pp_value );
|
|
if ( $css ) {
|
|
$renderer->add( $css );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
$selfcss = $out->getProperty( 'templatestyles' );
|
|
if ( $selfcss ) {
|
|
$selfcss = self::decodeFromBlob( unserialize( gzdecode( $selfcss ) ) );
|
|
if ( $selfcss ) {
|
|
$renderer->add( $selfcss );
|
|
}
|
|
}
|
|
|
|
$css = $renderer->render();
|
|
if ( $css ) {
|
|
$out->addInlineStyle( $css );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parser hook for <templatestyles>.
|
|
* If there is a CSS provided, render its source on the page and attach the
|
|
* parsed stylesheet to the page as a Property.
|
|
*
|
|
* @param string $input: The content of the tag.
|
|
* @param array $args: The attributes of the tag.
|
|
* @param Parser $parser: Parser instance available to render
|
|
* wikitext into html, or parser methods.
|
|
* @param PPFrame $frame: Can be used to see what template parameters ("{{{1}}}", etc.)
|
|
* this hook was used with.
|
|
*
|
|
* @return string: HTML to insert in the page.
|
|
*/
|
|
public static function render( $input, $args, $parser, $frame ) {
|
|
$css = new CSSParser( $input );
|
|
|
|
if ( $css ) {
|
|
$parser->getOutput()->setProperty( 'templatestyles', self::encodeToBlob( $css->rules() ) );
|
|
}
|
|
|
|
// TODO: The UX would benefit from the CSS being run through the
|
|
// hook for syntax highlighting rather that simply being presented
|
|
// as a preformatted block.
|
|
$html =
|
|
Html::openElement( 'div', [ 'class' => 'mw-templatestyles-doc' ] )
|
|
. Html::rawElement(
|
|
'p',
|
|
[ 'class' => 'mw-templatestyles-caption' ],
|
|
wfMessage( 'templatedata-doc-title' ) )
|
|
. Html::element(
|
|
'pre',
|
|
[ 'class' => 'mw-templatestyles-stylesheet' ],
|
|
$input )
|
|
. Html::closeElement( 'div' );
|
|
|
|
return $html;
|
|
}
|
|
|
|
}
|