Revert "Correctly size cross axis when measuring flex basis"

This commit is contained in:
Emil Sjölander
2016-07-13 10:42:03 +01:00
committed by GitHub
parent 8b7f353746
commit 57874a1a9e
17 changed files with 307 additions and 362 deletions

1
.gitignore vendored
View File

@@ -5,4 +5,3 @@ a.out
/lib/ /lib/
/node_modules/ /node_modules/
npm-debug.log npm-debug.log
TestResult.xml

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--This file represents the results of running a test suite--> <!--This file represents the results of running a test suite-->
<test-results name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" total="0" failures="0" not-run="0" date="2016-07-08" time="16:05:12"> <test-results name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" total="0" failures="0" not-run="0" date="2016-07-08" time="14:42:41">
<environment nunit-version="2.4.8.0" clr-version="4.0.30319.17020" os-version="Unix 15.5.0.0" platform="Unix" cwd="/Volumes/Source/css-layout" machine-name="emilsj-pro" user="emilsj" user-domain="emilsj-pro" /> <environment nunit-version="2.4.8.0" clr-version="4.0.30319.17020" os-version="Unix 15.5.0.0" platform="Unix" cwd="/Volumes/Source/css-layout" machine-name="emilsj-pro" user="emilsj" user-domain="emilsj-pro" />
<culture-info current-culture="en-US" current-uiculture="en-US" /> <culture-info current-culture="en-US" current-uiculture="en-US" />
<test-suite name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" success="True" time="0.001" asserts="0"> <test-suite name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" success="True" time="0.001" asserts="0">

73
dist/css-layout.h vendored
View File

