@@ -16,6 +16,7 @@ import {
1616 updateProperties ,
1717 diffHydratedProperties ,
1818 diffHydratedText ,
19+ trapClickOnNonInteractiveElement ,
1920 warnForUnmatchedText ,
2021 warnForDeletedHydratableElement ,
2122 warnForDeletedHydratableText ,
@@ -343,10 +344,24 @@ export function appendChildToContainer(
343344 container : Container ,
344345 child : Instance | TextInstance ,
345346) : void {
347+ let parentNode ;
346348 if ( container . nodeType === COMMENT_NODE ) {
347- ( container . parentNode : any ) . insertBefore ( child , container ) ;
349+ parentNode = ( container . parentNode : any ) ;
350+ parentNode . insertBefore ( child , container ) ;
348351 } else {
349- container . appendChild ( child ) ;
352+ parentNode = container ;
353+ parentNode . appendChild ( child ) ;
354+ }
355+ // This container might be used for a portal.
356+ // If something inside a portal is clicked, that click should bubble
357+ // through the React tree. However, on Mobile Safari the click would
358+ // never bubble through the *DOM* tree unless an ancestor with onclick
359+ // event exists. So we wouldn't see it and dispatch it.
360+ // This is why we ensure that containers have inline onclick defined.
361+ // https://github.com/facebook/react/issues/11918
362+ if ( parentNode . onclick === null ) {
363+ // TODO: This cast may not be sound for SVG, MathML or custom elements.
364+ trapClickOnNonInteractiveElement ( ( ( parentNode : any ) : HTMLElement ) ) ;
350365 }
351366}
352367
0 commit comments