Skip to content

Commit 7939dcb

Browse files
committed
WIP: Add support for the rest of the common IN BODY tags.
1 parent edcc85c commit 7939dcb

6 files changed

Lines changed: 91 additions & 52 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: 65 additions & 8 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

@@ -948,6 +967,18 @@ private function step_in_body() {
948967
$this->run_adoption_agency_algorithm();
949968
return true;
950969

970+
/*
971+
* > A start tag whose tag name is one of: "applet", "marquee", "object"
972+
*/
973+
case '+APPLET':
974+
case '+MARQUEE':
975+
case '+OBJECT':
976+
$this->reconstruct_active_formatting_elements();
977+
$this->insert_html_element( $this->state->current_token );
978+
$this->state->active_formatting_elements->insert_marker();
979+
$this->state->frameset_ok = false;
980+
return true;
981+
951982
/*
952983
* > An end tag whose tag name is "br"
953984
* > Parse error. Drop the attributes from the token, and act as described in the next
@@ -982,6 +1013,39 @@ private function step_in_body() {
9821013
$this->insert_html_element( $this->state->current_token );
9831014
$this->state->frameset_ok = false;
9841015
return true;
1016+
1017+
/*
1018+
* > A start tag whose tag name is "textarea"
1019+
*/
1020+
case '+TEXTAREA':
1021+
$this->insert_html_element( $this->state->current_token );
1022+
$this->state->frameset_ok = false;
1023+
return true;
1024+
1025+
/*
1026+
* > A start tag whose tag name is "xmp"
1027+
*/
1028+
case '+XMP':
1029+
if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) {
1030+
$this->close_a_p_element();
1031+
}
1032+
$this->reconstruct_active_formatting_elements();
1033+
$this->insert_html_element( $this->state->current_token );
1034+
$this->state->frameset_ok = false;
1035+
return true;
1036+
1037+
/*
1038+
* > A start tag whose tag name is "iframe"
1039+
*/
1040+
case '+IFRAME':
1041+
$this->state->frameset_ok = false;
1042+
return true;
1043+
1044+
/*
1045+
* > A start tag whose tag name is "noembed"
1046+
*/
1047+
case '+NOEMBED':
1048+
return true;
9851049
}
9861050

