From 88e60d601cb1d799d3af6f912ca070eba79d9c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 27 Oct 2026 09:36:28 -0700 Subject: [PATCH 1/2] Sync OSS Fabric renderers for null-target native events (#59546) Summary: Regenerate the development, production, and profiling Fabric renderer bundles from React revision `dc9aed364252a34966f4f2c4a98272317fdddb60`. Native events whose view has unmounted now reach the responder system even when their event target is null. This renderer-only update retains React version `19.3.0` and leaves package metadata and dependency versions unchanged. Changelog: [General][Fixed] - Fix lost taps after a touched view unmounts when EventTarget event dispatching is enabled Reviewed By: javache Differential Revision: D127828293 --- .../implementations/ReactFabric-dev.js | 52 +++---- .../implementations/ReactFabric-prod.js | 98 +++++++------- .../implementations/ReactFabric-profiling.js | 128 +++++++++--------- 3 files changed, 140 insertions(+), 138 deletions(-) diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js index 615eb9178009..ffa8c39b136d 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<12e935271cee5bbb34114c56f570f060>> + * @generated SignedSource<> * * This file was sync'd from the facebook/react repository. */ @@ -1307,12 +1307,11 @@ __DEV__ && (_enableNativeEventTargetEventDispatching = "function" === typeof event && event())); if (_enableNativeEventTargetEventDispatching) - null != eventTarget && - reactPrivateInterface.dispatchNativeEvent( - eventTarget, - topLevelType, - nativeEvent - ); + reactPrivateInterface.dispatchNativeEvent( + eventTarget, + topLevelType, + nativeEvent + ); else { event = eventTarget; for ( @@ -4094,7 +4093,7 @@ __DEV__ && )), thenable.then(noop, noop), (thenable = index)); - if (void 0 === thenable._debugInfo) { + if (void 0 === thenable._debugInfo && Object.isExtensible(thenable)) { thenableState = performance.now(); trackedThenables = thenable.displayName; var ioInfo = { @@ -11766,10 +11765,6 @@ __DEV__ && current = finishedWork.alternate, flags = finishedWork.flags; switch (finishedWork.tag) { - case 0: - case 11: - case 15: - break; case 1: 0 !== (flags & 1024) && null !== current && @@ -11777,6 +11772,9 @@ __DEV__ && break; case 3: break; + case 0: + case 11: + case 15: case 5: case 26: case 27: @@ -12363,8 +12361,8 @@ __DEV__ && null !== current) ) for (var ii = 0; ii < current.length; ii++) { - var _eventPayloads$ii2 = current[ii]; - _eventPayloads$ii2.ref.impl = _eventPayloads$ii2.nextImpl; + var _eventPayloads$ii = current[ii]; + _eventPayloads$ii.ref.impl = _eventPayloads$ii.nextImpl; } recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); @@ -12484,18 +12482,18 @@ __DEV__ && break; case 22: ii = null !== finishedWork.memoizedState; - _eventPayloads$ii2 = + _eventPayloads$ii = null !== current && null !== current.memoizedState; if (finishedWork.mode & 1) { var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || ii; offscreenSubtreeWasHidden = - prevOffscreenSubtreeWasHidden || _eventPayloads$ii2; + prevOffscreenSubtreeWasHidden || _eventPayloads$ii; recursivelyTraverseMutationEffects(root, finishedWork, lanes); offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - _eventPayloads$ii2 && + _eventPayloads$ii && !ii && !prevOffscreenSubtreeIsHidden && !prevOffscreenSubtreeWasHidden && @@ -12517,11 +12515,11 @@ __DEV__ && : root._visibility | OffscreenVisible), !ii || null === current || - _eventPayloads$ii2 || + _eventPayloads$ii || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || 0 === (finishedWork.mode & 1) || - ((root = _eventPayloads$ii2 || offscreenSubtreeWasHidden), + ((root = _eventPayloads$ii || offscreenSubtreeWasHidden), (lanes = offscreenSubtreeIsHidden), (current = offscreenSubtreeWasHidden), (offscreenSubtreeIsHidden = ii || offscreenSubtreeIsHidden), @@ -12563,10 +12561,10 @@ __DEV__ && safelyDetachRef(current, current.return)); flags = pushMutationContext(); ii = inUpdateViewTransition; - _eventPayloads$ii2 = (lanes & 335544064) === lanes; + _eventPayloads$ii = (lanes & 335544064) === lanes; prevOffscreenSubtreeIsHidden = finishedWork.memoizedProps; inUpdateViewTransition = - _eventPayloads$ii2 && + _eventPayloads$ii && "none" !== getViewTransitionClassName( prevOffscreenSubtreeIsHidden.default, @@ -12574,7 +12572,7 @@ __DEV__ && ); recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); - _eventPayloads$ii2 && + _eventPayloads$ii && null !== current && viewTransitionMutationContext && (finishedWork.flags |= 4); @@ -14231,10 +14229,12 @@ __DEV__ && exitStatus = workInProgressRootConcurrentErrors; var wasRootDehydrated = supportsHydration; startTime = renderRootSync(yieldedFiber, startTime, !1); - if ( - startTime !== RootErrored && - startTime !== RootSuspendedAtTheShell - ) { + if (startTime === RootSuspendedAtTheShell) + yieldedFiber.errorRecoveryDisabledLanes = + yieldedFiber.errorRecoveryDisabledLanes | + lanesThatJustErrored | + workInProgressDeferredLane; + else if (startTime !== RootErrored) { if ( workInProgressRootDidAttachPingListener && !wasRootDehydrated diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js index bf3cacd4395c..97526fd2a9bf 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<3c59d85aa170213f7f757b2501b0b2f6>> + * @generated SignedSource<> * * This file was sync'd from the facebook/react repository. */ @@ -1209,7 +1209,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_294 = { +var injectedNamesToPlugins$jscomp$inline_295 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1255,32 +1255,32 @@ var injectedNamesToPlugins$jscomp$inline_294 = { } } }, - isOrderingDirty$jscomp$inline_295 = !1, - pluginName$jscomp$inline_296; -for (pluginName$jscomp$inline_296 in injectedNamesToPlugins$jscomp$inline_294) + isOrderingDirty$jscomp$inline_296 = !1, + pluginName$jscomp$inline_297; +for (pluginName$jscomp$inline_297 in injectedNamesToPlugins$jscomp$inline_295) if ( - injectedNamesToPlugins$jscomp$inline_294.hasOwnProperty( - pluginName$jscomp$inline_296 + injectedNamesToPlugins$jscomp$inline_295.hasOwnProperty( + pluginName$jscomp$inline_297 ) ) { - var pluginModule$jscomp$inline_297 = - injectedNamesToPlugins$jscomp$inline_294[pluginName$jscomp$inline_296]; + var pluginModule$jscomp$inline_298 = + injectedNamesToPlugins$jscomp$inline_295[pluginName$jscomp$inline_297]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_296) || - namesToPlugins[pluginName$jscomp$inline_296] !== - pluginModule$jscomp$inline_297 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_297) || + namesToPlugins[pluginName$jscomp$inline_297] !== + pluginModule$jscomp$inline_298 ) { - if (namesToPlugins[pluginName$jscomp$inline_296]) + if (namesToPlugins[pluginName$jscomp$inline_297]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_296 + "`.") + (pluginName$jscomp$inline_297 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_296] = - pluginModule$jscomp$inline_297; - isOrderingDirty$jscomp$inline_295 = !0; + namesToPlugins[pluginName$jscomp$inline_297] = + pluginModule$jscomp$inline_298; + isOrderingDirty$jscomp$inline_296 = !0; } } -isOrderingDirty$jscomp$inline_295 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_296 && recomputePluginOrdering(); function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } @@ -1338,12 +1338,11 @@ function dispatchEvent(target, topLevelType, nativeEventParam) { (_enableNativeEventTargetEventDispatching = "function" === typeof event && event())); if (_enableNativeEventTargetEventDispatching) - null != eventTarget && - reactPrivateInterface.dispatchNativeEvent( - eventTarget, - topLevelType, - nativeEvent - ); + reactPrivateInterface.dispatchNativeEvent( + eventTarget, + topLevelType, + nativeEvent + ); else { event = eventTarget; for ( @@ -8391,10 +8390,6 @@ function commitBeforeMutationEffects_complete( current = fiber.alternate, flags = fiber.flags; switch (fiber.tag) { - case 0: - case 11: - case 15: - break; case 1: if (0 !== (flags & 1024) && null !== current) { isViewTransitionEligible = void 0; @@ -8419,6 +8414,9 @@ function commitBeforeMutationEffects_complete( break; case 3: break; + case 0: + case 11: + case 15: case 5: case 26: case 27: @@ -8797,8 +8795,8 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { null !== current) ) for (var ii = 0; ii < current.length; ii++) { - var _eventPayloads$ii2 = current[ii]; - _eventPayloads$ii2.ref.impl = _eventPayloads$ii2.nextImpl; + var _eventPayloads$ii = current[ii]; + _eventPayloads$ii.ref.impl = _eventPayloads$ii.nextImpl; } recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); @@ -8897,13 +8895,13 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { break; case 22: ii = null !== finishedWork.memoizedState; - _eventPayloads$ii2 = null !== current && null !== current.memoizedState; + _eventPayloads$ii = null !== current && null !== current.memoizedState; if (finishedWork.mode & 1) { var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || ii; offscreenSubtreeWasHidden = - prevOffscreenSubtreeWasHidden || _eventPayloads$ii2; + prevOffscreenSubtreeWasHidden || _eventPayloads$ii; recursivelyTraverseMutationEffects(root, finishedWork, lanes); offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; @@ -8914,11 +8912,11 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { (root._visibility = ii ? root._visibility & -2 : root._visibility | 1), !ii || null === current || - _eventPayloads$ii2 || + _eventPayloads$ii || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || 0 === (finishedWork.mode & 1) || - ((root = _eventPayloads$ii2 || offscreenSubtreeWasHidden), + ((root = _eventPayloads$ii || offscreenSubtreeWasHidden), (lanes = offscreenSubtreeIsHidden), (current = offscreenSubtreeWasHidden), (offscreenSubtreeIsHidden = ii || offscreenSubtreeIsHidden), @@ -8950,12 +8948,12 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { safelyDetachRef(current, current.return)); flags = pushMutationContext(); ii = (lanes & 335544064) === lanes; - _eventPayloads$ii2 = finishedWork.memoizedProps; + _eventPayloads$ii = finishedWork.memoizedProps; ii && "none" !== getViewTransitionClassName( - _eventPayloads$ii2.default, - _eventPayloads$ii2.update + _eventPayloads$ii.default, + _eventPayloads$ii.update ); recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); @@ -9974,10 +9972,12 @@ function performWorkOnRoot(root$jscomp$0, lanes, forceSync) { JSCompiler_inline_result, !1 ); - if ( - 2 !== JSCompiler_inline_result && - 6 !== JSCompiler_inline_result - ) { + if (6 === JSCompiler_inline_result) + root.errorRecoveryDisabledLanes = + root.errorRecoveryDisabledLanes | + renderWasConcurrent | + workInProgressDeferredLane; + else if (2 !== JSCompiler_inline_result) { if (workInProgressRootDidAttachPingListener) { root.errorRecoveryDisabledLanes |= renderWasConcurrent; workInProgressRootInterleavedUpdatedLanes |= @@ -11742,7 +11742,7 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - internals$jscomp$inline_1347 = { + internals$jscomp$inline_1351 = { bundleType: 0, version: "19.3.0", rendererPackageName: "react-native-renderer", @@ -11750,18 +11750,18 @@ var roots = new Map(), reconcilerVersion: "19.3.0" }; null !== extraDevToolsConfig && - (internals$jscomp$inline_1347.rendererConfig = extraDevToolsConfig); + (internals$jscomp$inline_1351.rendererConfig = extraDevToolsConfig); if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1663 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1672 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1663.isDisabled && - hook$jscomp$inline_1663.supportsFiber + !hook$jscomp$inline_1672.isDisabled && + hook$jscomp$inline_1672.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1663.inject( - internals$jscomp$inline_1347 + (rendererID = hook$jscomp$inline_1672.inject( + internals$jscomp$inline_1351 )), - (injectedHook = hook$jscomp$inline_1663); + (injectedHook = hook$jscomp$inline_1672); } catch (err) {} } exports.createPortal = function (children, containerTag) { diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js index 1934f48a23dc..dbffa3aca64f 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<9f9934c9c6457b3e7ada8ebf2d803424>> * * This file was sync'd from the facebook/react repository. */ @@ -1276,7 +1276,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_336 = { +var injectedNamesToPlugins$jscomp$inline_337 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -1322,32 +1322,32 @@ var injectedNamesToPlugins$jscomp$inline_336 = { } } }, - isOrderingDirty$jscomp$inline_337 = !1, - pluginName$jscomp$inline_338; -for (pluginName$jscomp$inline_338 in injectedNamesToPlugins$jscomp$inline_336) + isOrderingDirty$jscomp$inline_338 = !1, + pluginName$jscomp$inline_339; +for (pluginName$jscomp$inline_339 in injectedNamesToPlugins$jscomp$inline_337) if ( - injectedNamesToPlugins$jscomp$inline_336.hasOwnProperty( - pluginName$jscomp$inline_338 + injectedNamesToPlugins$jscomp$inline_337.hasOwnProperty( + pluginName$jscomp$inline_339 ) ) { - var pluginModule$jscomp$inline_339 = - injectedNamesToPlugins$jscomp$inline_336[pluginName$jscomp$inline_338]; + var pluginModule$jscomp$inline_340 = + injectedNamesToPlugins$jscomp$inline_337[pluginName$jscomp$inline_339]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_338) || - namesToPlugins[pluginName$jscomp$inline_338] !== - pluginModule$jscomp$inline_339 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_339) || + namesToPlugins[pluginName$jscomp$inline_339] !== + pluginModule$jscomp$inline_340 ) { - if (namesToPlugins[pluginName$jscomp$inline_338]) + if (namesToPlugins[pluginName$jscomp$inline_339]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - (pluginName$jscomp$inline_338 + "`.") + (pluginName$jscomp$inline_339 + "`.") ); - namesToPlugins[pluginName$jscomp$inline_338] = - pluginModule$jscomp$inline_339; - isOrderingDirty$jscomp$inline_337 = !0; + namesToPlugins[pluginName$jscomp$inline_339] = + pluginModule$jscomp$inline_340; + isOrderingDirty$jscomp$inline_338 = !0; } } -isOrderingDirty$jscomp$inline_337 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_338 && recomputePluginOrdering(); function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } @@ -1405,12 +1405,11 @@ function dispatchEvent(target, topLevelType, nativeEventParam) { (_enableNativeEventTargetEventDispatching = "function" === typeof event && event())); if (_enableNativeEventTargetEventDispatching) - null != eventTarget && - reactPrivateInterface.dispatchNativeEvent( - eventTarget, - topLevelType, - nativeEvent - ); + reactPrivateInterface.dispatchNativeEvent( + eventTarget, + topLevelType, + nativeEvent + ); else { event = eventTarget; for ( @@ -9090,10 +9089,6 @@ function commitBeforeMutationEffects_complete( current = fiber.alternate, flags = fiber.flags; switch (fiber.tag) { - case 0: - case 11: - case 15: - break; case 1: if (0 !== (flags & 1024) && null !== current) { isViewTransitionEligible = void 0; @@ -9118,6 +9113,9 @@ function commitBeforeMutationEffects_complete( break; case 3: break; + case 0: + case 11: + case 15: case 5: case 26: case 27: @@ -9622,8 +9620,8 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { null !== current) ) for (var ii = 0; ii < current.length; ii++) { - var _eventPayloads$ii2 = current[ii]; - _eventPayloads$ii2.ref.impl = _eventPayloads$ii2.nextImpl; + var _eventPayloads$ii = current[ii]; + _eventPayloads$ii.ref.impl = _eventPayloads$ii.nextImpl; } recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); @@ -9727,17 +9725,17 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { break; case 22: ii = null !== finishedWork.memoizedState; - _eventPayloads$ii2 = null !== current && null !== current.memoizedState; + _eventPayloads$ii = null !== current && null !== current.memoizedState; if (finishedWork.mode & 1) { var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden, prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden || ii; offscreenSubtreeWasHidden = - prevOffscreenSubtreeWasHidden || _eventPayloads$ii2; + prevOffscreenSubtreeWasHidden || _eventPayloads$ii; recursivelyTraverseMutationEffects(root, finishedWork, lanes); offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; - _eventPayloads$ii2 && + _eventPayloads$ii && !ii && !prevOffscreenSubtreeIsHidden && !prevOffscreenSubtreeWasHidden && @@ -9757,11 +9755,11 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { (root._visibility = ii ? root._visibility & -2 : root._visibility | 1), !ii || null === current || - _eventPayloads$ii2 || + _eventPayloads$ii || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || 0 === (finishedWork.mode & 1) || - ((root = _eventPayloads$ii2 || offscreenSubtreeWasHidden), + ((root = _eventPayloads$ii || offscreenSubtreeWasHidden), (lanes = offscreenSubtreeIsHidden), (current = offscreenSubtreeWasHidden), (offscreenSubtreeIsHidden = ii || offscreenSubtreeIsHidden), @@ -9803,12 +9801,12 @@ function commitMutationEffectsOnFiber(finishedWork, root, lanes) { safelyDetachRef(current, current.return)); flags = pushMutationContext(); ii = (lanes & 335544064) === lanes; - _eventPayloads$ii2 = finishedWork.memoizedProps; + _eventPayloads$ii = finishedWork.memoizedProps; ii && "none" !== getViewTransitionClassName( - _eventPayloads$ii2.default, - _eventPayloads$ii2.update + _eventPayloads$ii.default, + _eventPayloads$ii.update ); recursivelyTraverseMutationEffects(root, finishedWork, lanes); commitReconciliationEffects(finishedWork); @@ -11311,23 +11309,27 @@ function performWorkOnRoot(root$jscomp$0, lanes, forceSync) { var root = root$jscomp$0; yieldDuration = workInProgressRootConcurrentErrors; exitStatus = renderRootSync(root, JSCompiler_inline_result, !1); - 2 !== exitStatus && - 6 !== exitStatus && - (workInProgressRootDidAttachPingListener - ? ((root.errorRecoveryDisabledLanes |= renderWasConcurrent), - (workInProgressRootInterleavedUpdatedLanes |= - renderWasConcurrent), - (exitStatus = 4)) - : ((renderWasConcurrent = workInProgressRootRecoverableErrors), - (workInProgressRootRecoverableErrors = yieldDuration), - null !== renderWasConcurrent && - ((yieldDuration = renderWasConcurrent), - null === workInProgressRootRecoverableErrors - ? (workInProgressRootRecoverableErrors = yieldDuration) - : workInProgressRootRecoverableErrors.push.apply( - workInProgressRootRecoverableErrors, - yieldDuration - )))); + 6 === exitStatus + ? (root.errorRecoveryDisabledLanes = + root.errorRecoveryDisabledLanes | + renderWasConcurrent | + workInProgressDeferredLane) + : 2 !== exitStatus && + (workInProgressRootDidAttachPingListener + ? ((root.errorRecoveryDisabledLanes |= renderWasConcurrent), + (workInProgressRootInterleavedUpdatedLanes |= + renderWasConcurrent), + (exitStatus = 4)) + : ((renderWasConcurrent = workInProgressRootRecoverableErrors), + (workInProgressRootRecoverableErrors = yieldDuration), + null !== renderWasConcurrent && + ((yieldDuration = renderWasConcurrent), + null === workInProgressRootRecoverableErrors + ? (workInProgressRootRecoverableErrors = yieldDuration) + : workInProgressRootRecoverableErrors.push.apply( + workInProgressRootRecoverableErrors, + yieldDuration + )))); renderWasConcurrent = !1; if (2 !== exitStatus) continue; else yieldDuration = now$1(); @@ -13644,7 +13646,7 @@ batchedUpdatesImpl = function (fn, a) { } }; var roots = new Map(), - internals$jscomp$inline_1630 = { + internals$jscomp$inline_1634 = { bundleType: 0, version: "19.3.0", rendererPackageName: "react-native-renderer", @@ -13652,18 +13654,18 @@ var roots = new Map(), reconcilerVersion: "19.3.0" }; null !== extraDevToolsConfig && - (internals$jscomp$inline_1630.rendererConfig = extraDevToolsConfig); + (internals$jscomp$inline_1634.rendererConfig = extraDevToolsConfig); if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1972 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1981 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1972.isDisabled && - hook$jscomp$inline_1972.supportsFiber + !hook$jscomp$inline_1981.isDisabled && + hook$jscomp$inline_1981.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1972.inject( - internals$jscomp$inline_1630 + (rendererID = hook$jscomp$inline_1981.inject( + internals$jscomp$inline_1634 )), - (injectedHook = hook$jscomp$inline_1972); + (injectedHook = hook$jscomp$inline_1981); } catch (err) {} } exports.createPortal = function (children, containerTag) { From b0f7c256672308c04476410e0d51c644d216f5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Tue, 27 Oct 2026 09:36:28 -0700 Subject: [PATCH 2/2] Run the unmounted-touch responder test with both dispatch systems (#59545) Summary: Remove the flag-dependent skip from the Fantom regression test for a touched view unmounting before its touch ends. Fabric now forwards native events with a null target, so both dispatch systems must release the stale responder and grant the next touch. Keep the existing `enableNativeEventTargetEventDispatching:*` test matrix and remove the unused feature-flag import and obsolete TODO. Changelog: [Internal] ___ landed-with-radar-review Differential Revision: D127828380 --- .../__tests__/ResponderEventTarget-itest.js | 100 ++++++++---------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/packages/react-native/src/private/renderer/core/__tests__/ResponderEventTarget-itest.js b/packages/react-native/src/private/renderer/core/__tests__/ResponderEventTarget-itest.js index 5016c87f635e..5fe4be506587 100644 --- a/packages/react-native/src/private/renderer/core/__tests__/ResponderEventTarget-itest.js +++ b/packages/react-native/src/private/renderer/core/__tests__/ResponderEventTarget-itest.js @@ -14,7 +14,6 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; import * as Fantom from '@react-native/fantom'; import * as React from 'react'; import {View} from 'react-native'; -import {ReactNativeFeatureFlags} from 'react-native/react-private-interface'; // Helpers for common touch event payloads function touchStart(identifier: number = 0): { @@ -133,67 +132,60 @@ describe('Responder System', () => { expect(onResponderRelease).toHaveBeenCalledTimes(1); }); - // TODO(react/react#38006): run this with the flag on too once the synced - // renderer stops dropping events whose target is null. - (ReactNativeFeatureFlags.enableNativeEventTargetEventDispatching() - ? it.skip - : it)( - 'releases the responder when the touched view unmounts before the touch ends', - () => { - const root = Fantom.createRoot(); - const firstRef = React.createRef>(); - const secondRef = React.createRef>(); - const onFirstResponderGrant = jest.fn(); - const onSecondResponderGrant = jest.fn(); - - Fantom.runTask(() => { - root.render( - true} - onResponderGrant={onFirstResponderGrant} - />, - ); - }); + it('releases the responder when the touched view unmounts before the touch ends', () => { + const root = Fantom.createRoot(); + const firstRef = React.createRef>(); + const secondRef = React.createRef>(); + const onFirstResponderGrant = jest.fn(); + const onSecondResponderGrant = jest.fn(); - Fantom.dispatchNativeEvent(firstRef, 'onTouchStart', touchStart(), { - category: Fantom.NativeEventCategory.Discrete, - }); + Fantom.runTask(() => { + root.render( + true} + onResponderGrant={onFirstResponderGrant} + />, + ); + }); - expect(onFirstResponderGrant).toHaveBeenCalledTimes(1); + Fantom.dispatchNativeEvent(firstRef, 'onTouchStart', touchStart(), { + category: Fantom.NativeEventCategory.Discrete, + }); - // Queue the touch end without flushing it, then unmount the view, so the - // event reaches JS without a target. - Fantom.enqueueNativeEvent(firstRef, 'onTouchEnd', touchEnd(), { - category: Fantom.NativeEventCategory.Discrete, - }); + expect(onFirstResponderGrant).toHaveBeenCalledTimes(1); - Fantom.runTask(() => { - root.render( - true} - onResponderGrant={onSecondResponderGrant} - />, - ); - }); + // Queue the touch end without flushing it, then unmount the view, so the + // event reaches JS without a target. + Fantom.enqueueNativeEvent(firstRef, 'onTouchEnd', touchEnd(), { + category: Fantom.NativeEventCategory.Discrete, + }); + + Fantom.runTask(() => { + root.render( + true} + onResponderGrant={onSecondResponderGrant} + />, + ); + }); - Fantom.flushAllNativeEvents(); + Fantom.flushAllNativeEvents(); - // The responder was released, so the next touch is granted - Fantom.dispatchNativeEvent(secondRef, 'onTouchStart', touchStart(), { - category: Fantom.NativeEventCategory.Discrete, - }); + // The responder was released, so the next touch is granted + Fantom.dispatchNativeEvent(secondRef, 'onTouchStart', touchStart(), { + category: Fantom.NativeEventCategory.Discrete, + }); - expect(onSecondResponderGrant).toHaveBeenCalledTimes(1); + expect(onSecondResponderGrant).toHaveBeenCalledTimes(1); - Fantom.dispatchNativeEvent(secondRef, 'onTouchEnd', touchEnd(), { - category: Fantom.NativeEventCategory.Discrete, - }); - }, - ); + Fantom.dispatchNativeEvent(secondRef, 'onTouchEnd', touchEnd(), { + category: Fantom.NativeEventCategory.Discrete, + }); + }); it('dispatches responderTerminate on touch cancel', () => { const root = Fantom.createRoot();