mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateStyles
synced 2024-11-24 16:26:05 +00:00
29bdd0c18e
Properties listed in $wgTemplateStylesPropertyBlacklist, or those that contain function-like values not listed in $wgTemplateStylesFunctionWhitelist cause the containing declaration to be omitted from rendering entirely. Additionally, rule selectors are unconditionally prepended with '#mw-content-text' so that they cannot be applied to UI elements outside the actual page content. Change-Id: Id3d7dff465363d0163e4a5a1f31e770b4b0a67e2
98 lines
2.1 KiB
PHP
98 lines
2.1 KiB
PHP
<?php
|
|
|
|
|
|
/**
|
|
* @file
|
|
* @ingroup Extensions
|
|
*/
|
|
|
|
/**
|
|
* Collects parsed CSS trees, and merges them for rendering into text.
|
|
*
|
|
* @class
|
|
*/
|
|
class CSSRenderer {
|
|
|
|
private $bymedia;
|
|
|
|
function __construct() {
|
|
$this->bymedia = [];
|
|
}
|
|
|
|
/**
|
|
* Adds (and merge) a parsed CSS tree to the render list.
|
|
*
|
|
* @param array $rules The parsed tree as created by CSSParser::rules()
|
|
* @param string $media Forcibly specified @media block selector. Normally unspecified
|
|
* and defaults to the empty string.
|
|
*/
|
|
function add( $rules, $media = '' ) {
|
|
if ( !array_key_exists( $media, $this->bymedia ) ) {
|
|
$this->bymedia[$media] = [];
|
|
}
|
|
|
|
foreach ( $rules as $at ) {
|
|
switch ( strtolower( $at['name'] ) ) {
|
|
case '@media':
|
|
if ( $media == '' ) {
|
|
$this->add( $at['rules'], "@media ".$at['text'] );
|
|
}
|
|
break;
|
|
case '':
|
|
$this->bymedia[$media] = array_merge( $this->bymedia[$media], $at['rules'] );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders the collected CSS trees into a string suitable for inclusion
|
|
* in a <style> tag.
|
|
*
|
|
* @return string Rendered CSS
|
|
*/
|
|
function render( $functionWhitelist = [], $propertyBlacklist = [] ) {
|
|
|
|
$css = '';
|
|
|
|
foreach ( $this->bymedia as $at => $rules ) {
|
|
if ( $at != '' ) {
|
|
$css .= "$at {\n";
|
|
}
|
|
foreach ( $rules as $rule ) {
|
|
if ( $rule
|
|
and array_key_exists( 'selectors', $rule )
|
|
and array_key_exists( 'decls', $rule ) )
|
|
{
|
|
$css .= implode( ',', $rule['selectors'] ) . "{";
|
|
foreach ( $rule['decls'] as $key => $value ) {
|
|
if ( !in_array( strtolower( $key ), $propertyBlacklist ) ) {
|
|
$blacklisted = false;
|
|
foreach ( $value as $prop ) {
|
|
if ( preg_match( '/^ ([^ \n\t]+) [ \n\t]* \( $/x', $prop, $match ) ) {
|
|
if ( !in_array( strtolower( $match[1] ), $functionWhitelist ) ) {
|
|
$blacklisted = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( !$blacklisted ) {
|
|
$css .= "$key:" . implode( '', $value ) . ';';
|
|
}
|
|
}
|
|
}
|
|
$css .= "} ";
|
|
}
|
|
}
|
|
if ( $at != '' ) {
|
|
$css .= "} ";
|
|
}
|
|
}
|
|
|
|
return $css;
|
|
}
|
|
|
|
}
|
|
|
|
|