From fee822de6ba5c586b20131e4882a62a8f73e9af3 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Thu, 4 Jul 2024 23:14:44 +0000 Subject: [PATCH] HTML API: Add `current_node_is()` helper method to stack of open elements. As part of work to add more spec support to the HTML API, this new method will make it easier to implement the logic when in the SELECT and TABLE insertion modes. Developed in https://github.com/WordPress/wordpress-develop/pull/6968 Discussed in https://core.trac.wordpress.org/ticket/51576 Props dmsnell, jonsurrell. See #61576. git-svn-id: https://develop.svn.wordpress.org/trunk@58676 602fd350-edb4-49c9-b593-d223f7449a82 --- .../html-api/class-wp-html-open-elements.php | 42 +++++++++++++++++++ .../html-api/class-wp-html-processor.php | 8 ++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index 15479801dda10..b1ca2a5dfa918 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -144,6 +144,48 @@ public function current_node() { return $current_node ? $current_node : null; } + /** + * Indicates if the current node is of a given type or name. + * + * It's possible to pass either a node type or a node name to this function. + * In the case there is no current element it will always return `false`. + * + * Example: + * + * // Is the current node a text node? + * $stack->current_node_is( '#text' ); + * + * // Is the current node a DIV element? + * $stack->current_node_is( 'DIV' ); + * + * // Is the current node any element/tag? + * $stack->current_node_is( '#tag' ); + * + * @see WP_HTML_Tag_Processor::get_token_type + * @see WP_HTML_Tag_Processor::get_token_name + * + * @since 6.7.0 + * + * @access private + * + * @param string $identity Check if the current node has this name or type (depending on what is provided). + * @return bool Whether there is a current element that matches the given identity, whether a token name or type. + */ + public function current_node_is( string $identity ): bool { + $current_node = end( $this->stack ); + if ( false === $current_node ) { + return false; + } + + $current_node_name = $current_node->node_name; + + return ( + $current_node_name === $identity || + ( '#doctype' === $identity && 'html' === $current_node_name ) || + ( '#tag' === $identity && ctype_upper( $current_node_name ) ) + ); + } + /** * Returns whether an element is in a specific scope. * diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 32800218f6404..f187ef7fd1b66 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1029,7 +1029,7 @@ private function step_in_body() { } $this->generate_implied_end_tags(); - if ( $this->state->stack_of_open_elements->current_node()->node_name !== $token_name ) { + if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Record parse error: this error doesn't impact parsing. } $this->state->stack_of_open_elements->pop_until( $token_name ); @@ -1094,7 +1094,7 @@ private function step_in_body() { $this->generate_implied_end_tags(); - if ( $this->state->stack_of_open_elements->current_node()->node_name !== $token_name ) { + if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Record parse error: this error doesn't impact parsing. } @@ -1120,7 +1120,7 @@ private function step_in_body() { if ( $is_li ? 'LI' === $node->node_name : ( 'DD' === $node->node_name || 'DT' === $node->node_name ) ) { $node_name = $is_li ? 'LI' : $node->node_name; $this->generate_implied_end_tags( $node_name ); - if ( $node_name !== $this->state->stack_of_open_elements->current_node()->node_name ) { + if ( ! $this->state->stack_of_open_elements->current_node_is( $node_name ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. } @@ -1197,7 +1197,7 @@ private function step_in_body() { $this->generate_implied_end_tags( $token_name ); - if ( $token_name !== $this->state->stack_of_open_elements->current_node()->node_name ) { + if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. }