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.