@@ -537,6 +537,39 @@ public static function data_intervening_foreign_anchor_html() {
537537 );
538538 }
539539
540+ /**
541+ * Ensures that an HTML heading end tag inside a MathML text integration
542+ * point is ignored, so following content stays inside the integration point.
543+ *
544+ * The `</h2>` is dispatched through the foreign-content rules, which walk up
545+ * to the HTML-namespace `H2` and hand off to the "in body" heading end-tag
546+ * steps. Those require the heading to be in scope, but a MathML text
547+ * integration point (`MI`) is a scope boundary, so `H2` is not in scope and
548+ * the end tag is dropped. The following `<x-0>` is therefore inserted into
549+ * `MI` rather than becoming a sibling of `H2`.
550+ *
551+ * This matches the HTML specification and browsers (verified against
552+ * Chromium); PHP's `Dom\HTMLDocument` reparents `<x-0>` out of `MI`, which is
553+ * a limitation of that parser, not of the HTML API.
554+ *
555+ * @see https://software.hixie.ch/utilities/js/live-dom-viewer/?%3Ch2%3E%3Cmath%3E%3Cmi%3Ea%3C%2Fh2%3E%3Cx-0%3Eb%3C%2Fx-0%3E
556+ *
557+ * @ticket 61576
558+ *
559+ * @covers WP_HTML_Processor::get_breadcrumbs
560+ */
561+ public function test_heading_end_tag_in_mathml_text_integration_point_is_ignored () {
562+ $ processor = WP_HTML_Processor::create_fragment ( '<h2><math><mi>a</h2><x-0>b</x-0> ' );
563+
564+ $ this ->assertTrue ( $ processor ->next_tag ( 'X-0 ' ), 'Failed to find the X-0 element following the ignored heading end tag. ' );
565+
566+ $ this ->assertSame (
567+ array ( 'HTML ' , 'BODY ' , 'H2 ' , 'MATH ' , 'MI ' , 'X-0 ' ),
568+ $ processor ->get_breadcrumbs (),
569+ 'The X-0 element should remain inside the MathML MI text integration point because the </h2> end tag is not in scope and is ignored. '
570+ );
571+ }
572+
540573 /**
541574 * Ensures that an outer A element removed from the stack of open elements
542575 * remains visitable as a virtual closer after its existing child subtree closes.
0 commit comments