@@ -1032,61 +1032,56 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSS_UNDEFINED; childWidth = CSS_UNDEFINED;
childHeight = CSS_UNDEFINED; childHeight = CSS_UNDEFINED;
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
// Main axis if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
if (isMainAxisRow) { childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
childWidth = CSS_UNDEFINED; }
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
} else { childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childWidth = availableInnerMainDim; childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSS_UNDEFINED; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
} else { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { if (!isMainAxisRow &&
if (!isUndefined(availableInnerCrossDim) && !isUndefined(availableInnerWidth) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
}
} else {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) { getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
// Measure the child // Measure the child

BIN
dist/css-layout.jar vendored

Binary file not shown.

73
dist/css-layout.js vendored
View File

@@ -795,61 +795,56 @@ var computeLayout = (function() {
child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSS_UNDEFINED; childWidth = CSS_UNDEFINED;
childHeight = CSS_UNDEFINED; childHeight = CSS_UNDEFINED;
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
// Main axis if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
if (isMainAxisRow) { childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
childWidth = CSS_UNDEFINED; }
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
} else { childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childWidth = availableInnerMainDim; childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSS_UNDEFINED; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
} else { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { if (!isMainAxisRow &&
if (!isUndefined(availableInnerCrossDim) && !isUndefined(availableInnerWidth) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
}
} else {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) { getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
// Measure the child // Measure the child

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -90,29 +90,23 @@ css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, floa
width = 1000000; width = 1000000;
} }
dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width); dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width);
dim.dimensions[CSS_HEIGHT] = SMALL_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT;
return dim; return dim;
} }
if (strcmp(text, LONG_TEXT) == 0) { if (strcmp(text, LONG_TEXT) == 0) {
if (widthMode == CSS_MEASURE_MODE_UNDEFINED) { if (widthMode == CSS_MEASURE_MODE_UNDEFINED) {
width = 1000000; width = 1000000;
} }
dim.dimensions[CSS_WIDTH] = fminf(BIG_WIDTH, width); dim.dimensions[CSS_WIDTH] = width >= BIG_WIDTH ? BIG_WIDTH : fmaxf(BIG_MIN_WIDTH, width);
dim.dimensions[CSS_HEIGHT] = BIG_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; dim.dimensions[CSS_HEIGHT] = width >= BIG_WIDTH ? SMALL_HEIGHT : BIG_HEIGHT;
return dim; return dim;
} }
if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) { if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) {
if (widthMode == CSS_MEASURE_MODE_EXACTLY) { if (widthMode != CSS_MEASURE_MODE_UNDEFINED) {
dim.dimensions[CSS_WIDTH] = width; dim.dimensions[CSS_WIDTH] = width;
dim.dimensions[CSS_HEIGHT] = width * 2; dim.dimensions[CSS_HEIGHT] = width * 2;
} else if (heightMode == CSS_MEASURE_MODE_EXACTLY) { } else if (heightMode != CSS_MEASURE_MODE_UNDEFINED) {
dim.dimensions[CSS_WIDTH] = height * 2;
dim.dimensions[CSS_HEIGHT] = height;
} else if (widthMode == CSS_MEASURE_MODE_AT_MOST) {
dim.dimensions[CSS_WIDTH] = width;
dim.dimensions[CSS_HEIGHT] = width * 2;
} else if (heightMode == CSS_MEASURE_MODE_AT_MOST) {
dim.dimensions[CSS_WIDTH] = height * 2; dim.dimensions[CSS_WIDTH] = height * 2;
dim.dimensions[CSS_HEIGHT] = height; dim.dimensions[CSS_HEIGHT] = height;
} else { } else {

View File

@@ -548,14 +548,15 @@ var layoutTestUtils = (function() {
if (text === texts.small) { if (text === texts.small) {
return { return {
width: Math.min(textSizes.smallWidth, width), width: Math.min(textSizes.smallWidth, width),
height: textSizes.smallWidth > width ? textSizes.bigHeight : textSizes.smallHeight height: textSizes.smallHeight
}; };
} }
if (text === texts.big) { if (text === texts.big) {
return { var res = {
width: Math.min(textSizes.bigWidth, width), width: width >= textSizes.bigWidth ? textSizes.bigWidth : Math.max(textSizes.bigMinWidth, width),
height: textSizes.bigWidth > width ? textSizes.bigHeight : textSizes.smallHeight height: width >= textSizes.bigWidth ? textSizes.smallHeight : textSizes.bigHeight
}; };
return res;
} }
}; };
// Name of the function is used in DOM tests as a text in the measured node // Name of the function is used in DOM tests as a text in the measured node
@@ -565,13 +566,9 @@ var layoutTestUtils = (function() {
}, },
measureWithRatio2: function() { measureWithRatio2: function() {
var fn = function(width, widthMode, height, heightMode) { var fn = function(width, widthMode, height, heightMode) {
if (widthMode === 'exactly') { if (widthMode !== 'undefined') {
height = width * 2; height = width * 2;
} else if (heightMode === 'exactly') { } else if (heightMode !== 'undefined') {
width = height * 2;
} else if (widthMode === 'at-most') {
height = width * 2;
} else if (heightMode === 'at-most') {
width = height * 2; width = height * 2;
} else { } else {
// This should be Infinity, but it would be pain to transpile, // This should be Infinity, but it would be pain to transpile,

View File

@@ -826,61 +826,56 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSS_UNDEFINED; childWidth = CSS_UNDEFINED;
childHeight = CSS_UNDEFINED; childHeight = CSS_UNDEFINED;
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
// Main axis if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
if (isMainAxisRow) { childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
childWidth = CSS_UNDEFINED; }
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
} else { childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childWidth = availableInnerMainDim; childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSS_UNDEFINED; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
} else { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { if (!isMainAxisRow &&
if (!isUndefined(availableInnerCrossDim) && !isUndefined(availableInnerWidth) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
}
} else {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) { getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
// Measure the child // Measure the child

View File

@@ -776,61 +776,56 @@ var computeLayout = (function() {
child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSS_UNDEFINED; childWidth = CSS_UNDEFINED;
childHeight = CSS_UNDEFINED; childHeight = CSS_UNDEFINED;
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
// Main axis if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
if (isMainAxisRow) { childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
childWidth = CSS_UNDEFINED; }
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
} else { childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childWidth = availableInnerMainDim; childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSS_UNDEFINED; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
} else { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { if (!isMainAxisRow &&
if (!isUndefined(availableInnerCrossDim) && !isUndefined(availableInnerWidth) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
}
} else {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) { getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} }
// Measure the child // Measure the child

View File

@@ -4140,7 +4140,7 @@ int main()
node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_TOP] = 0;
node_0->layout.position[CSS_LEFT] = 0; node_0->layout.position[CSS_LEFT] = 0;
node_0->layout.dimensions[CSS_WIDTH] = 10; node_0->layout.dimensions[CSS_WIDTH] = 10;
node_0->layout.dimensions[CSS_HEIGHT] = 36; node_0->layout.dimensions[CSS_HEIGHT] = 18;
} }
test("should layout node with text and width", root_node, root_layout); test("should layout node with text and width", root_node, root_layout);
@@ -4512,7 +4512,7 @@ int main()
node_2 = node_1->get_child(node_1->context, 0); node_2 = node_1->get_child(node_1->context, 0);
node_2->layout.position[CSS_TOP] = 0; node_2->layout.position[CSS_TOP] = 0;
node_2->layout.position[CSS_LEFT] = 0; node_2->layout.position[CSS_LEFT] = 0;
node_2->layout.dimensions[CSS_WIDTH] = 60; node_2->layout.dimensions[CSS_WIDTH] = 100;
node_2->layout.dimensions[CSS_HEIGHT] = 36; node_2->layout.dimensions[CSS_HEIGHT] = 36;
} }
} }
@@ -4698,7 +4698,7 @@ int main()
node_2->style.margin[CSS_START] = 20; node_2->style.margin[CSS_START] = 20;
node_2->style.margin[CSS_END] = 20; node_2->style.margin[CSS_END] = 20;
node_2->measure = measure; node_2->measure = measure;
node_2->context = "small"; node_2->context = "loooooooooong with space";
} }
} }
} }
@@ -4724,7 +4724,7 @@ int main()
node_2 = node_1->get_child(node_1->context, 0); node_2 = node_1->get_child(node_1->context, 0);
node_2->layout.position[CSS_TOP] = 20; node_2->layout.position[CSS_TOP] = 20;
node_2->layout.position[CSS_LEFT] = 20; node_2->layout.position[CSS_LEFT] = 20;
node_2->layout.dimensions[CSS_WIDTH] = 35; node_2->layout.dimensions[CSS_WIDTH] = 172;
node_2->layout.dimensions[CSS_HEIGHT] = 18; node_2->layout.dimensions[CSS_HEIGHT] = 18;
} }
} }
@@ -4755,7 +4755,7 @@ int main()
node_2->style.margin[CSS_START] = 20; node_2->style.margin[CSS_START] = 20;
node_2->style.margin[CSS_END] = 20; node_2->style.margin[CSS_END] = 20;
node_2->measure = measure; node_2->measure = measure;
node_2->context = "small"; node_2->context = "loooooooooong with space";
} }
} }
} }
@@ -4780,8 +4780,8 @@ int main()
css_node_t *node_2; css_node_t *node_2;
node_2 = node_1->get_child(node_1->context, 0); node_2 = node_1->get_child(node_1->context, 0);
node_2->layout.position[CSS_TOP] = 20; node_2->layout.position[CSS_TOP] = 20;
node_2->layout.position[CSS_LEFT] = 145; node_2->layout.position[CSS_LEFT] = 8;
node_2->layout.dimensions[CSS_WIDTH] = 35; node_2->layout.dimensions[CSS_WIDTH] = 172;
node_2->layout.dimensions[CSS_HEIGHT] = 18; node_2->layout.dimensions[CSS_HEIGHT] = 18;
} }
} }

