diff --git a/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js b/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js index c2cec8b1ca..044c381e9f 100644 --- a/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js @@ -281,7 +281,7 @@ describe('ReactDOMEventListener', () => { // This is a special case for submit and reset events as they are listened on // at the element level and not the document. // @see https://github.com/facebook/react/pull/13462 - it('should not receive submit events if native, interim DOM handler prevents it', () => { + it('should (or not) receive submit events if native, interim DOM handler prevents it', () => { const container = document.createElement('div'); document.body.appendChild(container); @@ -316,8 +316,13 @@ describe('ReactDOMEventListener', () => { }), ); - expect(handleSubmit).toHaveBeenCalled(); - expect(handleReset).toHaveBeenCalled(); + if (gate(flags => flags.enableFormEventDelegation)) { + expect(handleSubmit).not.toHaveBeenCalled(); + expect(handleReset).not.toHaveBeenCalled(); + } else { + expect(handleSubmit).toHaveBeenCalled(); + expect(handleReset).toHaveBeenCalled(); + } } finally { document.body.removeChild(container); } diff --git a/packages/react-dom/src/events/DOMModernPluginEventSystem.js b/packages/react-dom/src/events/DOMModernPluginEventSystem.js index e41072dec4..a36c934abf 100644 --- a/packages/react-dom/src/events/DOMModernPluginEventSystem.js +++ b/packages/react-dom/src/events/DOMModernPluginEventSystem.js @@ -85,6 +85,7 @@ import getListener from './getListener'; import {passiveBrowserEventsSupported} from './checkPassiveEvents'; import { + enableFormEventDelegation, enableLegacyFBSupport, enableCreateEventHandleAPI, enableScopeAPI, @@ -222,8 +223,6 @@ export const capturePhaseEvents: Set = new Set([ TOP_CANCEL, TOP_CLOSE, TOP_INVALID, - TOP_RESET, - TOP_SUBMIT, TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, @@ -249,6 +248,11 @@ export const capturePhaseEvents: Set = new Set([ TOP_WAITING, ]); +if (!enableFormEventDelegation) { + capturePhaseEvents.add(TOP_SUBMIT); + capturePhaseEvents.add(TOP_RESET); +} + if (enableCreateEventHandleAPI) { capturePhaseEvents.add(TOP_AFTER_BLUR); } diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 0837686bf1..4c76b7f09d 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -127,3 +127,6 @@ export const deferRenderPhaseUpdateToNextBatch = true; // Replacement for runWithPriority in React internals. export const decoupleUpdatePriorityFromScheduler = false; + +// Enables delegation for submit and reset events. +export const enableFormEventDelegation = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 1ac12703a2..b607bc5e9b 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -44,6 +44,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 1e41269fc8..77a1010082 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -43,6 +43,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = false; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 0425f62fc0..cfc511a0c2 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -43,6 +43,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 2e2f0aab0d..4402ee3221 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -43,6 +43,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index b60f732c38..33d56da4d6 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -43,6 +43,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = false; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index 72cb1a10e1..1abc93999f 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -43,6 +43,7 @@ export const warnAboutSpreadingKeyToJSX = false; export const enableComponentStackLocations = true; export const enableLegacyFBSupport = !__EXPERIMENTAL__; export const enableFilterEmptyStringAttributesDOM = false; +export const enableFormEventDelegation = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 84fafd6e14..d244b0fda6 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -43,3 +43,5 @@ export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__; // to __VARIANT__. export const enableTrustedTypesIntegration = false; export const disableSchedulerTimeoutBasedOnReactExpirationTime = false; + +export const enableFormEventDelegation = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index f8d399b9cf..4b6e29fb21 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -27,6 +27,7 @@ export const { decoupleUpdatePriorityFromScheduler, enableDebugTracing, enableSchedulingProfiler, + enableFormEventDelegation, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.