10
10
import { registrationNameModules } from 'legacy-events/EventPluginRegistry' ;
11
11
import { canUseDOM } from 'shared/ExecutionEnvironment' ;
12
12
import endsWith from 'shared/endsWith' ;
13
+ import invariant from 'shared/invariant' ;
13
14
import { setListenToResponderEventTypes } from '../events/DeprecatedDOMEventResponderSystem' ;
14
15
15
16
import {
@@ -59,7 +60,6 @@ import {getListenerMapForElement} from '../events/DOMEventListenerMap';
59
60
import {
60
61
addResponderEventSystemEvent ,
61
62
removeActiveResponderEventSystemEvent ,
62
- trapBubbledEvent ,
63
63
} from '../events/ReactDOMEventListener.js' ;
64
64
import { mediaEventTypes } from '../events/DOMTopLevelEventTypes' ;
65
65
import {
@@ -74,7 +74,12 @@ import {
74
74
shouldRemoveAttribute ,
75
75
} from '../shared/DOMProperty' ;
76
76
import 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' ;
78
83
import isCustomComponent from '../shared/isCustomComponent' ;
79
84
import possibleStandardNames from '../shared/possibleStandardNames' ;
80
85
import { validateProperties as validateARIAProperties } from '../shared/ReactDOMInvalidARIAHook' ;
@@ -84,8 +89,13 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO
84
89
import {
85
90
enableDeprecatedFlareAPI ,
86
91
enableTrustedTypesIntegration ,
92
+ enableModernEventSystem ,
87
93
} 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' ;
89
99
90
100
let didWarnInvalidHydration = false ;
91
101
let didWarnScriptTags = false ;
@@ -260,16 +270,36 @@ if (__DEV__) {
260
270
}
261
271
262
272
function ensureListeningTo (
263
- rootContainerElement : Element | Node ,
273
+ rootContainerInstance : Element | Node ,
264
274
registrationName : string ,
265
275
) : 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
+ }
273
303
}
274
304
275
305
function getOwnerDocumentFromRootContainer (
@@ -514,41 +544,55 @@ export function setInitialProperties(
514
544
case 'iframe' :
515
545
case 'object' :
516
546
case 'embed' :
517
- trapBubbledEvent ( TOP_LOAD , domElement ) ;
547
+ if ( ! enableModernEventSystem ) {
548
+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
549
+ }
518
550
props = rawProps ;
519
551
break ;
520
552
case 'video' :
521
553
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
+ }
525
559
}
526
560
props = rawProps ;
527
561
break ;
528
562
case 'source' :
529
- trapBubbledEvent ( TOP_ERROR , domElement ) ;
563
+ if ( ! enableModernEventSystem ) {
564
+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
565
+ }
530
566
props = rawProps ;
531
567
break ;
532
568
case 'img' :
533
569
case 'image' :
534
570
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
+ }
537
575
props = rawProps ;
538
576
break ;
539
577
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
+ }
542
582
props = rawProps ;
543
583
break ;
544
584
case 'details' :
545
- trapBubbledEvent ( TOP_TOGGLE , domElement ) ;
585
+ if ( ! enableModernEventSystem ) {
586
+ legacyTrapBubbledEvent ( TOP_TOGGLE , domElement ) ;
587
+ }
546
588
props = rawProps ;
547
589
break ;
548
590
case 'input' :
549
591
ReactDOMInputInitWrapperState ( domElement , rawProps ) ;
550
592
props = ReactDOMInputGetHostProps ( domElement , rawProps ) ;
551
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
593
+ if ( ! enableModernEventSystem ) {
594
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
595
+ }
552
596
// For controlled components we always need to ensure we're listening
553
597
// to onChange. Even if there is no listener.
554
598
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -560,15 +604,19 @@ export function setInitialProperties(
560
604
case 'select' :
561
605
ReactDOMSelectInitWrapperState ( domElement , rawProps ) ;
562
606
props = ReactDOMSelectGetHostProps ( domElement , rawProps ) ;
563
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
607
+ if ( ! enableModernEventSystem ) {
608
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
609
+ }
564
610
// For controlled components we always need to ensure we're listening
565
611
// to onChange. Even if there is no listener.
566
612
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
567
613
break ;
568
614
case 'textarea' :
569
615
ReactDOMTextareaInitWrapperState ( domElement , rawProps ) ;
570
616
props = ReactDOMTextareaGetHostProps ( domElement , rawProps ) ;
571
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
617
+ if ( ! enableModernEventSystem ) {
618
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
619
+ }
572
620
// For controlled components we always need to ensure we're listening
573
621
// to onChange. Even if there is no listener.
574
622
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -898,34 +946,48 @@ export function diffHydratedProperties(
898
946
case 'iframe' :
899
947
case 'object' :
900
948
case 'embed' :
901
- trapBubbledEvent ( TOP_LOAD , domElement ) ;
949
+ if ( ! enableModernEventSystem ) {
950
+ legacyTrapBubbledEvent ( TOP_LOAD , domElement ) ;
951
+ }
902
952
break ;
903
953
case 'video' :
904
954
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
+ }
908
960
}
909
961
break ;
910
962
case 'source' :
911
- trapBubbledEvent ( TOP_ERROR , domElement ) ;
963
+ if ( ! enableModernEventSystem ) {
964
+ legacyTrapBubbledEvent ( TOP_ERROR , domElement ) ;
965
+ }
912
966
break ;
913
967
case 'img' :
914
968
case 'image' :
915
969
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
+ }
918
974
break ;
919
975
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
+ }
922
980
break ;
923
981
case 'details' :
924
- trapBubbledEvent ( TOP_TOGGLE , domElement ) ;
982
+ if ( ! enableModernEventSystem ) {
983
+ legacyTrapBubbledEvent ( TOP_TOGGLE , domElement ) ;
984
+ }
925
985
break ;
926
986
case 'input' :
927
987
ReactDOMInputInitWrapperState ( domElement , rawProps ) ;
928
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
988
+ if ( ! enableModernEventSystem ) {
989
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
990
+ }
929
991
// For controlled components we always need to ensure we're listening
930
992
// to onChange. Even if there is no listener.
931
993
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
@@ -935,14 +997,18 @@ export function diffHydratedProperties(
935
997
break ;
936
998
case 'select' :
937
999
ReactDOMSelectInitWrapperState ( domElement , rawProps ) ;
938
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
1000
+ if ( ! enableModernEventSystem ) {
1001
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
1002
+ }
939
1003
// For controlled components we always need to ensure we're listening
940
1004
// to onChange. Even if there is no listener.
941
1005
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
942
1006
break ;
943
1007
case 'textarea' :
944
1008
ReactDOMTextareaInitWrapperState ( domElement , rawProps ) ;
945
- trapBubbledEvent ( TOP_INVALID , domElement ) ;
1009
+ if ( ! enableModernEventSystem ) {
1010
+ legacyTrapBubbledEvent ( TOP_INVALID , domElement ) ;
1011
+ }
946
1012
// For controlled components we always need to ensure we're listening
947
1013
// to onChange. Even if there is no listener.
948
1014
ensureListeningTo ( rootContainerElement , 'onChange' ) ;
0 commit comments