1010import { registrationNameModules } from 'legacy-events/EventPluginRegistry' ;
1111import { canUseDOM } from 'shared/ExecutionEnvironment' ;
1212import endsWith from 'shared/endsWith' ;
13+ import invariant from 'shared/invariant' ;
1314import { setListenToResponderEventTypes } from '../events/DeprecatedDOMEventResponderSystem' ;
1415
1516import {
@@ -59,7 +60,6 @@ import {getListenerMapForElement} from '../events/DOMEventListenerMap';
5960import {
6061 addResponderEventSystemEvent ,
6162 removeActiveResponderEventSystemEvent ,
62- trapBubbledEvent ,
6363} from '../events/ReactDOMEventListener.js' ;
6464import { mediaEventTypes } from '../events/DOMTopLevelEventTypes' ;
6565import {
@@ -74,7 +74,12 @@ import {
7474 shouldRemoveAttribute ,
7575} from '../shared/DOMProperty' ;
7676import assertValidProps from '../shared/assertValidProps' ;
77- import { DOCUMENT_NODE , DOCUMENT_FRAGMENT_NODE } from '../shared/HTMLNodeType' ;
77+ import {
78+ DOCUMENT_NODE ,
79+ DOCUMENT_FRAGMENT_NODE ,
80+ ELEMENT_NODE ,
81+ COMMENT_NODE ,
82+ } from '../shared/HTMLNodeType' ;
7883import isCustomComponent from '../shared/isCustomComponent' ;
7984import possibleStandardNames from '../shared/possibleStandardNames' ;
8085import { validateProperties as validateARIAProperties } from '../shared/ReactDOMInvalidARIAHook' ;
@@ -84,8 +89,13 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO
8489import {
8590 enableDeprecatedFlareAPI ,
8691 enableTrustedTypesIntegration ,
92+ enableModernEventSystem ,
8793} from 'shared/ReactFeatureFlags' ;
88- import { legacyListenToEvent } from '../events/DOMLegacyEventPluginSystem' ;
94+ import {
95+ legacyListenToEvent ,
96+ legacyTrapBubbledEvent ,
97+ } from '../events/DOMLegacyEventPluginSystem' ;
98+ import { listenToEvent } from '../events/DOMModernPluginEventSystem' ;
8999
90100let didWarnInvalidHydration = false ;
91101let didWarnScriptTags = false ;
@@ -260,16 +270,36 @@ if (__DEV__) {
260270}
261271
262272function ensureListeningTo (
263- rootContainerElement : Element | Node ,
273+ rootContainerInstance : Element | Node ,
264274 registrationName : string ,
265275) : void {
266- const isDocumentOrFragment =
267- rootContainerElement . nodeType === DOCUMENT_NODE ||
268- rootContainerElement . nodeType === DOCUMENT_FRAGMENT_NODE ;
269- const doc = isDocumentOrFragment
270- ? rootContainerElement
271- : rootContainerElement . ownerDocument ;
272- legacyListenToEvent ( registrationName , doc ) ;
276+ if ( enableModernEventSystem ) {
277+ // If we have a comment node, then use the parent node,
278+ // which should be an element.
279+ const rootContainerElement =
280+ rootContainerInstance . nodeType === COMMENT_NODE
281+ ? rootContainerInstance . parentNode
282+ : rootContainerInstance ;
283+ // Containers can only ever be element nodes. We do not
284+ // want to register events to document fragments or documents
285+ // with the modern plugin event system.
286+ invariant (
287+ rootContainerElement != null &&
288+ rootContainerElement . nodeType === ELEMENT_NODE ,
289+ 'ensureListeningTo(): received a container that was not an element node. ' +
290+ 'This is likely a bug in React.' ,
291+ ) ;
292+ listenToEvent ( registrationName , ( ( rootContainerElement : any ) : Element ) ) ;
293+ } else {
294+ // Legacy plugin event system path
295+ const isDocumentOrFragment =
296+ rootContainerInstance . nodeType === DOCUMENT_NODE ||
297+ rootContainerInstance . nodeType === DOCUMENT_FRAGMENT_NODE ;
298+ const doc = isDocumentOrFragment
299+ ? rootContainerInstance
300+ : rootContainerInstance . ownerDocument ;
301+ legacyListenToEvent ( registrationName , ( ( doc : any ) : Document ) ) ;
302+ }
273303}
274304
275305function getOwnerDocumentFromRootContainer (
@@ -514,41 +544,55 @@ export function setInitialProperties(
514544 case 'iframe' :
515545 case 'object' :
516546 case 'embed' :
517- trapBubbledEvent ( TOP_LOAD , domElement ) ;
547+ if ( ! enableModernEventSystem ) {
548+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
549+ }
518550 props = rawProps ;
519551 break ;
520552 case 'video' :
521553 case 'audio' :
522- // Create listener for each media event
523- for ( let i = 0 ; i < mediaEventTypes . length ; i ++ ) {
524- trapBubbledEvent ( mediaEventTypes [ i ] , domElement ) ;
554+ if ( ! enableModernEventSystem ) {
555+ // Create listener for each media event
556+ for ( let i = 0 ; i < mediaEventTypes . length ; i ++ ) {
557+ legacyTrapBubbledEvent ( mediaEventTypes [ i ] , domElement ) ;
558+ }
525559 }
526560 props = rawProps ;
527561 break ;
528562 case 'source' :
529- trapBubbledEvent ( TOP_ERROR , domElement ) ;
563+ if ( ! enableModernEventSystem ) {
564+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
565+ }
530566 props = rawProps ;
531567 break ;
532568 case 'img' :
533569 case 'image' :
534570 case 'link' :
535- trapBubbledEvent ( TOP_ERROR , domElement ) ;
536- trapBubbledEvent ( TOP_LOAD , domElement ) ;
571+ if ( ! enableModernEventSystem ) {
572+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
573+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
574+ }
537575 props = rawProps ;
538576 break ;
539577 case 'form' :
540- trapBubbledEvent ( TOP_RESET , domElement ) ;
541- trapBubbledEvent ( TOP_SUBMIT , domElement ) ;
578+ if ( ! enableModernEventSystem ) {
579+ legacyTrapBubbledEvent ( TOP_RESET , domElement ) ;
580+ legacyTrapBubbledEvent ( TOP_SUBMIT , domElement ) ;
581+ }
542582 props = rawProps ;
543583 break ;
544584 case 'details' :
545- trapBubbledEvent ( TOP_TOGGLE , domElement ) ;
585+ if ( ! enableModernEventSystem ) {
586+ legacyTrapBubbledEvent ( TOP_TOGGLE , domElement ) ;
587+ }
546588 props = rawProps ;
547589 break ;
548590 case 'input' :
549591 ReactDOMInputInitWrapperState ( domElement , rawProps ) ;
550592 props = ReactDOMInputGetHostProps ( domElement , rawProps ) ;
551- trapBubbledEvent ( TOP_INVALID , domElement ) ;
593+ if ( ! enableModernEventSystem ) {
594+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
595+ }
552596 // For controlled components we always need to ensure we're listening
553597 // to onChange. Even if there is no listener.
554598 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -560,15 +604,19 @@ export function setInitialProperties(
560604 case 'select' :
561605 ReactDOMSelectInitWrapperState ( domElement , rawProps ) ;
562606 props = ReactDOMSelectGetHostProps ( domElement , rawProps ) ;
563- trapBubbledEvent ( TOP_INVALID , domElement ) ;
607+ if ( ! enableModernEventSystem ) {
608+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
609+ }
564610 // For controlled components we always need to ensure we're listening
565611 // to onChange. Even if there is no listener.
566612 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
567613 break ;
568614 case 'textarea' :
569615 ReactDOMTextareaInitWrapperState ( domElement , rawProps ) ;
570616 props = ReactDOMTextareaGetHostProps ( domElement , rawProps ) ;
571- trapBubbledEvent ( TOP_INVALID , domElement ) ;
617+ if ( ! enableModernEventSystem ) {
618+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
619+ }
572620 // For controlled components we always need to ensure we're listening
573621 // to onChange. Even if there is no listener.
574622 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -898,34 +946,48 @@ export function diffHydratedProperties(
898946 case 'iframe' :
899947 case 'object' :
900948 case 'embed' :
901- trapBubbledEvent ( TOP_LOAD , domElement ) ;
949+ if ( ! enableModernEventSystem ) {
950+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
951+ }
902952 break ;
903953 case 'video' :
904954 case 'audio' :
905- // Create listener for each media event
906- for ( let i = 0 ; i < mediaEventTypes . length ; i ++ ) {
907- trapBubbledEvent ( mediaEventTypes [ i ] , domElement ) ;
955+ if ( ! enableModernEventSystem ) {
956+ // Create listener for each media event
957+ for ( let i = 0 ; i < mediaEventTypes . length ; i ++ ) {
958+ legacyTrapBubbledEvent ( mediaEventTypes [ i ] , domElement ) ;
959+ }
908960 }
909961 break ;
910962 case 'source' :
911- trapBubbledEvent ( TOP_ERROR , domElement ) ;
963+ if ( ! enableModernEventSystem ) {
964+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
965+ }
912966 break ;
913967 case 'img' :
914968 case 'image' :
915969 case 'link' :
916- trapBubbledEvent ( TOP_ERROR , domElement ) ;
917- trapBubbledEvent ( TOP_LOAD , domElement ) ;
970+ if ( ! enableModernEventSystem ) {
971+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
972+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
973+ }
918974 break ;
919975 case 'form' :
920- trapBubbledEvent ( TOP_RESET , domElement ) ;
921- trapBubbledEvent ( TOP_SUBMIT , domElement ) ;
976+ if ( ! enableModernEventSystem ) {
977+ legacyTrapBubbledEvent ( TOP_RESET , domElement ) ;
978+ legacyTrapBubbledEvent ( TOP_SUBMIT , domElement ) ;
979+ }
922980 break ;
923981 case 'details' :
924- trapBubbledEvent ( TOP_TOGGLE , domElement ) ;
982+ if ( ! enableModernEventSystem ) {
983+ legacyTrapBubbledEvent ( TOP_TOGGLE , domElement ) ;
984+ }
925985 break ;
926986 case 'input' :
927987 ReactDOMInputInitWrapperState ( domElement , rawProps ) ;
928- trapBubbledEvent ( TOP_INVALID , domElement ) ;
988+ if ( ! enableModernEventSystem ) {
989+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
990+ }
929991 // For controlled components we always need to ensure we're listening
930992 // to onChange. Even if there is no listener.
931993 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -935,14 +997,18 @@ export function diffHydratedProperties(
935997 break ;
936998 case 'select' :
937999 ReactDOMSelectInitWrapperState ( domElement , rawProps ) ;
938- trapBubbledEvent ( TOP_INVALID , domElement ) ;
1000+ if ( ! enableModernEventSystem ) {
1001+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
1002+ }
9391003 // For controlled components we always need to ensure we're listening
9401004 // to onChange. Even if there is no listener.
9411005 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
9421006 break ;
9431007 case 'textarea' :
9441008 ReactDOMTextareaInitWrapperState ( domElement , rawProps ) ;
945- trapBubbledEvent ( TOP_INVALID , domElement ) ;
1009+ if ( ! enableModernEventSystem ) {
1010+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
1011+ }
9461012 // For controlled components we always need to ensure we're listening
9471013 // to onChange. Even if there is no listener.
9481014 ensureListeningTo ( rootContainerElement , 'onChange' ) ;
0 commit comments