Make WordPress Core


Ignore:
Timestamp:
08/10/2023 08:35:55 AM (3 years ago)
Author:
Bernhard Reiter
Message:

HTML API: Add support for BUTTON element.

This patch adds support to process the BUTTON element. This requires adding some additional semantic rules to handle situations where a BUTTON element is already in scope.

Also included is a fixup to enforce that WP_HTML_Processor::next_tag() never returns for a tag closer. This is useful with the Tag Processor, but not for the HTML Processor. There were tests relying on this behavior to assert that internal processes were working as they should, but those tests have been updated to use the semi-private step() function, which does stop on tag closers.

This patch is one in a series of changes to expand support within the HTML API, moving gradually to allow for more focused changes that are easier to review and test. The HTML Processor is a work in progress with a certain set of features slated to be ready and tested by 6.4.0, but it will only contain partial support of the HTML5 specification even after that. Whenever it cannot positively recognize and process its input it bails, and certain function stubs and logical stubs exist to structure future expansions of support.

Props dmsnell.
Fixes #58961.

File:
1 edited

Legend:

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

    r56376 r56380  
    350350        public function next_tag( $query = null ) {
    351351                if ( null === $query ) {
    352                         return $this->step();
     352                        while ( $this->step() ) {
     353                                if ( ! $this->is_tag_closer() ) {
     354                                        return true;
     355                                }
     356                        }
     357
     358                        return false;
    353359                }
    354360
    … …  
    367373
    368374                if ( ! ( array_key_exists( 'breadcrumbs', $query ) && is_array( $query['breadcrumbs'] ) ) ) {
    369                         return $this->step();
     375                        while ( $this->step() ) {
     376                                if ( ! $this->is_tag_closer() ) {
     377                                        return true;
     378                                }
     379                        }
     380
     381                        return false;
    370382                }
    371383
    … …  
    384396                $crumb  = end( $breadcrumbs );
    385397                $target = strtoupper( $crumb );
    386                 while ( $this->step() ) {
     398                while ( $match_offset > 0 && $this->step() ) {
    387399                        if ( $target !== $this->get_tag() ) {
    388400                                continue;
    … …  
    396408
    397409                                $crumb = prev( $breadcrumbs );
    398                                 if ( false === $crumb && 0 === --$match_offset ) {
     410                                if ( false === $crumb && 0 === --$match_offset && ! $this->is_tag_closer() ) {
    399411                                        return true;
    400412                                }
    … …  
    511523
    512524                switch ( $op ) {
     525                        /*
     526                         * > A start tag whose tag name is "button"
     527                         */
     528                        case '+BUTTON':
     529                                if ( $this->state->stack_of_open_elements->has_element_in_scope( 'BUTTON' ) ) {
     530                                        // @TODO: Indicate a parse error once it's possible. This error does not impact the logic here.
     531                                        $this->generate_implied_end_tags();
     532                                        $this->state->stack_of_open_elements->pop_until( 'BUTTON' );
     533                                }
     534
     535                                $this->reconstruct_active_formatting_elements();
     536                                $this->insert_html_element( $this->current_token );
     537                                $this->state->frameset_ok = false;
     538
     539                                return true;
     540
    513541                        /*
    514542                         * > A start tag whose tag name is one of: "address", "article", "aside",
    … …  
    536564                         */
    537565                        case '-BLOCKQUOTE':
     566                        case '-BUTTON':
    538567                        case '-DIV':
    539568                        case '-FIGCAPTION':
    540569                        case '-FIGURE':
    541570                                if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $tag_name ) ) {
     571                                        // @TODO: Report parse error.
    542572                                        // Ignore the token.
    543573                                        return $this->step();
    … …  
    545575
    546576                                $this->generate_implied_end_tags();
     577                                if ( $this->state->stack_of_open_elements->current_node()->node_name !== $tag_name ) {
     578                                        // @TODO: Record parse error: this error doesn't impact parsing.
     579                                }
    547580                                $this->state->stack_of_open_elements->pop_until( $tag_name );
    548581                                return true;
Note: See TracChangeset for help on using the changeset viewer.