View File

@@ -1403,7 +1403,7 @@ describe('Layout', function() {
it('should layout node with text and width', function() { it('should layout node with text and width', function() {
testLayout( testLayout(
{style: {measure: text(texts.small), width: 10}}, {style: {measure: text(texts.small), width: 10}},
{width: 10, height: textSizes.bigHeight, top: 0, left: 0} {width: 10, height: textSizes.smallHeight, top: 0, left: 0}
); );
}); });
@@ -1508,8 +1508,10 @@ describe('Layout', function() {
]} ]}
]}, ]},
{width: 100, height: 40 + textSizes.bigHeight, top: 0, left: 0, children: [ {width: 100, height: 40 + textSizes.bigHeight, top: 0, left: 0, children: [
{width: 60, height: textSizes.bigHeight, top: 20, left: 20, children: [ // In the flexbox engine implementation, min width of text is not supported so we max
{width: 60, height: textSizes.bigHeight, top: 0, left: 0} // out at the amount of available space (60)
{width: Math.min(60, textSizes.bigMinWidth), height: textSizes.bigHeight, top: 20, left: 20, children: [
{width: textSizes.bigMinWidth, height: textSizes.bigHeight, top: 0, left: 0}
]} ]}
]} ]}
); );
@@ -1567,12 +1569,12 @@ describe('Layout', function() {
testLayout( testLayout(
{style: {}, children: [ {style: {}, children: [
{style: {width: 200, flexDirection: 'row'}, children: [ {style: {width: 200, flexDirection: 'row'}, children: [
{style: {margin: 20, measure: text(texts.small)}} {style: {margin: 20, measure: text(texts.big)}}
]} ]}
]}, ]},
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
{width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 20} {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 20}
]} ]}
]} ]}
); );
@@ -1582,12 +1584,12 @@ describe('Layout', function() {
testLayout( testLayout(
{style: { direction: 'rtl' }, children: [ {style: { direction: 'rtl' }, children: [
{style: {width: 200, flexDirection: 'row'}, children: [ {style: {width: 200, flexDirection: 'row'}, children: [
{style: {margin: 20, measure: text(texts.small)}} {style: {margin: 20, measure: text(texts.big)}}
]} ]}
]}, ]},
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
{width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 200 - 20 - textSizes.smallWidth} {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 8}
]} ]}
]} ]}
); );

