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

Rendering portal in a new window causes error: "html" portalNodes must be used with html elements, but OutPortal is within DIV #29

Closed
RobRendell opened this issue Sep 18, 2021 · 1 comment · Fixed by #41

Comments

@RobRendell
Copy link
Contributor

I don't know if this is an issue I should raise with you, or the react-new-window maintainers, but I'll start here.

I'm using react-reverse-portal along with react-new-window to make a pop-out window... initially the portal is rendered inside a div with window-like chrome to allow dragging and resizing, but the user can click a "pop out" button to have the portal in an actual window outside their browser.

This used to work, but after upgrading react-new-window from version 0.1.2 to 0.1.3 I started to get the error "html" portalNodes must be used with html elements, but OutPortal is within <DIV>

It's correct, the parent of the OutPortal inside the new window is a DIV, but that doesn't seem to be a problem - nearly every example of react-reverse-portal puts the OutPortal in something other than the root of the page, and they don't complain. So, while the fix for me is to downgrade react-new-window, I'm uncertain why react-reverse-portal is complaining.

Here's a codesandbox demonstrating the issue: https://codesandbox.io/s/happy-benji-20o5q?file=/src/App.js

It won't work due to cross-origin issues inside the codesandbox editor, but you if open the page in a new window (or navigate directly to https://20o5q.csb.app/ ) you can press the "pop out" button and observe the issue. If you downgrade react-new-window to 0.1.2, the codesandbox will start to work as expected.

Thanks!

@pimterry
Copy link
Member

Hmm, interesting. That error comes from here, which simply checks that the OutPortal's parent element is an instance of HTMLElement:

const validateElementType = (domElement: Element, elementType: ANY_ELEMENT_TYPE) => {
if (elementType === ELEMENT_TYPE_HTML) {
return domElement instanceof HTMLElement;
}
if (elementType === ELEMENT_TYPE_SVG) {
return domElement instanceof SVGElement;
}
throw new Error(`Unrecognized element type "${elementType}" for validateElementType.`);
};

I've just done some testing on your example, and it is indeed an HTMLDivElement that should be an instance of HTMLElement, but domElement instanceof HTMLElement and HTMLDivElement both returns false.

I suspect this is because it's a div element created in a different window (https://github.com/rmariuzzo/react-new-window/pull/19/files is the relevant change from react-new-window).

Interestingly, your example does work perfectly for me in Firefox! It only fails in Chrome. Very odd. I'm not sure what the correct behaviour is here - is the browser wrong to say that a DOM element from a different window isn't an instance of our HTMLElement type, or is that expected? It might be worth filing a Chrome bug, or exploring the existing bugs, just to get confirmation on which of the Chrome or Firefox teams is correct here.

I am open to PRs to fix this, if you can find a reliable way to detect HTML vs SVG elements instances that works cross-browser under these constraints. I think it would be best to know for sure who is in the wrong here first though.

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

Successfully merging a pull request may close this issue.

2 participants