From 91c8e62c4f9d58192a8da9252ab0ad0fb5b8cc2a Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Mon, 15 Jan 2024 09:43:49 -0800 Subject: [PATCH] fix: patch public renderer implementations to include isChildPublicInstance (#42249) Summary: Changelog: [Internal] Manually patching public React renderers artifacts to include `isChildPublicInstance` method, which was added in https://github.com/facebook/react/pull/27783. To identifly the required changes in code I've ran a diff for 2 commits: 1. The one with the changes 2. Its parent FB implementation were synced in D51816108. Reviewed By: sammy-SC Differential Revision: D52697885 --- .../implementations/ReactFabric-dev.js | 57 ++++++++++++++++++- .../implementations/ReactFabric-prod.js | 3 + .../implementations/ReactFabric-profiling.js | 4 +- .../ReactNativeRenderer-dev.js | 57 ++++++++++++++++++- .../ReactNativeRenderer-prod.js | 3 + .../ReactNativeRenderer-profiling.js | 4 +- 6 files changed, 124 insertions(+), 4 deletions(-) diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js index 369663c6b8153d..309d1dd42a3fa8 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -3388,6 +3388,20 @@ function findCurrentHostFiberImpl(node) { return null; } +function doesFiberContain(parentFiber, childFiber) { + var node = childFiber; + var parentFiberAlternate = parentFiber.alternate; + + while (node !== null) { + if (node === parentFiber || node === parentFiberAlternate) { + return true; + } + + node = node.return; + } + + return false; +} /** * In the future, we should cleanup callbacks by cancelling them instead of @@ -24331,6 +24345,46 @@ function sendAccessibilityEvent(handle, eventType) { } } +function isChildPublicInstance(parentInstance, childInstance) { + { + // Paper + if ( + // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + parentInstance._internalFiberInstanceHandleDEV && // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + childInstance._internalFiberInstanceHandleDEV + ) { + return doesFiberContain( + // $FlowExpectedError[incompatible-call] + parentInstance._internalFiberInstanceHandleDEV, // $FlowExpectedError[incompatible-call] + childInstance._internalFiberInstanceHandleDEV + ); + } + + var parentInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for parentInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + parentInstance + ); + var childInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for childInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + childInstance + ); // Fabric + + if ( + parentInternalInstanceHandle != null && + childInternalInstanceHandle != null + ) { + return doesFiberContain( + parentInternalInstanceHandle, + childInternalInstanceHandle + ); + } // Means that one instance is from Fabric and other is from Paper. + + return false; + } +} + function onRecoverableError(error$1) { // TODO: Expose onRecoverableError option to userspace // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args @@ -24401,6 +24455,7 @@ exports.createPortal = createPortal$1; exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; +exports.isChildPublicInstance = isChildPublicInstance; exports.render = render; exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.stopSurface = stopSurface; @@ -24414,6 +24469,6 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); } - + })(); } diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js index e61e79886237ba..bc65526065c746 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -8386,6 +8386,9 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { }; exports.findNodeHandle = findNodeHandle; exports.getInspectorDataForInstance = void 0; +exports.isChildPublicInstance = function () { + throw Error("isChildPublicInstance() is not available in production."); +}; exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); root || diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js index 50397dda81d2bb..6dbee585b66575 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -8863,6 +8863,9 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { }; exports.findNodeHandle = findNodeHandle; exports.getInspectorDataForInstance = void 0; +exports.isChildPublicInstance = function () { + throw Error("isChildPublicInstance() is not available in production."); +}; exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); root || @@ -8931,4 +8934,3 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); } - diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index b104de13da53c2..f29201b97ecc70 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -3676,6 +3676,20 @@ function findCurrentHostFiberImpl(node) { return null; } +function doesFiberContain(parentFiber, childFiber) { + var node = childFiber; + var parentFiberAlternate = parentFiber.alternate; + + while (node !== null) { + if (node === parentFiber || node === parentFiberAlternate) { + return true; + } + + node = node.return; + } + + return false; +} // Modules provided by RN: var emptyObject = {}; @@ -24651,6 +24665,46 @@ function sendAccessibilityEvent(handle, eventType) { } } +function isChildPublicInstance(parentInstance, childInstance) { + { + // Paper + if ( + // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + parentInstance._internalFiberInstanceHandleDEV && // $FlowExpectedError[incompatible-type] + // $FlowExpectedError[prop-missing] Don't check via `instanceof ReactNativeFiberHostComponent`, so it won't be leaked to Fabric. + childInstance._internalFiberInstanceHandleDEV + ) { + return doesFiberContain( + // $FlowExpectedError[incompatible-call] + parentInstance._internalFiberInstanceHandleDEV, // $FlowExpectedError[incompatible-call] + childInstance._internalFiberInstanceHandleDEV + ); + } + + var parentInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for parentInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + parentInstance + ); + var childInternalInstanceHandle = // $FlowExpectedError[incompatible-call] Type for childInstance should have been PublicInstance from ReactFiberConfigFabric. + ReactNativePrivateInterface.getInternalInstanceHandleFromPublicInstance( + childInstance + ); // Fabric + + if ( + parentInternalInstanceHandle != null && + childInternalInstanceHandle != null + ) { + return doesFiberContain( + parentInternalInstanceHandle, + childInternalInstanceHandle + ); + } // Means that one instance is from Fabric and other is from Paper. + + return false; + } +} + function onRecoverableError(error$1) { // TODO: Expose onRecoverableError option to userspace // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args @@ -24738,6 +24792,7 @@ exports.createPortal = createPortal$1; exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; +exports.isChildPublicInstance = isChildPublicInstance; exports.render = render; exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.unmountComponentAtNode = unmountComponentAtNode; @@ -24752,6 +24807,6 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); } - + })(); } diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index dd65bf5b4b05a9..e12ea56d594fce 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -8564,6 +8564,9 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { }; exports.findNodeHandle = findNodeHandle; exports.getInspectorDataForInstance = void 0; +exports.isChildPublicInstance = function () { + throw Error("isChildPublicInstance() is not available in production."); +}; exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { diff --git a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index 7e4f65a4f73919..0159044f17e2a3 100644 --- a/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/packages/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -9040,6 +9040,9 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { }; exports.findNodeHandle = findNodeHandle; exports.getInspectorDataForInstance = void 0; +exports.isChildPublicInstance = function () { + throw Error("isChildPublicInstance() is not available in production."); +}; exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { @@ -9102,4 +9105,3 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); } -