mirror of
git://develop.git.wordpress.org/
synced 2025-03-15 01:19:51 +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. git-svn-id: https://develop.svn.wordpress.org/trunk@58588 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
d6bbd8ddf4
commit
9cbaee349c
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user