-
Notifications
You must be signed in to change notification settings - Fork 47.6k
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
Fix false positive hydration warning for SVG attributes #10676
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1325,19 +1325,30 @@ describe('ReactDOMServerIntegration', () => { | |
expect(e.namespaceURI).toBe('http://www.w3.org/2000/svg'); | ||
}); | ||
|
||
itRenders('svg child element', async render => { | ||
let e = await render( | ||
<svg><image xlinkHref="http://i.imgur.com/w7GCRPb.png" /></svg>, | ||
); | ||
e = e.firstChild; | ||
itRenders('svg child element with an attribute', async render => { | ||
let e = await render(<svg viewBox="0 0 0 0" />); | ||
expect(e.childNodes.length).toBe(0); | ||
expect(e.tagName).toBe('image'); | ||
expect(e.tagName).toBe('svg'); | ||
expect(e.namespaceURI).toBe('http://www.w3.org/2000/svg'); | ||
expect(e.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).toBe( | ||
'http://i.imgur.com/w7GCRPb.png', | ||
); | ||
expect(e.getAttribute('viewBox')).toBe('0 0 0 0'); | ||
}); | ||
|
||
itRenders( | ||
'svg child element with a namespace attribute', | ||
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. This is an old test. I just renamed it and moved down. |
||
async render => { | ||
let e = await render( | ||
<svg><image xlinkHref="http://i.imgur.com/w7GCRPb.png" /></svg>, | ||
); | ||
e = e.firstChild; | ||
expect(e.childNodes.length).toBe(0); | ||
expect(e.tagName).toBe('image'); | ||
expect(e.namespaceURI).toBe('http://www.w3.org/2000/svg'); | ||
expect(e.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).toBe( | ||
'http://i.imgur.com/w7GCRPb.png', | ||
); | ||
}, | ||
); | ||
|
||
itRenders('svg child element with a badly cased alias', async render => { | ||
let e = await render( | ||
<svg><image xlinkhref="http://i.imgur.com/w7GCRPb.png" /></svg>, | ||
|
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.
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.
This was intentional so that you would compare and display it in the case that it was received. For things like SVG where case matters.
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.
I don't think this is right because on SVG we do want things like
<svg foobar="" />
vs.<svg fooBar="" />
to show up as an extra attribute.It might make sense to deal with this at the same time as the "all attributes should be lower-case" warning though.
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.
I am not sure that we can, unless we can control for browsers that report casing from
attribute.name
inconsistently. For example, IE Edge reports SVGfill
and `stroke in all caps:Test: https://codepen.io/nhunzaker/pen/qXRPvY
Screenshot of IE Edge 15:
Screenshot of Chrome:
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.
@nhunzaker Can we special case the known ones since they will also have the warning about invalid case of the prop?
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.
I can start to compile a list of special cases. I'm sort of worried that this will be tedious and it'll end up being most of SVG, but I don't know that yet. I know of differences in casing of SVG in IE Edge. I didn't know about the cases alluded to in Chrome.
Should I just open up the attribute table in every browser using BrowserStack? How many versions back should I go?
Kind of makes me wonder if it could be automated using their remote API.
I have a few questions, and I apologize in advance if they sound cynical, but I don't want to assume anything so I can better understand the problem:
1: What is the advantage to case-sensitive hydration? Casing warnings for known attributes will raise server-side during markup generation (is this correct?), and then and on update client-side.
2: Wouldn't the same components consistently misspell attribute names server and client side?
3: Even if the casing is produced differently server/client-side, browsers don't appear to care about casing. I'm curious if this is generally true, or if my tests are flawed. They certainly aren't exhaustive.
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.
My concern is that just ignoring case doesn't take the core of the problem in to consideration because it's not the case that browsers completely ignore case. There are specific rules for it.
Specifically, the rules (other than bugs/quirks like the IE thing) is that the HTML parser of a server response makes them lower-case except for a whitelist. https://www.w3.org/TR/html5/syntax.html#adjust-svg-attributes
However, this whitelist doesn't apply to client code. Specifically cases like this is what I'm concerned about:
Rendering the "viewbox" attribute on the server and the client behaves differently because it is case-sensitive on the client but not on the server.
So simple saying that they're not case-sensitive is not the full story. It might be the case that this is the best compromise anyway but I want to make sure we've considered all the aspects because "DOM is case-insensitive" is an oversimplification so we might be missing something.
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.
Ah got it. So there are attributes that care about casing. That's frustrating...
Thank you for spelling this out for me. Prior to this point, I was not aware of the differences between HTML/SVG parsing and the DOM attribute manipulation. What a mess!