Make WordPress Core


Ignore:
Timestamp:
09/26/2023 08:18:25 AM (3 years ago)
Author:
Bernhard Reiter
Message:

HTML API: Add matches_breadcrumbs() method for better querying.

Inside a next_tag() loop it can be challenging to use breadcrumbs because they are only exposed inside the call to next_tag() via the $query arg.

In this patch a new method, matches_breadcrumbs(), is exposed which allows for querying within the next_tag() loop for more complicated queries.

This method exposes a wildcard * operator to allow matching any HTML tag that the currently-matched tag is a child or descendant of.

Props dmsnell, westonruter, mukesh27.
Fixes #59400.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php

    r56380 r56702  
    354354
    355355        /**
     356         * @ticket 59400
     357         *
     358         * @dataProvider data_html_with_breadcrumbs_of_various_specificity
     359         *
     360         * @param string   $html_with_target_node HTML with a node containing a "target" attribute.
     361         * @param string[] $breadcrumbs           Breadcrumbs to test at the target node.
     362         * @param bool     $should_match          Whether the target node should match the breadcrumbs.
     363         */
     364        public function test_reports_if_tag_matches_breadcrumbs_of_various_specificity( $html_with_target_node, $breadcrumbs, $should_match ) {
     365                $processor = WP_HTML_Processor::createFragment( $html_with_target_node );
     366                while ( $processor->next_tag() && null === $processor->get_attribute( 'target' ) ) {
     367                        continue;
     368                }
     369
     370                $matches = $processor->matches_breadcrumbs( $breadcrumbs );
     371                $path    = implode( ', ', $breadcrumbs );
     372                if ( $should_match ) {
     373                        $this->assertTrue( $matches, "HTML tag {$processor->get_tag()} should have matched breadcrumbs but didn't: {$path}." );
     374                } else {
     375                        $this->assertFalse( $matches, "HTML tag {$processor->get_tag()} should not have matched breadcrumbs but did: {$path}." );
     376                }
     377        }
     378
     379        /**
     380         * Data provider.
     381         *
     382         * @return array[].
     383         */
     384        public function data_html_with_breadcrumbs_of_various_specificity() {
     385                return array(
     386                        // Test with void elements.
     387                        'Inner IMG'                      => array( '<div><span><figure><img target></figure></span></div>', array( 'span', 'figure', 'img' ), true ),
     388                        'Inner IMG wildcard'             => array( '<div><span><figure><img target></figure></span></div>', array( 'span', '*', 'img' ), true ),
     389                        'Inner IMG no wildcard'          => array( '<div><span><figure><img target></figure></span></div>', array( 'span', 'img' ), false ),
     390                        'Full specification'             => array( '<div><span><figure><img target></figure></span></div>', array( 'html', 'body', 'div', 'span', 'figure', 'img' ), true ),
     391                        'Invalid Full specification'     => array( '<div><span><figure><img target></figure></span></div>', array( 'html', 'div', 'span', 'figure', 'img' ), false ),
     392
     393                        // Test also with non-void elements that open and close.
     394                        'Inner P'                        => array( '<div><span><figure><p target></figure></span></div>', array( 'span', 'figure', 'p' ), true ),
     395                        'Inner P wildcard'               => array( '<div><span><figure><p target></figure></span></div>', array( 'span', '*', 'p' ), true ),
     396                        'Inner P no wildcard'            => array( '<div><span><figure><p target></figure></span></div>', array( 'span', 'p' ), false ),
     397                        'Full specification (P)'         => array( '<div><span><figure><p target></figure></span></div>', array( 'html', 'body', 'div', 'span', 'figure', 'p' ), true ),
     398                        'Invalid Full specification (P)' => array( '<div><span><figure><p target></figure></span></div>', array( 'html', 'div', 'span', 'figure', 'p' ), false ),
     399
     400                        // Ensure that matches aren't on tag closers.
     401                        'Inner P'                        => array( '<div><span><figure></p target></figure></span></div>', array( 'span', 'figure', 'p' ), false ),
     402                        'Inner P wildcard'               => array( '<div><span><figure></p target></figure></span></div>', array( 'span', '*', 'p' ), false ),
     403                        'Inner P no wildcard'            => array( '<div><span><figure></p target></figure></span></div>', array( 'span', 'p' ), false ),
     404                        'Full specification (P)'         => array( '<div><span><figure></p target></figure></span></div>', array( 'html', 'body', 'div', 'span', 'figure', 'p' ), false ),
     405                        'Invalid Full specification (P)' => array( '<div><span><figure></p target></figure></span></div>', array( 'html', 'div', 'span', 'figure', 'p' ), false ),
     406
     407                        // Test wildcard behaviors.
     408                        'Single wildcard element'        => array( '<figure><code><div><p><span><img target></span></p></div></code></figure>', array( '*' ), true ),
     409                        'Child of wildcard element'      => array( '<figure><code><div><p><span><img target></span></p></div></code></figure>', array( 'SPAN', '*' ), true ),
     410                );
     411        }
     412
     413        /**
    356414         * Ensures that the ability to set attributes isn't broken by the HTML Processor.
    357415         *
Note: See TracChangeset for help on using the changeset viewer.