Make WordPress Core

Changeset 59757


Ignore:
Timestamp:
02/04/2025 02:47:41 AM (20 months ago)
Author:
jorbin
Message:

HTML API: Fix extensibility of WP_HTML_Processor::next_token().

Break out logic from the next_token() method into a private method which may call itself recursively. This allows for subclasses to override the next_token() method and be assured that each call to next_token() corresponds with the consumption of one single token. This also parallels how WP_HTML_Tag_Processor::next_token() wraps a private base_class_next_token() method.

Reviewed by jonsurrell.
Merges [59285], [59364], and [59747] to 6.7 branch.

Props westonruter, jonsurrell, dmsnell, jorbin.

Location:
branches/6.7
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • branches/6.7/src/wp-includes/html-api/class-wp-html-processor.php

    r59721 r59757  
    609609
    610610        /**
    611          * Ensures internal accounting is maintained for HTML semantic rules while
    612          * the underlying Tag Processor class is seeking to a bookmark.
     611         * Finds the next token in the HTML document.
    613612         *
    614613         * This doesn't currently have a way to represent non-tags and doesn't process
     
    617616         *
    618617         * @since 6.5.0 Added for internal support; do not use.
     618         * @since 6.7.2 Refactored so subclasses may extend.
     619         *
     620         * @return bool Whether a token was parsed.
     621         */
     622        public function next_token(): bool {
     623                return $this->next_visitable_token();
     624        }
     625
     626        /**
     627         * Ensures internal accounting is maintained for HTML semantic rules while
     628         * the underlying Tag Processor class is seeking to a bookmark.
     629         *
     630         * This doesn't currently have a way to represent non-tags and doesn't process
     631         * semantic rules for text nodes. For access to the raw tokens consider using
     632         * WP_HTML_Tag_Processor instead.
     633         *
     634         * Note that this method may call itself recursively. This is why it is not
     635         * implemented as {@see WP_HTML_Processor::next_token()}, which instead calls
     636         * this method similarly to how {@see WP_HTML_Tag_Processor::next_token()}
     637         * calls the {@see WP_HTML_Tag_Processor::base_class_next_token()} method.
     638         *
     639         * @since 6.7.2 Added for internal support.
    619640         *
    620641         * @access private
     
    622643         * @return bool
    623644         */
    624         public function next_token(): bool {
     645        private function next_visitable_token(): bool {
    625646                $this->current_element = null;
    626647
     
    640661                 */
    641662                if ( empty( $this->element_queue ) && $this->step() ) {
    642                         return $this->next_token();
     663                        return $this->next_visitable_token();
    643664                }
    644665
     
    651672                        }
    652673
    653                         return empty( $this->element_queue ) ? false : $this->next_token();
     674                        return empty( $this->element_queue ) ? false : $this->next_visitable_token();
    654675                }
    655676
     
    662683                 */
    663684                if ( 'root-node' === $this->current_element->token->bookmark_name ) {
    664                         return $this->next_token();
     685                        return $this->next_visitable_token();
    665686                }
    666687
     
    674695                // Avoid sending close events for elements which don't expect a closing.
    675696                if ( $is_pop && ! $this->expects_closer( $this->current_element->token ) ) {
    676                         return $this->next_token();
     697                        return $this->next_visitable_token();
    677698                }
    678699
  • branches/6.7/tests/phpunit/tests/html-api/wpHtmlProcessor.php

    r59721 r59757  
    910910
    911911        /**
     912         * Data provider.
     913         *
     914         * @return array
     915         */
     916        public function data_html_processor_with_extended_next_token() {
     917                return array(
     918                        'single_instance_per_tag'   => array(
     919                                'html'                  => '
     920                                        <html>
     921                                                <head>
     922                                                        <meta charset="utf-8">
     923                                                        <title>Hello World</title>
     924                                                </head>
     925                                                <body>
     926                                                        <h1>Hello World!</h1>
     927                                                        <img src="example.png">
     928                                                        <p>Each tag should occur only once in this document.<!--Closing P tag omitted intentionally.-->
     929                                                        <footer>The end.</footer>
     930                                                </body>
     931                                        </html>
     932                                ',
     933                                'expected_token_counts' => array(
     934                                        '+HTML'    => 1,
     935                                        '+HEAD'    => 1,
     936                                        '#text'    => 14,
     937                                        '+META'    => 1,
     938                                        '+TITLE'   => 1,
     939                                        '-HEAD'    => 1,
     940                                        '+BODY'    => 1,
     941                                        '+H1'      => 1,
     942                                        '-H1'      => 1,
     943                                        '+IMG'     => 1,
     944                                        '+P'       => 1,
     945                                        '#comment' => 1,
     946                                        '-P'       => 1,
     947                                        '+FOOTER'  => 1,
     948                                        '-FOOTER'  => 1,
     949                                        '-BODY'    => 1,
     950                                        '-HTML'    => 1,
     951                                        ''         => 1,
     952                                ),
     953                        ),
     954
     955                        'multiple_tag_instances'    => array(
     956                                'html'                  => '
     957                                        <html>
     958                                                <body>
     959                                                        <h1>Hello World!</h1>
     960                                                        <p>First
     961                                                        <p>Second
     962                                                        <p>Third
     963                                                        <ul>
     964                                                                <li>1
     965                                                                <li>2
     966                                                                <li>3
     967                                                        </ul>
     968                                                </body>
     969                                        </html>
     970                                ',
     971                                'expected_token_counts' => array(
     972                                        '+HTML' => 1,
     973                                        '+HEAD' => 1,
     974                                        '-HEAD' => 1,
     975                                        '+BODY' => 1,
     976                                        '#text' => 13,
     977                                        '+H1'   => 1,
     978                                        '-H1'   => 1,
     979                                        '+P'    => 3,
     980                                        '-P'    => 3,
     981                                        '+UL'   => 1,
     982                                        '+LI'   => 3,
     983                                        '-LI'   => 3,
     984                                        '-UL'   => 1,
     985                                        '-BODY' => 1,
     986                                        '-HTML' => 1,
     987                                        ''      => 1,
     988                                ),
     989                        ),
     990
     991                        'extreme_nested_formatting' => array(
     992                                'html'                  => '
     993                                        <html>
     994                                                <body>
     995                                                        <p>
     996                                                                <strong><em><strike><i><b><u>FORMAT</u></b></i></strike></em></strong>
     997                                                        </p>
     998                                                </body>
     999                                        </html>
     1000                                ',
     1001                                'expected_token_counts' => array(
     1002                                        '+HTML'   => 1,
     1003                                        '+HEAD'   => 1,
     1004                                        '-HEAD'   => 1,
     1005                                        '+BODY'   => 1,
     1006                                        '#text'   => 7,
     1007                                        '+P'      => 1,
     1008                                        '+STRONG' => 1,
     1009                                        '+EM'     => 1,
     1010                                        '+STRIKE' => 1,
     1011                                        '+I'      => 1,
     1012                                        '+B'      => 1,
     1013                                        '+U'      => 1,
     1014                                        '-U'      => 1,
     1015                                        '-B'      => 1,
     1016                                        '-I'      => 1,
     1017                                        '-STRIKE' => 1,
     1018                                        '-EM'     => 1,
     1019                                        '-STRONG' => 1,
     1020                                        '-P'      => 1,
     1021                                        '-BODY'   => 1,
     1022                                        '-HTML'   => 1,
     1023                                        ''        => 1,
     1024                                ),
     1025                        ),
     1026                );
     1027        }
     1028
     1029        /**
     1030         * Ensures that subclasses to WP_HTML_Processor can do bookkeeping by extending the next_token() method.
     1031         *
     1032         * @ticket 62269
     1033         * @dataProvider data_html_processor_with_extended_next_token
     1034         */
     1035        public function test_ensure_next_token_method_extensibility( $html, $expected_token_counts ) {
     1036                require_once DIR_TESTDATA . '/html-api/token-counting-html-processor.php';
     1037
     1038                $processor = Token_Counting_HTML_Processor::create_full_parser( $html );
     1039                while ( $processor->next_tag() ) {
     1040                        continue;
     1041                }
     1042
     1043                $this->assertEquals( $expected_token_counts, $processor->token_seen_count, 'Snapshot: ' . var_export( $processor->token_seen_count, true ) );
     1044        }
     1045
     1046        /**
    9121047         * Ensure that lowercased tag_name query matches tags case-insensitively.
    9131048         *
Note: See TracChangeset for help on using the changeset viewer.