-
Notifications
You must be signed in to change notification settings - Fork 47k
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
[Proof of Concept] Make React resilient to Google Translate #13341
Conversation
I'm going to need getHostSibling.
This might also fix the detachment issue in IE9 if we can't figure out how to avoid using the IE8 |
ReactDOM: size: 🔺+0.3%, gzip: 🔺+0.2% Details of bundled changes.Comparing: 3b3b7fc...90a9d78 react-dom
react-reconciler
Generated by 🚫 dangerJS |
Aren’t all translation wrapped in a font tag? I thought that’s the case I was implementing — is what you’re showing different?
I think it sounds simpler than it is. We’re already in the commit phase so we can’t re-render without finishing first. Then it’s not clear why a re-render would be helpful. What we really want is to re-create the nodes that were replaced. But that requires us to add logic that walks the DOM and compares them. That’s kind of what hydration does, but we’d have to do it on an already mounted tree. It sounds significantly more complicated than what I’m doing. |
😶 Yes. Sorry, this was in the PR description but I confused myself.
It is more complicated. Additionally, purging the DOM elements to do a clean re-render has a lot of problems too. I like this approach. Can you think of any case where a re-render would cause canonical text to show up adjacent to translated text? |
Not sure what you mean. |
Like if a future render could cause the untranslated text to show up next to the translated text. Thinking on it a bit more, I don't think it is an issue. Interestingly, it looks like Chrome is using MutationObserver to dynamically translate the text when the contents changes:
|
I've spent some time making a comprehensive test suite for this and it uncovered many edge cases where this code wouldn't work. Probably because by the time we're in the commit phase we can't actually rely on Fibers and nodes "lining up" — they've already been modified. |
@gaearon is there anyway that you could share that test suite? I'd like to play around with this a bit too. |
Sure. #13347 |
For future reference, see a workaround: #11538 (comment) |
Maybe fixes #11538.
Google Translate modifies the DOM in an unsupported way: #11538 (comment). It seems like what it does is pretty limited though (wrapping text nodes into DOM elements). Given how often Google Translate is used, it seems like it would be nice to be resilient to this particular case.
My strategy is that if
parentNode
is missing we know somebody messed with our DOM. We search for a node at the same position in the host parent as the now-detached node. We do this by reusing the existing Fiber host sibling search logic that we apply at the commit phase. If we find a node at that position, and it's not managed by React, we assume it's the node we need to use for best effort. Worst case — we'll crash anyway.The downside is that this adds a single
.parentNode
equality check on every insertion and deletion. Maybe there's a more scoped strategy. But maybe this is okay?