Skip to content

Commit 6ac78fa

Browse files
resolveStyleConditionsInSubtree in commit instead of commit hook
1 parent 001bdfa commit 6ac78fa

19 files changed

Lines changed: 54 additions & 199 deletions

packages/react-native/ReactCommon/react/renderer/components/root/RootProps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class RootProps final : public ViewProps {
3636
/*
3737
* The interface color scheme conditional (`@media (prefers-color-scheme)`)
3838
* styles are resolved against. Lives on the root (like `layoutConstraints`)
39-
* so the `StyleConditionCommitHook` can read it per surface.
39+
* so the `ShadowTree` can read it per surface when committing.
4040
*/
4141
ColorScheme colorScheme{ColorScheme::Light};
4242
};

packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ class ShadowNode : public Sealable, public DebugStringConvertible, public jsi::N
256256
/*
257257
* Recomputes the `HasStyleConditionsInSubtree` trait from this node's own
258258
* props (non-null `styleConditionData`) and its children's traits. Must run
259-
* whenever props or children change so that `StyleConditionCommitHook` can prune
260-
* whole subtrees and skip the whole tree at the root when no conditional
261-
* styles are present.
259+
* whenever props or children change so that `resolveStyleConditionsInSubtree`
260+
* can prune whole subtrees and skip the whole tree at the root when no
261+
* conditional styles are present.
262262
*/
263263
void propagateStyleConditionsTrait();
264264

packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ class ShadowNodeTraits {
9494

9595
// Indicates that this node or one of its descendants carries conditional
9696
// (media-query) style values (i.e. non-null `Props::styleConditionData`), so
97-
// the `StyleConditionCommitHook` must visit its subtree; a node without this
98-
// trait has an entire subtree free of conditional styles and can be
97+
// `resolveStyleConditionsInSubtree` must visit its subtree; a node without
98+
// this trait has an entire subtree free of conditional styles and can be
9999
// skipped, including skipping the whole tree at the root. Recomputed from
100100
// props and children on construction; must not be set directly.
101101
HasStyleConditionsInSubtree = 1 << 15,

packages/react-native/ReactCommon/react/renderer/core/StyleConditionResolver.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,18 @@ std::shared_ptr<const ShadowNode> resolveStyleConditionsInSubtree(
3030
return node;
3131
}
3232

33-
std::shared_ptr<std::vector<std::shared_ptr<const ShadowNode>>>
34-
newChildrenMutable = nullptr;
33+
auto newChildren = std::vector<std::shared_ptr<const ShadowNode>>{};
34+
auto areChildrenChanged = false;
3535
const auto& children = node->getChildren();
3636
for (size_t i = 0; i < children.size(); i++) {
3737
auto newChild = resolveStyleConditionsInSubtree(
3838
children[i], colorScheme, orientation, propsParserContext);
3939
if (newChild != children[i]) {
40-
if (newChildrenMutable == nullptr) {
41-
newChildrenMutable =
42-
std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>(
43-
children);
40+
if (!areChildrenChanged) {
41+
newChildren = children;
42+
areChildrenChanged = true;
4443
}
45-
(*newChildrenMutable)[i] = std::move(newChild);
44+
newChildren[i] = std::move(newChild);
4645
}
4746
}
4847

@@ -61,18 +60,17 @@ std::shared_ptr<const ShadowNode> resolveStyleConditionsInSubtree(
6160
}
6261
}
6362

64-
if (newChildrenMutable == nullptr && newProps == nullptr) {
63+
if (!areChildrenChanged && newProps == nullptr) {
6564
return node;
6665
}
6766

68-
auto newChildren =
69-
std::shared_ptr<const std::vector<std::shared_ptr<const ShadowNode>>>(
70-
newChildrenMutable);
7167
return node->clone(ShadowNodeFragment{
7268
.props = newProps != nullptr ? newProps
7369
: ShadowNodeFragment::propsPlaceholder(),
74-
.children = newChildren != nullptr
75-
? newChildren
70+
.children = areChildrenChanged
71+
? std::make_shared<
72+
const std::vector<std::shared_ptr<const ShadowNode>>>(
73+
std::move(newChildren))
7674
: ShadowNodeFragment::childrenPlaceholder(),
7775
// Preserve the original state of the node.
7876
.state = node->getState(),

packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,32 @@
1414
#include <react/renderer/components/view/ViewShadowNode.h>
1515
#include <react/renderer/core/LayoutContext.h>
1616
#include <react/renderer/core/LayoutPrimitives.h>
17+
#include <react/renderer/core/StyleConditionResolver.h>
1718
#include <react/renderer/mounting/ShadowTreeRevision.h>
1819
#include <react/renderer/mounting/ShadowViewMutation.h>
1920
#include <react/renderer/telemetry/TransactionTelemetry.h>
2021
#include "updateMountedFlag.h"
2122

2223
#include "ShadowTreeDelegate.h"
2324

25+
#include <cmath>
26+
2427
namespace facebook::react {
2528

2629
namespace {
2730
const int MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING = 3;
2831

32+
#ifndef __ANDROID__
33+
// The orientation for `@media (orientation)` is derived from the
34+
// surface's own viewport
35+
Orientation orientationOf(const RootShadowNode& rootShadowNode) {
36+
auto size = rootShadowNode.getConcreteProps().layoutConstraints.maximumSize;
37+
bool isLandscape = std::isfinite(size.width) && std::isfinite(size.height) &&
38+
size.width > size.height;
39+
return isLandscape ? Orientation::Landscape : Orientation::Portrait;
40+
}
41+
#endif
42+
2943
std::string getShadowTreeCommitSourceName(ShadowTreeCommitSource source) {
3044
switch (source) {
3145
case ShadowTreeCommitSource::Unknown:
@@ -230,7 +244,9 @@ ShadowTree::ShadowTree(
230244
ColorScheme colorScheme,
231245
const ShadowTreeDelegate& delegate,
232246
const ContextContainer& contextContainer)
233-
: surfaceId_(surfaceId), delegate_(delegate) {
247+
: surfaceId_(surfaceId),
248+
delegate_(delegate),
249+
contextContainer_(contextContainer) {
234250
static RootComponentDescriptor globalRootComponentDescriptor(
235251
ComponentDescriptorParameters{
236252
.eventDispatcher = EventDispatcher::Shared{},
@@ -407,6 +423,24 @@ CommitStatus ShadowTree::tryCommit(
407423
return CommitStatus::Cancelled;
408424
}
409425

426+
// Gate it on Android until conditional styles are supported there.
427+
#ifndef __ANDROID__
428+
// Resolve conditional (media-query) styles against the environment carried
429+
// by the root (color scheme on `RootProps`, orientation from the viewport)
430+
{
431+
PropsParserContext propsParserContext{surfaceId_, contextContainer_};
432+
auto resolved = resolveStyleConditionsInSubtree(
433+
newRootShadowNode,
434+
newRootShadowNode->getConcreteProps().colorScheme,
435+
orientationOf(*newRootShadowNode),
436+
propsParserContext);
437+
if (resolved != newRootShadowNode) {
438+
newRootShadowNode = std::static_pointer_cast<RootShadowNode>(
439+
std::const_pointer_cast<ShadowNode>(resolved));
440+
}
441+
}
442+
#endif
443+
410444
// Layout nodes.
411445
std::vector<const LayoutableShadowNode*> affectedLayoutableNodes{};
412446
affectedLayoutableNodes.reserve(1024);

packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class ShadowTree final {
169169

170170
const SurfaceId surfaceId_;
171171
const ShadowTreeDelegate &delegate_;
172+
const ContextContainer &contextContainer_;
172173
mutable std::shared_mutex revisionMutex_;
173174
mutable std::recursive_mutex revisionMutexRecursive_;
174175
mutable CommitMode commitMode_{CommitMode::Normal}; // Protected by `revisionMutex_`.

packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
1818
#include <react/renderer/core/EventQueueProcessor.h>
1919
#include <react/renderer/core/LayoutContext.h>
20-
#include <react/renderer/uimanager/StyleConditionCommitHook.h>
2120
#include <react/renderer/mounting/MountingOverrideDelegate.h>
2221
#include <react/renderer/mounting/ShadowViewMutation.h>
2322
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
@@ -151,14 +150,6 @@ Scheduler::Scheduler(
151150
commitHooks_ = schedulerToolbox.commitHooks;
152151
uiManager_ = uiManager;
153152

154-
#ifndef __ANDROID__
155-
// TODO: not registered on Android yet — the serialized-rawProps path can't
156-
// revert a resolved value cleanly, needs typed prop diffing (Props 2.0).
157-
// Android renders the default value from conditional styles until then.
158-
commitHooks_.push_back(
159-
std::make_shared<StyleConditionCommitHook>(contextContainer_));
160-
#endif
161-
162153
for (auto& commitHook : commitHooks_) {
163154
uiManager->registerCommitHook(*commitHook);
164155
}

packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceHandler.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,7 @@ class SurfaceHandler {
146146

147147
/*
148148
* Sets the interface color scheme conditional (`@media (prefers-color-scheme)`)
149-
* styles are resolved against, committing so the `StyleConditionCommitHook`
150-
* re-resolves.
149+
* styles are resolved against, committing so the tree re-resolves on commit.
151150
*/
152151
void setColorScheme(ColorScheme colorScheme) const;
153152

packages/react-native/ReactCommon/react/renderer/uimanager/StyleConditionCommitHook.cpp

Lines changed: 0 additions & 62 deletions
This file was deleted.

packages/react-native/ReactCommon/react/renderer/uimanager/StyleConditionCommitHook.h

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)