Make WordPress Core

Changeset 58588 for trunk


Ignore:
Timestamp:
06/27/2024 08:47:38 PM (2 years ago)
Author:
dmsnell
Message:

HTML API: Report breadcrumbs properly when visiting virtual nodes.

When [58304] introduced the abililty to visit virtual nodes in the HTML document,
those being the nodes which are implied by the HTML but no explicitly present in
the raw text, a bug was introduced in the get_breadcrumbs() method because it
wasn't updated to be aware of the virtual nodes. Therefore it would report the
wrong breadcrumbs for virtual nodes. Since the new get_depth() method is based
on the same logic it was also broken for virtual nodes.

In this patch, the breadcrumbs have been updated to account for the virtual nodes
and the depth method has been updated to rely on the fixed breadcrumb logic.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/6914
Discussed in https://core.trac.wordpress.org/ticket/61348

Follow-up to [58304].

Props dmsnell, jonsurrell, zieladam.
See #61348.

Location:
trunk/src/wp-includes/html-api
Files:
2 edited

Legend:

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

    r58441 r58588  
    309309        public function pop() {
    310310                $item = array_pop( $this->stack );
    311 
    312311                if ( null === $item ) {
    313312                        return false;
    314313                }
    315314
     315                if ( 'context-node' === $item->bookmark_name ) {
     316                        $this->stack[] = $item;
     317                        return false;
     318                }
     319
    316320                $this->after_element_pop( $item );
    317321                return true;
    … …  
    330334        public function pop_until( $tag_name ) {
    331335                foreach ( $this->walk_up() as $item ) {
     336                        if ( 'context-node' === $item->bookmark_name ) {
     337                                return true;
     338                        }
     339
    332340                        $this->pop();
    333341
    … …  
    370378         */
    371379        public function remove_node( $token ) {
     380                if ( 'context-node' === $token->bookmark_name ) {
     381                        return false;
     382                }
     383
    372384                foreach ( $this->walk_up() as $position_from_end => $item ) {
    373385                        if ( $token->bookmark_name !== $item->bookmark_name ) {
  • trunk/src/wp-includes/html-api/class-wp-html-processor.php

    r58558 r58588  
    520520                }
    521521
    522                 if ( 0 === count( $this->element_queue ) && ! $this->step() ) {
    523                         while ( $this->state->stack_of_open_elements->pop() ) {
     522                if ( 'done' !== $this->has_seen_context_node && 0 === count( $this->element_queue ) && ! $this->step() ) {
     523                        while ( 'context-node' !== $this->state->stack_of_open_elements->current_node()->bookmark_name && $this->state->stack_of_open_elements->pop() ) {
    524524                                continue;
    525525                        }
     526                        $this->has_seen_context_node = 'done';
     527                        return $this->next_token();
    526528                }
    527529
    … …  
    538540
    539541                if ( ! isset( $this->current_element ) ) {
    540                         return $this->next_token();
     542                        if ( 'done' === $this->has_seen_context_node ) {
     543                                return false;
     544                        } else {
     545                                return $this->next_token();
     546                        }
    541547                }
    542548
    … …  
    783789         * @since 6.4.0
    784790         *
    785          * @todo make aware of queue of elements, because stack operations have already been done by now.
    786          *
    787791         * @return string[]|null Array of tag names representing path to matched node, if matched, otherwise NULL.
    788792         */
    789793        public function get_breadcrumbs() {
    790794                $breadcrumbs = array();
     795
    791796                foreach ( $this->state->stack_of_open_elements->walk_down() as $stack_item ) {
    792797                        $breadcrumbs[] = $stack_item->node_name;
     798                }
     799
     800                if ( ! $this->is_virtual() ) {
     801                        return $breadcrumbs;
     802                }
     803
     804                foreach ( $this->element_queue as $queue_item ) {
     805                        if ( $this->current_element->token->bookmark_name === $queue_item->token->bookmark_name ) {
     806                                break;
     807                        }
     808
     809                        if ( 'context-node' === $queue_item->token->bookmark_name ) {
     810                                break;
     811                        }
     812
     813                        if ( 'real' === $queue_item->provenance ) {
     814                                break;
     815                        }
     816
     817                        if ( WP_HTML_Stack_Event::PUSH === $queue_item->operation ) {
     818                                $breadcrumbs[] = $queue_item->token->node_name;
     819                        } else {
     820                                array_pop( $breadcrumbs );
     821                        }
     822                }
     823
     824                if ( null !== parent::get_token_name() && ! parent::is_tag_closer() ) {
     825                        array_pop( $breadcrumbs );
     826                }
     827
     828                // Add the virtual node we're at.
     829                if ( WP_HTML_Stack_Event::PUSH === $this->current_element->operation ) {
     830                        $breadcrumbs[] = $this->current_element->token->node_name;
    793831                }
    794832
    … …  
    822860         */
    823861        public function get_current_depth() {
    824                 return $this->state->stack_of_open_elements->count();
     862                return $this->is_virtual()
     863                        ? count( $this->get_breadcrumbs() )
     864                        : $this->state->stack_of_open_elements->count();
    825865        }
    826866
Note: See TracChangeset for help on using the changeset viewer.