false ] ), new VarNameMatcher(), new WhitespaceMatcher( [ 'significant' => false ] ), ] ) ); $anyProperty = Quantifier::star( new Alternative( [ $var, $factory->color(), $factory->image(), $factory->length(), $factory->integer(), $factory->percentage(), $factory->number(), $factory->angle(), $factory->frequency(), $factory->resolution(), $factory->position(), $factory->cssSingleTimingFunction(), $factory->comma(), $factory->cssWideKeywords(), new KeywordMatcher( [ 'solid', 'double', 'dotted', 'dashed', 'wavy' ] ) ] ) ); // Match anything*\s?[var anything|anything var]+\s?anything*(!important)? // The problem is, that var() can be used more or less anywhere // Setting ONLY var as a CssWideKeywordMatcher would limit the matching to one property // E.g.: color: var( --color-base ); would work // border: 1px var( --border-type ) black; would not // So we need to construct a matcher that matches anything + var somewhere $propertySanitizer->setCssWideKeywordsMatcher( new Juxtaposition( [ $anyProperty, new WhitespaceMatcher( [ 'significant' => false ] ), Quantifier::plus( new Alternative( [ new Juxtaposition( [ $var, $anyProperty ] ), new Juxtaposition( [ $anyProperty, $var ] ), ] ) ), new WhitespaceMatcher( [ 'significant' => false ] ), $anyProperty, Quantifier::optional( new KeywordMatcher( [ '!important' ] ) ) ] ), ); } /** * Adds the image-rendering matcher * T222678 * * @param StylePropertySanitizer $propertySanitizer */ public function addImageRendering( StylePropertySanitizer $propertySanitizer ): void { try { $propertySanitizer->addKnownProperties( [ 'image-rendering' => new KeywordMatcher( [ 'auto', 'crisp-edges', 'pixelated', ] ) ] ); } catch ( InvalidArgumentException $e ) { // Fail silently } } /** * Adds the ruby-position and ruby-align matcher * T277755 * * @param StylePropertySanitizer $propertySanitizer */ public function addRuby( StylePropertySanitizer $propertySanitizer ): void { try { $propertySanitizer->addKnownProperties( [ 'ruby-position' => new KeywordMatcher( [ 'start', 'center', 'space-between', 'space-around', ] ) ] ); $propertySanitizer->addKnownProperties( [ 'ruby-align' => new KeywordMatcher( [ 'over', 'under', 'inter-character', ] ) ] ); } catch ( InvalidArgumentException $e ) { // Fail silently } } /** * Adds scroll-margin-* and scroll-padding-* matcher * TODO: This is not well tested * T271598 * * @param StylePropertySanitizer $propertySanitizer * @param MatcherFactory $factory */ public function addScrollMarginProperties( $propertySanitizer, $factory ): void { $suffixes = [ 'margin-block-end', 'margin-block-start', 'margin-block', 'margin-bottom', 'margin-inline-end', 'margin-inline-start', 'margin-inline', 'margin-left', 'margin-right', 'margin-top', 'margin', 'padding-block-end', 'padding-block-start', 'padding-block', 'padding-bottom', 'padding-inline-end', 'padding-inline-start', 'padding-inline', 'padding-left', 'padding-right', 'padding-top', 'padding', ]; foreach ( $suffixes as $suffix ) { try { $propertySanitizer->addKnownProperties( [ sprintf( 'scroll-%s', $suffix ) => new Alternative( [ $factory->length() ] ) ] ); } catch ( InvalidArgumentException $e ) { // Fail silently } } } /** * Loads a config value for a given key from the main config * Returns null on if an ConfigException was thrown * * @param string $key The config key * @param null $default * @return mixed|null */ public static function getConfigValue( string $key, $default = null ) { try { $value = MediaWikiServices::getInstance()->getMainConfig()->get( $key ); } catch ( ConfigException $e ) { wfLogWarning( sprintf( 'Could not get config for "$wg%s". %s', $key, $e->getMessage() ) ); return $default; } return $value; } }