Skip to content

Commit 8c1fc37

Browse files
committed
Cleanup and dedupe code
1 parent b39654f commit 8c1fc37

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/index.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ export interface SvgPortalNode<C extends Component<any> = Component<any>> extend
3939
type AnyPortalNode<C extends Component<any> = Component<any>> = HtmlPortalNode<C> | SvgPortalNode<C>;
4040

4141

42+
const validateElementType = (domElement: Element, elementType: ANY_ELEMENT_TYPE) => {
43+
if (elementType === ELEMENT_TYPE_HTML) {
44+
return domElement instanceof HTMLElement;
45+
}
46+
if (elementType === ELEMENT_TYPE_SVG) {
47+
return domElement instanceof SVGElement;
48+
}
49+
throw new Error(`Unrecognized element type "${elementType}" for validateElementType.`);
50+
};
51+
4252
// This is the internal implementation: the public entry points set elementType to an appropriate value
4353
const createPortalNode = <C extends Component<any>>(elementType: ANY_ELEMENT_TYPE): AnyPortalNode<C> => {
4454
let initialProps = {} as ComponentProps<C>;
@@ -52,7 +62,7 @@ const createPortalNode = <C extends Component<any>>(elementType: ANY_ELEMENT_TYP
5262
} else if (elementType === ELEMENT_TYPE_SVG){
5363
element= document.createElementNS(SVG_NAMESPACE, 'g');
5464
} else {
55-
throw new Error(`Invalid element type "${elementType}" for createPortalNode: must be "html" or "svg".`)
65+
throw new Error(`Invalid element type "${elementType}" for createPortalNode: must be "html" or "svg".`);
5666
}
5767

5868
const portalNode: AnyPortalNode<C> = {
@@ -74,9 +84,8 @@ const createPortalNode = <C extends Component<any>>(elementType: ANY_ELEMENT_TYP
7484
// To support SVG and other non-html elements, the portalNode's elementType needs to match
7585
// the elementType it's being rendered into
7686
if (newParent !== parent) {
77-
if ((elementType === ELEMENT_TYPE_HTML && !(newParent instanceof HTMLElement)) ||
78-
(elementType === ELEMENT_TYPE_SVG && !(newParent instanceof SVGElement))) {
79-
throw new Error(`Invalid element type for portal: "${elementType}" portalNodes must be used with ${elementType} elements.`)
87+
if (!validateElementType(newParent, elementType)) {
88+
throw new Error(`Invalid element type for portal: "${elementType}" portalNodes must be used with ${elementType} elements, but OutPortal is within <${newParent.tagName}>.`);
8089
}
8190
}
8291

@@ -141,11 +150,10 @@ class InPortal extends React.PureComponent<InPortalProps, { nodeProps: {} }> {
141150

142151
// To support SVG and other non-html elements, every element that gets rendered
143152
// into the InPortal needs to match the portalNode's elementType.
144-
// Non-elements like text and comments are fine with any portal type.
153+
// Non-elements like Text aren't checkable.
145154
childNodes.forEach((childNode) => {
146155
if (childNode instanceof Element) {
147-
if ((elementType === ELEMENT_TYPE_HTML && !(childNode instanceof HTMLElement)) ||
148-
(elementType === ELEMENT_TYPE_SVG && !(childNode instanceof SVGElement))) {
156+
if (!validateElementType(childNode, elementType)) {
149157
throw new Error(`Invalid content for portal: "${elementType}" portalNodes must be used with ${elementType} elements, but InPortal received <${childNode.tagName}>.`);
150158
}
151159
}

0 commit comments

Comments
 (0)