@@ -462,10 +462,9 @@ private function buildCommand(
462462 }
463463
464464 return sprintf (
465- ' <a class="%s" href="%s" title="%s" %s>%s</a> ' ,
465+ ' <a class="%s" href="%s" %s>%s</a> ' ,
466466 $ command ->getName (),
467467 $ buttonEvent ->getHref () ?? '' ,
468- StringUtil::specialchars ($ buttonEvent ->getTitle ()),
469468 ltrim ($ buttonEvent ->getAttributes ()),
470469 $ this ->renderImageAsHtml ($ icon , $ this ->getButtonImageAlt ($ buttonEvent ))
471470 );
@@ -476,7 +475,11 @@ private function buildCommand(
476475 *
477476 * The Contao tooltip controller reads the image "alt" (selector "a img[alt]"), so we use the full
478477 * title/description and fall back to the label when a command has no description (e.g. the
479- * MetaModels child-table operations) - otherwise the tooltip would be empty.
478+ * MetaModels child-table operations) - otherwise the tooltip would be empty. The anchor itself must
479+ * stay without a "title" attribute: core's tooltip migration tags both an "a[title]" and an inner
480+ * "img[alt]" independently, and since hovering the image (the visible target) resolves to the
481+ * innermost match, a title left on the anchor is never cleared and shows the browser's native
482+ * tooltip on top of Contao's styled one.
480483 *
481484 * @param GetOperationButtonEvent $buttonEvent The button event.
482485 *
@@ -617,9 +620,8 @@ private function renderPasteNewFor(string $modelId): string
617620 );
618621
619622 return sprintf (
620- '<a class="pasteNew" href="%s" title="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
623+ '<a class="pasteNew" href="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
621624 $ this ->addToUrl ('act=create&after= ' . $ modelId ),
622- StringUtil::specialchars ($ label ),
623625 $ this ->renderImageAsHtml ('new.svg ' , $ label )
624626 );
625627 }
@@ -651,10 +653,9 @@ private function renderPasteIntoButton(GetPasteButtonEvent $event): string
651653 $ title = $ this ->translateButtonDescription ('pasteinto ' , $ definitionName , ['%id% ' => $ model ->getId ()]);
652654
653655 return sprintf (
654- ' <a href="%s" title="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
656+ ' <a href="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
655657 $ event ->getHrefInto () ?? '' ,
656- StringUtil::specialchars ($ title ),
657- $ this ->renderImageAsHtml ('pasteinto.svg ' , $ label , 'class="blink" ' )
658+ $ this ->renderImageAsHtml ('pasteinto.svg ' , $ title , 'class="blink" ' )
658659 );
659660 }
660661
@@ -683,10 +684,9 @@ private function renderPasteAfterButton(GetPasteButtonEvent $event): string
683684 $ title = $ this ->translateButtonDescription ('pasteafter ' , $ definitionName , ['%id% ' => $ model ->getId ()]);
684685
685686 return sprintf (
686- ' <a href="%s" title="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
687+ ' <a href="%s" data-action="contao--scroll-offset#store">%s</a> ' ,
687688 $ event ->getHrefAfter () ?? '' ,
688- StringUtil::specialchars ($ title ),
689- $ this ->renderImageAsHtml ('pasteafter.svg ' , $ label , 'class="blink" ' )
689+ $ this ->renderImageAsHtml ('pasteafter.svg ' , $ title , 'class="blink" ' )
690690 );
691691 }
692692
0 commit comments