capture( 'url' ), Quantifier::star( $modifierMatcher->capture( 'modifier' ) ), ] ); $this->urlCheck = $urlCheck; parent::__construct( 'url', $funcContents ); } /** * Return a Matcher for any grammatically-correct modifier * @return Matcher */ public static function anyModifierMatcher() { return Alternative::create( [ new TokenMatcher( Token::T_IDENT ), new FunctionMatcher( null, new AnythingMatcher( [ 'quantifier' => '*' ] ) ), ] ); } protected function generateMatches( ComponentValueList $values, $start, array $options ) { // First, is it a URL token? $cv = isset( $values[$start] ) ? $values[$start] : null; if ( $cv instanceof Token && $cv->type() === Token::T_URL ) { $url = $cv->value(); if ( !$this->urlCheck || call_user_func( $this->urlCheck, $url, [] ) ) { $match = new Match( $values, $start, 1, 'url' ); yield $this->makeMatch( $values, $start, $this->next( $values, $start, $options ), $match ); } return; } // Nope. Try it as a FunctionMatcher and extract the URL and modifiers // for each match. foreach ( parent::generateMatches( $values, $start, $options ) as $match ) { $url = null; $modifiers = []; foreach ( $match->getCapturedMatches() as $submatch ) { $cvs = $submatch->getValues(); if ( $submatch->getName() === 'url' ) { $url = $cvs[0]->value(); } elseif ( $submatch->getName() === 'modifier' ) { if ( $cvs[0] instanceof CSSFunction ) { $modifiers[] = $cvs[0]; } elseif ( $cvs[0]->type() === Token::T_IDENT ) { $modifiers[] = $cvs[0]; } } } if ( $url && ( !$this->urlCheck || call_user_func( $this->urlCheck, $url, $modifiers ) ) ) { yield $match; } } } }