@@ -39,6 +39,16 @@ export interface SvgPortalNode<C extends Component<any> = Component<any>> extend
3939type 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
4353const 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