diff --git a/lib/experimental/html/class-wp-html-attribute-sourcer.php b/lib/experimental/html/class-wp-html-attribute-sourcer.php index ea178cbf2eafd..c2be48ee429b6 100644 --- a/lib/experimental/html/class-wp-html-attribute-sourcer.php +++ b/lib/experimental/html/class-wp-html-attribute-sourcer.php @@ -12,6 +12,7 @@ * @TODO: * - [ ] Handle multiple joined constraints for classes and attributes * e.g. ".locale-en-US.localized[data-translation-id][data-translate]" + * - [ ] Handle comma-separated selector sequences; apparently we only grab the first right now */ /** @@ -158,6 +159,10 @@ public static function select_match( $tags, $s ) { return $tags; } + /** + * @TODO: This needs to be able to continue to the next match + * Pass in $tags? Pass in a bookmark? + */ public static function select( $selectors, $html ) { $selector_index = 0; @@ -165,7 +170,7 @@ public static function select( $selectors, $html ) { $tags = new WP_HTML_Processor( $html ); $outer_state = $tags->new_state(); - $next = $selectors[$selector_index]; + $next = $selectors[ $selector_index ]; loop: while ( $tags->balanced_next( $outer_state ) ) { diff --git a/lib/experimental/html/class-wp-html-processor.php b/lib/experimental/html/class-wp-html-processor.php index ced54246cf35e..6fa236aa94a33 100644 --- a/lib/experimental/html/class-wp-html-processor.php +++ b/lib/experimental/html/class-wp-html-processor.php @@ -4,6 +4,7 @@ * @TODO: Handle self-closing foreign elements. * @TODO: Detect non-normative HTML input. * @TODO: Consider parsing non-normative HTML input, support adoption agency algorithm. + * @TODO: Figure out how multiple external states can conflict. * * If we support non-normative HTML we can probably handle significantly more * HTML without introducing unexpected results, but I'm not sure yet if we can @@ -65,6 +66,10 @@ public function balanced_next( WP_HTML_Processor_Scan_State $state, $query = nul * need to separately track those, but their behavior matches * this case. The self-closing flag is ignored for HTML5 tags. */ + if ( 0 === $state->relative_depth() ) { + return false; + } + break; case 'opener': diff --git a/phpunit/html/wp-html-attribute-sourcer-test.php b/phpunit/html/wp-html-attribute-sourcer-test.php index fda53531baaaa..38a274008a9de 100644 --- a/phpunit/html/wp-html-attribute-sourcer-test.php +++ b/phpunit/html/wp-html-attribute-sourcer-test.php @@ -22,6 +22,56 @@ class WP_UnitTestCase extends PHPUnit\Framework\TestCase {} * @coversDefaultClass WP_HTML_Attribute_Sourcer */ class WP_HTML_Attribute_Sourcer_Test extends WP_UnitTestCase { + /** + * @dataProvider data_ids_and_their_selectors + */ + public function test_selects_proper_html_from_selector( $wanted_ids, $selector ) { + $html = << +
+ +
+ +
+

The antics of ants with antlers

+

+ + Ants + with antlers can be funny. +

+ +
+ +HTML; + + list( $selectors ) = WP_HTML_Attribute_Sourcer::parse_selector( $selector ); + $this->assertIsArray( $selectors ); + + $found_ids = array(); + if ( $tags = WP_HTML_Attribute_Sourcer::select( [ $selectors ], $html ) ) { + $found_ids[] = $tags->get_attribute( 'id' ); + } + + $this->assertEqualsCanonicalizing( $wanted_ids, $found_ids ); + } + + public function data_ids_and_their_selectors() { + return array( + array( array( 'li-1' ), 'li' ), + array( array(), 'section > p img + em' ), + array( array( 'strong-ants' ), 'section > p img + strong' ), + array( array( 'funny-stuff' ), 'section > p strong + em' ), + array( array( 'page-title' ), 'section h2' ), + array( array( 'post-title' ), 'section > h2' ), + array( array( 'ant-logo' ), '[href]' ), + array( array(), '.non-existent' ), + ); + } + /** * @dataProvider data_single_combinators */