View File

@@ -32,36 +32,23 @@ public class LayoutEngineTest
if (widthMode == CSSMeasureMode.Undefined) { if (widthMode == CSSMeasureMode.Undefined) {
width = 10000000; width = 10000000;
} }
float textHeight = TestConstants.SMALL_HEIGHT;
if (TestConstants.SMALL_WIDTH > width) {
textHeight = TestConstants.BIG_HEIGHT;
}
return new MeasureOutput( return new MeasureOutput(
Math.Min(width, TestConstants.SMALL_WIDTH), Math.Min(width, TestConstants.SMALL_WIDTH),
textHeight); TestConstants.SMALL_HEIGHT);
} else if (testNode.context.Equals(TestConstants.LONG_TEXT)) { } else if (testNode.context.Equals(TestConstants.LONG_TEXT)) {
if (widthMode == CSSMeasureMode.Undefined) { if (widthMode == CSSMeasureMode.Undefined) {
width = 10000000; width = 10000000;
} }
return new MeasureOutput(width >= TestConstants.BIG_WIDTH
float textHeight = TestConstants.SMALL_HEIGHT; ? TestConstants.BIG_WIDTH
if (TestConstants.BIG_WIDTH > width) { : Math.Max(TestConstants.BIG_MIN_WIDTH, width),
textHeight = TestConstants.BIG_HEIGHT; width >= TestConstants.BIG_WIDTH
} ? TestConstants.SMALL_HEIGHT
: TestConstants.BIG_HEIGHT);
return new MeasureOutput(
Math.Min(width, TestConstants.BIG_WIDTH),
textHeight);
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) { } else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) {
if (widthMode == CSSMeasureMode.Exactly) { if (widthMode != CSSMeasureMode.Undefined) {
return new MeasureOutput(width, width * 2); return new MeasureOutput(width, width * 2);
} else if (heightMode == CSSMeasureMode.Exactly) { } else if (heightMode != CSSMeasureMode.Undefined) {
return new MeasureOutput(height * 2, height);
} else if (widthMode == CSSMeasureMode.AtMost) {
return new MeasureOutput(width, width * 2);
} else if (heightMode == CSSMeasureMode.AtMost) {
return new MeasureOutput(height * 2, height); return new MeasureOutput(height * 2, height);
} else { } else {
return new MeasureOutput(99999, 99999); return new MeasureOutput(99999, 99999);
@@ -4456,7 +4443,7 @@ public class LayoutEngineTest
node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_TOP] = 0;
node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.position[POSITION_LEFT] = 0;
node_0.layout.dimensions[DIMENSION_WIDTH] = 10; node_0.layout.dimensions[DIMENSION_WIDTH] = 10;
node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; node_0.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
test("should layout node with text and width", root_node, root_layout); test("should layout node with text and width", root_node, root_layout);
@@ -4844,7 +4831,7 @@ public class LayoutEngineTest
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_TOP] = 0;
node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.position[POSITION_LEFT] = 0;
node_2.layout.dimensions[DIMENSION_WIDTH] = 60; node_2.layout.dimensions[DIMENSION_WIDTH] = 100;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; node_2.layout.dimensions[DIMENSION_HEIGHT] = 36;
} }
} }
@@ -5040,7 +5027,7 @@ public class LayoutEngineTest
node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.START, 20);
node_2.setMargin(Spacing.END, 20); node_2.setMargin(Spacing.END, 20);
node_2.setMeasureFunction(sTestMeasureFunction); node_2.setMeasureFunction(sTestMeasureFunction);
node_2.context = "small"; node_2.context = "loooooooooong with space";
} }
} }
} }
@@ -5066,7 +5053,7 @@ public class LayoutEngineTest
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_TOP] = 20;
node_2.layout.position[POSITION_LEFT] = 20; node_2.layout.position[POSITION_LEFT] = 20;
node_2.layout.dimensions[DIMENSION_WIDTH] = 35; node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
} }
@@ -5099,7 +5086,7 @@ public class LayoutEngineTest
node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.START, 20);
node_2.setMargin(Spacing.END, 20); node_2.setMargin(Spacing.END, 20);
node_2.setMeasureFunction(sTestMeasureFunction); node_2.setMeasureFunction(sTestMeasureFunction);
node_2.context = "small"; node_2.context = "loooooooooong with space";
} }
} }
} }
@@ -5124,8 +5111,8 @@ public class LayoutEngineTest
TestCSSNode node_2; TestCSSNode node_2;
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_TOP] = 20;
node_2.layout.position[POSITION_LEFT] = 145; node_2.layout.position[POSITION_LEFT] = 8;
node_2.layout.dimensions[DIMENSION_WIDTH] = 35; node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
} }

