mirror of
https://github.com/WordPress/WordPress.git
synced 2025-01-10 18:37:58 +01:00
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. Built from https://develop.svn.wordpress.org/trunk@58588 git-svn-id: http://core.svn.wordpress.org/trunk@58035 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
c1d1be9745
commit
ede77aca35
wp-includes
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user