Skip to content

Commit

Permalink
Implement insertion mode algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
sirreal committed Feb 2, 2024
1 parent 2a494ac commit 596a977
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
108 changes: 108 additions & 0 deletions src/wp-includes/html-api/class-wp-html-processor-state.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
80 changes: 80 additions & 0 deletions src/wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,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.
*
Expand Down

0 comments on commit 596a977

Please sign in to comment.