fix: render button tooltips through CardBody once - #499
Open
dungdong-aws wants to merge 3 commits into
Open
dungdong-aws wants to merge 3 commits into
dungdong-aws wants to merge 3 commits into
Conversation
Button converted tooltip markdown to HTML before passing it to CardBody, which then parsed the generated HTML as markdown again. Since raw HTML is escaped by the centralized parser, icon-only tab bar tooltips rendered without usable text. Pass the raw label and tooltip markdown to CardBody so it remains the single owner of rendering. Add coverage for explicit button tooltips and truncated-label auto-tooltips.
laileni-aws
reviewed
Sep 15, 2026
| tooltipText = ''; | ||
| } | ||
| tooltipText += parseMarkdown(props.tooltip ?? '', { includeLineBreaks: true }); | ||
| // CardBody owns markdown rendering; pre-rendering here causes its parser to escape the generated HTML. |
Contributor
There was a problem hiding this comment.
Instead we should not send tooltip option at all from the LS? keep this tooltip experience as optional
Contributor
Author
There was a problem hiding this comment.
As optional, do you mean by if LS does not send it, we should not render anything at all instead of an empty bubble?
Contributor
There was a problem hiding this comment.
Yes, LS should decide to show tooltip or not.
Contributor
Author
There was a problem hiding this comment.
actually it did check for null description but it did not check for empty string. I added it so it won't render empty string as well
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Icon-only buttons in the top navigation bar — including MCP and chat history — opened a tooltip bubble with no usable text.
Screenshots
Before
After
Root cause
Button tooltips were parsed twice:
Buttonconverted the label/tooltip markdown to HTML withparseMarkdown(...).Buttonpassed that generated HTML toCardBody, which owns markdown rendering and parsed it again.This double parse was latent from the original Button tooltip implementation (
1d733b7c, March 2024). It remained harmless while marked passed raw HTML through, including when the MCP/history descriptions were present in July 2025 with mynah-ui 4.36.2.The XSS hardening in #484 /
571d6c25correctly began escaping all raw HTML. From mynah-ui 4.40.2 onward, the second parse therefore treated the first parse's generated<p>...</p>as untrusted HTML, exposing the latent defect. The security protection should remain unchanged.Fix
Make
CardBodythe single owner of markdown rendering.Buttonnow assembles and passes raw label/tooltip markdown instead of pre-rendered HTML.This preserves markdown formatting while avoiding the security-hardened second parse.
Tests
Added focused coverage for both affected paths:
Each test captures the content passed through the tooltip Overlay and verifies it was rendered exactly once, including a real
<strong>element rather than escaped generated HTML.Validation