Changeset 58833
- Timestamp:
- 07/30/2024 06:44:45 PM (6 months ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/html-api/class-wp-html-open-elements.php
r58806 r58833 309 309 'OBJECT', 310 310 'TEMPLATE', 311 // @todo: Support SVG and MathML nodes when support for foreign content is added. 311 312 /* 313 * @todo Support SVG and MathML nodes when support for foreign content is added. 314 * 315 * - MathML mi 316 * - MathML mo 317 * - MathML mn 318 * - MathML ms 319 * - MathML mtext 320 * - MathML annotation-xml 321 * - SVG foreignObject 322 * - SVG desc 323 * - SVG title 324 */ 312 325 ) 313 326 ); … … 350 363 'TEMPLATE', 351 364 'UL', 352 // @todo: Support SVG and MathML nodes when support for foreign content is added. 365 366 /* 367 * @todo Support SVG and MathML nodes when support for foreign content is added. 368 * 369 * - MathML mi 370 * - MathML mo 371 * - MathML mn 372 * - MathML ms 373 * - MathML mtext 374 * - MathML annotation-xml 375 * - SVG foreignObject 376 * - SVG desc 377 * - SVG title 378 */ 353 379 ) 354 380 ); … … 387 413 'OBJECT', 388 414 'TEMPLATE', 389 // @todo: Support SVG and MathML nodes when support for foreign content is added. 415 416 /* 417 * @todo Support SVG and MathML nodes when support for foreign content is added. 418 * 419 * - MathML mi 420 * - MathML mo 421 * - MathML mn 422 * - MathML ms 423 * - MathML mtext 424 * - MathML annotation-xml 425 * - SVG foreignObject 426 * - SVG desc 427 * - SVG title 428 */ 390 429 ) 391 430 ); -
trunk/src/wp-includes/html-api/class-wp-html-processor.php
r58828 r58833 1041 1041 * logic for the generalized WP_HTML_Processor::step() function. 1042 1042 * 1043 * @since 6.7.0 Stub implementation.1043 * @since 6.7.0 1044 1044 * 1045 1045 * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. … … 1051 1051 */ 1052 1052 private function step_in_head(): bool { 1053 $this->bail( 'No support for parsing in the ' . WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD . ' state.' ); 1053 $token_name = $this->get_token_name(); 1054 $token_type = $this->get_token_type(); 1055 $is_closer = parent::is_tag_closer(); 1056 $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; 1057 $op = "{$op_sigil}{$token_name}"; 1058 1059 /* 1060 * > A character token that is one of U+0009 CHARACTER TABULATION, 1061 * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), 1062 * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE 1063 */ 1064 if ( '#text' === $op ) { 1065 $text = $this->get_modifiable_text(); 1066 if ( '' === $text ) { 1067 /* 1068 * If the text is empty after processing HTML entities and stripping 1069 * U+0000 NULL bytes then ignore the token. 1070 */ 1071 return $this->step(); 1072 } 1073 1074 if ( strlen( $text ) === strspn( $text, " \t\n\f\r" ) ) { 1075 // Insert the character. 1076 $this->insert_html_element( $this->state->current_token ); 1077 return true; 1078 } 1079 } 1080 1081 switch ( $op ) { 1082 /* 1083 * > A comment token 1084 */ 1085 case '#comment': 1086 case '#funky-comment': 1087 case '#presumptuous-tag': 1088 $this->insert_html_element( $this->state->current_token ); 1089 return true; 1090 1091 /* 1092 * > A DOCTYPE token 1093 */ 1094 case 'html': 1095 // Parse error: ignore the token. 1096 return $this->step(); 1097 1098 /* 1099 * > A start tag whose tag name is "html" 1100 */ 1101 case '+HTML': 1102 return $this->step_in_body(); 1103 1104 /* 1105 * > A start tag whose tag name is one of: "base", "basefont", "bgsound", "link" 1106 */ 1107 case '+BASE': 1108 case '+BASEFONT': 1109 case '+BGSOUND': 1110 case '+LINK': 1111 $this->insert_html_element( $this->state->current_token ); 1112 return true; 1113 1114 /* 1115 * > A start tag whose tag name is "meta" 1116 */ 1117 case '+META': 1118 $this->insert_html_element( $this->state->current_token ); 1119 1120 /* 1121 * > If the active speculative HTML parser is null, then: 1122 * > - If the element has a charset attribute, and getting an encoding from 1123 * > its value results in an encoding, and the confidence is currently 1124 * > tentative, then change the encoding to the resulting encoding. 1125 */ 1126 $charset = $this->get_attribute( 'charset' ); 1127 if ( is_string( $charset ) ) { 1128 $this->bail( 'Cannot yet process META tags with charset to determine encoding.' ); 1129 } 1130 1131 /* 1132 * > - Otherwise, if the element has an http-equiv attribute whose value is 1133 * > an ASCII case-insensitive match for the string "Content-Type", and 1134 * > the element has a content attribute, and applying the algorithm for 1135 * > extracting a character encoding from a meta element to that attribute's 1136 * > value returns an encoding, and the confidence is currently tentative, 1137 * > then change the encoding to the extracted encoding. 1138 */ 1139 $http_equiv = $this->get_attribute( 'http-equiv' ); 1140 $content = $this->get_attribute( 'content' ); 1141 if ( 1142 is_string( $http_equiv ) && 1143 is_string( $content ) && 1144 0 === strcasecmp( $http_equiv, 'Content-Type' ) 1145 ) { 1146 $this->bail( 'Cannot yet process META tags with http-equiv Content-Type to determine encoding.' ); 1147 } 1148 1149 return true; 1150 1151 /* 1152 * > A start tag whose tag name is "title" 1153 */ 1154 case '+TITLE': 1155 $this->insert_html_element( $this->state->current_token ); 1156 return true; 1157 1158 /* 1159 * > A start tag whose tag name is "noscript", if the scripting flag is enabled 1160 * > A start tag whose tag name is one of: "noframes", "style" 1161 * 1162 * The scripting flag is never enabled in this parser. 1163 */ 1164 case '+NOFRAMES': 1165 case '+STYLE': 1166 $this->insert_html_element( $this->state->current_token ); 1167 return true; 1168 1169 /* 1170 * > A start tag whose tag name is "noscript", if the scripting flag is disabled 1171 */ 1172 case '+NOSCRIPT': 1173 $this->insert_html_element( $this->state->current_token ); 1174 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT; 1175 return true; 1176 1177 /* 1178 * > A start tag whose tag name is "script" 1179 * 1180 * @todo Could the adjusted insertion location be anything other than the current location? 1181 */ 1182 case '+SCRIPT': 1183 $this->insert_html_element( $this->state->current_token ); 1184 return true; 1185 1186 /* 1187 * > An end tag whose tag name is "head" 1188 */ 1189 case '-HEAD': 1190 $this->state->stack_of_open_elements->pop(); 1191 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; 1192 return true; 1193 1194 /* 1195 * > An end tag whose tag name is one of: "body", "html", "br" 1196 */ 1197 case '-BODY': 1198 case '-HTML': 1199 case '-BR': 1200 /* 1201 * > Act as described in the "anything else" entry below. 1202 */ 1203 goto in_head_anything_else; 1204 break; 1205 1206 /* 1207 * > A start tag whose tag name is "template" 1208 * 1209 * @todo Could the adjusted insertion location be anything other than the current location? 1210 */ 1211 case '+TEMPLATE': 1212 $this->state->active_formatting_elements->insert_marker(); 1213 $this->state->frameset_ok = false; 1214 1215 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; 1216 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; 1217 1218 $this->insert_html_element( $this->state->current_token ); 1219 return true; 1220 1221 /* 1222 * > An end tag whose tag name is "template" 1223 */ 1224 case '-TEMPLATE': 1225 if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { 1226 // @todo Indicate a parse error once it's possible. 1227 return $this->step(); 1228 } 1229 1230 $this->generate_implied_end_tags_thoroughly(); 1231 if ( ! $this->state->stack_of_open_elements->current_node_is( 'TEMPLATE' ) ) { 1232 // @todo Indicate a parse error once it's possible. 1233 } 1234 1235 $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); 1236 $this->state->active_formatting_elements->clear_up_to_last_marker(); 1237 array_pop( $this->state->stack_of_template_insertion_modes ); 1238 $this->reset_insertion_mode(); 1239 return true; 1240 } 1241 1242 /* 1243 * > A start tag whose tag name is "head" 1244 * > Any other end tag 1245 */ 1246 if ( '+HEAD' === $op || $is_closer ) { 1247 // Parse error: ignore the token. 1248 return $this->step(); 1249 } 1250 1251 /* 1252 * > Anything else 1253 */ 1254 in_head_anything_else: 1255 $this->state->stack_of_open_elements->pop(); 1256 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; 1257 return $this->step( self::REPROCESS_CURRENT_NODE ); 1054 1258 } 1055 1259 … … 2992 3196 */ 2993 3197 private function step_in_template(): bool { 2994 $this->bail( 'No support for parsing in the ' . WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE . ' state.' ); 3198 $token_name = $this->get_token_name(); 3199 $token_type = $this->get_token_type(); 3200 $is_closer = $this->is_tag_closer(); 3201 $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; 3202 $op = "{$op_sigil}{$token_name}"; 3203 3204 switch ( $op ) { 3205 /* 3206 * > A character token 3207 * > A comment token 3208 * > A DOCTYPE token 3209 */ 3210 case '#text': 3211 case '#comment': 3212 case '#funky-comment': 3213 case '#presumptuous-tag': 3214 case 'html': 3215 return $this->step_in_body(); 3216 3217 /* 3218 * > A start tag whose tag name is one of: "base", "basefont", "bgsound", "link", 3219 * > "meta", "noframes", "script", "style", "template", "title" 3220 * > An end tag whose tag name is "template" 3221 */ 3222 case '+BASE': 3223 case '+BASEFONT': 3224 case '+BGSOUND': 3225 case '+LINK': 3226 case '+META': 3227 case '+NOFRAMES': 3228 case '+SCRIPT': 3229 case '+STYLE': 3230 case '+TEMPLATE': 3231 case '+TITLE': 3232 case '-TEMPLATE': 3233 return $this->step_in_head(); 3234 3235 /* 3236 * > A start tag whose tag name is one of: "caption", "colgroup", "tbody", "tfoot", "thead" 3237 */ 3238 case '+CAPTION': 3239 case '+COLGROUP': 3240 case '+TBODY': 3241 case '+TFOOT': 3242 case '+THEAD': 3243 array_pop( $this->state->stack_of_template_insertion_modes ); 3244 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; 3245 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; 3246 return $this->step( self::REPROCESS_CURRENT_NODE ); 3247 3248 /* 3249 * > A start tag whose tag name is "col" 3250 */ 3251 case '+COL': 3252 array_pop( $this->state->stack_of_template_insertion_modes ); 3253 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; 3254 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; 3255 return $this->step( self::REPROCESS_CURRENT_NODE ); 3256 3257 /* 3258 * > A start tag whose tag name is "tr" 3259 */ 3260 case '+TR': 3261 array_pop( $this->state->stack_of_template_insertion_modes ); 3262 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; 3263 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; 3264 return $this->step( self::REPROCESS_CURRENT_NODE ); 3265 3266 /* 3267 * > A start tag whose tag name is one of: "td", "th" 3268 */ 3269 case '+TD': 3270 case '+TH': 3271 array_pop( $this->state->stack_of_template_insertion_modes ); 3272 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; 3273 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; 3274 return $this->step( self::REPROCESS_CURRENT_NODE ); 3275 } 3276 3277 /* 3278 * > Any other start tag 3279 */ 3280 if ( ! $is_closer ) { 3281 array_pop( $this->state->stack_of_template_insertion_modes ); 3282 $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; 3283 $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; 3284 return $this->step( self::REPROCESS_CURRENT_NODE ); 3285 } 3286 3287 /* 3288 * > Any other end tag 3289 */ 3290 if ( $is_closer ) { 3291 // Parse error: ignore the token. 3292 return $this->step(); 3293 } 3294 3295 /* 3296 * > An end-of-file token 3297 */ 3298 if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { 3299 // Stop parsing. 3300 return false; 3301 } 3302 3303 // @todo Indicate a parse error once it's possible. 3304 $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); 3305 $this->state->active_formatting_elements->clear_up_to_last_marker(); 3306 array_pop( $this->state->stack_of_template_insertion_modes ); 3307 $this->reset_insertion_mode(); 3308 return $this->step( self::REPROCESS_CURRENT_NODE ); 2995 3309 } 2996 3310 -
trunk/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php
r58806 r58833 47 47 'AUDIO', 48 48 'B', 49 'BASE', 49 50 'BDI', 50 51 'BDO', 52 'BGSOUND', // Deprectated. 51 53 'BIG', 52 54 'BLINK', // Deprecated. … … 94 96 'LABEL', 95 97 'LEGEND', 98 'LINK', 96 99 'LISTING', // Deprecated. 97 100 'MAIN', … … 100 103 'MARQUEE', // Deprecated. 101 104 'MENU', 105 'META', 102 106 'METER', 103 107 'MULTICOL', // Deprecated. … … 179 183 public static function data_unsupported_elements() { 180 184 $unsupported_elements = array( 181 'BASE',182 'BGSOUND', // Deprecated; self-closing if self-closing flag provided, otherwise normal.183 185 'BODY', 184 186 'FRAME', … … 187 189 'HTML', 188 190 'IFRAME', 189 'LINK',190 191 'MATH', 191 'META',192 192 'NOEMBED', // Neutralized. 193 193 'NOFRAMES', // Neutralized. … … 196 196 'STYLE', 197 197 'SVG', 198 'TEMPLATE',199 198 'TEXTAREA', 200 199 'TITLE', -
trunk/tests/phpunit/tests/html-api/wpHtmlProcessorHtml5lib.php
r58779 r58833 35 35 'adoption01/line0159' => 'Unimplemented: Reconstruction of active formatting elements.', 36 36 'adoption01/line0318' => 'Unimplemented: Reconstruction of active formatting elements.', 37 'template/line0885' => 'Unimplemented: no parsing of attributes on context node.', 37 38 'tests1/line0720' => 'Unimplemented: Reconstruction of active formatting elements.', 38 39 'tests15/line0001' => 'Unimplemented: Reconstruction of active formatting elements.', … … 164 165 } 165 166 166 if ( $was_text && '#text' !== $processor->get_token_name() ) { 167 $token_name = $processor->get_token_name(); 168 $token_type = $processor->get_token_type(); 169 $is_closer = $processor->is_tag_closer(); 170 171 if ( $was_text && '#text' !== $token_name ) { 167 172 $output .= "{$text_node}\"\n"; 168 173 $was_text = false; … … 170 175 } 171 176 172 switch ( $ processor->get_token_type()) {177 switch ( $token_type ) { 173 178 case '#tag': 174 $tag_name = strtolower( $ processor->get_tag());175 176 if ( $ processor->is_tag_closer()) {179 $tag_name = strtolower( $token_name ); 180 181 if ( $is_closer ) { 177 182 --$indent_level; 183 184 if ( 'TEMPLATE' === $token_name ) { 185 --$indent_level; 186 } 187 178 188 break; 179 189 } 180 190 181 $tag_indent = count( $processor->get_breadcrumbs() ) - 1;191 $tag_indent = $indent_level; 182 192 183 193 if ( ! WP_HTML_Processor::is_void( $tag_name ) ) { 184 $indent_level = $tag_indent + 1;194 ++$indent_level; 185 195 } 186 196 … … 208 218 if ( '' !== $modifiable_text ) { 209 219 $output .= str_repeat( $indent, $indent_level ) . "\"{$modifiable_text}\"\n"; 220 } 221 222 if ( 'TEMPLATE' === $token_name ) { 223 $output .= str_repeat( $indent, $indent_level ) . "content\n"; 224 ++$indent_level; 210 225 } 211 226
Note: See TracChangeset
for help on using the changeset viewer.