mirror of
https://github.com/status-im/react-native.git
synced 2025-02-26 16:10:58 +00:00
Move flex basis calculation out into seperate function
Reviewed By: gkassabli Differential Revision: D4028328 fbshipit-source-id: 6d5f3bf1321077675eaa65408a70c9dc92a675be
This commit is contained in:
parent
d376155e2c
commit
72cd12ed13
@ -826,6 +826,111 @@ static void setPosition(const CSSNodeRef node, const CSSDirection direction) {
|
|||||||
getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis);
|
getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void computeChildFlexBasis(
|
||||||
|
const CSSNodeRef node,
|
||||||
|
const CSSNodeRef child,
|
||||||
|
const float width,
|
||||||
|
const CSSMeasureMode widthMode,
|
||||||
|
const float height,
|
||||||
|
const CSSMeasureMode heightMode,
|
||||||
|
const CSSDirection direction) {
|
||||||
|
|
||||||
|
const CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction);
|
||||||
|
const bool isMainAxisRow = isRowDirection(mainAxis);
|
||||||
|
|
||||||
|
float childWidth;
|
||||||
|
float childHeight;
|
||||||
|
CSSMeasureMode childWidthMeasureMode;
|
||||||
|
CSSMeasureMode childHeightMeasureMode;
|
||||||
|
|
||||||
|
if (isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow)) {
|
||||||
|
// The width is definite, so use that as the flex basis.
|
||||||
|
child->layout.computedFlexBasis =
|
||||||
|
fmaxf(child->style.dimensions[CSSDimensionWidth],
|
||||||
|
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||||
|
} else if (!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) {
|
||||||
|
// The height is definite, so use that as the flex basis.
|
||||||
|
child->layout.computedFlexBasis =
|
||||||
|
fmaxf(child->style.dimensions[CSSDimensionHeight],
|
||||||
|
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||||
|
} else if (!CSSValueIsUndefined(child->style.flexBasis) &&
|
||||||
|
!CSSValueIsUndefined(isMainAxisRow ? width : height)) {
|
||||||
|
if (CSSValueIsUndefined(child->layout.computedFlexBasis)) {
|
||||||
|
child->layout.computedFlexBasis =
|
||||||
|
fmaxf(child->style.flexBasis, getPaddingAndBorderAxis(child, mainAxis));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Compute the flex basis and hypothetical main size (i.e. the clamped
|
||||||
|
// flex basis).
|
||||||
|
childWidth = CSSUndefined;
|
||||||
|
childHeight = CSSUndefined;
|
||||||
|
childWidthMeasureMode = CSSMeasureModeUndefined;
|
||||||
|
childHeightMeasureMode = CSSMeasureModeUndefined;
|
||||||
|
|
||||||
|
if (isStyleDimDefined(child, CSSFlexDirectionRow)) {
|
||||||
|
childWidth = child->style.dimensions[CSSDimensionWidth] +
|
||||||
|
getMarginAxis(child, CSSFlexDirectionRow);
|
||||||
|
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||||
|
}
|
||||||
|
if (isStyleDimDefined(child, CSSFlexDirectionColumn)) {
|
||||||
|
childHeight = child->style.dimensions[CSSDimensionHeight] +
|
||||||
|
getMarginAxis(child, CSSFlexDirectionColumn);
|
||||||
|
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||||
|
// but all major browsers appear to implement the following logic.
|
||||||
|
if ((!isMainAxisRow && node->style.overflow == CSSOverflowScroll) ||
|
||||||
|
node->style.overflow != CSSOverflowScroll) {
|
||||||
|
if (CSSValueIsUndefined(childWidth) && !CSSValueIsUndefined(width)) {
|
||||||
|
childWidth = width;
|
||||||
|
childWidthMeasureMode = CSSMeasureModeAtMost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isMainAxisRow && node->style.overflow == CSSOverflowScroll) ||
|
||||||
|
node->style.overflow != CSSOverflowScroll) {
|
||||||
|
if (CSSValueIsUndefined(childHeight) && !CSSValueIsUndefined(height)) {
|
||||||
|
childHeight = height;
|
||||||
|
childHeightMeasureMode = CSSMeasureModeAtMost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If child has no defined size in the cross axis and is set to stretch,
|
||||||
|
// set the cross
|
||||||
|
// axis to be measured exactly with the available inner width
|
||||||
|
if (!isMainAxisRow && !CSSValueIsUndefined(width) &&
|
||||||
|
!isStyleDimDefined(child, CSSFlexDirectionRow) &&
|
||||||
|
widthMode == CSSMeasureModeExactly &&
|
||||||
|
getAlignItem(node, child) == CSSAlignStretch) {
|
||||||
|
childWidth = width;
|
||||||
|
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||||
|
}
|
||||||
|
if (isMainAxisRow && !CSSValueIsUndefined(height) &&
|
||||||
|
!isStyleDimDefined(child, CSSFlexDirectionColumn) &&
|
||||||
|
heightMode == CSSMeasureModeExactly &&
|
||||||
|
getAlignItem(node, child) == CSSAlignStretch) {
|
||||||
|
childHeight = height;
|
||||||
|
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Measure the child
|
||||||
|
layoutNodeInternal(child,
|
||||||
|
childWidth,
|
||||||
|
childHeight,
|
||||||
|
direction,
|
||||||
|
childWidthMeasureMode,
|
||||||
|
childHeightMeasureMode,
|
||||||
|
false,
|
||||||
|
"measure");
|
||||||
|
|
||||||
|
child->layout.computedFlexBasis =
|
||||||
|
fmaxf(isMainAxisRow ? child->layout.measuredDimensions[CSSDimensionWidth]
|
||||||
|
: child->layout.measuredDimensions[CSSDimensionHeight],
|
||||||
|
getPaddingAndBorderAxis(child, mainAxis));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is the main routine that implements a subset of the flexbox layout
|
// This is the main routine that implements a subset of the flexbox layout
|
||||||
// algorithm
|
// algorithm
|
||||||
@ -1101,10 +1206,6 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
|
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
|
||||||
|
|
||||||
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
|
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
|
||||||
float childWidth;
|
|
||||||
float childHeight;
|
|
||||||
CSSMeasureMode childWidthMeasureMode;
|
|
||||||
CSSMeasureMode childHeightMeasureMode;
|
|
||||||
for (uint32_t i = 0; i < childCount; i++) {
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
const CSSNodeRef child = CSSNodeListGet(node->children, i);
|
const CSSNodeRef child = CSSNodeListGet(node->children, i);
|
||||||
|
|
||||||
@ -1128,92 +1229,14 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
currentAbsoluteChild = child;
|
currentAbsoluteChild = child;
|
||||||
child->nextChild = NULL;
|
child->nextChild = NULL;
|
||||||
} else {
|
} else {
|
||||||
if (isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow)) {
|
computeChildFlexBasis(
|
||||||
// The width is definite, so use that as the flex basis.
|
node,
|
||||||
child->layout.computedFlexBasis =
|
child,
|
||||||
fmaxf(child->style.dimensions[CSSDimensionWidth],
|
availableInnerWidth,
|
||||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
widthMeasureMode,
|
||||||
} else if (!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) {
|
availableInnerHeight,
|
||||||
// The height is definite, so use that as the flex basis.
|
heightMeasureMode,
|
||||||
child->layout.computedFlexBasis =
|
direction);
|
||||||
fmaxf(child->style.dimensions[CSSDimensionHeight],
|
|
||||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
|
||||||
} else if (!CSSValueIsUndefined(child->style.flexBasis) &&
|
|
||||||
!CSSValueIsUndefined(availableInnerMainDim)) {
|
|
||||||
if (CSSValueIsUndefined(child->layout.computedFlexBasis)) {
|
|
||||||
child->layout.computedFlexBasis =
|
|
||||||
fmaxf(child->style.flexBasis, getPaddingAndBorderAxis(child, mainAxis));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Compute the flex basis and hypothetical main size (i.e. the clamped
|
|
||||||
// flex basis).
|
|
||||||
childWidth = CSSUndefined;
|
|
||||||
childHeight = CSSUndefined;
|
|
||||||
childWidthMeasureMode = CSSMeasureModeUndefined;
|
|
||||||
childHeightMeasureMode = CSSMeasureModeUndefined;
|
|
||||||
|
|
||||||
if (isStyleDimDefined(child, CSSFlexDirectionRow)) {
|
|
||||||
childWidth = child->style.dimensions[CSSDimensionWidth] +
|
|
||||||
getMarginAxis(child, CSSFlexDirectionRow);
|
|
||||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
|
||||||
}
|
|
||||||
if (isStyleDimDefined(child, CSSFlexDirectionColumn)) {
|
|
||||||
childHeight = child->style.dimensions[CSSDimensionHeight] +
|
|
||||||
getMarginAxis(child, CSSFlexDirectionColumn);
|
|
||||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
|
||||||
// but all major browsers appear to implement the following logic.
|
|
||||||
if ((!isMainAxisRow && node->style.overflow == CSSOverflowScroll) ||
|
|
||||||
node->style.overflow != CSSOverflowScroll) {
|
|
||||||
if (CSSValueIsUndefined(childWidth) && !CSSValueIsUndefined(availableInnerWidth)) {
|
|
||||||
childWidth = availableInnerWidth;
|
|
||||||
childWidthMeasureMode = CSSMeasureModeAtMost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((isMainAxisRow && node->style.overflow == CSSOverflowScroll) ||
|
|
||||||
node->style.overflow != CSSOverflowScroll) {
|
|
||||||
if (CSSValueIsUndefined(childHeight) && !CSSValueIsUndefined(availableInnerHeight)) {
|
|
||||||
childHeight = availableInnerHeight;
|
|
||||||
childHeightMeasureMode = CSSMeasureModeAtMost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If child has no defined size in the cross axis and is set to stretch,
|
|
||||||
// set the cross
|
|
||||||
// axis to be measured exactly with the available inner width
|
|
||||||
if (!isMainAxisRow && !CSSValueIsUndefined(availableInnerWidth) &&
|
|
||||||
!isStyleDimDefined(child, CSSFlexDirectionRow) &&
|
|
||||||
widthMeasureMode == CSSMeasureModeExactly &&
|
|
||||||
getAlignItem(node, child) == CSSAlignStretch) {
|
|
||||||
childWidth = availableInnerWidth;
|
|
||||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
|
||||||
}
|
|
||||||
if (isMainAxisRow && !CSSValueIsUndefined(availableInnerHeight) &&
|
|
||||||
!isStyleDimDefined(child, CSSFlexDirectionColumn) &&
|
|
||||||
heightMeasureMode == CSSMeasureModeExactly &&
|
|
||||||
getAlignItem(node, child) == CSSAlignStretch) {
|
|
||||||
childHeight = availableInnerHeight;
|
|
||||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Measure the child
|
|
||||||
layoutNodeInternal(child,
|
|
||||||
childWidth,
|
|
||||||
childHeight,
|
|
||||||
direction,
|
|
||||||
childWidthMeasureMode,
|
|
||||||
childHeightMeasureMode,
|
|
||||||
false,
|
|
||||||
"measure");
|
|
||||||
|
|
||||||
child->layout.computedFlexBasis =
|
|
||||||
fmaxf(isMainAxisRow ? child->layout.measuredDimensions[CSSDimensionWidth]
|
|
||||||
: child->layout.measuredDimensions[CSSDimensionHeight],
|
|
||||||
getPaddingAndBorderAxis(child, mainAxis));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,6 +1466,11 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
|
|
||||||
deltaFreeSpace -= updatedMainSize - childFlexBasis;
|
deltaFreeSpace -= updatedMainSize - childFlexBasis;
|
||||||
|
|
||||||
|
float childWidth;
|
||||||
|
float childHeight;
|
||||||
|
CSSMeasureMode childWidthMeasureMode;
|
||||||
|
CSSMeasureMode childHeightMeasureMode;
|
||||||
|
|
||||||
if (isMainAxisRow) {
|
if (isMainAxisRow) {
|
||||||
childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow);
|
childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow);
|
||||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||||
@ -1654,6 +1682,11 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
(isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) ||
|
(isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) ||
|
||||||
(!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow));
|
(!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow));
|
||||||
|
|
||||||
|
float childWidth;
|
||||||
|
float childHeight;
|
||||||
|
CSSMeasureMode childWidthMeasureMode;
|
||||||
|
CSSMeasureMode childHeightMeasureMode;
|
||||||
|
|
||||||
if (isMainAxisRow) {
|
if (isMainAxisRow) {
|
||||||
childHeight = crossDim;
|
childHeight = crossDim;
|
||||||
childWidth = child->layout.measuredDimensions[CSSDimensionWidth] +
|
childWidth = child->layout.measuredDimensions[CSSDimensionWidth] +
|
||||||
@ -1749,26 +1782,30 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
|
|
||||||
if (child->style.positionType == CSSPositionTypeRelative) {
|
if (child->style.positionType == CSSPositionTypeRelative) {
|
||||||
switch (getAlignItem(node, child)) {
|
switch (getAlignItem(node, child)) {
|
||||||
case CSSAlignFlexStart:
|
case CSSAlignFlexStart: {
|
||||||
child->layout.position[pos[crossAxis]] =
|
child->layout.position[pos[crossAxis]] =
|
||||||
currentLead + getLeadingMargin(child, crossAxis);
|
currentLead + getLeadingMargin(child, crossAxis);
|
||||||
break;
|
break;
|
||||||
case CSSAlignFlexEnd:
|
}
|
||||||
|
case CSSAlignFlexEnd: {
|
||||||
child->layout.position[pos[crossAxis]] =
|
child->layout.position[pos[crossAxis]] =
|
||||||
currentLead + lineHeight - getTrailingMargin(child, crossAxis) -
|
currentLead + lineHeight - getTrailingMargin(child, crossAxis) -
|
||||||
child->layout.measuredDimensions[dim[crossAxis]];
|
child->layout.measuredDimensions[dim[crossAxis]];
|
||||||
break;
|
break;
|
||||||
case CSSAlignCenter:
|
}
|
||||||
childHeight = child->layout.measuredDimensions[dim[crossAxis]];
|
case CSSAlignCenter: {
|
||||||
|
float childHeight = child->layout.measuredDimensions[dim[crossAxis]];
|
||||||
child->layout.position[pos[crossAxis]] =
|
child->layout.position[pos[crossAxis]] =
|
||||||
currentLead + (lineHeight - childHeight) / 2;
|
currentLead + (lineHeight - childHeight) / 2;
|
||||||
break;
|
break;
|
||||||
case CSSAlignStretch:
|
}
|
||||||
|
case CSSAlignStretch: {
|
||||||
child->layout.position[pos[crossAxis]] =
|
child->layout.position[pos[crossAxis]] =
|
||||||
currentLead + getLeadingMargin(child, crossAxis);
|
currentLead + getLeadingMargin(child, crossAxis);
|
||||||
// TODO(prenaux): Correctly set the height of items with indefinite
|
// TODO(prenaux): Correctly set the height of items with indefinite
|
||||||
// (auto) crossAxis dimension.
|
// (auto) crossAxis dimension.
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1819,8 +1856,10 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||||||
// Now that we know the bounds of the container, perform layout again on the
|
// Now that we know the bounds of the container, perform layout again on the
|
||||||
// absolutely-positioned children.
|
// absolutely-positioned children.
|
||||||
if (performLayout) {
|
if (performLayout) {
|
||||||
childWidth = CSSUndefined;
|
float childWidth = CSSUndefined;
|
||||||
childHeight = CSSUndefined;
|
float childHeight = CSSUndefined;
|
||||||
|
CSSMeasureMode childWidthMeasureMode = CSSMeasureModeUndefined;
|
||||||
|
CSSMeasureMode childHeightMeasureMode = CSSMeasureModeUndefined;
|
||||||
|
|
||||||
if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionRow)) {
|
if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionRow)) {
|
||||||
childWidth = currentAbsoluteChild->style.dimensions[CSSDimensionWidth] +
|
childWidth = currentAbsoluteChild->style.dimensions[CSSDimensionWidth] +
|
||||||
|
Loading…
x
Reference in New Issue
Block a user