Support transforms forming containing blocks (#1539)
Summary: X-link: https://github.com/facebook/react-native/pull/42191 Pull Request resolved: https://github.com/facebook/yoga/pull/1539 React native supports transforms and if a node has a transform it will [form a containing block for absolute descendants regardless of position type](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block). So we need to pass that information into Yoga to ensure this happens. The verbiage for the field "alwaysFormsContainingBlock" is very specific. In a vacuum a node cannot simply "form a containing block". It only forms a containing block in reference to a different node. This can be illustrated in a scenario where we have a static node that is a flex container which has 1 absolute child and 1 relative child. This static node will form a containing block for the relative child but not the absolute one. We could just pass the information on rather something has a transform or not but Yoga is not supposed to know about transforms in general. As a result we have a notion of "always" forming a containing block. Since Yoga is a flexbox spec, non-absolute nodes' containing blocks will ways be their parent. If we add something like a transform to a node then that will also apply to absolute nodes - hence we can say the node will **always** form a CB, no matter who is the descendant. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D52521160 fbshipit-source-id: bab9319ffddec617f5281823930f2a00cc2967f2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
94e7336394
commit
5425107246
@@ -328,6 +328,12 @@ void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) {
|
|||||||
resolveRef(node)->setPrintFunc(printFunc);
|
resolveRef(node)->setPrintFunc(printFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void YGNodeSetAlwaysFormsContainingBlock(
|
||||||
|
YGNodeRef node,
|
||||||
|
bool alwaysFormsContainingBlock) {
|
||||||
|
resolveRef(node)->setAlwaysFormsContainingBlock(alwaysFormsContainingBlock);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void YGNodePrint(const YGNodeConstRef node, const YGPrintOptions options) {
|
void YGNodePrint(const YGNodeConstRef node, const YGPrintOptions options) {
|
||||||
yoga::print(resolveRef(node), scopedEnum(options));
|
yoga::print(resolveRef(node), scopedEnum(options));
|
||||||
|
@@ -270,6 +270,17 @@ typedef void (*YGPrintFunc)(YGNodeConstRef node);
|
|||||||
*/
|
*/
|
||||||
YG_EXPORT void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc);
|
YG_EXPORT void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make it so that this node will always form a containing block for any
|
||||||
|
* descendant nodes. This is useful for when a node has a property outside of
|
||||||
|
* of Yoga that will form a containing block. For example, transforms or some of
|
||||||
|
* the others listed in
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block
|
||||||
|
*/
|
||||||
|
YG_EXPORT void YGNodeSetAlwaysFormsContainingBlock(
|
||||||
|
YGNodeRef node,
|
||||||
|
bool alwaysFormsContainingBlock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a node to log output.
|
* Print a node to log output.
|
||||||
*/
|
*/
|
||||||
|
@@ -528,7 +528,9 @@ void layoutAbsoluteDescendants(
|
|||||||
if (needsTrailingPosition(crossAxis)) {
|
if (needsTrailingPosition(crossAxis)) {
|
||||||
setChildTrailingPosition(currentNode, child, crossAxis);
|
setChildTrailingPosition(currentNode, child, crossAxis);
|
||||||
}
|
}
|
||||||
} else if (child->getStyle().positionType() == PositionType::Static) {
|
} else if (
|
||||||
|
child->getStyle().positionType() == PositionType::Static &&
|
||||||
|
!child->alwaysFormsContainingBlock()) {
|
||||||
const Direction childDirection =
|
const Direction childDirection =
|
||||||
child->resolveDirection(currentNodeDirection);
|
child->resolveDirection(currentNodeDirection);
|
||||||
const float childMainOffsetFromContainingBlock =
|
const float childMainOffsetFromContainingBlock =
|
||||||
|
@@ -2034,7 +2034,7 @@ static void calculateLayoutImpl(
|
|||||||
// Let the containing block layout its absolute descendants. By definition
|
// Let the containing block layout its absolute descendants. By definition
|
||||||
// the containing block will not be static unless we are at the root.
|
// the containing block will not be static unless we are at the root.
|
||||||
if (node->getStyle().positionType() != PositionType::Static ||
|
if (node->getStyle().positionType() != PositionType::Static ||
|
||||||
depth == 1) {
|
node->alwaysFormsContainingBlock() || depth == 1) {
|
||||||
layoutAbsoluteDescendants(
|
layoutAbsoluteDescendants(
|
||||||
node,
|
node,
|
||||||
node,
|
node,
|
||||||
|
@@ -48,6 +48,10 @@ class YG_EXPORT Node : public ::YGNode {
|
|||||||
return context_;
|
return context_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool alwaysFormsContainingBlock() const {
|
||||||
|
return alwaysFormsContainingBlock_;
|
||||||
|
}
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
bool getHasNewLayout() const {
|
bool getHasNewLayout() const {
|
||||||
@@ -242,6 +246,10 @@ class YG_EXPORT Node : public ::YGNode {
|
|||||||
context_ = context;
|
context_ = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAlwaysFormsContainingBlock(bool alwaysFormsContainingBlock) {
|
||||||
|
alwaysFormsContainingBlock_ = alwaysFormsContainingBlock;
|
||||||
|
}
|
||||||
|
|
||||||
void setPrintFunc(YGPrintFunc printFunc) {
|
void setPrintFunc(YGPrintFunc printFunc) {
|
||||||
printFunc_ = printFunc;
|
printFunc_ = printFunc;
|
||||||
}
|
}
|
||||||
@@ -369,6 +377,7 @@ class YG_EXPORT Node : public ::YGNode {
|
|||||||
bool hasNewLayout_ : 1 = true;
|
bool hasNewLayout_ : 1 = true;
|
||||||
bool isReferenceBaseline_ : 1 = false;
|
bool isReferenceBaseline_ : 1 = false;
|
||||||
bool isDirty_ : 1 = false;
|
bool isDirty_ : 1 = false;
|
||||||
|
bool alwaysFormsContainingBlock_ : 1 = false;
|
||||||
NodeType nodeType_ : bitCount<NodeType>() = NodeType::Default;
|
NodeType nodeType_ : bitCount<NodeType>() = NodeType::Default;
|
||||||
void* context_ = nullptr;
|
void* context_ = nullptr;
|
||||||
YGMeasureFunc measureFunc_ = {nullptr};
|
YGMeasureFunc measureFunc_ = {nullptr};
|
||||||
|
Reference in New Issue
Block a user