-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Fix rendering of foreignObject
in SVGs
#32417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
// browsers will fail to render the foreign object content. Here, we ensure that if | ||
// we encounter a `foreignObject` in the SVG, then all its children will be placed | ||
// under the XHTML namespace. | ||
const isSvg = (tagName === 'svg' || isSvgElement(parent)) && !isForeignObject(parent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this isn't the only place where we check isSvgElement(parent)
. We also do that in insertMarkup
to vary how we parse markup strings. My guess is that we'd also need to update insertMarkup
in the same way as this in case we're inserting a markup block as the top-level thing inside a foreign element. Does that sound correct to you?
If this is all true, it suggests to me that instead of having both isSvgElement
and isForeignObject
as separate things we have to remember to use together, we should instead replace them both with a single shouldInsertImmediateChildrenAsSvg
function. This would also have an efficiency benefit, since that function would only need to evaluate getClosestDomElement(element)
once instead of two methods both evaluating that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch!
Yep -- it makes sense to refactor things a bit with an efficiency focus if these check happens more than once.
Will update PR accordingly.
6a1c610
to
ed9e738
Compare
Resolves #30973.
SVG supports a
foreignObject
element that can be used to display arbitrary HTML within an SVG. Particularly for Blazor, this HTML can represent a render fragment or Blazor component, like so:Currently, our client-side rendering logic renders the SVG element and all its children under the SVG namespace by invoking
document.createElementNS('http://www.w3.org/2000/svg', tagName)
. However, for the browser to correctly render the HTML content under theforeignObject
it must be rendered under an XHTML namespace.To resolve this, we add an additional check to set the namespace to XHTML for elements that are children of a
foreignObject
.Previous:
Current: