WP_Block_Parser::proceed()publicWP 5.0.0

Processes the next token from the input document and returns whether to proceed eating more tokens

This is the "next step" function that essentially takes a token as its input and decides what to do with that token before descending deeper into a nested block tree or continuing along the document or breaking out of a level of nesting.

Method of the class: WP_Block_Parser{}

No Hooks.

Return

true|false.

Usage

$WP_Block_Parser = new WP_Block_Parser();
$WP_Block_Parser->proceed();

Changelog

Since 5.0.0 Introduced.

WP_Block_Parser::proceed() code WP 6.5.2

public function proceed() {
	$next_token = $this->next_token();
	list( $token_type, $block_name, $attrs, $start_offset, $token_length ) = $next_token;
	$stack_depth = count( $this->stack );

	// we may have some HTML soup before the next block.
	$leading_html_start = $start_offset > $this->offset ? $this->offset : null;

	switch ( $token_type ) {
		case 'no-more-tokens':
			// if not in a block then flush output.
			if ( 0 === $stack_depth ) {
				$this->add_freeform();
				return false;
			}

			/*
			 * Otherwise we have a problem
			 * This is an error
			 *
			 * we have options
			 * - treat it all as freeform text
			 * - assume an implicit closer (easiest when not nesting)
			 */

			// for the easy case we'll assume an implicit closer.
			if ( 1 === $stack_depth ) {
				$this->add_block_from_stack();
				return false;
			}

			/*
			 * for the nested case where it's more difficult we'll
			 * have to assume that multiple closers are missing
			 * and so we'll collapse the whole stack piecewise
			 */
			while ( 0 < count( $this->stack ) ) {
				$this->add_block_from_stack();
			}
			return false;

		case 'void-block':
			/*
			 * easy case is if we stumbled upon a void block
			 * in the top-level of the document
			 */
			if ( 0 === $stack_depth ) {
				if ( isset( $leading_html_start ) ) {
					$this->output[] = (array) $this->freeform(
						substr(
							$this->document,
							$leading_html_start,
							$start_offset - $leading_html_start
						)
					);
				}

				$this->output[] = (array) new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() );
				$this->offset   = $start_offset + $token_length;
				return true;
			}

			// otherwise we found an inner block.
			$this->add_inner_block(
				new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() ),
				$start_offset,
				$token_length
			);
			$this->offset = $start_offset + $token_length;
			return true;

		case 'block-opener':
			// track all newly-opened blocks on the stack.
			array_push(
				$this->stack,
				new WP_Block_Parser_Frame(
					new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() ),
					$start_offset,
					$token_length,
					$start_offset + $token_length,
					$leading_html_start
				)
			);
			$this->offset = $start_offset + $token_length;
			return true;

		case 'block-closer':
			/*
			 * if we're missing an opener we're in trouble
			 * This is an error
			 */
			if ( 0 === $stack_depth ) {
				/*
				 * we have options
				 * - assume an implicit opener
				 * - assume _this_ is the opener
				 * - give up and close out the document
				 */
				$this->add_freeform();
				return false;
			}

			// if we're not nesting then this is easy - close the block.
			if ( 1 === $stack_depth ) {
				$this->add_block_from_stack( $start_offset );
				$this->offset = $start_offset + $token_length;
				return true;
			}

			/*
			 * otherwise we're nested and we have to close out the current
			 * block and add it as a new innerBlock to the parent
			 */
			$stack_top                        = array_pop( $this->stack );
			$html                             = substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset );
			$stack_top->block->innerHTML     .= $html;
			$stack_top->block->innerContent[] = $html;
			$stack_top->prev_offset           = $start_offset + $token_length;

			$this->add_inner_block(
				$stack_top->block,
				$stack_top->token_start,
				$stack_top->token_length,
				$start_offset + $token_length
			);
			$this->offset = $start_offset + $token_length;
			return true;

		default:
			// This is an error.
			$this->add_freeform();
			return false;
	}
}