View File

@@ -762,61 +762,56 @@ namespace Facebook.CSSLayout
child.layout.flexBasis = Math.Max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); child.layout.flexBasis = Math.Max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]))));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSSConstants.Undefined; childWidth = CSSConstants.Undefined;
childHeight = CSSConstants.Undefined; childHeight = CSSConstants.Undefined;
childWidthMeasureMode = CSSMeasureMode.Undefined; childWidthMeasureMode = CSSMeasureMode.Undefined;
childHeightMeasureMode = CSSMeasureMode.Undefined; childHeightMeasureMode = CSSMeasureMode.Undefined;
// Main axis if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
if (isMainAxisRow) { childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]));
if (widthMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) { childWidthMeasureMode = CSSMeasureMode.Exactly;
childWidth = CSSConstants.Undefined; }
childWidthMeasureMode = CSSMeasureMode.Undefined; if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
} else { childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]));
childWidth = availableInnerMainDim; childHeightMeasureMode = CSSMeasureMode.Exactly;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && float.IsNaN(childWidth) && !float.IsNaN(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSSMeasureMode.AtMost; childWidthMeasureMode = CSSMeasureMode.AtMost;
} }
} else if (node.style.overflow == CSSOverflow.Hidden) {
if (heightMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSSConstants.Undefined; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSSMeasureMode.Undefined; if (node.style.overflow == CSSOverflow.Hidden) {
} else { if (isMainAxisRow && float.IsNaN(childHeight) && !float.IsNaN(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSSMeasureMode.AtMost; childHeightMeasureMode = CSSMeasureMode.AtMost;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (node.style.overflow == CSSOverflow.Hidden) { if (!isMainAxisRow &&
if (!float.IsNaN(availableInnerCrossDim) && !float.IsNaN(availableInnerWidth) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.Exactly &&
getAlignItem(node, child) == CSSAlign.Stretch) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSSMeasureMode.Exactly;
} else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = float.IsNaN(childHeight) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost;
} else {
childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]));
childHeightMeasureMode = CSSMeasureMode.Exactly;
}
}
} else {
if (!float.IsNaN(availableInnerCrossDim) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
widthMeasureMode == CSSMeasureMode.Exactly && widthMeasureMode == CSSMeasureMode.Exactly &&
getAlignItem(node, child) == CSSAlign.Stretch) { getAlignItem(node, child) == CSSAlign.Stretch) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSSMeasureMode.Exactly;
} else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = float.IsNaN(childWidth) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost;
} else {
childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]));
childWidthMeasureMode = CSSMeasureMode.Exactly; childWidthMeasureMode = CSSMeasureMode.Exactly;
} }
if (isMainAxisRow &&
!float.IsNaN(availableInnerHeight) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.Exactly &&
getAlignItem(node, child) == CSSAlign.Stretch) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSSMeasureMode.Exactly;
} }
// Measure the child // Measure the child

