name = $name; $this->valueMatcher = $valueMatcher; } public function handlesRule( Rule $rule ) { return $rule instanceof AtRule && !strcasecmp( $rule->getName(), $this->name ); } protected function doSanitize( CSSObject $object ) { if ( !$object instanceof Rule || !$this->handlesRule( $object ) ) { $this->sanitizationError( 'expected-at-rule', $object, [ $this->name ] ); return null; } if ( $object->getBlock() === null ) { $this->sanitizationError( 'at-rule-block-required', $object, [ $this->name ] ); return null; } // No non-whitespace prelude allowed if ( Util::findFirstNonWhitespace( $object->getPrelude() ) ) { $this->sanitizationError( 'invalid-font-feature-value', $object, [ $this->name ] ); return null; } $ret = clone( $object ); $this->fixPreludeWhitespace( $ret, false ); // Parse the block's contents into a list of declarations, sanitize it, // and put it back into the block. $blockContents = $ret->getBlock()->getValue(); $parser = Parser::newFromTokens( $blockContents->toTokenArray() ); $oldDeclarations = $parser->parseDeclarationList(); $this->sanitizationErrors = array_merge( $this->sanitizationErrors, $parser->getParseErrors() ); $newDeclarations = new DeclarationList(); foreach ( $oldDeclarations as $declaration ) { if ( $this->valueMatcher->match( $declaration->getValue(), [ 'mark-significance' => true ] ) ) { $newDeclarations->add( $declaration ); } else { $this->sanitizationError( 'invalid-font-feature-value-declaration', $declaration, [ $this->name ] ); } } $blockContents->clear(); $blockContents->add( $newDeclarations->toComponentValueArray() ); return $ret; } }