From ddbebacea75b7204895a42f7595775166c95a272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Mon, 10 Mar 2025 05:37:09 -0700 Subject: [PATCH] Fix documentElement methods for element not working correctly (#49898) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49898 Changelog: [internal] In the method to access the native node reference from elements, we weren't considering the case where the element is the `documentElement`, which is a special case we were handling correctly in the case of native node references from nodes (where we also handle it possibly being a document node). Because of this, methods in `Element` and `ReactNativeElement` weren't working correctly on the `documentElement`. We didn't catch this initially because we only tested the traversal methods defined in node in the test for `ReactNativeDocument`. This fixes the issue. Reviewed By: javache Differential Revision: D70792748 fbshipit-source-id: c42d05a066efaffccade94e9d3835fb7172e2335 --- .../__tests__/ReactNativeDocument-itest.js | 26 +++++++++++++++++++ .../dom/nodes/internals/NodeInternals.js | 6 +++++ 2 files changed, 32 insertions(+) diff --git a/packages/react-native/src/private/webapis/dom/nodes/__tests__/ReactNativeDocument-itest.js b/packages/react-native/src/private/webapis/dom/nodes/__tests__/ReactNativeDocument-itest.js index 75afc1751af..ccfdd12129e 100644 --- a/packages/react-native/src/private/webapis/dom/nodes/__tests__/ReactNativeDocument-itest.js +++ b/packages/react-native/src/private/webapis/dom/nodes/__tests__/ReactNativeDocument-itest.js @@ -125,6 +125,32 @@ describe('ReactNativeDocument', () => { expect(document.textContent).toBe(null); }); + it('provides a documentElement node that behaves like a regular element', () => { + let lastNode; + + const root = Fantom.createRoot({viewportWidth: 200, viewportHeight: 100}); + Fantom.runTask(() => { + root.render( + { + lastNode = node; + }} + />, + ); + }); + + const element = ensureInstance(lastNode, ReactNativeElement); + const document = ensureInstance(element.ownerDocument, ReactNativeDocument); + + const {x, y, width, height} = + document.documentElement.getBoundingClientRect(); + + expect(x).toBe(0); + expect(y).toBe(0); + expect(width).toBe(200); + expect(height).toBe(100); + }); + it('implements compareDocumentPosition correctly', () => { let lastNode; diff --git a/packages/react-native/src/private/webapis/dom/nodes/internals/NodeInternals.js b/packages/react-native/src/private/webapis/dom/nodes/internals/NodeInternals.js index 77cd8a796f0..44e105c869e 100644 --- a/packages/react-native/src/private/webapis/dom/nodes/internals/NodeInternals.js +++ b/packages/react-native/src/private/webapis/dom/nodes/internals/NodeInternals.js @@ -129,6 +129,12 @@ export function getNativeElementReference( // $FlowExpectedError[incompatible-cast] We know ReadOnlyElement instances provide InternalInstanceHandle const instanceHandle = getInstanceHandle(node) as InternalInstanceHandle; + if (isReactNativeDocumentElementInstanceHandle(instanceHandle)) { + return getNativeElementReferenceFromReactNativeDocumentElementInstanceHandle( + instanceHandle, + ); + } + // $FlowExpectedError[incompatible-return] return getRendererProxy().getNodeFromInternalInstanceHandle(instanceHandle); }