WP_HTML_Processor::step_in_table(): bool

This function’s access is marked private. This means it is not intended for use by plugin or theme developers, only in other core functions. It is listed here for completeness. Use https://html.spec.whatwg.org/#parsing-main-intable instead.

Parses next element in the ‘in table’ insertion mode.

Description

This internal function performs the ‘in table’ insertion mode logic for the generalized WP_HTML_Processor::step() function.

See also

Return

bool Whether an element was found.

Source

private function step_in_table(): bool {
	$token_name = $this->get_token_name();
	$token_type = $this->get_token_type();
	$op_sigil   = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : '';
	$op         = "{$op_sigil}{$token_name}";

	switch ( $op ) {
		/*
		 * > A character token, if the current node is table,
		 * > tbody, template, tfoot, thead, or tr element
		 */
		case '#text':
			$current_node      = $this->state->stack_of_open_elements->current_node();
			$current_node_name = $current_node ? $current_node->node_name : null;
			if (
				$current_node_name && (
					'TABLE' === $current_node_name ||
					'TBODY' === $current_node_name ||
					'TEMPLATE' === $current_node_name ||
					'TFOOT' === $current_node_name ||
					'THEAD' === $current_node_name ||
					'TR' === $current_node_name
				)
			) {
				/*
				 * If the text is empty after processing HTML entities and stripping
				 * U+0000 NULL bytes then ignore the token.
				 */
				if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) {
					return $this->step();
				}

				/*
				 * This follows the rules for "in table text" insertion mode.
				 *
				 * Whitespace-only text nodes are inserted in-place. Otherwise
				 * foster parenting is enabled and the nodes would be
				 * inserted out-of-place.
				 *
				 * > If any of the tokens in the pending table character tokens
				 * > list are character tokens that are not ASCII whitespace,
				 * > then this is a parse error: reprocess the character tokens
				 * > in the pending table character tokens list using the rules
				 * > given in the "anything else" entry in the "in table"
				 * > insertion mode.
				 * >
				 * > Otherwise, insert the characters given by the pending table
				 * > character tokens list.
				 *
				 * @see https://html.spec.whatwg.org/#parsing-main-intabletext
				 */
				if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) {
					$this->insert_html_element( $this->state->current_token );
					return true;
				}

				// Non-whitespace would trigger fostering, unsupported at this time.
				$this->bail( 'Foster parenting is not supported.' );
				break;
			}
			break;

		/*
		 * > A comment token
		 */
		case '#comment':
		case '#funky-comment':
		case '#presumptuous-tag':
			$this->insert_html_element( $this->state->current_token );
			return true;

		/*
		 * > A DOCTYPE token
		 */
		case 'html':
			// Parse error: ignore the token.
			return $this->step();

		/*
		 * > A start tag whose tag name is "caption"
		 */
		case '+CAPTION':
			$this->state->stack_of_open_elements->clear_to_table_context();
			$this->state->active_formatting_elements->insert_marker();
			$this->insert_html_element( $this->state->current_token );
			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION;
			return true;

		/*
		 * > A start tag whose tag name is "colgroup"
		 */
		case '+COLGROUP':
			$this->state->stack_of_open_elements->clear_to_table_context();
			$this->insert_html_element( $this->state->current_token );
			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
			return true;

		/*
		 * > A start tag whose tag name is "col"
		 */
		case '+COL':
			$this->state->stack_of_open_elements->clear_to_table_context();

			/*
			 * > Insert an HTML element for a "colgroup" start tag token with no attributes,
			 * > then switch the insertion mode to "in column group".
			 */
			$this->insert_virtual_node( 'COLGROUP' );
			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
			return $this->step( self::REPROCESS_CURRENT_NODE );

		/*
		 * > A start tag whose tag name is one of: "tbody", "tfoot", "thead"
		 */
		case '+TBODY':
		case '+TFOOT':
		case '+THEAD':
			$this->state->stack_of_open_elements->clear_to_table_context();
			$this->insert_html_element( $this->state->current_token );
			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
			return true;

		/*
		 * > A start tag whose tag name is one of: "td", "th", "tr"
		 */
		case '+TD':
		case '+TH':
		case '+TR':
			$this->state->stack_of_open_elements->clear_to_table_context();
			/*
			 * > Insert an HTML element for a "tbody" start tag token with no attributes,
			 * > then switch the insertion mode to "in table body".
			 */
			$this->insert_virtual_node( 'TBODY' );
			$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
			return $this->step( self::REPROCESS_CURRENT_NODE );

		/*
		 * > A start tag whose tag name is "table"
		 *
		 * This tag in the IN TABLE insertion mode is a parse error.
		 */
		case '+TABLE':
			if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) {
				return $this->step();
			}

			$this->state->stack_of_open_elements->pop_until( 'TABLE' );
			$this->reset_insertion_mode_appropriately();
			return $this->step( self::REPROCESS_CURRENT_NODE );

		/*
		 * > An end tag whose tag name is "table"
		 */
		case '-TABLE':
			if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) {
				// @todo Indicate a parse error once it's possible.
				return $this->step();
			}

			$this->state->stack_of_open_elements->pop_until( 'TABLE' );
			$this->reset_insertion_mode_appropriately();
			return true;

		/*
		 * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr"
		 */
		case '-BODY':
		case '-CAPTION':
		case '-COL':
		case '-COLGROUP':
		case '-HTML':
		case '-TBODY':
		case '-TD':
		case '-TFOOT':
		case '-TH':
		case '-THEAD':
		case '-TR':
			// Parse error: ignore the token.
			return $this->step();

		/*
		 * > A start tag whose tag name is one of: "style", "script", "template"
		 * > An end tag whose tag name is "template"
		 */
		case '+STYLE':
		case '+SCRIPT':
		case '+TEMPLATE':
		case '-TEMPLATE':
			/*
			 * > Process the token using the rules for the "in head" insertion mode.
			 */
			return $this->step_in_head();

		/*
		 * > A start tag whose tag name is "input"
		 *
		 * > If the token does not have an attribute with the name "type", or if it does, but
		 * > that attribute's value is not an ASCII case-insensitive match for the string
		 * > "hidden", then: act as described in the "anything else" entry below.
		 */
		case '+INPUT':
			$type_attribute = $this->get_attribute( 'type' );
			if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) {
				goto anything_else;
			}
			// @todo Indicate a parse error once it's possible.
			$this->insert_html_element( $this->state->current_token );
			return true;

		/*
		 * > A start tag whose tag name is "form"
		 *
		 * This tag in the IN TABLE insertion mode is a parse error.
		 */
		case '+FORM':
			if (
				$this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) ||
				isset( $this->state->form_element )
			) {
				return $this->step();
			}

			// This FORM is special because it immediately closes and cannot have other children.
			$this->insert_html_element( $this->state->current_token );
			$this->state->form_element = $this->state->current_token;
			$this->state->stack_of_open_elements->pop();
			return true;
	}

	/*
	 * > Anything else
	 * > Parse error. Enable foster parenting, process the token using the rules for the
	 * > "in body" insertion mode, and then disable foster parenting.
	 *
	 * @todo Indicate a parse error once it's possible.
	 */
	anything_else:
	$this->bail( 'Foster parenting is not supported.' );
}

Changelog

VersionDescription
6.7.0Introduced.

User Contributed Notes

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