diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index e46c368c702d4..41823af00ff93 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -100,15 +100,19 @@ * The following list specifies the HTML tags that _are_ supported: * * - Containers: ADDRESS, BLOCKQUOTE, DETAILS, DIALOG, DIV, FOOTER, HEADER, MAIN, MENU, SPAN, SUMMARY. - * - Form elements: BUTTON, FIELDSET, SEARCH. + * - Custom elements: All custom elements are supported. :) + * - Form elements: BUTTON, DATALIST, FIELDSET, LABEL, LEGEND, METER, PROGRESS, SEARCH. * - Formatting elements: B, BIG, CODE, EM, FONT, I, SMALL, STRIKE, STRONG, TT, U. * - Heading elements: H1, H2, H3, H4, H5, H6, HGROUP. * - Links: A. * - Lists: DL. - * - Media elements: FIGCAPTION, FIGURE, IMG. + * - Media elements: AUDIO, CANVAS, FIGCAPTION, FIGURE, IMG, MAP, PICTURE, VIDEO. * - Paragraph: P. - * - Sectioning elements: ARTICLE, ASIDE, NAV, SECTION - * - Deprecated elements: CENTER, DIR + * - Phrasing elements: ABBR, BDI, BDO, CITE, DATA, DEL, DFN, INS, MARK, OUTPUT, Q, SAMP, SUB, SUP, TIME, VAR. + * - Sectioning elements: ARTICLE, ASIDE, NAV, SECTION. + * - Templating elements: SLOT. + * - Text decoration: RUBY. + * - Deprecated elements: ACRONYM, BLINK, CENTER, DIR, ISINDEX, MULTICOL, NEXTID, SPACER. * * ### Supported markup * @@ -830,41 +834,132 @@ private function step_in_body() { $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; + } + + /* + * These tags require special handling in the 'in body' insertion mode + * but that handling hasn't yet been implemented. + * + * As the rules for each tag are implemented, the corresponding tag + * name should be removed from this list. An accompanying test should + * help ensure this list is maintained. + * + * @see Tests_HtmlApi_WpHtmlProcessor::test_step_in_body_fails_on_unsupported_tags + * + * Since this switch structure throws a WP_HTML_Unsupported_Exception, it's + * possible to handle "any other start tag" and "any other end tag" below, + * as that guarantees execution doesn't proceed for the unimplemented tags. + * + * @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': + case 'RTC': + case 'SARCASM': + case 'SCRIPT': + case 'SELECT': + case 'SOURCE': + case 'STYLE': + case 'SVG': + case 'TABLE': + 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." ); + } + if ( ! $this->is_tag_closer() ) { /* * > Any other start tag */ - case '+SPAN': - $this->reconstruct_active_formatting_elements(); - $this->insert_html_element( $this->state->current_token ); - return true; + $this->reconstruct_active_formatting_elements(); + $this->insert_html_element( $this->state->current_token ); + return true; + } else { + /* + * > Any other end tag + */ /* - * Any other end tag + * Find the corresponding tag opener in the stack of open elements, if + * it exists before reaching a special element, which provides a kind + * of boundary in the stack. For example, a `` should not + * close anything beyond its containing `P` or `DIV` element. */ - case '-SPAN': - foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { - // > If node is an HTML element with the same tag name as the token, then: - if ( $item->node_name === $tag_name ) { - $this->generate_implied_end_tags( $tag_name ); + foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { + if ( $tag_name === $node->node_name ) { + break; + } - // > If node is not the current node, then this is a parse error. + if ( self::is_special( $node->node_name ) ) { + // This is a parse error, ignore the token. + return $this->step(); + } + } - $this->state->stack_of_open_elements->pop_until( $tag_name ); - return true; - } + $this->generate_implied_end_tags( $tag_name ); + if ( $node !== $this->state->stack_of_open_elements->current_node() ) { + // @todo Record parse error: this error doesn't impact parsing. + } - // > Otherwise, if node is in the special category, then this is a parse error; ignore the token, and return. - if ( self::is_special( $item->node_name ) ) { - return $this->step(); - } + foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { + $this->state->stack_of_open_elements->pop(); + if ( $node === $item ) { + return true; } - // Execution should not reach here; if it does then something went wrong. - return false; - - default: - $this->last_error = self::ERROR_UNSUPPORTED; - throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + } } } @@ -1264,7 +1359,7 @@ private function run_adoption_agency_algorithm() { // > If formatting element is not in the stack of open elements, then this is a parse error; remove the element from the list, and return. if ( ! $this->state->stack_of_open_elements->contains_node( $formatting_element ) ) { - $this->state->active_formatting_elements->remove_node( $formatting_element->bookmark_name ); + $this->state->active_formatting_elements->remove_node( $formatting_element ); return; } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index a9af5d790fc53..2e5565c9734fa 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -60,22 +60,6 @@ public function test_get_tag_is_null_once_document_is_finished() { $this->assertNull( $p->get_tag() ); } - /** - * Ensures that if the HTML Processor encounters inputs that it can't properly handle, - * that it stops processing the rest of the document. This prevents data corruption. - * - * @ticket 59167 - * - * @covers WP_HTML_Processor::next_tag - */ - public function test_stops_processing_after_unsupported_elements() { - $p = WP_HTML_Processor::create_fragment( '

