Skip to content

Commit 8818c97

Browse files
committed
WIP: Add support for the rest of the common IN BODY tags.
1 parent 454f2bf commit 8818c97

6 files changed

Lines changed: 135 additions & 73 deletions

File tree

src/wp-includes/html-api/class-wp-html-active-formatting-elements.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public function current_node() {
8686
return $current_node ? $current_node : null;
8787
}
8888

89+
/**
90+
* Inserts a marker at the end of the list of active formatting elements.
91+
*
92+
* @since 6.5.0
93+
*/
94+
public function insert_marker() {
95+
$marker = new WP_HTML_Token( null, 'marker', false );
96+
$this->push( $marker );
97+
}
98+
8999
/**
90100
* Pushes a node onto the stack of active formatting elements.
91101
*

src/wp-includes/html-api/class-wp-html-open-elements.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,9 @@ public function has_element_in_scope( $tag_name ) {
150150
return $this->has_element_in_specific_scope(
151151
$tag_name,
152152
array(
153-
154-
/*
155-
* Because it's not currently possible to encounter
156-
* one of the termination elements, they don't need
157-
* to be listed here. If they were, they would be
158-
* unreachable and only waste CPU cycles while
159-
* scanning through HTML.
160-
*/
153+
'APPLET',
154+
'MARQUEE',
155+
'OBJECT',
161156
)
162157
);
163158
}
@@ -421,7 +416,10 @@ public function after_element_push( $item ) {
421416
* cases where the precalculated value needs to change.
422417
*/
423418
switch ( $item->node_name ) {
419+
case 'APPLET':
424420
case 'BUTTON':
421+
case 'MARQUEE':
422+
case 'OBJECT':
425423
$this->has_p_in_button_scope = false;
426424
break;
427425

src/wp-includes/html-api/class-wp-html-processor.php

Lines changed: 105 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,26 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) {
516516
* is provided in the opening tag, otherwise it expects a tag closer.
517517
*/
518518
$top_node = $this->state->stack_of_open_elements->current_node();
519-
if ( $top_node && self::is_void( $top_node->node_name ) ) {
519+
if (
520+
$top_node &&
521+
(
522+
self::is_void( $top_node->node_name ) ||
523+
524+
// Special: Skips SCRIPT data in Tag Processor.
525+
'SCRIPT' === $top_node->node_name ||
526+
527+
// Special: Skips RCDATA data in Tag Processor.
528+
'TEXTAREA' === $top_node->node_name ||
529+
'TITLE' === $top_node->node_name ||
530+
531+
// Special: Skips RAWTEXT data in Tag Processor.
532+
'IFRAME' === $top_node->node_name ||
533+
'NOEMBED' === $top_node->node_name ||
534+
'NOFRAMES' === $top_node->node_name ||
535+
'STYLE' === $top_node->node_name ||
536+
'XMP' === $top_node->node_name
537+
)
538+
) {
520539
$this->state->stack_of_open_elements->pop();
521540
}
522541

@@ -688,6 +707,7 @@ private function step_in_body() {
688707
case '-MENU':
689708
case '-NAV':
690709
case '-OL':
710+
case '-PRE':
691711
case '-SEARCH':
692712
case '-SECTION':
693713
case '-SUMMARY':
@@ -732,6 +752,17 @@ private function step_in_body() {
732752
$this->insert_html_element( $this->state->current_token );
733753
return true;
734754

755+
/*
756+
* > A start tag whose tag name is one of: "pre", "listing"
757+
*/
758+
case '+PRE':
759+
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
760+
$this->close_a_p_element();
761+
}
762+
$this->insert_html_element( $this->state->current_token );
763+
$this->state->frameset_ok = false;
764+
return true;
765+
735766
/*
736767
* > An end tag whose tag name is one of: "h1", "h2", "h3", "h4", "h5", "h6"
737768
*/
@@ -934,12 +965,84 @@ private function step_in_body() {
934965
$this->run_adoption_agency_algorithm();
935966
return true;
936967

968+
/*
969+
* > A start tag whose tag name is one of: "applet", "marquee", "object"
970+
*/
971+
case '+APPLET':
972+
case '+MARQUEE':
973+
case '+OBJECT':
974+
$this->reconstruct_active_formatting_elements();
975+
$this->insert_html_element( $this->state->current_token );
976+
$this->state->active_formatting_elements->insert_marker();
977+
$this->state->frameset_ok = false;
978+
return true;
979+
980+
/*
981+
* > An end tag whose tag name is "br"
982+
*
983+
* This is supposed to create a BR element with no attributes,
984+
* which the HTML Processor doesn't currently have a way to
985+
* represent.
986+
*/
987+
case '-BR':
988+
$this->last_error = self::ERROR_UNSUPPORTED;
989+
throw new WP_HTML_Unsupported_Exception( 'Cannot process unexpecdted BR closer' );
990+
937991
/*
938992
* > A start tag whose tag name is one of: "area", "br", "embed", "img", "keygen", "wbr"
939993
*/
994+
case '+AREA':
995+
case '+BR':
996+
case '+EMBED':
940997
case '+IMG':
998+
case '+WBR':
941999
$this->reconstruct_active_formatting_elements();
9421000
$this->insert_html_element( $this->state->current_token );
1001+
$this->state->frameset_ok = false;
1002+
return true;
1003+
1004+
/*
1005+
* > A start tag whose tag name is "hr"
1006+
*/
1007+
case '+HR':
1008+
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
1009+
$this->close_a_p_element();
1010+
}
1011+
$this->insert_html_element( $this->state->current_token );
1012+
$this->state->frameset_ok = false;
1013+
return true;
1014+
1015+
/*
1016+
* > A start tag whose tag name is "textarea"
1017+
*/
1018+
case '+TEXTAREA':
1019+
$this->insert_html_element( $this->state->current_token );
1020+
$this->state->frameset_ok = false;
1021+
return true;
1022+
1023+
/*
1024+
* > A start tag whose tag name is "xmp"
1025+
*/
1026+
case '+XMP':
1027+
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
1028+
$this->close_a_p_element();
1029+
}
1030+
$this->reconstruct_active_formatting_elements();
1031+
$this->insert_html_element( $this->state->current_token );
1032+
$this->state->frameset_ok = false;
1033+
return true;
1034+
1035+
/*
1036+
* > A start tag whose tag name is "iframe"
1037+
*/
1038+
case '+IFRAME':
1039+
$this->state->frameset_ok = false;
1040+
return true;
1041+
1042+
/*
1043+
* > A start tag whose tag name is "noembed"
1044+
*/
1045+
case '+NOEMBED':
9431046
return true;
9441047
}
9451048

@@ -960,45 +1063,32 @@ private function step_in_body() {
9601063
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
9611064
*/
9621065
switch ( $tag_name ) {
963-
case 'APPLET':
9641066
case 'AREA':
9651067
case 'BASE':
9661068
case 'BASEFONT':
9671069
case 'BGSOUND':
9681070
case 'BODY':
969-
case 'BR':
9701071
case 'CAPTION':
9711072
case 'COL':
9721073
case 'COLGROUP':
973-
case 'DD':
974-
case 'DT':
975-
case 'EMBED':
9761074
case 'FORM':
9771075
case 'FRAME':
9781076
case 'FRAMESET':
9791077
case 'HEAD':
980-
case 'HR':
9811078
case 'HTML':
982-
case 'IFRAME':
9831079
case 'INPUT':
9841080
case 'KEYGEN':
985-
case 'LI':
9861081
case 'LINK':
9871082
case 'LISTING':
988-
case 'MARQUEE':
9891083
case 'MATH':
9901084
case 'META':
9911085
case 'NOBR':
992-
case 'NOEMBED':
9931086
case 'NOFRAMES':
9941087
case 'NOSCRIPT':
995-
case 'OBJECT':
996-
case 'OL':
9971088
case 'OPTGROUP':
9981089
case 'OPTION':
9991090
case 'PARAM':
10001091
case 'PLAINTEXT':
1001-
case 'PRE':
10021092
case 'RB':
10031093
case 'RP':
10041094
case 'RT':
@@ -1013,16 +1103,13 @@ private function step_in_body() {
10131103
case 'TBODY':
10141104
case 'TD':
10151105
case 'TEMPLATE':
1016-
case 'TEXTAREA':
10171106
case 'TFOOT':
10181107
case 'TH':
10191108
case 'THEAD':
10201109
case 'TITLE':
10211110
case 'TR':
10221111
case 'TRACK':
10231112
case 'UL':
1024-
case 'WBR':
1025-
case 'XMP':
10261113
$this->last_error = self::ERROR_UNSUPPORTED;
10271114
throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." );
10281115
}
@@ -1682,6 +1769,7 @@ public static function is_void( $tag_name ) {
16821769
'IMG' === $tag_name ||
16831770
'INPUT' === $tag_name ||
16841771
'LINK' === $tag_name ||
1772+
'KEYGEN' === $tag_name ||
16851773
'META' === $tag_name ||
16861774
'SOURCE' === $tag_name ||
16871775
'TRACK' === $tag_name ||

tests/phpunit/tests/html-api/wpHtmlProcessor.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -158,41 +158,31 @@ public function test_step_in_body_fails_on_unsupported_tags( $tag_name ) {
158158
*/
159159
public function data_unsupported_special_in_body_tags() {
160160
return array(
161-
'APPLET' => array( 'APPLET' ),
162-
'AREA' => array( 'AREA' ),
163161
'BASE' => array( 'BASE' ),
164162
'BASEFONT' => array( 'BASEFONT' ),
165163
'BGSOUND' => array( 'BGSOUND' ),
166164
'BODY' => array( 'BODY' ),
167-
'BR' => array( 'BR' ),
168165
'CAPTION' => array( 'CAPTION' ),
169166
'COL' => array( 'COL' ),
170167
'COLGROUP' => array( 'COLGROUP' ),
171-
'EMBED' => array( 'EMBED' ),
172168
'FORM' => array( 'FORM' ),
173169
'FRAME' => array( 'FRAME' ),
174170
'FRAMESET' => array( 'FRAMESET' ),
175171
'HEAD' => array( 'HEAD' ),
176-
'HR' => array( 'HR' ),
177172
'HTML' => array( 'HTML' ),
178-
'IFRAME' => array( 'IFRAME' ),
179173
'INPUT' => array( 'INPUT' ),
180174
'KEYGEN' => array( 'KEYGEN' ),
181175
'LINK' => array( 'LINK' ),
182176
'LISTING' => array( 'LISTING' ),
183-
'MARQUEE' => array( 'MARQUEE' ),
184177
'MATH' => array( 'MATH' ),
185178
'META' => array( 'META' ),
186179
'NOBR' => array( 'NOBR' ),
187-
'NOEMBED' => array( 'NOEMBED' ),
188180
'NOFRAMES' => array( 'NOFRAMES' ),
189181
'NOSCRIPT' => array( 'NOSCRIPT' ),
190-
'OBJECT' => array( 'OBJECT' ),
191182
'OPTGROUP' => array( 'OPTGROUP' ),
192183
'OPTION' => array( 'OPTION' ),
193184
'PARAM' => array( 'PARAM' ),
194185
'PLAINTEXT' => array( 'PLAINTEXT' ),
195-
'PRE' => array( 'PRE' ),
196186
'RB' => array( 'RB' ),
197187
'RP' => array( 'RP' ),
198188
'RT' => array( 'RT' ),
@@ -207,15 +197,12 @@ public function data_unsupported_special_in_body_tags() {
207197
'TBODY' => array( 'TBODY' ),
208198
'TD' => array( 'TD' ),
209199
'TEMPLATE' => array( 'TEMPLATE' ),
210-
'TEXTAREA' => array( 'TEXTAREA' ),
211200
'TFOOT' => array( 'TFOOT' ),
212201
'TH' => array( 'TH' ),
213202
'THEAD' => array( 'THEAD' ),
214203
'TITLE' => array( 'TITLE' ),
215204
'TR' => array( 'TR' ),
216205
'TRACK' => array( 'TRACK' ),
217-
'WBR' => array( 'WBR' ),
218-
'XMP' => array( 'XMP' ),
219206
);
220207
}
221208
}

0 commit comments

Comments
 (0)