From 3920a0157b571595473b52e77360d4fdd84ef4a2 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 21 Dec 2022 17:55:59 -0700 Subject: [PATCH] Remove bail depth since we can't track a negative-sized stack For sibling navigation we have to continue processing outside of balanced_next(). --- .../html/class-wp-html-attribute-sourcer.php | 19 ++---------- .../html/class-wp-html-processor.php | 26 ++++++++--------- phpunit/html/wp-html-processor-test.php | 29 +++++++------------ 3 files changed, 25 insertions(+), 49 deletions(-) diff --git a/lib/experimental/html/class-wp-html-attribute-sourcer.php b/lib/experimental/html/class-wp-html-attribute-sourcer.php index 22bfb94ea05c4..da4fb73689fa3 100644 --- a/lib/experimental/html/class-wp-html-attribute-sourcer.php +++ b/lib/experimental/html/class-wp-html-attribute-sourcer.php @@ -62,19 +62,6 @@ function array_is_list( $array ) { } } -class Selector { - public $element = null; - public $class = null; - public $hash = null; - public $has_attribute = null; - public $then = null; -} - -class ParseResult { - public $last_index; - public $selector = null; -} - class WP_HTML_Attribute_Sourcer { /** * Attributes definitions, typically from `block.json`. @@ -208,7 +195,7 @@ public static function select( $selectors, $html ) { 'tag' => $tags->get_tag(), 'selector' => $next ] ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); while ( $tags->balanced_next( $state ) ) { continue; } @@ -234,7 +221,7 @@ public static function select( $selectors, $html ) { 'tag' => $tags->get_tag(), 'selector' => $next ] ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $state->match_depth = 1; while ( $tags->balanced_next( $state ) ) { if ( null === self::select_match( $tags, $next ) ) { @@ -260,7 +247,7 @@ public static function select( $selectors, $html ) { 'tag' => $tags->get_tag(), 'selector' => $next ] ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); while ( $tags->balanced_next( $state ) ) { if ( null === self::select_match( $tags, $next ) ) { continue; diff --git a/lib/experimental/html/class-wp-html-processor.php b/lib/experimental/html/class-wp-html-processor.php index 7a207f287abc9..a36d77750466a 100644 --- a/lib/experimental/html/class-wp-html-processor.php +++ b/lib/experimental/html/class-wp-html-processor.php @@ -20,22 +20,24 @@ class WP_HTML_Processor_Scan_State { public $budget = 1000; public $open_tags = array(); - public $bail_depth = 0; public $match_depth = null; public function relative_depth() { return count( $this->open_tags ); } - - public function also_scan_siblings() { - $this->bail_depth = -1; - } } class WP_HTML_Processor extends WP_HTML_Tag_Processor { - public static function new_state() { - return new WP_HTML_Processor_Scan_State(); + public function new_state() { + $state = new WP_HTML_Processor_Scan_State(); + $tag_name = $this->get_tag(); + + if ( ! self::is_html_void_element( $tag_name ) && ! $this->is_tag_closer() ) { + $state->open_tags[] = $tag_name; + } + + return $state; } public function balanced_next( WP_HTML_Processor_Scan_State $state, $query = null ) { @@ -98,13 +100,9 @@ public function balanced_next( WP_HTML_Processor_Scan_State $state, $query = nul : $state->relative_depth(); /* - * Step 2. If we've reached the depth at which we want to stop searching, - * then bail at the current tag. This is mostly used to stop at the end - * of the opening tag's closing tag, but if set negative can continue - * scanning sibling elements (-1) or parents (-2) and so on. + * Step 2. Bail if we've reached the end of the tag in which we started. */ - - if ( $state->bail_depth === $depth ) { + if ( 0 === $depth ) { return false; } @@ -119,7 +117,7 @@ public function balanced_next( WP_HTML_Processor_Scan_State $state, $query = nul * searching once we've exited the tag on which we started, or reach its parent. */ - if ( ! isset( $state->match_depth ) || $state->match_depth === $depth ) { + if ( ! isset( $state->match_depth ) || $state->match_depth + 1 === $depth ) { $this->parse_query( $query ); if ( $this->matches() ) { return true; diff --git a/phpunit/html/wp-html-processor-test.php b/phpunit/html/wp-html-processor-test.php index b14408f0ee287..36ec241f1fd26 100644 --- a/phpunit/html/wp-html-processor-test.php +++ b/phpunit/html/wp-html-processor-test.php @@ -10,7 +10,7 @@ require_once __DIR__ . '/../../lib/experimental/html/class-wp-html-processor.php'; /** - * @group html-proc + * @group html-processor * * @coversDefaultClass WP_HTML_Processor */ @@ -19,11 +19,11 @@ public function test_find_descendant_tag() { $tags = new WP_HTML_Processor( '
outside
inside
' ); $tags->next_tag( 'div' ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $this->assertFalse( $tags->balanced_next( $state, 'img' ) ); $this->assertTrue( $tags->next_tag( 'div' ) ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $this->assertTrue( $tags->balanced_next( $state, 'img' ) ); } @@ -31,35 +31,26 @@ public function test_find_immediate_child_tag() { $tags = new WP_HTML_Processor( '
' ); $tags->next_tag( 'div' ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $state->match_depth = 1; $this->assertFalse( $tags->balanced_next( $state, 'img' ) ); } - public function test_find_immediate_child_of_fails_when_inside_sibling_of_current_tag() { - $tags = new WP_HTML_Processor( '
' ); + public function test_find_immediate_child_tag2() { + $tags = new WP_HTML_Processor( '
' ); $tags->next_tag( 'div' ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $state->match_depth = 1; - $this->assertFalse( $tags->balanced_next( $state, 'img' ) ); - } - - public function test_find_immediate_child_succeeds_when_inside_sibling_of_current_tag_and_searchign_siblings() { - $tags = new WP_HTML_Processor( '
' ); - - $tags->next_tag( 'div' ); - $state = WP_HTML_Processor::new_state(); - $state->also_scan_siblings(); - $state->match_depth = 1; - $this->assertTrue( $tags->balanced_next( $state, 'img' ) ); + $this->assertTrue( $tags->balanced_next( $state, 'img' ), 'Did not find the wanted ' ); + $this->assertTrue( $tags->get_attribute( 'wanted' ), 'Found the wrong ' ); } public function test_find_child_tag() { $tags = new WP_HTML_Processor( '
' ); $tags->next_tag( 'div' ); - $state = WP_HTML_Processor::new_state(); + $state = $tags->new_state(); $state->match_depth = 3; $this->assertTrue( $tags->balanced_next( $state, 'img' ) ); }