Skip to content

Commit

Permalink
Work on complex selector handling
Browse files Browse the repository at this point in the history
  • Loading branch information
sirreal committed Nov 28, 2024
1 parent 95efc50 commit 2e81b2f
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions src/wp-includes/html-api/class-wp-css-selectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -1033,11 +1033,47 @@ private static function parse_subclass_selector( string $input, int &$offset ) {
*/
final class WP_CSS_Complex_Selector extends WP_CSS_Selector_Parser {
public function matches( WP_HTML_Processor $processor ): bool {
// @todo this can throw on parse.
if ( count( $this->selectors ) > 1 ) {
throw new Exception( 'Combined complex selectors are not supported yet.' );
if ( count( $this->selectors ) === 1 ) {
return $this->selectors[0]->matches( $processor );
}

// First selector must match this location.
if ( ! $this->selectors[0]->matches( $processor ) ) {
return false;
}

$breadcrumbs = array_slice( array_reverse( $processor->get_breadcrumbs() ), 1 );
$selectors = array_slice( $this->selectors, 1 );
return $this->explore_matches( $selectors, $breadcrumbs );
}

/**
* This only looks at breadcrumbs and can therefore only support type selectors.
*
* @param array<WP_CSS_Selector> $selectors
*/
private function explore_matches( array $selectors, array $breadcrumbs ): bool {
if ( array() === $selectors ) {
return true;
}
if ( array() === $breadcrumbs ) {
return false;
}

$combinator = $selectors[0];
$selector = $selectors[1];

switch ( $combinator ) {
case self::COMBINATOR_CHILD:
if ( '*' === $selector->type_selector->ident || strcasecmp( $breadcrumbs[0], $selector->type_selector->ident ) === 0 ) {
return $this->explore_matches( array_slice( $selectors, 2 ), array_slice( $breadcrumbs, 1 ) );
}
return $this->explore_matches( $selectors, array_slice( $breadcrumbs, 1 ) );

case self::COMBINATOR_DESCENDANT:
default:
throw new Exception( "Combinator '{$combinator}' is not supported yet." );
}
return $this->selectors[0]->matches( $processor );
}

const COMBINATOR_CHILD = '>';
Expand All @@ -1047,12 +1083,15 @@ public function matches( WP_HTML_Processor $processor ): bool {

/**
* even indexes are WP_CSS_Selector, odd indexes are string combinators.
* In reverse order to match the current element and then work up the tree.
* Any non-final selector is a type selector.
*
* @var array<WP_CSS_Selector>
*/
public $selectors = array();

private function __construct( array $selectors ) {
$this->selectors = $selectors;
$this->selectors = array_reverse( $selectors );
}

public static function parse( string $input, int &$offset ): ?self {
Expand Down

0 comments on commit 2e81b2f

Please sign in to comment.