WP_HTML_Processor::seek( string $bookmark_name ): bool

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


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.


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


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


public function seek( $bookmark_name ) {
	// Flush any pending updates to the document before beginning.

	$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 ) {
		 * 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 ) {

			$this->state->stack_of_open_elements->remove_node( $item );

		foreach ( $this->state->active_formatting_elements->walk_up() as $item ) {
			if ( 'context-node' === $item->bookmark_name ) {

			$this->state->active_formatting_elements->remove_node( $item );

		parent::seek( 'context-node' );
		$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
		$this->state->frameset_ok    = true;

	// 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 ) {
		return true;

	while ( $this->step() ) {
		if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
			return true;

	return false;



User Contributed Notes

You must log in before being able to contribute a note or feedback.