Skip to content

Commit 7459529

Browse files
joevilchesfacebook-github-bot
authored andcommitted
Introduce positionAbsoluteChild (#41491)
Summary: X-link: facebook/yoga#1473 Pull Request resolved: #41491 To simplify the logic a bit I introduce a new function called `positionAbsoluteChild`. This function will, eventually, be the **sole function that matters** when determining the layout position of an absolute node. Because [absolute nodes do not participate in flex layout](https://drafts.csswg.org/css-flexbox/#abspos-items), we can determine the position of said node independently of its siblings. The only information we need are the node itself, its parent, and its containing block - which we have all of in `layoutAbsoluteChild`. Right now, however, this is purely a BE change with no functionality different. There was a big set of if statements at the end of `layoutAbsoluteChild` that would position the node on the main and cross axis for certain cases. The old code had it so that the main and cross axis had basically the same logic but the code was repeated. This puts that logic, as is, in `positionAbsoluteChild` and calls that from `layoutAbsoluteChild`. I will soon edit this function to actually do what it is envisioned to do (i.e. be the sole place that position is set for absolute nodes). Reviewed By: NickGerleman Differential Revision: D51272855 fbshipit-source-id: 68fa1f0e0f4d595faf2af1d9eaceb467382ca406
1 parent a48e0d5 commit 7459529

File tree

1 file changed

+90
-88
lines changed

1 file changed

+90
-88
lines changed

packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp

Lines changed: 90 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,78 @@ static void computeFlexBasisForChild(
318318
child->setLayoutComputedFlexBasisGeneration(generationCount);
319319
}
320320

321+
/*
322+
* Absolutely positioned nodes do not participate in flex layout and thus their
323+
* positions can be determined independently from the rest of their siblings.
324+
* For each axis there are essentially two cases:
325+
*
326+
* 1) The node has insets defined. In this case we can just use these to
327+
* determine the position of the node.
328+
* 2) The node does not have insets defined. In this case we look at the style
329+
* of the parent to position the node. Things like justify content and
330+
* align content will move absolute children around. If none of these
331+
* special properties are defined, the child is positioned at the start
332+
* (defined by flex direction) of the leading flex line.
333+
*
334+
* This function does that positioning for the given axis. The spec has more
335+
* information on this topic: https://www.w3.org/TR/css-flexbox-1/#abspos-items
336+
*/
337+
static void positionAbsoluteChild(
338+
const yoga::Node* const containingNode,
339+
const yoga::Node* const parent,
340+
yoga::Node* child,
341+
const Direction direction,
342+
const FlexDirection axis,
343+
const bool isMainAxis,
344+
const float containingBlockWidth,
345+
const float containingBlockHeight) {
346+
const bool isAxisRow = isRow(axis);
347+
const bool shouldCenter = isMainAxis
348+
? parent->getStyle().justifyContent() == Justify::Center
349+
: resolveChildAlignment(parent, child) == Align::Center;
350+
const bool shouldFlexEnd = isMainAxis
351+
? parent->getStyle().justifyContent() == Justify::FlexEnd
352+
: ((resolveChildAlignment(parent, child) == Align::FlexEnd) ^
353+
(parent->getStyle().flexWrap() == Wrap::WrapReverse));
354+
355+
if (child->isFlexEndPositionDefined(axis) &&
356+
!child->isFlexStartPositionDefined(axis)) {
357+
child->setLayoutPosition(
358+
containingNode->getLayout().measuredDimension(dimension(axis)) -
359+
child->getLayout().measuredDimension(dimension(axis)) -
360+
containingNode->getFlexEndBorder(axis, direction) -
361+
child->getFlexEndMargin(
362+
axis,
363+
isAxisRow ? containingBlockWidth : containingBlockHeight) -
364+
child->getFlexEndPosition(
365+
axis, isAxisRow ? containingBlockWidth : containingBlockHeight),
366+
flexStartEdge(axis));
367+
} else if (!child->isFlexStartPositionDefined(axis) && shouldCenter) {
368+
child->setLayoutPosition(
369+
(parent->getLayout().measuredDimension(dimension(axis)) -
370+
child->getLayout().measuredDimension(dimension(axis))) /
371+
2.0f,
372+
flexStartEdge(axis));
373+
} else if (!child->isFlexStartPositionDefined(axis) && shouldFlexEnd) {
374+
child->setLayoutPosition(
375+
(parent->getLayout().measuredDimension(dimension(axis)) -
376+
child->getLayout().measuredDimension(dimension(axis))),
377+
flexStartEdge(axis));
378+
} else if (
379+
parent->getConfig()->isExperimentalFeatureEnabled(
380+
ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) &&
381+
child->isFlexStartPositionDefined(axis)) {
382+
child->setLayoutPosition(
383+
child->getFlexStartPosition(
384+
axis,
385+
containingNode->getLayout().measuredDimension(dimension(axis))) +
386+
containingNode->getFlexStartBorder(axis, direction) +
387+
child->getFlexStartMargin(
388+
axis, isAxisRow ? containingBlockWidth : containingBlockHeight),
389+
flexStartEdge(axis));
390+
}
391+
}
392+
321393
static void layoutAbsoluteChild(
322394
const yoga::Node* const containingNode,
323395
const yoga::Node* const node,
@@ -472,94 +544,24 @@ static void layoutAbsoluteChild(
472544
depth,
473545
generationCount);
474546

475-
if (child->isFlexEndPositionDefined(mainAxis) &&
476-
!child->isFlexStartPositionDefined(mainAxis)) {
477-
child->setLayoutPosition(
478-
containingNode->getLayout().measuredDimension(dimension(mainAxis)) -
479-
child->getLayout().measuredDimension(dimension(mainAxis)) -
480-
containingNode->getFlexEndBorder(mainAxis, direction) -
481-
child->getFlexEndMargin(
482-
mainAxis,
483-
isMainAxisRow ? containingBlockWidth : containingBlockHeight) -
484-
child->getFlexEndPosition(
485-
mainAxis,
486-
isMainAxisRow ? containingBlockWidth : containingBlockHeight),
487-
flexStartEdge(mainAxis));
488-
} else if (
489-
!child->isFlexStartPositionDefined(mainAxis) &&
490-
node->getStyle().justifyContent() == Justify::Center) {
491-
child->setLayoutPosition(
492-
(node->getLayout().measuredDimension(dimension(mainAxis)) -
493-
child->getLayout().measuredDimension(dimension(mainAxis))) /
494-
2.0f,
495-
flexStartEdge(mainAxis));
496-
} else if (
497-
!child->isFlexStartPositionDefined(mainAxis) &&
498-
node->getStyle().justifyContent() == Justify::FlexEnd) {
499-
child->setLayoutPosition(
500-
(node->getLayout().measuredDimension(dimension(mainAxis)) -
501-
child->getLayout().measuredDimension(dimension(mainAxis))),
502-
flexStartEdge(mainAxis));
503-
} else if (
504-
node->getConfig()->isExperimentalFeatureEnabled(
505-
ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) &&
506-
child->isFlexStartPositionDefined(mainAxis)) {
507-
child->setLayoutPosition(
508-
child->getFlexStartPosition(
509-
mainAxis,
510-
containingNode->getLayout().measuredDimension(
511-
dimension(mainAxis))) +
512-
containingNode->getFlexStartBorder(mainAxis, direction) +
513-
child->getFlexStartMargin(
514-
mainAxis,
515-
isMainAxisRow ? containingBlockWidth : containingBlockHeight),
516-
flexStartEdge(mainAxis));
517-
}
518-
519-
if (child->isFlexEndPositionDefined(crossAxis) &&
520-
!child->isFlexStartPositionDefined(crossAxis)) {
521-
child->setLayoutPosition(
522-
containingNode->getLayout().measuredDimension(dimension(crossAxis)) -
523-
child->getLayout().measuredDimension(dimension(crossAxis)) -
524-
containingNode->getFlexEndBorder(crossAxis, direction) -
525-
child->getFlexEndMargin(
526-
crossAxis,
527-
isMainAxisRow ? containingBlockHeight : containingBlockWidth) -
528-
child->getFlexEndPosition(
529-
crossAxis,
530-
isMainAxisRow ? containingBlockHeight : containingBlockWidth),
531-
flexStartEdge(crossAxis));
532-
} else if (
533-
!child->isFlexStartPositionDefined(crossAxis) &&
534-
resolveChildAlignment(node, child) == Align::Center) {
535-
child->setLayoutPosition(
536-
(node->getLayout().measuredDimension(dimension(crossAxis)) -
537-
child->getLayout().measuredDimension(dimension(crossAxis))) /
538-
2.0f,
539-
flexStartEdge(crossAxis));
540-
} else if (
541-
!child->isFlexStartPositionDefined(crossAxis) &&
542-
((resolveChildAlignment(node, child) == Align::FlexEnd) ^
543-
(node->getStyle().flexWrap() == Wrap::WrapReverse))) {
544-
child->setLayoutPosition(
545-
(node->getLayout().measuredDimension(dimension(crossAxis)) -
546-
child->getLayout().measuredDimension(dimension(crossAxis))),
547-
flexStartEdge(crossAxis));
548-
} else if (
549-
containingNode->getConfig()->isExperimentalFeatureEnabled(
550-
ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) &&
551-
child->isFlexStartPositionDefined(crossAxis)) {
552-
child->setLayoutPosition(
553-
child->getFlexStartPosition(
554-
crossAxis,
555-
containingNode->getLayout().measuredDimension(
556-
dimension(crossAxis))) +
557-
containingNode->getFlexStartBorder(crossAxis, direction) +
558-
child->getFlexStartMargin(
559-
crossAxis,
560-
isMainAxisRow ? containingBlockHeight : containingBlockWidth),
561-
flexStartEdge(crossAxis));
562-
}
547+
positionAbsoluteChild(
548+
containingNode,
549+
node,
550+
child,
551+
direction,
552+
mainAxis,
553+
true /*isMainAxis*/,
554+
containingBlockWidth,
555+
containingBlockHeight);
556+
positionAbsoluteChild(
557+
containingNode,
558+
node,
559+
child,
560+
direction,
561+
crossAxis,
562+
false /*isMainAxis*/,
563+
containingBlockWidth,
564+
containingBlockHeight);
563565
}
564566

565567
static void layoutAbsoluteDescendants(

0 commit comments

Comments
 (0)