View File

@@ -723,61 +723,56 @@ public class LayoutEngine {
child.layout.flexBasis = Math.max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); child.layout.flexBasis = Math.max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]))));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
childWidth = CSSConstants.UNDEFINED; childWidth = CSSConstants.UNDEFINED;
childHeight = CSSConstants.UNDEFINED; childHeight = CSSConstants.UNDEFINED;
childWidthMeasureMode = CSSMeasureMode.UNDEFINED; childWidthMeasureMode = CSSMeasureMode.UNDEFINED;
childHeightMeasureMode = CSSMeasureMode.UNDEFINED; childHeightMeasureMode = CSSMeasureMode.UNDEFINED;
// Main axis if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
if (isMainAxisRow) { childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]));
if (widthMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) { childWidthMeasureMode = CSSMeasureMode.EXACTLY;
childWidth = CSSConstants.UNDEFINED; }
childWidthMeasureMode = CSSMeasureMode.UNDEFINED; if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
} else { childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]));
childWidth = availableInnerMainDim; childHeightMeasureMode = CSSMeasureMode.EXACTLY;
}
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
// horizontal), the child should be sized using "UNDEFINED" in
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && Float.isNaN(childWidth) && !Float.isNaN(availableInnerWidth)) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSSMeasureMode.AT_MOST; childWidthMeasureMode = CSSMeasureMode.AT_MOST;
} }
} else if (node.style.overflow == CSSOverflow.HIDDEN) {
if (heightMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) { // The W3C spec doesn't say anything about the 'overflow' property,
childHeight = CSSConstants.UNDEFINED; // but all major browsers appear to implement the following logic.
childHeightMeasureMode = CSSMeasureMode.UNDEFINED; if (node.style.overflow == CSSOverflow.HIDDEN) {
} else { if (isMainAxisRow && Float.isNaN(childHeight) && !Float.isNaN(availableInnerHeight)) {
childHeight = availableInnerMainDim; childHeight = availableInnerHeight;
childHeightMeasureMode = CSSMeasureMode.AT_MOST; childHeightMeasureMode = CSSMeasureMode.AT_MOST;
} }
} }
// Cross axis // If child has no defined size in the cross axis and is set to stretch, set the cross
if (isMainAxisRow) { // axis to be measured exactly with the available inner width
if (node.style.overflow == CSSOverflow.HIDDEN) { if (!isMainAxisRow &&
if (!Float.isNaN(availableInnerCrossDim) && !Float.isNaN(availableInnerWidth) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, child) == CSSAlign.STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
} else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = Float.isNaN(childHeight) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST;
} else {
childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]));
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
}
}
} else {
if (!Float.isNaN(availableInnerCrossDim) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
widthMeasureMode == CSSMeasureMode.EXACTLY && widthMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, child) == CSSAlign.STRETCH) { getAlignItem(node, child) == CSSAlign.STRETCH) {
childWidth = availableInnerCrossDim; childWidth = availableInnerWidth;
childWidthMeasureMode = CSSMeasureMode.EXACTLY;
} else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = Float.isNaN(childWidth) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST;
} else {
childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]));
childWidthMeasureMode = CSSMeasureMode.EXACTLY; childWidthMeasureMode = CSSMeasureMode.EXACTLY;
} }
if (isMainAxisRow &&
!Float.isNaN(availableInnerHeight) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, child) == CSSAlign.STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
} }
// Measure the child // Measure the child

View File

