@@ -492,6 +492,51 @@ public function test_removes_outer_anchor_breadcrumb_after_mathml_text_integrati
492492 );
493493 }
494494
495+ /**
496+ * Ensures that a removed outer A element's breadcrumb is not confused with
497+ * a same-named foreign element between it and the integration point.
498+ *
499+ * Foreign A elements never participate in the active formatting elements,
500+ * so the removed node is the outer HTML A element, not the foreign one.
501+ *
502+ * @ticket 61576
503+ *
504+ * @covers WP_HTML_Processor::get_breadcrumbs
505+ * @covers WP_HTML_Processor::matches_breadcrumbs
506+ *
507+ * @dataProvider data_intervening_foreign_anchor_html
508+ *
509+ * @param string $html HTML with a foreign A element between the removed outer A element and the integration point.
510+ */
511+ public function test_removes_outer_anchor_breadcrumb_with_intervening_foreign_anchor ( string $ html ) {
512+ $ processor = WP_HTML_Processor::create_fragment ( $ html );
513+
514+ $ this ->assertTrue ( $ processor ->next_tag ( 'SPAN ' ), 'Failed to find the SPAN element after the foreign subtree. ' );
515+
516+ $ this ->assertSame (
517+ array ( 'HTML ' , 'BODY ' , 'SPAN ' ),
518+ $ processor ->get_breadcrumbs (),
519+ 'The SPAN element after the foreign subtree should not remain nested inside the removed outer A element. '
520+ );
521+
522+ $ this ->assertFalse (
523+ $ processor ->matches_breadcrumbs ( array ( 'A ' , 'SPAN ' ) ),
524+ 'The SPAN element should not match breadcrumbs inside the removed outer A element. '
525+ );
526+ }
527+
528+ /**
529+ * Data provider.
530+ *
531+ * @return array[]
532+ */
533+ public static function data_intervening_foreign_anchor_html () {
534+ return array (
535+ 'MathML A before text integration point ' => array ( '<a><math><a><mtext>x<a>y</a></mtext></a></math>z<span>t ' ),
536+ 'SVG A before integration point ' => array ( '<a><svg><a><foreignObject>x<a>y</a></foreignObject></a></svg>z<span>t ' ),
537+ );
538+ }
539+
495540 /**
496541 * Ensures that an outer A element removed from the stack of open elements
497542 * remains visitable as a virtual closer after its existing child subtree closes.
0 commit comments