9871051
/*
@@ -1001,7 +1065,6 @@ private function step_in_body() {
10011065
* @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
10021066
*/
10031067
switch ( $tag_name ) {
1004-
case 'APPLET':
10051068
case 'BASE':
10061069
case 'BASEFONT':
10071070
case 'BGSOUND':
@@ -1014,17 +1077,13 @@ private function step_in_body() {
10141077
case 'FRAMESET':
10151078
case 'HEAD':
10161079
case 'HTML':
1017-
case 'IFRAME':
10181080
case 'INPUT':
10191081
case 'LINK':
1020-
case 'MARQUEE':
10211082
case 'MATH':
10221083
case 'META':
10231084
case 'NOBR':
1024-
case 'NOEMBED':
10251085
case 'NOFRAMES':
10261086
case 'NOSCRIPT':
1027-
case 'OBJECT':
10281087
case 'OPTGROUP':
10291088
case 'OPTION':
10301089
case 'PARAM':
@@ -1043,14 +1102,12 @@ private function step_in_body() {
10431102
case 'TBODY':
10441103
case 'TD':
10451104
case 'TEMPLATE':
1046-
case 'TEXTAREA':
10471105
case 'TFOOT':
10481106
case 'TH':
10491107
case 'THEAD':
10501108
case 'TITLE':
10511109
case 'TR':
10521110
case 'TRACK':
1053-
case 'XMP':
10541111
$this->last_error = self::ERROR_UNSUPPORTED;
10551112
throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." );
10561113
}

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ public function test_step_in_body_fails_on_unsupported_tags( $tag_name ) {
238238
*/
239239
public function data_unsupported_special_in_body_tags() {
240240
return array(
241-
'APPLET' => array( 'APPLET' ),
242241
'BASE' => array( 'BASE' ),
243242
'BASEFONT' => array( 'BASEFONT' ),
244243
'BGSOUND' => array( 'BGSOUND' ),
@@ -251,17 +250,13 @@ public function data_unsupported_special_in_body_tags() {
251250
'FRAMESET' => array( 'FRAMESET' ),
252251
'HEAD' => array( 'HEAD' ),
253252
'HTML' => array( 'HTML' ),
254-
'IFRAME' => array( 'IFRAME' ),
255253
'INPUT' => array( 'INPUT' ),
256254
'LINK' => array( 'LINK' ),
257-
'MARQUEE' => array( 'MARQUEE' ),
258255
'MATH' => array( 'MATH' ),
259256
'META' => array( 'META' ),
260257
'NOBR' => array( 'NOBR' ),
261-
'NOEMBED' => array( 'NOEMBED' ),
262258
'NOFRAMES' => array( 'NOFRAMES' ),
263259
'NOSCRIPT' => array( 'NOSCRIPT' ),
264-
'OBJECT' => array( 'OBJECT' ),
265260
'OPTGROUP' => array( 'OPTGROUP' ),
266261
'OPTION' => array( 'OPTION' ),
267262
'PARAM' => array( 'PARAM' ),
@@ -280,14 +275,12 @@ public function data_unsupported_special_in_body_tags() {
280275
'TBODY' => array( 'TBODY' ),
281276
'TD' => array( 'TD' ),
282277
'TEMPLATE' => array( 'TEMPLATE' ),
283-
'TEXTAREA' => array( 'TEXTAREA' ),
284278
'TFOOT' => array( 'TFOOT' ),
285279
'TH' => array( 'TH' ),
286280
'THEAD' => array( 'THEAD' ),
287281
'TITLE' => array( 'TITLE' ),
288282
'TR' => array( 'TR' ),
289283
'TRACK' => array( 'TRACK' ),
290-
'XMP' => array( 'XMP' ),
291284
);
292285
}
293286
}

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function data_single_tag_of_supported_elements() {
4040
'ABBR',
4141
'ACRONYM', // Neutralized.
4242
'ADDRESS',
43+
'APPLET', // Deprecated.
4344
'AREA',
4445
'ARTICLE',
4546
'ASIDE',
@@ -85,8 +86,8 @@ public function data_single_tag_of_supported_elements() {
8586
'I',
8687
'IMG',
8788
'INS',
89+
'ISINDEX', // Deprecated
8890
'LI',
89-
'ISINDEX', // Deprecated.
9091
'KBD',
9192
'KEYGEN', // Deprecated.
9293
'LABEL',
@@ -95,15 +96,18 @@ public function data_single_tag_of_supported_elements() {
9596
'MAIN',
9697
'MAP',
9798
'MARK',
99+
'MARQUEE', // Deprecated.
98100
'MENU',
99101
'METER',
100102
'MULTICOL', // Deprecated.
101103
'NAV',
102104
'NEXTID', // Deprecated.
105+
'OBJECT',
103106
'OL',
104107
'OUTPUT',
105108
'P',
106109
'PICTURE',
110+
'PRE',
107111
'PROGRESS',
108112
'Q',
109113
'RUBY',
@@ -125,14 +129,19 @@ public function data_single_tag_of_supported_elements() {
125129
'UL',
126130
'VAR',
127131
'VIDEO',
132+
'WBR',
128133
);
129134

130135
$data = array();
131136
foreach ( $supported_elements as $tag_name ) {
132137
$data[ $tag_name ] = array( "<{$tag_name}>", $tag_name );
133138
}
134139

140+
$data['IFRAME'] = array( '<iframe></iframe>', 'IFRAME' );
135141
$data['IMAGE (treated as an IMG)'] = array( '<image>', 'IMG' );
142+
$data['NOEMBED'] = array( '<noembed></noembed>', 'NOEMBED' ); // Neutralized.
143+
$data['TEXTAREA'] = array( '<textarea></textarea>', 'TEXTAREA' );
144+
$data['XMP'] = array( '<xmp></xmp>', 'XMP' ); // Deprecated, use PRE instead.
136145

137146
return $data;
138147
}
@@ -167,7 +176,6 @@ public function test_fails_when_encountering_unsupported_tag( $html ) {
167176
*/
168177
public function data_unsupported_elements() {
169178
$unsupported_elements = array(
170-
'APPLET', // Deprecated.
171179
'BASE',
172180
'BGSOUND', // Deprecated; self-closing if self-closing flag provided, otherwise normal.
173181
'BODY',
@@ -179,17 +187,13 @@ public function data_unsupported_elements() {
179187
'FRAMESET',
180188
'HEAD',
181189
'HTML',
182-
'IFRAME',
183190
'INPUT',
184191
'LINK',
185-
'MARQUEE', // Deprecated.
186192
'MATH',
187193
'META',
188194
'NOBR', // Neutralized.
189-
'NOEMBED', // Neutralized.
190195
'NOFRAMES', // Neutralized.
191196
'NOSCRIPT',
192-
'OBJECT',
193197
'OPTGROUP',
194198
'OPTION',
195199
'PLAINTEXT', // Neutralized.
@@ -206,14 +210,12 @@ public function data_unsupported_elements() {
206210
'TBODY',
207211
'TD',
208212
'TEMPLATE',
209-
'TEXTAREA',
210213
'TFOOT',
211214
'TH',
212215
'THEAD',
213216
'TITLE',
214217
'TR',
215218
'TRACK',
216-
'XMP', // Deprecated, use PRE instead.
217219
);
218220

219221
$data = array();

0 commit comments

Comments
 (0)