Skip to content
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

Ignore CR/LF differences when warning about markup mismatch #11119

Merged
merged 15 commits into from
Oct 5, 2017

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Oct 5, 2017

Fixes #11103.

According to the spec, HTML parser turns \r\n or lone \r into \n.

Since we compare JS app string (which might have \r) with the representation parsed from HTML (which can't), we have a false positive text mismatch warning.

I am solving this by adding a second check. It's only activated when we have a mismatch, so it only penalizes users with mismatching markup, or users with \r in content.

I opted not to patch up the markup when the only difference is \r normalization. This is because we never did that before, and nobody complained. So it's probably unobservable to the user anyway (even though it's observable from the DOM—you can't have \r by setting innerHTML or parsing, but you can if you createTextNodes with it directly).

An alternative could be to always normalize \r when creating text nodes (and patch up markup if we encounter it). This would also make the behavior consistent between innerHTML and createTextNode path on the client side.

It seems like we can always do the latter if we want to, but the former is an unobtrusive fix that can be applied now.

Updated it to just ignore the warning, but still patch up. Production logic doesn't change now.

Later updated to normalize both server and client values before emitting the warning. I started stripping both null and "replacement" character (browser sometimes turns null into it) since that's the only other corner case I know.

@reactjs-bot
Copy link

reactjs-bot commented Oct 5, 2017

Deploy preview ready!

Built with commit 72e67ff

https://deploy-preview-11119--reactjs.netlify.com

@gaearon
Copy link
Collaborator Author

gaearon commented Oct 5, 2017

I haven’t thought about attributes though. I guess they also need it.

Copy link
Collaborator

@sebmarkbage sebmarkbage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If all you want to do is ignore the warning your logic should be able to be self-contained completely in warnForTextDifference and fully behind a __DEV__ flag so we don't need to ship this logic nor use it in production.

I.e. we shouldn't need to change the behavior of the isDifferent flag if we don't expect to patch it up.

if (normalizedClientText === serverText) {
return false;
}
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This return value is meant to indicate that it should patch it up. So this says that we will patch up the DOM if it differs, which is not what your comment says.

@gaearon gaearon changed the title Normalize line endings when comparing hydrated markup Ignore CR/LF differences when warning about markup mismatch Oct 5, 2017
Copy link
Contributor

@aickin aickin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. I love the test cases especially!

var normalizeMarkupForTextOrAttribute = function(markup: mixed): string {
const markupString = typeof markup === 'string'
? markup
: '' + (markup: any);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super proud but I couldn't get Flow to understand I'm just trying to cast to string.

Copy link
Contributor

@vjeux vjeux Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String(markup)

@gaearon
Copy link
Collaborator Author

gaearon commented Oct 5, 2017

They took some head scratching 😛

@gaearon gaearon merged commit 44c32fc into facebook:master Oct 5, 2017
@johnnysprinkles
Copy link

Thanks for the fix, that was quick!

@syranide
Copy link
Contributor

syranide commented Oct 7, 2017

@Gaeron I think there's a "bug" here, if you render \r\0 in some browsers it should still emit the message because they actually do support the null-character. In the DOM it will then be \n\0 whereas you will compare with \n as expected. So you should probably filter both strings for the null-character at the very least.

Nvm, failed my reading comprehension of the source code.

@gaearon
Copy link
Collaborator Author

gaearon commented Oct 7, 2017

I believe the PR normalises both now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SSR: ReactDOM client and server handling newlines differently causing mismatch warnings
8 participants