@@ -430,13 +430,14 @@ function wp_get_toggletip( $content, $args ) {
430430 $ args ['type ' ] = 'toggletip ' ;
431431 return wp_get_tooltip_helper ( $ content , $ args );
432432}
433+
433434/**
434435 * Retrieves the markup for an accessible tooltip or toggletip.
435436 *
436437 * Returns a button and either a hover/focus triggered tooltip popover or an action
437438 * triggered toggle tip. Enqueue the `wp-tooltip` style and script where it is used.
438439 * Tooltips are used to show the accessible name of a control.
439- * Toggletips are be used for longer supporting text explaining context.
440+ * Toggletips are used for longer supporting text explaining context.
440441 *
441442 * @since 7.1.0
442443 *
@@ -474,7 +475,6 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
474475 'icon ' => 'dashicons-editor-help ' ,
475476 'class ' => '' ,
476477 'type ' => 'tooltip ' ,
477- 'attributes ' => array (),
478478 );
479479
480480 $ args = wp_parse_args ( $ args , $ defaults );
@@ -488,37 +488,48 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
488488
489489 $ icon = '' !== $ args ['icon ' ] ? ' ' . $ args ['icon ' ] : '' ;
490490
491+ /*
492+ * The markup only uses phrasing content so it is valid when nested
493+ * in a phrasing context. Sectioning content (e.g. `div`, `dialog`) will
494+ * cause the parser to close an open `p`, creating an empty and breaking
495+ * the layout. See #65660.
496+ */
491497 if ( 'tooltip ' === $ args ['type ' ] ) {
492498 // Tooltips are only used to visually display labels.
493499 $ label = wp_strip_all_tags ( $ content , true );
494500 $ markup = sprintf (
495- '<div class="%1$s"> ' .
501+ '<span class="%1$s"> ' .
496502 '<button type="button" class="wp-tooltip__toggle" popovertarget="%2$s" aria-label="%3$s"> ' .
497503 '<span class="dashicons%4$s" aria-hidden="true"></span> ' .
498504 '</button> ' .
499505 '<span popover="hint" id="%2$s" class="wp-tooltip__bubble" role="tooltip"> ' .
500506 '<span id="%2$s-text" class="wp-tooltip__text">%5$s</span> ' .
501507 '</span> ' .
502- '</div > ' ,
508+ '</span > ' ,
503509 esc_attr ( $ classes ),
504510 esc_attr ( $ id ),
505511 esc_attr ( $ label ),
506512 esc_attr ( $ icon ),
507513 esc_html ( $ content ),
508514 );
509515 } else {
516+ /*
517+ * A `span` with `role="dialog"` is used instead of a `dialog` element to keep the
518+ * markup as phrasing content. The `aria-label`, `tabindex`, and `autofocus`
519+ * attributes reproduce the accessible name and focus handling of the native element.
520+ */
510521 $ markup = sprintf (
511- '<div class="%1$s"> ' .
522+ '<span class="%1$s"> ' .
512523 '<button type="button" class="wp-tooltip__toggle" popovertarget="%2$s" aria-label="%3$s" aria-haspopup="dialog"> ' .
513524 '<span class="dashicons%4$s" aria-hidden="true"></span> ' .
514525 '</button> ' .
515- '<dialog popover="auto" id="%2$s" class="wp-tooltip__bubble" autofocus> ' .
526+ '<span popover="auto" id="%2$s" class="wp-tooltip__bubble" role="dialog" aria-label="%3$s" tabindex="-1 " autofocus> ' .
516527 '<span id="%2$s-text" class="wp-tooltip__text">%5$s</span> ' .
517528 '<button type="button" class="wp-tooltip__close" popovertarget="%2$s" popovertargetaction="hide" aria-label="%6$s"> ' .
518529 '<span class="dashicons dashicons-no-alt" aria-hidden="true"></span> ' .
519530 '</button> ' .
520- '</dialog > ' .
521- '</div > ' ,
531+ '</span > ' .
532+ '</span > ' ,
522533 esc_attr ( $ classes ),
523534 esc_attr ( $ id ),
524535 esc_attr ( $ args ['label ' ] ),
0 commit comments