' ); - $p->next_tag( 'P' ); - $this->assertFalse( $p->next_tag(), 'Stepped into a tag after encountering X-NOT-SUPPORTED element when it should have aborted.' ); - $this->assertNull( $p->get_tag(), "Should have aborted processing, but still reported tag {$p->get_tag()} after properly failing to step into tag." ); - $this->assertFalse( $p->next_tag( 'P' ), 'Stepped into normal P element after X-NOT-SUPPORTED element when it should have aborted.' ); - } - /** * Ensures that the HTML Processor maintains its internal state through seek calls. * @@ -147,4 +131,96 @@ public function test_fails_to_reconstruct_formatting_elements() { $this->assertTrue( $p->next_tag( 'EM' ), 'Could not find first EM.' ); $this->assertFalse( $p->next_tag( 'EM' ), 'Should have aborted before finding second EM as it required reconstructing the first EM.' ); } + + /** + * Ensures that special handling of unsupported tags is cleaned up + * as handling is implemented. Otherwise there's risk of leaving special + * handling (that is never reached) when tag handling is implemented. + * + * @ticket 60092 + * + * @dataProvider data_unsupported_special_in_body_tags + * + * @covers WP_HTML_Processor::step_in_body + * + * @param string $tag_name Name of the tag to test. + */ + public function test_step_in_body_fails_on_unsupported_tags( $tag_name ) { + $fragment = WP_HTML_Processor::create_fragment( '<' . $tag_name . '>' ); + $this->assertFalse( $fragment->next_tag(), 'Should fail to find tag: ' . $tag_name . '.' ); + $this->assertEquals( $fragment->get_last_error(), WP_HTML_Processor::ERROR_UNSUPPORTED, 'Should have unsupported last error.' ); + } + + /** + * Data provider. + * + * @return array[] + */ + 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' ), + 'DD' => array( 'DD' ), + 'DT' => array( 'DT' ), + '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' ), + 'LI' => array( 'LI' ), + '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' ), + 'OL' => array( 'OL' ), + 'OPTGROUP' => array( 'OPTGROUP' ), + 'OPTION' => array( 'OPTION' ), + 'PARAM' => array( 'PARAM' ), + 'PLAINTEXT' => array( 'PLAINTEXT' ), + 'PRE' => array( 'PRE' ), + 'RB' => array( 'RB' ), + 'RP' => array( 'RP' ), + 'RT' => array( 'RT' ), + 'RTC' => array( 'RTC' ), + 'SARCASM' => array( 'SARCASM' ), + 'SCRIPT' => array( 'SCRIPT' ), + 'SELECT' => array( 'SELECT' ), + 'SOURCE' => array( 'SOURCE' ), + 'STYLE' => array( 'STYLE' ), + 'SVG' => array( 'SVG' ), + 'TABLE' => array( 'TABLE' ), + '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' ), + 'UL' => array( 'UL' ), + 'WBR' => array( 'WBR' ), + 'XMP' => array( 'XMP' ), + ); + } } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php index 2fd852e434412..3b339e4f82ee9 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php @@ -37,14 +37,26 @@ public function test_navigates_into_normative_html_for_supported_elements( $html public function data_single_tag_of_supported_elements() { $supported_elements = array( 'A', + 'ABBR', + 'ACRONYM', // Neutralized 'ADDRESS', 'ARTICLE', 'ASIDE', + 'AUDIO', 'B', + 'BDI', + 'BDO', 'BIG', + 'BLINK', // Deprecated 'BUTTON', + 'CANVAS', 'CENTER', // Neutralized + 'CITE', 'CODE', + 'DATA', + 'DATALIST', + 'DFN', + 'DEL', 'DETAILS', 'DIALOG', 'DIR', @@ -66,19 +78,42 @@ public function data_single_tag_of_supported_elements() { 'HGROUP', 'I', 'IMG', + 'INS', + 'ISINDEX', // Deprecated + 'KBD', + 'LABEL', + 'LEGEND', 'MAIN', + 'MAP', + 'MARK', 'MENU', + 'METER', + 'MULTICOL', // Deprecated 'NAV', + 'NEXTID', // Deprecated + 'OUTPUT', 'P', + 'PICTURE', + 'PROGRESS', + 'Q', + 'RUBY', + 'SAMP', 'SEARCH', 'SECTION', + 'SLOT', 'SMALL', + 'SPACER', // Deprecated 'SPAN', 'STRIKE', 'STRONG', + 'SUB', 'SUMMARY', + 'SUP', + 'TIME', 'TT', 'U', + 'VAR', + 'VIDEO', ); $data = array(); @@ -121,28 +156,16 @@ public function test_fails_when_encountering_unsupported_tag( $html ) { */ public function data_unsupported_elements() { $unsupported_elements = array( - 'ABBR', - 'ACRONYM', // Neutralized 'APPLET', // Deprecated 'AREA', - 'AUDIO', 'BASE', - 'BDI', - 'BDO', 'BGSOUND', // Deprecated; self-closing if self-closing flag provided, otherwise normal. - 'BLINK', // Deprecated 'BODY', 'BR', - 'CANVAS', 'CAPTION', - 'CITE', 'COL', 'COLGROUP', - 'DATA', - 'DATALIST', 'DD', - 'DEL', - 'DEFN', 'DT', 'EMBED', 'FORM', @@ -153,23 +176,13 @@ public function data_unsupported_elements() { 'HTML', 'IFRAME', 'INPUT', - 'INS', - 'ISINDEX', // Deprecated - 'KBD', 'KEYGEN', // Deprecated; void - 'LABEL', - 'LEGEND', 'LI', 'LINK', 'LISTING', // Deprecated, use PRE instead. - 'MAP', - 'MARK', 'MARQUEE', // Deprecated 'MATH', 'META', - 'METER', - 'MULTICOL', // Deprecated - 'NEXTID', // Deprecated 'NOBR', // Neutralized 'NOEMBED', // Neutralized 'NOFRAMES', // Neutralized @@ -178,26 +191,16 @@ public function data_unsupported_elements() { 'OL', 'OPTGROUP', 'OPTION', - 'OUTPUT', - 'PICTURE', 'PLAINTEXT', // Neutralized 'PRE', - 'PROGRESS', - 'Q', 'RB', // Neutralized 'RP', 'RT', 'RTC', // Neutralized - 'RUBY', - 'SAMP', 'SCRIPT', 'SELECT', - 'SLOT', 'SOURCE', - 'SPACER', // Deprecated 'STYLE', - 'SUB', - 'SUP', 'SVG', 'TABLE', 'TBODY', @@ -207,19 +210,12 @@ public function data_unsupported_elements() { 'TFOOT', 'TH', 'THEAD', - 'TIME', 'TITLE', 'TR', 'TRACK', 'UL', - 'VAR', - 'VIDEO', 'WBR', 'XMP', // Deprecated, use PRE instead. - - // Made up elements, custom elements. - 'X-NOT-AN-HTML-ELEMENT', - 'HUMAN-TIME', ); $data = array(); @@ -360,6 +356,10 @@ public function data_html_target_with_breadcrumbs() { 'H4 inside H2' => array( '

