GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||
GeezerVison is showing github.com — Render hover labels through MathJax when the whole label is one tex expression by SergeyAxiomatic · Pull Request #8051 · plotly/plotly.js Conversation
Contributor
Render hover labels through MathJax when the whole label is one tex expression SummaryThis change renders a hover label through MathJax when the whole label is one tex expression. Fixes #559. Why this is correctEvery hover text node sets This change lifts Enabling this exposed a second bug. MathJax types the label async, so the label's box used a placeholder size from before the real content existed, and produced Mixing text and a formula in one hover labelA hover label with a formula AND plain text still shows the literal tex source, on purpose: text = [r'$\text{Value: } \alpha \text{ units}$', ...]
Tests
Run No new mock. No baseline image changed. Manual verificationI checked the rendered plot in the dev dashboard for: a pure-tex per-point label, a pure-tex shared axis label, two labels shown at once (overlap avoidance), unified hover ( Deviation from writing-style.mdThis body keeps
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions…xpression Fixes plotly#559. Hover labels unconditionally set data-notex, which blocks convertToTspans from ever handing them to MathJax, so a hover string like "$\alpha$" rendered as literal source instead of the typeset symbol. Axis titles and annotations already support this; hover never did because convertToTspans drops any text outside the $...$ delimiters, and most hover strings mix formatted values with literal text, so blanket-enabling it would silently lose content. This only lifts the restriction when the whole label is one tex expression (isPureTex), which convertToTspans can render without dropping anything, and applies it to every hover label surface: the main per-point label, the secondary trace-name label, the shared axis label, and the "unified hover" legend-based label. Enabling this exposes a second, previously moot problem: MathJax typesets asynchronously, so the label's box is sized from a degenerate placeholder measurement before the real content exists. hover.js now runs its existing (idempotent) sizing and overlap- avoidance pass a second time once typesetting finishes, and svg_text_utils gains repositionMathGroup to move the already-rendered math group to match, since convertToTspans only positions it once, at typeset time. Co-Authored-By: Claude Sonnet 5 <[email protected]> Co-Authored-By: Claude Sonnet 5 <[email protected]>
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. The 3 new tests passed 'closest'/'x' as Fx.hover's subplot argument, not a hovermode; the real subplot id is 'xy', so no hover ever fired. The category-axis test also needed its x-range shifted, since [0, 4] put category 0 at the left edge, not the intended pixel target. Two assertions also needed a fix: strict-d3 disallows selection.style as a getter outside an event handler, and the label-width threshold was a few pixels tighter than actual cross-environment rendering allows. Verified locally: `karma start test/jasmine/karma.conf.js --bundleTest=mathjax_test.js --nowatch` -> 7 of 7 pass. Co-Authored-By: Claude Sonnet 5 <[email protected]>
KoolADE85
requested changes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the PR! I’ve tested it out and confirmed it works as advertised. I was a bit skeptical of scoping this to narrowly fix hover labels (rather than a general fix for everything that uses the With that, my comments are all with an eye toward making the improvements here reusable for later. Also, I do want to ensure that labels are thoroughly handled:
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsUh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. …d tests Fx.loneHover called the modified createHoverText but never read the new mathjaxPromise, so a pure-tex loneHover label kept the placeholder size and position forever. It now reruns its own overlap-fix and alignHoverText once MathJax resolves, and repositions the math group to match, the same way hover() already does. repositionMathGroup duplicated the coordinate math inside convertToTspans, and the two had already drifted (repositionMathGroup lacked the Firefox v82+ overflow workaround). Both now call one shared positionMathGroup. getHoverTextBBox's "measure the math group if MathJax replaced this text" lookup was private to hover.js. Moved it to svg_text_utils.js as getMathOrTextNode, so annotations and titles can reuse it later. Added tests for the paths the last round left uncovered: a label where both the value and the name are tex, two labels shown together (the only case that exercises hoverAvoidOverlaps for real), a unified hover title set through unifiedhovertitle, and the Fx.loneHover regression. Verified locally: `karma start test/jasmine/karma.conf.js --bundleTest=mathjax_test.js --nowatch` -> 11 of 11 pass, and `npm run test-jasmine -- svg_text_utils hover legend annotations --nowatch` -> 439 of 439 pass. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. MathJax's \href{url}{...} copies its argument into an <a href> with no
scheme check of its own. $\href{javascript:alert(1)}{click}$ rendered
into a live, clickable <a href="javascript:alert(1)"> in the DOM.
Confirmed this by rendering it and reading the resulting attribute,
not just from reading MathJax's source.
This predates the hover PR -- the same unguarded convertToTspans path
is already reachable today via axis/plot titles, annotations, and
non-hover legend text. Hover just became a new delivery surface for
it, since hover text more often comes from less-trusted per-point
data.
svg_text_utils.js already has an established fix for exactly this
shape of problem: sanitizeHref(), an http:/https:/mailto:/relative
allowlist, used for the pseudo-HTML <a href> tags in plain text.
sanitizeMathJaxLinks() applies the same allowlist to any <a> MathJax
produces, called once from convertToTspans right after the rendered
SVG is inserted. Since the fix lives in the shared function, it closes
the gap for titles/annotations/legends too, not just hover.
Added tests for both a hover label and a title with a javascript:
\href, confirming the link's href is stripped while a plain
\href{https://...}{...} keeps working.
Verified locally: `karma start test/jasmine/karma.conf.js
--bundleTest=mathjax_test.js --nowatch` -> 13 of 13 pass. Also ran the
full svg_text_utils/hover/legend/annotations/titles suite against
both this branch and unmodified main -- both show the same 8
pre-existing titles_test.js failures and the same intermittent "full
page reload" flakiness at random points in either case, confirming
neither is caused by this change.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. sanitizeMathJaxLinks already covers these paths since it's applied inside the shared convertToTspans, but only hover/title had explicit coverage. Requested by @archmoj on PR plotly#8051. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
KoolADE85
reviewed
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @SergeyAxiomatic sorry for the delay here, I was off for a little bit. After that, I'll be good to approve! And thanks to @archmoj for the XSS callout! Great catch :)
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsUh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Legend text elements are reused across unified-hover redraws, so a row that was plain text left data-notex set when a later hover put pure tex in the same element, leaving it unrendered. Set or clear the attribute on every call, with a regression test. Also trim explanatory comments per review and mention the XSS fix in the draftlog. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
KoolADE85
previously approved these changes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the nice contribution! 💃
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsUh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
|
I noticed an issue: The rendered LaTeX expression is incorrectly positioned when using
ref: #8115 (comment) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
MathJax does not render in hover labels
There was an error while loading. Please reload this page.