@@ -34,24 +34,20 @@ public class LayoutEngineTest {
width = 10000000; width = 10000000;
} }
measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH); measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH);
measureOutput.height = TestConstants.SMALL_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; measureOutput.height = TestConstants.SMALL_HEIGHT;
} else if (testNode.context.equals(TestConstants.LONG_TEXT)) { } else if (testNode.context.equals(TestConstants.LONG_TEXT)) {
if (widthMode == CSSMeasureMode.UNDEFINED) { if (widthMode == CSSMeasureMode.UNDEFINED) {
width = 10000000; width = 10000000;
} }
measureOutput.width = Math.min(width, TestConstants.BIG_WIDTH); measureOutput.width = width >= TestConstants.BIG_WIDTH ?
measureOutput.height = TestConstants.BIG_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; TestConstants.BIG_WIDTH : Math.max(TestConstants.BIG_MIN_WIDTH, width);
measureOutput.height = width >= TestConstants.BIG_WIDTH ?
TestConstants.SMALL_HEIGHT : TestConstants.BIG_HEIGHT;
} else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) { } else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) {
if (widthMode == CSSMeasureMode.EXACTLY) { if (widthMode != CSSMeasureMode.UNDEFINED) {
measureOutput.width = width; measureOutput.width = width;
measureOutput.height = width * 2; measureOutput.height = width * 2;
} else if (heightMode == CSSMeasureMode.EXACTLY) { } else if (heightMode != CSSMeasureMode.UNDEFINED) {
measureOutput.width = height * 2;
measureOutput.height = height;
} else if (widthMode == CSSMeasureMode.AT_MOST) {
measureOutput.width = width;
measureOutput.height = width * 2;
} else if (heightMode == CSSMeasureMode.AT_MOST) {
measureOutput.width = height * 2; measureOutput.width = height * 2;
measureOutput.height = height; measureOutput.height = height;
} else { } else {
@@ -4450,7 +4446,7 @@ public class LayoutEngineTest {
node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_TOP] = 0;
node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.position[POSITION_LEFT] = 0;
node_0.layout.dimensions[DIMENSION_WIDTH] = 10; node_0.layout.dimensions[DIMENSION_WIDTH] = 10;
node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; node_0.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
test("should layout node with text and width", root_node, root_layout); test("should layout node with text and width", root_node, root_layout);
@@ -4838,7 +4834,7 @@ public class LayoutEngineTest {
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_TOP] = 0;
node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.position[POSITION_LEFT] = 0;
node_2.layout.dimensions[DIMENSION_WIDTH] = 60; node_2.layout.dimensions[DIMENSION_WIDTH] = 100;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; node_2.layout.dimensions[DIMENSION_HEIGHT] = 36;
} }
} }
@@ -5034,7 +5030,7 @@ public class LayoutEngineTest {
node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.START, 20);
node_2.setMargin(Spacing.END, 20); node_2.setMargin(Spacing.END, 20);
node_2.setMeasureFunction(sTestMeasureFunction); node_2.setMeasureFunction(sTestMeasureFunction);
node_2.context = "small"; node_2.context = "loooooooooong with space";
} }
} }
} }
@@ -5060,7 +5056,7 @@ public class LayoutEngineTest {
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_TOP] = 20;
node_2.layout.position[POSITION_LEFT] = 20; node_2.layout.position[POSITION_LEFT] = 20;
node_2.layout.dimensions[DIMENSION_WIDTH] = 35; node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
} }
@@ -5093,7 +5089,7 @@ public class LayoutEngineTest {
node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.START, 20);
node_2.setMargin(Spacing.END, 20); node_2.setMargin(Spacing.END, 20);
node_2.setMeasureFunction(sTestMeasureFunction); node_2.setMeasureFunction(sTestMeasureFunction);
node_2.context = "small"; node_2.context = "loooooooooong with space";
} }
} }
} }
@@ -5118,8 +5114,8 @@ public class LayoutEngineTest {
TestCSSNode node_2; TestCSSNode node_2;
node_2 = node_1.getChildAt(0); node_2 = node_1.getChildAt(0);
node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_TOP] = 20;
node_2.layout.position[POSITION_LEFT] = 145; node_2.layout.position[POSITION_LEFT] = 8;
node_2.layout.dimensions[DIMENSION_WIDTH] = 35; node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
} }
} }