pokemon-showdown-client/lib/css-sanitizer/Wikimedia/CSS/Sanitizer/RuleSanitizer.php

114 lines
3.4 KiB
PHP

<?php
/**
* @file
* @license https://opensource.org/licenses/Apache-2.0 Apache-2.0
*/
namespace Wikimedia\CSS\Sanitizer;
use Wikimedia\CSS\Objects\Rule;
use Wikimedia\CSS\Objects\AtRule;
use Wikimedia\CSS\Objects\CSSFunction;
use Wikimedia\CSS\Objects\SimpleBlock;
use Wikimedia\CSS\Objects\Token;
use Wikimedia\CSS\Parser\Parser;
use Wikimedia\CSS\Util;
/**
* Base class for CSS rule sanitizers
*/
abstract class RuleSanitizer extends Sanitizer {
/**
* Return an integer indicating ordering constraints. Lower numbers must
* come earlier in the document.
* @return int|int[] If two numbers are returned, these are the test and
* the newly-set indexes, respectively.
*/
public function getIndex() {
return 1000;
}
/**
* Sanitize a block's contents as a DeclarationList, in place
* @param SimpleBlock $block
* @param PropertySanitizer $sanitizer
*/
protected function sanitizeDeclarationBlock( SimpleBlock $block, PropertySanitizer $sanitizer ) {
$blockContents = $block->getValue();
$parser = Parser::newFromTokens( $blockContents->toTokenArray() );
$declarations = $parser->parseDeclarationList();
$this->sanitizationErrors = array_merge( $this->sanitizationErrors, $parser->getParseErrors() );
$declarations = $this->sanitizeList( $sanitizer, $declarations );
$blockContents->clear();
$blockContents->add( $declarations->toComponentValueArray() );
}
/**
* Sanitize a block's contents as a RuleList, in place
* @param SimpleBlock $block
* @param RuleSanitizer[] $sanitizers
*/
protected function sanitizeRuleBlock( SimpleBlock $block, array $sanitizers ) {
$blockContents = $block->getValue();
$parser = Parser::newFromTokens( $blockContents->toTokenArray() );
$rules = $parser->parseRuleList();
$this->sanitizationErrors = array_merge( $this->sanitizationErrors, $parser->getParseErrors() );
$rules = $this->sanitizeRules( $sanitizers, $rules );
$blockContents->clear();
$blockContents->add( $rules->toComponentValueArray() );
}
/**
* For the whitespace at the start of the prelude
*
* The matcher probably marked it insignificant, but it's actually
* significant if it's needed to separate the at-keyword and the first
* thing in the prelude. And if there isn't a whitespace there, add one if
* it would be significant.
*
* @param AtRule $rule
* @param bool $cloneIfNecessary
* @return AtRule
*/
protected function fixPreludeWhitespace( AtRule $rule, $cloneIfNecessary ) {
$prelude = $rule->getPrelude();
if ( !count( $prelude ) ) {
return $rule;
}
$cv = Util::findFirstNonWhitespace( $rule->getPrelude() );
if ( !$cv ) {
foreach ( $prelude as $i => $v ) {
if ( $v instanceof Token && $v->significant() ) {
$prelude[$i] = $v->copyWithSignificance( false );
}
}
return $rule;
}
$significant = $cv instanceof CSSFunction ||
$cv instanceof Token &&
Token::separate( new Token( Token::T_AT_KEYWORD, $rule->getName() ), $cv );
if ( $prelude[0] instanceof Token && $prelude[0]->type() === Token::T_WHITESPACE ) {
$prelude[0] = $prelude[0]->copyWithSignificance( $significant );
} elseif ( $significant ) {
if ( $cloneIfNecessary ) {
$rule = clone( $rule );
$prelude = $rule->getPrelude();
}
$prelude->add( new Token( Token::T_WHITESPACE ), 0 );
}
return $rule;
}
/**
* Indicate whether this rule is handled by this sanitizer.
* @param Rule $rule
* @return bool
*/
abstract public function handlesRule( Rule $rule );
}