Skip to content

Commit fc9dfc8

Browse files
committed
Pass committed view props to the platform routing predicate
1 parent 3b6d0b2 commit fc9dfc8

8 files changed

Lines changed: 62 additions & 17 deletions

File tree

packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSPlatformTransitionProxy.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,18 @@ bool valueShapeRoutable(
2929
CSSPlatformTransitionProxy::CSSPlatformTransitionProxy(
3030
CSSCanRoutePropertyFunction canRoute,
3131
CSSApplyTransitionFunction applyTransition,
32-
CSSRemoveTransitionFunction removeTransition)
32+
CSSRemoveTransitionFunction removeTransition,
33+
std::shared_ptr<ViewStylesRepository> viewStylesRepository)
3334
: canRoute_(std::move(canRoute)),
3435
applyTransition_(std::move(applyTransition)),
35-
removeTransition_(std::move(removeTransition)) {}
36+
removeTransition_(std::move(removeTransition)),
37+
viewStylesRepository_(std::move(viewStylesRepository)) {}
3638

37-
bool CSSPlatformTransitionProxy::canRoute(const std::string &propertyName, const EasingConfig &easing) const {
38-
return canRoute_ && canRoute_(propertyName, easing);
39+
bool CSSPlatformTransitionProxy::canRoute(
40+
const std::string &propertyName,
41+
const EasingConfig &easing,
42+
const ShadowNode &shadowNode) const {
43+
return canRoute_ && canRoute_(propertyName, easing, shadowNode);
3944
}
4045

4146
void CSSPlatformTransitionProxy::run(const CSSPlatformTransitionPropertyConfig &config) const {
@@ -56,11 +61,15 @@ void CSSPlatformTransitionProxy::remove(const Tag viewTag, const std::string &pr
5661
// the prop is migrating sides - that's how we emit cancels.
5762
CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processConfig(
5863
jsi::Runtime &rt,
64+
const std::shared_ptr<const ShadowNode> &shadowNode,
5965
CSSTransitionConfig &&config,
6066
const CSSTransitionRouting &previousRouting) const {
6167
ProcessedConfig result;
6268
result.routing = previousRouting;
6369

70+
// Eligibility is decided against the view's latest committed props.
71+
const auto newestShadowNode = viewStylesRepository_->getNewestShadowNode(shadowNode);
72+
6473
// The sibling-aware border check below needs to see all transitioning props.
6574
std::unordered_set<std::string> transitioningNames;
6675
transitioningNames.reserve(config.changedPropertiesSettings.size());
@@ -82,7 +91,7 @@ CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processC
8291
const bool valuesRoutable = valueIt == config.changedProperties.end() ||
8392
valueShapeRoutable(rt, propertyName, valueIt->second.first, valueIt->second.second);
8493

85-
if (canRoute(propertyName, settings.easingConfig) &&
94+
if (canRoute(propertyName, settings.easingConfig, *newestShadowNode) &&
8695
!hasNonUniformBorderSibling(propertyName, transitioningNames) && valuesRoutable) {
8796
// loop -> platform migration: cancel on loop.
8897
if (result.routing.loop.erase(propertyName) > 0) {

packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSPlatformTransitionProxy.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
#include <reanimated/CSS/common/definitions.h>
44
#include <reanimated/CSS/configs/CSSTransitionConfig.h>
55
#include <reanimated/CSS/easing/EasingConfigs.h>
6+
#include <reanimated/CSS/misc/ViewStylesRepository.h>
67
#include <reanimated/CSS/utils/platform.h>
78

89
#include <jsi/jsi.h>
910
#include <react/renderer/core/ReactPrimitives.h>
11+
#include <react/renderer/core/ShadowNode.h>
1012

1113
#include <functional>
14+
#include <memory>
1215
#include <string>
1316
#include <vector>
1417

@@ -47,7 +50,11 @@ struct CSSPlatformTransitionConfig {
4750
}
4851
};
4952

50-
using CSSCanRoutePropertyFunction = std::function<bool(const std::string &propertyName, const EasingConfig &easing)>;
53+
// The shadow node carries the view's latest committed props so platform
54+
// implementations can reject properties whose rendering depends on sibling
55+
// style (e.g. border drawing paths).
56+
using CSSCanRoutePropertyFunction =
57+
std::function<bool(const std::string &propertyName, const EasingConfig &easing, const ShadowNode &shadowNode)>;
5158
using CSSApplyTransitionFunction = std::function<void(const CSSPlatformTransitionPropertyConfig &config)>;
5259
using CSSRemoveTransitionFunction = std::function<void(Tag viewTag, const std::string &propertyName)>;
5360

@@ -67,26 +74,32 @@ class CSSPlatformTransitionProxy {
6774
CSSPlatformTransitionProxy(
6875
CSSCanRoutePropertyFunction canRoute,
6976
CSSApplyTransitionFunction applyTransition,
70-
CSSRemoveTransitionFunction removeTransition);
77+
CSSRemoveTransitionFunction removeTransition,
78+
std::shared_ptr<ViewStylesRepository> viewStylesRepository);
7179

7280
void run(const CSSPlatformTransitionPropertyConfig &config) const;
7381
void remove(Tag viewTag, const std::string &propertyName) const;
7482

7583
// Filters the incoming config into loop / platform buckets and emits implicit
7684
// cancels on the old side when a property migrates compared to previousRouting.
7785
// A property routes to the platform only when the platform declares it
78-
// routable (canRoute), no non-uniform border sibling is transitioning along
79-
// with it, and both endpoint values are expressible as platform values;
80-
// otherwise it goes to the loop, which can animate everything.
81-
ProcessedConfig
82-
processConfig(jsi::Runtime &rt, CSSTransitionConfig &&config, const CSSTransitionRouting &previousRouting) const;
86+
// routable (canRoute, given the view's latest committed props), no
87+
// non-uniform border sibling is transitioning along with it, and both
88+
// endpoint values are expressible as platform values; otherwise it goes to
89+
// the loop, which can animate everything.
90+
ProcessedConfig processConfig(
91+
jsi::Runtime &rt,
92+
const std::shared_ptr<const ShadowNode> &shadowNode,
93+
CSSTransitionConfig &&config,
94+
const CSSTransitionRouting &previousRouting) const;
8395

8496
private:
85-
bool canRoute(const std::string &propertyName, const EasingConfig &easing) const;
97+
bool canRoute(const std::string &propertyName, const EasingConfig &easing, const ShadowNode &shadowNode) const;
8698

8799
CSSCanRoutePropertyFunction canRoute_;
88100
CSSApplyTransitionFunction applyTransition_;
89101
CSSRemoveTransitionFunction removeTransition_;
102+
std::shared_ptr<ViewStylesRepository> viewStylesRepository_;
90103
};
91104

92105
} // namespace reanimated::css

packages/react-native-reanimated/Common/cpp/reanimated/CSS/core/transition/CSSTransition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ folly::dynamic CSSTransition::run(jsi::Runtime &rt, CSSTransitionConfig &&config
3838

3939
// CSSTransition owns routing: platform-routed props run immediately on the platform
4040
// transition; the loop-routed remainder is applied to the loop transition below.
41-
auto processed = platformTransitionProxy_->processConfig(rt, std::move(config), routing_);
41+
auto processed = platformTransitionProxy_->processConfig(rt, shadowNode_, std::move(config), routing_);
4242
routing_ = std::move(processed.routing);
4343

4444
if (!processed.platform.empty()) {

packages/react-native-reanimated/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ folly::dynamic ViewStylesRepository::getStyleProp(const Tag tag, const PropertyP
7474
return getPropertyValue(staticPropsRegistry_->get(tag), propertyPath);
7575
}
7676

77+
std::shared_ptr<const ShadowNode> ViewStylesRepository::getNewestShadowNode(
78+
const std::shared_ptr<const ShadowNode> &shadowNode) {
79+
if (!uiManager_) {
80+
return shadowNode;
81+
}
82+
auto newestClone = uiManager_->getNewestCloneOfShadowNode(*shadowNode);
83+
return newestClone ? newestClone : shadowNode;
84+
}
85+
7786
void ViewStylesRepository::clearNodesCache() {
7887
shadowNodeCache_.clear();
7988
}

packages/react-native-reanimated/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class ViewStylesRepository {
3636
jsi::Value getParentNodeProp(const std::shared_ptr<const ShadowNode> &shadowNode, const std::string &propName);
3737
folly::dynamic getStyleProp(Tag tag, const PropertyPath &propertyPath);
3838

39+
// Resolves the latest committed clone of the node (the caller's reference may
40+
// be stale); falls back to the given node when no newer clone exists.
41+
std::shared_ptr<const ShadowNode> getNewestShadowNode(const std::shared_ptr<const ShadowNode> &shadowNode);
42+
3943
void clearNodesCache();
4044

4145
private:

packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ ReanimatedModuleProxy::ReanimatedModuleProxy(
223223
std::make_shared<CSSPlatformTransitionProxy>(
224224
platformDepMethodsHolder.cssCanRouteProperty,
225225
platformDepMethodsHolder.cssApplyTransition,
226-
platformDepMethodsHolder.cssRemoveTransition))),
226+
platformDepMethodsHolder.cssRemoveTransition,
227+
viewStylesRepository_))),
227228
pseudoStylesRegistry_(std::make_shared<PseudoStylesRegistry>(
228229
platformDepMethodsHolder.attachPseudoSelector,
229230
platformDepMethodsHolder.detachPseudoSelector,

packages/react-native-reanimated/apple/reanimated/apple/CSS/REACSSPlatformTransitions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ NS_ASSUME_NONNULL_BEGIN
1717

1818
@end
1919

20-
bool canRouteCSSProperty(const std::string &propertyName, const reanimated::css::EasingConfig &easing);
20+
bool canRouteCSSProperty(
21+
const std::string &propertyName,
22+
const reanimated::css::EasingConfig &easing,
23+
const facebook::react::ShadowNode &shadowNode);
2124

2225
NS_ASSUME_NONNULL_END

packages/react-native-reanimated/apple/reanimated/apple/CSS/REACSSPlatformTransitions.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,17 @@ static CGColorSpaceRef sharedSRGBColorSpace()
3030
return space;
3131
}
3232

33-
bool canRouteCSSProperty(const std::string &propertyName, const EasingConfig &easing)
33+
bool canRouteCSSProperty(
34+
const std::string &propertyName,
35+
const EasingConfig &easing,
36+
const facebook::react::ShadowNode & /*shadowNode*/)
3437
{
3538
if constexpr (!StaticFeatureFlags::getFlag("IOS_CSS_CORE_ANIMATION")) {
3639
return false;
3740
}
41+
// The shadow node carries the view's committed props; properties whose
42+
// rendering depends on sibling style will consult it here when they are
43+
// added to the routable set.
3844
if (propertyName != "opacity") {
3945
return false;
4046
}

0 commit comments

Comments
 (0)