diff --git a/src/wp-includes/html-api/class-wp-html-processor-state.php b/src/wp-includes/html-api/class-wp-html-processor-state.php
index 9cf10c344107a..f72b6ebd765c9 100644
--- a/src/wp-includes/html-api/class-wp-html-processor-state.php
+++ b/src/wp-includes/html-api/class-wp-html-processor-state.php
@@ -59,6 +59,114 @@ class WP_HTML_Processor_State {
*/
const INSERTION_MODE_IN_BODY = 'insertion-mode-in-body';
+ /**
+ * In select insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-inselect
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_SELECT = 'insertion-mode-in-select';
+
+ /**
+ * In select in table insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-inselectintable
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_SELECT_IN_TABLE = 'insertion-mode-in-select-in-table';
+
+ /**
+ * In table insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-intable
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_TABLE = 'insertion-mode-in-table';
+
+ /**
+ * In caption insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-incaption
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_CAPTION = 'insertion-mode-in-caption';
+
+ /**
+ * In table body insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-intablebody
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_TABLE_BODY = 'insertion-mode-in-table-body';
+
+ /**
+ * In row insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-inrow
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_ROW = 'insertion-mode-in-row';
+
+ /**
+ * In cell insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-incell
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_CELL = 'insertion-mode-in-cell';
+
+ /**
+ * In column group insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-incolumngroup
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_COLUMN_GROUP = 'insertion-mode-in-column-group';
+
+ /**
+ * In frameset insertion mode for full HTML parser.
+ *
+ * @since 6.5.0
+ *
+ * @see https://html.spec.whatwg.org/#parsing-main-inframeset
+ * @see WP_HTML_Processor_State::$insertion_mode
+ *
+ * @var string
+ */
+ const INSERTION_MODE_IN_FRAMESET = 'insertion-mode-in-frameset';
+
/**
* Tracks open elements while scanning HTML.
*
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 29f1c7ac6d4cc..d597be34d12fa 100644
--- a/src/wp-includes/html-api/class-wp-html-processor.php
+++ b/src/wp-includes/html-api/class-wp-html-processor.php
@@ -2129,6 +2129,86 @@ private function reconstruct_active_formatting_elements() {
throw new WP_HTML_Unsupported_Exception( 'Cannot reconstruct active formatting elements when advancing and rewinding is required.' );
}
+ /**
+ * Runs the reset the insertion mode appropriately algorithm.
+ *
+ * @since 6.5.0
+ *
+ * @throws WP_HTML_Unsupported_Exception When encoutering unsupported nodes.
+ *
+ * @see https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately
+ */
+ private function reset_insertion_mode() {
+ foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) {
+ switch ( $node->node_name ) {
+ case 'SELECT':
+ foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $ancestor ) {
+ switch ( $ancestor ) {
+ // > If ancestor is a table node, switch the insertion mode to "in select in table" and return.
+ case 'TABLE':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE;
+ return;
+ // > If ancestor is a template node, jump to the step below labeled done.
+ case 'TEMPLATE':
+ break 2;
+ }
+ }
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT;
+ return;
+
+ case 'TD':
+ case 'TH':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL;
+ return;
+
+ case 'TR':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW;
+ return;
+
+ case 'TBODY':
+ case 'THEAD':
+ case 'TFOOT':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
+ return;
+
+ case 'CAPTION':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION;
+ return;
+
+ case 'COLGROUP':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
+ return;
+
+ case 'TABLE':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
+ return;
+
+ case 'TEMPLATE':
+ $this->last_error = self::ERROR_UNSUPPORTED;
+ throw new WP_HTML_Unsupported_Exception( 'Cannot reset insertion mode at TEMPLATE node.' );
+
+ case 'HEAD':
+ $this->last_error = self::ERROR_UNSUPPORTED;
+ throw new WP_HTML_Unsupported_Exception( 'Cannot reset insertion mode at HEAD node.' );
+
+ case 'BODY':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
+ return;
+
+ case 'FRAMESET':
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET;
+ return;
+
+ case 'HTML':
+ $this->last_error = self::ERROR_UNSUPPORTED;
+ throw new WP_HTML_Unsupported_Exception( 'Cannot reset insertion mode at HTML node.' );
+ }
+ }
+
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
+ return;
+ }
+
/**
* Runs the adoption agency algorithm.
*