@@ -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+
321393static 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
565567static void layoutAbsoluteDescendants (
0 commit comments