diff --git a/wp-includes/html-api/class-wp-html-open-elements.php b/wp-includes/html-api/class-wp-html-open-elements.php index 7f148a7af7..15479801dd 100644 --- a/wp-includes/html-api/class-wp-html-open-elements.php +++ b/wp-includes/html-api/class-wp-html-open-elements.php @@ -308,11 +308,15 @@ class WP_HTML_Open_Elements { */ public function pop() { $item = array_pop( $this->stack ); - if ( null === $item ) { return false; } + if ( 'context-node' === $item->bookmark_name ) { + $this->stack[] = $item; + return false; + } + $this->after_element_pop( $item ); return true; } @@ -329,6 +333,10 @@ class WP_HTML_Open_Elements { */ public function pop_until( $tag_name ) { foreach ( $this->walk_up() as $item ) { + if ( 'context-node' === $item->bookmark_name ) { + return true; + } + $this->pop(); if ( @@ -369,6 +377,10 @@ class WP_HTML_Open_Elements { * @return bool Whether the node was found and removed from the stack of open elements. */ public function remove_node( $token ) { + if ( 'context-node' === $token->bookmark_name ) { + return false; + } + foreach ( $this->walk_up() as $position_from_end => $item ) { if ( $token->bookmark_name !== $item->bookmark_name ) { continue; diff --git a/wp-includes/html-api/class-wp-html-processor.php b/wp-includes/html-api/class-wp-html-processor.php index 0eb597edcd..29f1c7ac6d 100644 --- a/wp-includes/html-api/class-wp-html-processor.php +++ b/wp-includes/html-api/class-wp-html-processor.php @@ -519,10 +519,12 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { return false; } - if ( 0 === count( $this->element_queue ) && ! $this->step() ) { - while ( $this->state->stack_of_open_elements->pop() ) { + if ( 'done' !== $this->has_seen_context_node && 0 === count( $this->element_queue ) && ! $this->step() ) { + while ( 'context-node' !== $this->state->stack_of_open_elements->current_node()->bookmark_name && $this->state->stack_of_open_elements->pop() ) { continue; } + $this->has_seen_context_node = 'done'; + return $this->next_token(); } $this->current_element = array_shift( $this->element_queue ); @@ -537,7 +539,11 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { } if ( ! isset( $this->current_element ) ) { - return $this->next_token(); + if ( 'done' === $this->has_seen_context_node ) { + return false; + } else { + return $this->next_token(); + } } if ( isset( $this->context_node ) && WP_HTML_Stack_Event::POP === $this->current_element->operation && $this->context_node === $this->current_element->token ) { @@ -782,16 +788,48 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { * * @since 6.4.0 * - * @todo make aware of queue of elements, because stack operations have already been done by now. - * * @return string[]|null Array of tag names representing path to matched node, if matched, otherwise NULL. */ public function get_breadcrumbs() { $breadcrumbs = array(); + foreach ( $this->state->stack_of_open_elements->walk_down() as $stack_item ) { $breadcrumbs[] = $stack_item->node_name; } + if ( ! $this->is_virtual() ) { + return $breadcrumbs; + } + + foreach ( $this->element_queue as $queue_item ) { + if ( $this->current_element->token->bookmark_name === $queue_item->token->bookmark_name ) { + break; + } + + if ( 'context-node' === $queue_item->token->bookmark_name ) { + break; + } + + if ( 'real' === $queue_item->provenance ) { + break; + } + + if ( WP_HTML_Stack_Event::PUSH === $queue_item->operation ) { + $breadcrumbs[] = $queue_item->token->node_name; + } else { + array_pop( $breadcrumbs ); + } + } + + if ( null !== parent::get_token_name() && ! parent::is_tag_closer() ) { + array_pop( $breadcrumbs ); + } + + // Add the virtual node we're at. + if ( WP_HTML_Stack_Event::PUSH === $this->current_element->operation ) { + $breadcrumbs[] = $this->current_element->token->node_name; + } + return $breadcrumbs; } @@ -821,7 +859,9 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor { * @return int Nesting-depth of current location in the document. */ public function get_current_depth() { - return $this->state->stack_of_open_elements->count(); + return $this->is_virtual() + ? count( $this->get_breadcrumbs() ) + : $this->state->stack_of_open_elements->count(); } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index f065f49a47..db02b31126 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.7-alpha-58585'; +$wp_version = '6.7-alpha-58588'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.