Skip to content

Commit

Permalink
HTML API: Add method to report depth of currently-matched node.
Browse files Browse the repository at this point in the history
The HTML Processor maintains a stack of open elements, where every element,
every `#text` node, every HTML comment, and other node is pushed and popped while
traversing the document. The "depth" of each of these nodes represents how deep
that stack is where the node appears. Unfortunately this information isn't
exposed to calling code, which has led different projects to attempt to
calculate this value externally. This isn't always trivial, but the HTML
Processor could make it so by exposing the internal knowledge in a new method.

In this patch the `get_current_depth()` method returns just that. Since the
processor always exists within a context, the depth includes nesting from the
always-present html element and also the body, since currently the HTML
Processor only supports parsing in the IN BODY context.

This means that the depth reported for the `DIV` in `<div>` is 3, not 1, because
its breadcrumbs path is `HTML > BODY > DIV`.

Developed in WordPress/wordpress-develop#6589
Discussed in https://core.trac.wordpress.org/ticket/61255

Fixes #61255.
Props dmsnell, jonsurrell.

Built from https://develop.svn.wordpress.org/trunk@58191


git-svn-id: https://core.svn.wordpress.org/trunk@57654 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
dmsnell committed May 23, 2024
1 parent 4b6ee8a commit e0ef9ec
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
29 changes: 29 additions & 0 deletions wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,35 @@ public function get_breadcrumbs() {
return $breadcrumbs;
}

/**
* Returns the nesting depth of the current location in the document.
*
* Example:
*
* $processor = WP_HTML_Processor::create_fragment( '<div><p></p></div>' );
* // The processor starts in the BODY context, meaning it has depth from the start: HTML > BODY.
* 2 === $processor->get_current_depth();
*
* // Opening the DIV element increases the depth.
* $processor->next_token();
* 3 === $processor->get_current_depth();
*
* // Opening the P element increases the depth.
* $processor->next_token();
* 4 === $processor->get_current_depth();
*
* // The P element is closed during `next_token()` so the depth is decreased to reflect that.
* $processor->next_token();
* 3 === $processor->get_current_depth();
*
* @since 6.6.0
*
* @return int Nesting-depth of current location in the document.
*/
public function get_current_depth() {
return $this->state->stack_of_open_elements->count();
}

/**
* Parses next element in the 'in body' insertion mode.
*
Expand Down
2 changes: 1 addition & 1 deletion wp-includes/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.6-alpha-58190';
$wp_version = '6.6-alpha-58191';

/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
Expand Down

0 comments on commit e0ef9ec

Please sign in to comment.