From 87fc8d4d30a063d5f7c5472d3e7ce55a610acf9d Mon Sep 17 00:00:00 2001 From: Soe Lynn Date: Fri, 7 Jun 2024 10:52:17 -0700 Subject: [PATCH] Make getContentOriginOffset to know info about if call-site want transform or not (#44822) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44822 Changelog: [Internal] This is to make `getContentOriginOffset` to have `includeTransform` information passed during Layout computation. Differential Revision: D58223380 --- .../components/scrollview/ScrollViewShadowNode.cpp | 5 ++++- .../components/scrollview/ScrollViewShadowNode.h | 2 +- .../react/renderer/core/LayoutableShadowNode.cpp | 12 +++++++++--- .../react/renderer/core/LayoutableShadowNode.h | 2 +- .../react/renderer/core/tests/TestComponent.h | 4 +++- .../ReactCommon/react/renderer/dom/DOM.cpp | 2 +- 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp index a8ecce51c482f7..3425a732f57734 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp @@ -63,9 +63,12 @@ void ScrollViewShadowNode::layout(LayoutContext layoutContext) { updateStateIfNeeded(); } -Point ScrollViewShadowNode::getContentOriginOffset() const { +Point ScrollViewShadowNode::getContentOriginOffset( + bool /* includeTransform */) const { + auto stateData = getStateData(); auto contentOffset = stateData.contentOffset; + return {-contentOffset.x, -contentOffset.y + stateData.scrollAwayPaddingTop}; } diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h index cc4d7e119cc2d1..a0fbcf4ca1e9a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h @@ -37,7 +37,7 @@ class ScrollViewShadowNode final : public ConcreteViewShadowNode< #pragma mark - LayoutableShadowNode void layout(LayoutContext layoutContext) override; - Point getContentOriginOffset() const override; + Point getContentOriginOffset(bool includeTransform) const override; private: void updateStateIfNeeded(); diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp index 5ddb4c38996850..2756ea30769065 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.cpp @@ -151,7 +151,11 @@ LayoutMetrics LayoutableShadowNode::computeRelativeLayoutMetrics( } if (i != 0 && policy.includeTransform) { - resultFrame.origin += currentShadowNode->getContentOriginOffset(); + // Transformation is not applied here and instead we delegated out in + // getContentOriginOffset. The reason is that for `ScrollViewShadowNode`, + // we need to consider `scrollAwayPaddingTop` which should NOT be included + // in the transform. + resultFrame.origin += currentShadowNode->getContentOriginOffset(true); } if (policy.enableOverflowClipping) { @@ -188,7 +192,9 @@ Transform LayoutableShadowNode::getTransform() const { return Transform::Identity(); } -Point LayoutableShadowNode::getContentOriginOffset() const { +Point LayoutableShadowNode::getContentOriginOffset( + bool /*includeTransform*/) const { + return {0, 0}; } @@ -269,7 +275,7 @@ ShadowNode::Shared LayoutableShadowNode::findNodeAtPoint( } auto newPoint = point - transformedFrame.origin - - layoutableShadowNode->getContentOriginOffset(); + layoutableShadowNode->getContentOriginOffset(false); auto sortedChildren = node->getChildren(); std::stable_sort( diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h index cae02ce15d1ab3..849ccc6aca04f5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h @@ -123,7 +123,7 @@ class LayoutableShadowNode : public ShadowNode { * `LayoutableShadowNode::getRelativeLayoutMetrics` and * `LayoutableShadowNode::findNodeAtPoint`. */ - virtual Point getContentOriginOffset() const; + virtual Point getContentOriginOffset(bool includeTransform) const; /* * Sets layout metrics for the shadow node. diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h b/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h index b3f5fefe499331..f639aa8e00c915 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h @@ -76,7 +76,9 @@ class TestShadowNode final : public ConcreteViewShadowNode< facebook::react::Point _contentOriginOffset{}; - facebook::react::Point getContentOriginOffset() const override { + facebook::react::Point getContentOriginOffset( + bool /* includeTransform */) const override { + return _contentOriginOffset; } }; diff --git a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp index 417e19ce2df4bc..37d784cade03c3 100644 --- a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp +++ b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp @@ -357,7 +357,7 @@ DOMPoint getScrollPosition( return DOMPoint{}; } - auto scrollPosition = layoutableShadowNode->getContentOriginOffset(); + auto scrollPosition = layoutableShadowNode->getContentOriginOffset(false); return DOMPoint{ .x = scrollPosition.x == 0 ? 0 : -scrollPosition.x,