Major

Minor

', array( 'HTML', 'BODY', 'H2', 'SPAN', 'H4' ), 1 ), 'H5 after unclosed H4 inside H2' => array( '

Major

Minor

', array( 'HTML', 'BODY', 'H2', 'SPAN', 'H5' ), 1 ), 'H5 after H4 inside H2' => array( '

Major

Minor

', array( 'HTML', 'BODY', 'H5' ), 1 ), + + // Custom elements. + 'WP-EMOJI' => array( '
', array( 'HTML', 'BODY', 'DIV', 'WP-EMOJI' ), 1 ), + 'WP-EMOJI then IMG' => array( '
', array( 'HTML', 'BODY', 'DIV', 'IMG' ), 1 ), ); } diff --git a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php index 9dbb689df0329..a0c9c600c1e45 100644 --- a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php +++ b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php @@ -72,21 +72,16 @@ public function test_has_element_in_scope_needs_support() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); } /** @@ -115,21 +110,16 @@ public function test_has_element_in_list_item_scope_needs_support() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); // These elements are specific to list item scope. $this->ensure_support_is_added_everywhere( 'OL' ); @@ -161,21 +151,16 @@ public function test_has_element_in_button_scope_needs_support() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); } /** @@ -201,21 +186,16 @@ public function test_after_element_pop_must_maintain_p_in_button_scope_flag() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); } /** @@ -241,21 +221,16 @@ public function test_after_element_push_must_maintain_p_in_button_scope_flag() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); } /** @@ -280,21 +255,16 @@ public function test_has_element_in_table_scope_needs_support() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); // These elements are specific to TABLE scope. $this->ensure_support_is_added_everywhere( 'HTML' ); @@ -335,21 +305,16 @@ public function test_has_element_in_select_scope_needs_support() { $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - // MathML Elements - $this->ensure_support_is_added_everywhere( 'MI' ); - $this->ensure_support_is_added_everywhere( 'MO' ); - $this->ensure_support_is_added_everywhere( 'MN' ); - $this->ensure_support_is_added_everywhere( 'MS' ); - $this->ensure_support_is_added_everywhere( 'MTEXT' ); - $this->ensure_support_is_added_everywhere( 'ANNOTATION-XML' ); + // MathML Elements: MI, MO, MN, MS, MTEXT, ANNOTATION-XML. + $this->ensure_support_is_added_everywhere( 'MATH' ); /* * SVG elements: note that TITLE is both an HTML element and an SVG element * so care must be taken when adding support for either one. + * + * FOREIGNOBJECT, DESC, TITLE. */ - $this->ensure_support_is_added_everywhere( 'FOREIGNOBJECT' ); - $this->ensure_support_is_added_everywhere( 'DESC' ); - $this->ensure_support_is_added_everywhere( 'TITLE' ); + $this->ensure_support_is_added_everywhere( 'SVG' ); // These elements are specific to SELECT scope. $this->ensure_support_is_added_everywhere( 'OPTGROUP' );