From f9e93348a20fe9b2cb0c0152b72730bc5420f40c Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 25 Oct 2024 23:15:51 +0200 Subject: [PATCH] Work on fix --- .../html-api/class-wp-html-processor.php | 72 ++++++++++++------- .../html-api/class-wp-html-tag-processor.php | 5 +- 2 files changed, 51 insertions(+), 26 deletions(-) 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 4003cf48c1b69..7d3a3d56329bd 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -5286,6 +5286,8 @@ public function seek( $bookmark_name ): bool { // Flush any pending updates to the document before beginning. $this->get_updated_html(); + echo 'Seeking to ' . $bookmark_name . "\n"; + $actual_bookmark_name = "_{$bookmark_name}"; $processor_started_at = $this->state->current_token ? $this->bookmarks[ $this->state->current_token->bookmark_name ]->start @@ -5323,45 +5325,64 @@ public function seek( $bookmark_name ): bool { * and computation time. */ if ( 'backward' === $direction ) { - /* - * Instead of clearing the parser state and starting fresh, calling the stack methods - * maintains the proper flags in the parser. - */ - foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { - if ( 'context-node' === $item->bookmark_name ) { - break; - } + echo 'back: ' . "\n"; + // Reset necessary parser state + $this->state->frameset_ok = true; + $this->state->stack_of_template_insertion_modes = array(); + $this->state->head_element = null; + $this->state->form_element = null; + $this->state->current_token = null; + $this->element_queue = array(); + $this->current_element = null; + + if ( null === $this->context_node ) { + echo 'full parser' . "\n"; + /* + * In the case of a full parser, the processor needs to be + * reset to a clean state and start over. + */ + $this->state->stack_of_open_elements = new WP_HTML_Open_Elements(); + $this->state->active_formatting_elements = new WP_HTML_Active_Formatting_Elements(); - $this->state->stack_of_open_elements->remove_node( $item ); - } + $this->breadcrumbs = array(); + $this->bytes_already_parsed = 0; + $this->parser_state = self::STATE_READY; + } else { + /* + * In case the parser is a fragment parser, instead of clearing the + * parser state and starting fresh, calling the stack methods + * maintains the proper flags in the parser. + */ + foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { + if ( 'context-node' === $item->bookmark_name ) { + break; + } - foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { - if ( 'context-node' === $item->bookmark_name ) { - break; + $this->state->stack_of_open_elements->remove_node( $item ); } - $this->state->active_formatting_elements->remove_node( $item ); - } + foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { + if ( 'context-node' === $item->bookmark_name ) { + break; + } - parent::seek( 'context-node' ); - $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; - $this->state->frameset_ok = true; - $this->element_queue = array(); - $this->current_element = null; + $this->state->active_formatting_elements->remove_node( $item ); + } - if ( isset( $this->context_node ) ) { - $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 ); - } else { - $this->breadcrumbs = array(); + parent::seek( 'context-node' ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; + $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 ); } } + // When moving forwards, reparse the document until reaching the same location as the original bookmark. - if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) { + if ( null !== $this->state->current_token && $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) { return true; } while ( $this->next_token() ) { + echo 'bm starts at ' . $bookmark_starts_at . ' and current token starts at ' . $this->bookmarks[ $this->state->current_token->bookmark_name ]->start . "\n"; if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) { while ( isset( $this->current_element ) && WP_HTML_Stack_Event::POP === $this->current_element->operation ) { $this->current_element = array_shift( $this->element_queue ); @@ -5370,6 +5391,7 @@ public function seek( $bookmark_name ): bool { } } + echo 'false' . "\n"; return false; } diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index e2632c80f6da5..ecce9b285c779 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -591,7 +591,7 @@ class WP_HTML_Tag_Processor { * @since 6.2.0 * @var int */ - private $bytes_already_parsed = 0; + protected $bytes_already_parsed = 0; /** * Byte offset in input document where current token starts. @@ -946,6 +946,8 @@ private function base_class_next_token(): bool { $was_at = $this->bytes_already_parsed; $this->after_tag(); + var_dump( $was_at, $this->parser_state ); + // Don't proceed if there's nothing more to scan. if ( self::STATE_COMPLETE === $this->parser_state || @@ -2542,6 +2544,7 @@ public function has_bookmark( $bookmark_name ): bool { * @return bool Whether the internal cursor was successfully moved to the bookmark's location. */ public function seek( $bookmark_name ): bool { + var_dump( $bookmark_name, $this->bookmarks ); if ( ! array_key_exists( $bookmark_name, $this->bookmarks ) ) { _doing_it_wrong( __METHOD__,