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

targetWithinDownshift always return false with different execution environment #1255

Closed
KaiminHuang opened this issue Mar 28, 2021 · 11 comments

Comments

@KaiminHuang
Copy link
Contributor

Hi there,

I recently found an issue with downshift while the component is rendered in a different execution environment using React Portal.

What you did:
Rendering a downshift component which is declared in an iframe module into the parent window DOM using Portal.

Problem description:
The existing downshift code always check whether the target element is an instance of the original environment Node (in my case, iframeWindow.Node).

Screen Shot 2021-03-28 at 9 04 27 pm

Different scopes have different execution environments. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance, [] instanceof window.frames[0].Array will return false, because Array.prototype !== window.frames[0].Array.prototype and arrays inherit from the former.

quote from MDN instanceof and multiple context (e.g. frames or windows)

What happened:
It resets downshift state on mouse up.

Relevant code or config

child instanceof Node always return false because the target element is rendered in a different environment.

function isOrContainsNode(parent, child) {
  return (
    parent === child ||
    (child instanceof Node && parent.contains && parent.contains(child))
  )
}

Suggested solution:
🤔 I can think of two possible solutions here:

  1. use the environment prop. And replace child instanceof Node with child instanceof environment.document.Node
  2. Or follow this example from MDN, and change it to child instanceof child.ownerDocument.defaultView.Node
@silviuaavram
Copy link
Collaborator

Thanks for posting this. Will also take a look to understand what's going on.

@silviuaavram
Copy link
Collaborator

Ok, got it @KaiminHuang . I did not get the solution #1 to work, maybe it's environment.Node instead of environment.document.Node?

Can you create a PR with the fix? We should also write a unit test for this, somehow.

@silviuaavram
Copy link
Collaborator

Can you check with 6.1.2-alpha.0?

@KaiminHuang
Copy link
Contributor Author

Ok, got it @KaiminHuang . I did not get the solution #1 to work, maybe it's environment.Node instead of environment.document.Node?

Can you create a PR with the fix? We should also write a unit test for this, somehow.

Yes, my mistake. It should just be environment.Node.

@KaiminHuang
Copy link
Contributor Author

@silviuaavram Thanks for you help friend. I think there might be a mistake in v6.1.2-alpha.0.
The Node variable exist on window or environment rather than document.
But in onMouseUp, seems like you are trying to pass down environment.document. Instead we should pass down environment. It might be easier to explain if you can share me your branch link.

@silviuaavram
Copy link
Collaborator

I think I deleted it by accident. Can you create a PR with the fix and we can take it from there?

@KaiminHuang
Copy link
Contributor Author

Hi @silviuaavram, could I get your review on this PR?

@silviuaavram
Copy link
Collaborator

Fixed by #1264

@silviuaavram
Copy link
Collaborator

@all-contributors please add @KaiminHuang for code, bug

@allcontributors
Copy link
Contributor

@silviuaavram

I've put up a pull request to add @KaiminHuang! 🎉

@rrabii
Copy link

rrabii commented May 31, 2021

@silviuaavram @KaiminHuang the issue is still there in iOS browsers when using iframe, works fine on other platforms.

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

No branches or pull requests

3 participants