mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
[fabric] Fixed updating font size after system change
When updating accessibility text size there is an issue in the current code that would cut the tree enumeration and not update all the shadownodes in the tree - causing the layout in parent elements (of the text element) to not update its layout. This commit fixes this by simplifying the code a lot - we don't need any optimizations here - we can update the whole tree each time the system font size is changed. Tested in RN Tester and Expo Go (with the `enableFontScaleChangesUpdatingLayout` feature flag enabled)
This commit is contained in:
@@ -233,75 +233,14 @@ Size SurfaceHandler::measure(
|
||||
return rootShadowNode->getLayoutMetrics().frame.size;
|
||||
}
|
||||
|
||||
std::shared_ptr<const ShadowNode> SurfaceHandler::dirtyMeasurableNodesRecursive(
|
||||
std::shared_ptr<const ShadowNode> node) const {
|
||||
const auto nodeHasChildren = !node->getChildren().empty();
|
||||
const auto isMeasurableYogaNode =
|
||||
node->getTraits().check(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
||||
|
||||
// Node is not measurable and has no children, its layout will not be affected
|
||||
if (!nodeHasChildren && !isMeasurableYogaNode) {
|
||||
return nullptr;
|
||||
void SurfaceHandler::dirtyMeasurableNodes(std::shared_ptr<const ShadowNode> node) const {
|
||||
if (auto* layoutableNode = dynamic_cast<const YogaLayoutableShadowNode*>(node.get())) {
|
||||
// Only cast away const where needed
|
||||
const_cast<YogaLayoutableShadowNode*>(layoutableNode)->dirtyLayout();
|
||||
}
|
||||
|
||||
ShadowNode::SharedListOfShared newChildren =
|
||||
ShadowNodeFragment::childrenPlaceholder();
|
||||
|
||||
if (nodeHasChildren) {
|
||||
std::shared_ptr<std::vector<std::shared_ptr<const ShadowNode>>>
|
||||
newChildrenMutable = nullptr;
|
||||
for (size_t i = 0; i < node->getChildren().size(); i++) {
|
||||
const auto& child = node->getChildren()[i];
|
||||
|
||||
if (const auto& layoutableNode =
|
||||
std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(
|
||||
child)) {
|
||||
auto newChild = dirtyMeasurableNodesRecursive(layoutableNode);
|
||||
|
||||
if (newChild != nullptr) {
|
||||
if (newChildrenMutable == nullptr) {
|
||||
newChildrenMutable = std::make_shared<
|
||||
std::vector<std::shared_ptr<const ShadowNode>>>(
|
||||
node->getChildren());
|
||||
newChildren = newChildrenMutable;
|
||||
}
|
||||
|
||||
(*newChildrenMutable)[i] = newChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Node is not measurable and its children were not dirtied, its layout will
|
||||
// not be affected
|
||||
if (!isMeasurableYogaNode && newChildrenMutable == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const auto newNode = node->getComponentDescriptor().cloneShadowNode(
|
||||
*node,
|
||||
{
|
||||
.children = newChildren,
|
||||
// Preserve the original state of the node
|
||||
.state = node->getState(),
|
||||
});
|
||||
|
||||
if (isMeasurableYogaNode) {
|
||||
std::static_pointer_cast<YogaLayoutableShadowNode>(newNode)->dirtyLayout();
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
void SurfaceHandler::dirtyMeasurableNodes(ShadowNode& root) const {
|
||||
for (const auto& child : root.getChildren()) {
|
||||
if (const auto& layoutableNode =
|
||||
std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(child)) {
|
||||
const auto newChild = dirtyMeasurableNodesRecursive(layoutableNode);
|
||||
if (newChild != nullptr) {
|
||||
root.replaceChild(*child, newChild);
|
||||
}
|
||||
}
|
||||
for (const auto& child : node->getChildren()) {
|
||||
dirtyMeasurableNodes(child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +283,7 @@ void SurfaceHandler::constraintLayout(
|
||||
layoutContext.fontSizeMultiplier !=
|
||||
oldRootShadowNode.getConcreteProps()
|
||||
.layoutContext.fontSizeMultiplier) {
|
||||
dirtyMeasurableNodes(*newRoot);
|
||||
dirtyMeasurableNodes(newRoot);
|
||||
}
|
||||
|
||||
return newRoot;
|
||||
|
||||
@@ -158,11 +158,9 @@ class SurfaceHandler {
|
||||
void applyDisplayMode(DisplayMode displayMode) const;
|
||||
|
||||
/*
|
||||
* An utility for dirtying all measurable shadow nodes present in the tree.
|
||||
* Marks all measurable shadow nodes in the given tree as dirty
|
||||
*/
|
||||
void dirtyMeasurableNodes(ShadowNode& root) const;
|
||||
std::shared_ptr<const ShadowNode> dirtyMeasurableNodesRecursive(
|
||||
std::shared_ptr<const ShadowNode> node) const;
|
||||
void dirtyMeasurableNodes(std::shared_ptr<const ShadowNode> node) const;
|
||||
|
||||
#pragma mark - Link & Parameters
|
||||
|
||||
|
||||
Reference in New Issue
Block a user