Skip to content

Commit

Permalink
WIP: Add support for the rest of the common IN BODY tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmsnell committed Jan 13, 2024
1 parent 454f2bf commit 8818c97
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ public function current_node() {
return $current_node ? $current_node : null;
}

/**
* Inserts a marker at the end of the list of active formatting elements.
*
* @since 6.5.0
*/
public function insert_marker() {
$marker = new WP_HTML_Token( null, 'marker', false );
$this->push( $marker );
}

/**
* Pushes a node onto the stack of active formatting elements.
*
Expand Down
14 changes: 6 additions & 8 deletions src/wp-includes/html-api/class-wp-html-open-elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,9 @@ public function has_element_in_scope( $tag_name ) {
return $this->has_element_in_specific_scope(
$tag_name,
array(

/*
* Because it's not currently possible to encounter
* one of the termination elements, they don't need
* to be listed here. If they were, they would be
* unreachable and only waste CPU cycles while
* scanning through HTML.
*/
'APPLET',
'MARQUEE',
'OBJECT',
)
);
}
Expand Down Expand Up @@ -421,7 +416,10 @@ public function after_element_push( $item ) {
* cases where the precalculated value needs to change.
*/
switch ( $item->node_name ) {
case 'APPLET':
case 'BUTTON':
case 'MARQUEE':
case 'OBJECT':
$this->has_p_in_button_scope = false;
break;

Expand Down
122 changes: 105 additions & 17 deletions src/wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,26 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) {
* is provided in the opening tag, otherwise it expects a tag closer.
*/
$top_node = $this->state->stack_of_open_elements->current_node();
if ( $top_node && self::is_void( $top_node->node_name ) ) {
if (
$top_node &&
(
self::is_void( $top_node->node_name ) ||

// Special: Skips SCRIPT data in Tag Processor.
'SCRIPT' === $top_node->node_name ||

// Special: Skips RCDATA data in Tag Processor.
'TEXTAREA' === $top_node->node_name ||
'TITLE' === $top_node->node_name ||

// Special: Skips RAWTEXT data in Tag Processor.
'IFRAME' === $top_node->node_name ||
'NOEMBED' === $top_node->node_name ||
'NOFRAMES' === $top_node->node_name ||
'STYLE' === $top_node->node_name ||
'XMP' === $top_node->node_name
)
) {
$this->state->stack_of_open_elements->pop();
}

Expand Down Expand Up @@ -688,6 +707,7 @@ private function step_in_body() {
case '-MENU':
case '-NAV':
case '-OL':
case '-PRE':
case '-SEARCH':
case '-SECTION':
case '-SUMMARY':
Expand Down Expand Up @@ -732,6 +752,17 @@ private function step_in_body() {
$this->insert_html_element( $this->state->current_token );
return true;

/*
* > A start tag whose tag name is one of: "pre", "listing"
*/
case '+PRE':
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
$this->close_a_p_element();
}
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
return true;

/*
* > An end tag whose tag name is one of: "h1", "h2", "h3", "h4", "h5", "h6"
*/
Expand Down Expand Up @@ -934,12 +965,84 @@ private function step_in_body() {
$this->run_adoption_agency_algorithm();
return true;

/*
* > A start tag whose tag name is one of: "applet", "marquee", "object"
*/
case '+APPLET':
case '+MARQUEE':
case '+OBJECT':
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->active_formatting_elements->insert_marker();
$this->state->frameset_ok = false;
return true;

/*
* > An end tag whose tag name is "br"
*
* This is supposed to create a BR element with no attributes,
* which the HTML Processor doesn't currently have a way to
* represent.
*/
case '-BR':
$this->last_error = self::ERROR_UNSUPPORTED;
throw new WP_HTML_Unsupported_Exception( 'Cannot process unexpecdted BR closer' );

/*
* > A start tag whose tag name is one of: "area", "br", "embed", "img", "keygen", "wbr"
*/
case '+AREA':
case '+BR':
case '+EMBED':
case '+IMG':
case '+WBR':
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
return true;

/*
* > A start tag whose tag name is "hr"
*/
case '+HR':
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
$this->close_a_p_element();
}
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
return true;

/*
* > A start tag whose tag name is "textarea"
*/
case '+TEXTAREA':
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
return true;

/*
* > A start tag whose tag name is "xmp"
*/
case '+XMP':
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
$this->close_a_p_element();
}
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
return true;

/*
* > A start tag whose tag name is "iframe"
*/
case '+IFRAME':
$this->state->frameset_ok = false;
return true;

/*
* > A start tag whose tag name is "noembed"
*/
case '+NOEMBED':
return true;
}

Expand All @@ -960,45 +1063,32 @@ private function step_in_body() {
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
*/
switch ( $tag_name ) {
case 'APPLET':
case 'AREA':
case 'BASE':
case 'BASEFONT':
case 'BGSOUND':
case 'BODY':
case 'BR':
case 'CAPTION':
case 'COL':
case 'COLGROUP':
case 'DD':
case 'DT':
case 'EMBED':
case 'FORM':
case 'FRAME':
case 'FRAMESET':
case 'HEAD':
case 'HR':
case 'HTML':
case 'IFRAME':
case 'INPUT':
case 'KEYGEN':
case 'LI':
case 'LINK':
case 'LISTING':
case 'MARQUEE':
case 'MATH':
case 'META':
case 'NOBR':
case 'NOEMBED':
case 'NOFRAMES':
case 'NOSCRIPT':
case 'OBJECT':
case 'OL':
case 'OPTGROUP':
case 'OPTION':
case 'PARAM':
case 'PLAINTEXT':
case 'PRE':
case 'RB':
case 'RP':
case 'RT':
Expand All @@ -1013,16 +1103,13 @@ private function step_in_body() {
case 'TBODY':
case 'TD':
case 'TEMPLATE':
case 'TEXTAREA':
case 'TFOOT':
case 'TH':
case 'THEAD':
case 'TITLE':
case 'TR':
case 'TRACK':
case 'UL':
case 'WBR':
case 'XMP':
$this->last_error = self::ERROR_UNSUPPORTED;
throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." );
}
Expand Down Expand Up @@ -1682,6 +1769,7 @@ public static function is_void( $tag_name ) {
'IMG' === $tag_name ||
'INPUT' === $tag_name ||
'LINK' === $tag_name ||
'KEYGEN' === $tag_name ||
'META' === $tag_name ||
'SOURCE' === $tag_name ||
'TRACK' === $tag_name ||
Expand Down
13 changes: 0 additions & 13 deletions tests/phpunit/tests/html-api/wpHtmlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,41 +158,31 @@ public function test_step_in_body_fails_on_unsupported_tags( $tag_name ) {
*/
public function data_unsupported_special_in_body_tags() {
return array(
'APPLET' => array( 'APPLET' ),
'AREA' => array( 'AREA' ),
'BASE' => array( 'BASE' ),
'BASEFONT' => array( 'BASEFONT' ),
'BGSOUND' => array( 'BGSOUND' ),
'BODY' => array( 'BODY' ),
'BR' => array( 'BR' ),
'CAPTION' => array( 'CAPTION' ),
'COL' => array( 'COL' ),
'COLGROUP' => array( 'COLGROUP' ),
'EMBED' => array( 'EMBED' ),
'FORM' => array( 'FORM' ),
'FRAME' => array( 'FRAME' ),
'FRAMESET' => array( 'FRAMESET' ),
'HEAD' => array( 'HEAD' ),
'HR' => array( 'HR' ),
'HTML' => array( 'HTML' ),
'IFRAME' => array( 'IFRAME' ),
'INPUT' => array( 'INPUT' ),
'KEYGEN' => array( 'KEYGEN' ),
'LINK' => array( 'LINK' ),
'LISTING' => array( 'LISTING' ),
'MARQUEE' => array( 'MARQUEE' ),
'MATH' => array( 'MATH' ),
'META' => array( 'META' ),
'NOBR' => array( 'NOBR' ),
'NOEMBED' => array( 'NOEMBED' ),
'NOFRAMES' => array( 'NOFRAMES' ),
'NOSCRIPT' => array( 'NOSCRIPT' ),
'OBJECT' => array( 'OBJECT' ),
'OPTGROUP' => array( 'OPTGROUP' ),
'OPTION' => array( 'OPTION' ),
'PARAM' => array( 'PARAM' ),
'PLAINTEXT' => array( 'PLAINTEXT' ),
'PRE' => array( 'PRE' ),
'RB' => array( 'RB' ),
'RP' => array( 'RP' ),
'RT' => array( 'RT' ),
Expand All @@ -207,15 +197,12 @@ public function data_unsupported_special_in_body_tags() {
'TBODY' => array( 'TBODY' ),
'TD' => array( 'TD' ),
'TEMPLATE' => array( 'TEMPLATE' ),
'TEXTAREA' => array( 'TEXTAREA' ),
'TFOOT' => array( 'TFOOT' ),
'TH' => array( 'TH' ),
'THEAD' => array( 'THEAD' ),
'TITLE' => array( 'TITLE' ),
'TR' => array( 'TR' ),
'TRACK' => array( 'TRACK' ),
'WBR' => array( 'WBR' ),
'XMP' => array( 'XMP' ),
);
}
}
Loading

0 comments on commit 8818c97

Please sign in to comment.