From 5b156f83fa9dc2d0af4016aed14a643a005c7a16 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 20 Jan 2020 01:28:55 -0800 Subject: [PATCH] Fix origin calculation in getRelativeLayoutMetrics Summary: # Problem The issue is in implementation of `LayoutableShadowNode::getRelativeLayoutMetrics`. If you have view tree (A has a child B), and you call `B.getRelativeLayoutMetrics(A)`, the expected result is B's origin within A. The implementation wasn't reflecting that, it was reflecting B's origin within A + A's origin within its parent. # Fix When iterating over ancestors of ShadowNode, the last ancestor should be skipped. AncestorList is a list that starts with provided ancestor and ends with parent of `this`. To skip provided ancestor we iterate to `rend() - 1`. # Why does it work in some cases? This function is triggered from `UIManager.getRelativeLayoutMetrics` without `ancestorShadowNode` provided, we find the RootShadowNode, which has origin `{0, 0}`. Changelog: [Internal] Reviewed By: shergin Differential Revision: D19447900 fbshipit-source-id: 4a9606dc1fab3fecfb85d337b014188d80e5b355 --- ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp index 05740d4bd75..b681634887f 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp @@ -55,7 +55,10 @@ LayoutMetrics LayoutableShadowNode::getRelativeLayoutMetrics( auto layoutMetrics = getLayoutMetrics(); - for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) { + // `AncestorList` starts from the given ancestor node and ends with the parent + // node. We iterate from parent node (reverse iteration) and stop before the + // given ancestor (rend() - 1). + for (auto it = ancestors.rbegin(); it != ancestors.rend() - 1; ++it) { auto ¤tShadowNode = it->first.get(); auto layoutableCurrentShadowNode =