Title: WP_HTML_Processor::seek
Published: November 8, 2023
Last modified: February 24, 2026

---

# WP_HTML_Processor::seek( string $bookmark_name ): bool

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#wp--skip-link--target)

Moves the internal cursor in the HTML Processor to a given bookmark’s location.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#description)󠁿

Be careful! Seeking backwards to a previous location resets the parser to the start
of the document and reparses the entire contents up until it finds the sought-after
bookmarked location.

In order to prevent accidental infinite loops, there’s a maximum limit on the number
of times seek() can be called.

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#parameters)󠁿

 `$bookmark_name`stringrequired

Jump to the place in the document identified by this bookmark name.

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#return)󠁿

 bool Whether the internal cursor was successfully moved to the bookmark’s location.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#source)󠁿

    ```php
    public function seek( $bookmark_name ): bool {
    	// Flush any pending updates to the document before beginning.
    	$this->get_updated_html();

    	$actual_bookmark_name = "_{$bookmark_name}";
    	$processor_started_at = $this->state->current_token
    		? $this->bookmarks[ $this->state->current_token->bookmark_name ]->start
    		: 0;
    	$bookmark_starts_at   = $this->bookmarks[ $actual_bookmark_name ]->start;
    	$direction            = $bookmark_starts_at > $processor_started_at ? 'forward' : 'backward';

    	/*
    	 * If seeking backwards, it's possible that the sought-after bookmark exists within an element
    	 * which has been closed before the current cursor; in other words, it has already been removed
    	 * from the stack of open elements. This means that it's insufficient to simply pop off elements
    	 * from the stack of open elements which appear after the bookmarked location and then jump to
    	 * that location, as the elements which were open before won't be re-opened.
    	 *
    	 * In order to maintain consistency, the HTML Processor rewinds to the start of the document
    	 * and reparses everything until it finds the sought-after bookmark.
    	 *
    	 * There are potentially better ways to do this: cache the parser state for each bookmark and
    	 * restore it when seeking; store an immutable and idempotent register of where elements open
    	 * and close.
    	 *
    	 * If caching the parser state it will be essential to properly maintain the cached stack of
    	 * open elements and active formatting elements when modifying the document. This could be a
    	 * tedious and time-consuming process as well, and so for now will not be performed.
    	 *
    	 * It may be possible to track bookmarks for where elements open and close, and in doing so
    	 * be able to quickly recalculate breadcrumbs for any element in the document. It may even
    	 * be possible to remove the stack of open elements and compute it on the fly this way.
    	 * If doing this, the parser would need to track the opening and closing locations for all
    	 * tokens in the breadcrumb path for any and all bookmarks. By utilizing bookmarks themselves
    	 * this list could be automatically maintained while modifying the document. Finding the
    	 * breadcrumbs would then amount to traversing that list from the start until the token
    	 * being inspected. Once an element closes, if there are no bookmarks pointing to locations
    	 * within that element, then all of these locations may be forgotten to save on memory use
    	 * and computation time.
    	 */
    	if ( 'backward' === $direction ) {

    		/*
    		 * When moving backward, stateful stacks should be cleared.
    		 */
    		foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) {
    			$this->state->stack_of_open_elements->remove_node( $item );
    		}

    		foreach ( $this->state->active_formatting_elements->walk_up() as $item ) {
    			$this->state->active_formatting_elements->remove_node( $item );
    		}

    		/*
    		 * **After** clearing stacks, more processor state can be reset.
    		 * This must be done after clearing the stack because those stacks generate events that
    		 * would appear on a subsequent call to `next_token()`.
    		 */
    		$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->current_element                          = null;
    		$this->element_queue                            = array();

    		/*
    		 * The absence of a context node indicates a full parse.
    		 * The presence of a context node indicates a fragment parser.
    		 */
    		if ( null === $this->context_node ) {
    			$this->change_parsing_namespace( 'html' );
    			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_INITIAL;
    			$this->breadcrumbs           = array();

    			$this->bookmarks['initial'] = new WP_HTML_Span( 0, 0 );
    			parent::seek( 'initial' );
    			unset( $this->bookmarks['initial'] );
    		} else {

    			/*
    			 * Push the root-node (HTML) back onto the stack of open elements.
    			 *
    			 * Fragment parsers require this extra bit of setup.
    			 * It's handled in full parsers by advancing the processor state.
    			 */
    			$this->state->stack_of_open_elements->push(
    				new WP_HTML_Token(
    					'root-node',
    					'HTML',
    					false
    				)
    			);

    			$this->change_parsing_namespace(
    				$this->context_node->integration_node_type
    					? 'html'
    					: $this->context_node->namespace
    			);

    			if ( 'TEMPLATE' === $this->context_node->node_name ) {
    				$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE;
    			}

    			$this->reset_insertion_mode_appropriately();
    			$this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 );
    			parent::seek( $this->context_node->bookmark_name );
    		}
    	}

    	/*
    	 * Here, the processor moves forward through the document until it matches the bookmark.
    	 * do-while is used here because the processor is expected to already be stopped on
    	 * a token than may match the bookmarked location.
    	 */
    	do {
    		/*
    		 * The processor will stop on virtual tokens, but bookmarks may not be set on them.
    		 * They should not be matched when seeking a bookmark, skip them.
    		 */
    		if ( $this->is_virtual() ) {
    			continue;
    		}
    		if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
    			return true;
    		}
    	} while ( $this->next_token() );

    	return false;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/html-api/class-wp-html-processor.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/html-api/class-wp-html-processor.php#L5507)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/html-api/class-wp-html-processor.php#L5507-L5636)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#related)󠁿

| Uses | Description | 
| [WP_HTML_Processor::reset_insertion_mode_appropriately()](https://developer.wordpress.org/reference/classes/wp_html_processor/reset_insertion_mode_appropriately/)`wp-includes/html-api/class-wp-html-processor.php` |

Runs the reset the insertion mode appropriately algorithm.

  | 
| [WP_HTML_Processor::is_virtual()](https://developer.wordpress.org/reference/classes/wp_html_processor/is_virtual/)`wp-includes/html-api/class-wp-html-processor.php` |

Indicates if the currently-matched token is virtual, created by a stack operation while processing HTML, rather than a token found in the HTML text itself.

  | 
| [WP_HTML_Processor::next_token()](https://developer.wordpress.org/reference/classes/wp_html_processor/next_token/)`wp-includes/html-api/class-wp-html-processor.php` |

Finds the next token in the HTML document.

  | 
| [WP_HTML_Token::__construct()](https://developer.wordpress.org/reference/classes/wp_html_token/__construct/)`wp-includes/html-api/class-wp-html-token.php` |

Constructor – creates a reference to a token in some external HTML string.

  | 
| [WP_HTML_Tag_Processor::seek()](https://developer.wordpress.org/reference/classes/wp_html_tag_processor/seek/)`wp-includes/html-api/class-wp-html-tag-processor.php` |

Move the internal cursor in the Tag Processor to a given bookmark’s location.

  | 
| [WP_HTML_Span::__construct()](https://developer.wordpress.org/reference/classes/wp_html_span/__construct/)`wp-includes/html-api/class-wp-html-span.php` |

Constructor.

  |

[Show 1 more](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_html_processor/seek/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.4.0](https://developer.wordpress.org/reference/since/6.4.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_html_processor%2Fseek%2F)
before being able to contribute a note or feedback.