Correctly size cross axis when measuring flex basis
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ a.out
|
||||
/lib/
|
||||
/node_modules/
|
||||
npm-debug.log
|
||||
TestResult.xml
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<!--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="14:42:41">
|
||||
<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">
|
||||
<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" />
|
||||
<test-suite name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" success="True" time="0.001" asserts="0">
|
||||
|
87
dist/css-layout.h
vendored
87
dist/css-layout.h
vendored
@@ -1032,56 +1032,61 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
|
||||
child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
|
||||
childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
|
||||
}
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
|
||||
childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
|
||||
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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
} else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!isUndefined(availableInnerWidth) &&
|
||||
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (!isUndefined(availableInnerCrossDim) &&
|
||||
!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) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
BIN
dist/css-layout.jar
vendored
BIN
dist/css-layout.jar
vendored
Binary file not shown.
87
dist/css-layout.js
vendored
87
dist/css-layout.js
vendored
@@ -795,56 +795,61 @@ var computeLayout = (function() {
|
||||
child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
|
||||
childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
|
||||
}
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
|
||||
childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
|
||||
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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
} else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!isUndefined(availableInnerWidth) &&
|
||||
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (!isUndefined(availableInnerCrossDim) &&
|
||||
!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) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
2
dist/css-layout.min.js
vendored
2
dist/css-layout.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/css-layout.min.js.map
vendored
2
dist/css-layout.min.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -90,23 +90,29 @@ css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, floa
|
||||
width = 1000000;
|
||||
}
|
||||
dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width);
|
||||
dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT;
|
||||
dim.dimensions[CSS_HEIGHT] = SMALL_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT;
|
||||
return dim;
|
||||
}
|
||||
if (strcmp(text, LONG_TEXT) == 0) {
|
||||
if (widthMode == CSS_MEASURE_MODE_UNDEFINED) {
|
||||
width = 1000000;
|
||||
}
|
||||
dim.dimensions[CSS_WIDTH] = width >= BIG_WIDTH ? BIG_WIDTH : fmaxf(BIG_MIN_WIDTH, width);
|
||||
dim.dimensions[CSS_HEIGHT] = width >= BIG_WIDTH ? SMALL_HEIGHT : BIG_HEIGHT;
|
||||
dim.dimensions[CSS_WIDTH] = fminf(BIG_WIDTH, width);
|
||||
dim.dimensions[CSS_HEIGHT] = BIG_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT;
|
||||
return dim;
|
||||
}
|
||||
|
||||
if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) {
|
||||
if (widthMode != CSS_MEASURE_MODE_UNDEFINED) {
|
||||
if (widthMode == CSS_MEASURE_MODE_EXACTLY) {
|
||||
dim.dimensions[CSS_WIDTH] = width;
|
||||
dim.dimensions[CSS_HEIGHT] = width * 2;
|
||||
} else if (heightMode != CSS_MEASURE_MODE_UNDEFINED) {
|
||||
} else if (heightMode == CSS_MEASURE_MODE_EXACTLY) {
|
||||
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_HEIGHT] = height;
|
||||
} else {
|
||||
|
@@ -548,15 +548,14 @@ var layoutTestUtils = (function() {
|
||||
if (text === texts.small) {
|
||||
return {
|
||||
width: Math.min(textSizes.smallWidth, width),
|
||||
height: textSizes.smallHeight
|
||||
height: textSizes.smallWidth > width ? textSizes.bigHeight : textSizes.smallHeight
|
||||
};
|
||||
}
|
||||
if (text === texts.big) {
|
||||
var res = {
|
||||
width: width >= textSizes.bigWidth ? textSizes.bigWidth : Math.max(textSizes.bigMinWidth, width),
|
||||
height: width >= textSizes.bigWidth ? textSizes.smallHeight : textSizes.bigHeight
|
||||
return {
|
||||
width: Math.min(textSizes.bigWidth, width),
|
||||
height: textSizes.bigWidth > width ? textSizes.bigHeight : textSizes.smallHeight
|
||||
};
|
||||
return res;
|
||||
}
|
||||
};
|
||||
// Name of the function is used in DOM tests as a text in the measured node
|
||||
@@ -566,9 +565,13 @@ var layoutTestUtils = (function() {
|
||||
},
|
||||
measureWithRatio2: function() {
|
||||
var fn = function(width, widthMode, height, heightMode) {
|
||||
if (widthMode !== 'undefined') {
|
||||
if (widthMode === 'exactly') {
|
||||
height = width * 2;
|
||||
} else if (heightMode !== 'undefined') {
|
||||
} else if (heightMode === 'exactly') {
|
||||
width = height * 2;
|
||||
} else if (widthMode === 'at-most') {
|
||||
height = width * 2;
|
||||
} else if (heightMode === 'at-most') {
|
||||
width = height * 2;
|
||||
} else {
|
||||
// This should be Infinity, but it would be pain to transpile,
|
||||
|
87
src/Layout.c
87
src/Layout.c
@@ -826,56 +826,61 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
|
||||
child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
|
||||
childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
|
||||
}
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
|
||||
childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
|
||||
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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
} else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!isUndefined(availableInnerWidth) &&
|
||||
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
|
||||
if (!isUndefined(availableInnerCrossDim) &&
|
||||
!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) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
@@ -776,56 +776,61 @@ var computeLayout = (function() {
|
||||
child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
|
||||
childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
|
||||
}
|
||||
if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
|
||||
childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
|
||||
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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childWidth = CSS_UNDEFINED;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
} else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {
|
||||
childHeight = CSS_UNDEFINED;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!isUndefined(availableInnerWidth) &&
|
||||
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {
|
||||
if (!isUndefined(availableInnerCrossDim) &&
|
||||
!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) &&
|
||||
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
|
||||
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
@@ -4140,7 +4140,7 @@ int main()
|
||||
node_0->layout.position[CSS_TOP] = 0;
|
||||
node_0->layout.position[CSS_LEFT] = 0;
|
||||
node_0->layout.dimensions[CSS_WIDTH] = 10;
|
||||
node_0->layout.dimensions[CSS_HEIGHT] = 18;
|
||||
node_0->layout.dimensions[CSS_HEIGHT] = 36;
|
||||
}
|
||||
|
||||
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->layout.position[CSS_TOP] = 0;
|
||||
node_2->layout.position[CSS_LEFT] = 0;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 100;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 60;
|
||||
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_END] = 20;
|
||||
node_2->measure = measure;
|
||||
node_2->context = "loooooooooong with space";
|
||||
node_2->context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4724,7 +4724,7 @@ int main()
|
||||
node_2 = node_1->get_child(node_1->context, 0);
|
||||
node_2->layout.position[CSS_TOP] = 20;
|
||||
node_2->layout.position[CSS_LEFT] = 20;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 172;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 35;
|
||||
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_END] = 20;
|
||||
node_2->measure = measure;
|
||||
node_2->context = "loooooooooong with space";
|
||||
node_2->context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4780,8 +4780,8 @@ int main()
|
||||
css_node_t *node_2;
|
||||
node_2 = node_1->get_child(node_1->context, 0);
|
||||
node_2->layout.position[CSS_TOP] = 20;
|
||||
node_2->layout.position[CSS_LEFT] = 8;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 172;
|
||||
node_2->layout.position[CSS_LEFT] = 145;
|
||||
node_2->layout.dimensions[CSS_WIDTH] = 35;
|
||||
node_2->layout.dimensions[CSS_HEIGHT] = 18;
|
||||
}
|
||||
}
|
||||
|
@@ -1403,7 +1403,7 @@ describe('Layout', function() {
|
||||
it('should layout node with text and width', function() {
|
||||
testLayout(
|
||||
{style: {measure: text(texts.small), width: 10}},
|
||||
{width: 10, height: textSizes.smallHeight, top: 0, left: 0}
|
||||
{width: 10, height: textSizes.bigHeight, top: 0, left: 0}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1508,10 +1508,8 @@ describe('Layout', function() {
|
||||
]}
|
||||
]},
|
||||
{width: 100, height: 40 + textSizes.bigHeight, top: 0, left: 0, children: [
|
||||
// In the flexbox engine implementation, min width of text is not supported so we max
|
||||
// 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}
|
||||
{width: 60, height: textSizes.bigHeight, top: 20, left: 20, children: [
|
||||
{width: 60, height: textSizes.bigHeight, top: 0, left: 0}
|
||||
]}
|
||||
]}
|
||||
);
|
||||
@@ -1569,12 +1567,12 @@ describe('Layout', function() {
|
||||
testLayout(
|
||||
{style: {}, children: [
|
||||
{style: {width: 200, flexDirection: 'row'}, children: [
|
||||
{style: {margin: 20, measure: text(texts.big)}}
|
||||
{style: {margin: 20, measure: text(texts.small)}}
|
||||
]}
|
||||
]},
|
||||
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
|
||||
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
|
||||
{width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 20}
|
||||
{width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 20}
|
||||
]}
|
||||
]}
|
||||
);
|
||||
@@ -1584,12 +1582,12 @@ describe('Layout', function() {
|
||||
testLayout(
|
||||
{style: { direction: 'rtl' }, children: [
|
||||
{style: {width: 200, flexDirection: 'row'}, children: [
|
||||
{style: {margin: 20, measure: text(texts.big)}}
|
||||
{style: {margin: 20, measure: text(texts.small)}}
|
||||
]}
|
||||
]},
|
||||
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
|
||||
{width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [
|
||||
{width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 8}
|
||||
{width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 200 - 20 - textSizes.smallWidth}
|
||||
]}
|
||||
]}
|
||||
);
|
||||
|
@@ -32,23 +32,36 @@ public class LayoutEngineTest
|
||||
if (widthMode == CSSMeasureMode.Undefined) {
|
||||
width = 10000000;
|
||||
}
|
||||
|
||||
float textHeight = TestConstants.SMALL_HEIGHT;
|
||||
if (TestConstants.SMALL_WIDTH > width) {
|
||||
textHeight = TestConstants.BIG_HEIGHT;
|
||||
}
|
||||
|
||||
return new MeasureOutput(
|
||||
Math.Min(width, TestConstants.SMALL_WIDTH),
|
||||
TestConstants.SMALL_HEIGHT);
|
||||
textHeight);
|
||||
} else if (testNode.context.Equals(TestConstants.LONG_TEXT)) {
|
||||
if (widthMode == CSSMeasureMode.Undefined) {
|
||||
width = 10000000;
|
||||
}
|
||||
return new MeasureOutput(width >= TestConstants.BIG_WIDTH
|
||||
? TestConstants.BIG_WIDTH
|
||||
: Math.Max(TestConstants.BIG_MIN_WIDTH, width),
|
||||
width >= TestConstants.BIG_WIDTH
|
||||
? TestConstants.SMALL_HEIGHT
|
||||
: TestConstants.BIG_HEIGHT);
|
||||
|
||||
float textHeight = TestConstants.SMALL_HEIGHT;
|
||||
if (TestConstants.BIG_WIDTH > width) {
|
||||
textHeight = TestConstants.BIG_HEIGHT;
|
||||
}
|
||||
|
||||
return new MeasureOutput(
|
||||
Math.Min(width, TestConstants.BIG_WIDTH),
|
||||
textHeight);
|
||||
} else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) {
|
||||
if (widthMode != CSSMeasureMode.Undefined) {
|
||||
if (widthMode == CSSMeasureMode.Exactly) {
|
||||
return new MeasureOutput(width, width * 2);
|
||||
} else if (heightMode != CSSMeasureMode.Undefined) {
|
||||
} else if (heightMode == CSSMeasureMode.Exactly) {
|
||||
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);
|
||||
} else {
|
||||
return new MeasureOutput(99999, 99999);
|
||||
@@ -4443,7 +4456,7 @@ public class LayoutEngineTest
|
||||
node_0.layout.position[POSITION_TOP] = 0;
|
||||
node_0.layout.position[POSITION_LEFT] = 0;
|
||||
node_0.layout.dimensions[DIMENSION_WIDTH] = 10;
|
||||
node_0.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
node_0.layout.dimensions[DIMENSION_HEIGHT] = 36;
|
||||
}
|
||||
|
||||
test("should layout node with text and width", root_node, root_layout);
|
||||
@@ -4831,7 +4844,7 @@ public class LayoutEngineTest
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 0;
|
||||
node_2.layout.position[POSITION_LEFT] = 0;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 100;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 60;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 36;
|
||||
}
|
||||
}
|
||||
@@ -5027,7 +5040,7 @@ public class LayoutEngineTest
|
||||
node_2.setMargin(Spacing.START, 20);
|
||||
node_2.setMargin(Spacing.END, 20);
|
||||
node_2.setMeasureFunction(sTestMeasureFunction);
|
||||
node_2.context = "loooooooooong with space";
|
||||
node_2.context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5053,7 +5066,7 @@ public class LayoutEngineTest
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 20;
|
||||
node_2.layout.position[POSITION_LEFT] = 20;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 35;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
}
|
||||
}
|
||||
@@ -5086,7 +5099,7 @@ public class LayoutEngineTest
|
||||
node_2.setMargin(Spacing.START, 20);
|
||||
node_2.setMargin(Spacing.END, 20);
|
||||
node_2.setMeasureFunction(sTestMeasureFunction);
|
||||
node_2.context = "loooooooooong with space";
|
||||
node_2.context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5111,8 +5124,8 @@ public class LayoutEngineTest
|
||||
TestCSSNode node_2;
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 20;
|
||||
node_2.layout.position[POSITION_LEFT] = 8;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
|
||||
node_2.layout.position[POSITION_LEFT] = 145;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 35;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
}
|
||||
}
|
||||
|
@@ -762,56 +762,61 @@ 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]))));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSSConstants.Undefined;
|
||||
childHeight = CSSConstants.Undefined;
|
||||
childWidthMeasureMode = CSSMeasureMode.Undefined;
|
||||
childHeightMeasureMode = CSSMeasureMode.Undefined;
|
||||
|
||||
if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
|
||||
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;
|
||||
}
|
||||
if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (node.style.overflow == CSSOverflow.Hidden) {
|
||||
if (isMainAxisRow && float.IsNaN(childHeight) && !float.IsNaN(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) {
|
||||
childWidth = CSSConstants.Undefined;
|
||||
childWidthMeasureMode = CSSMeasureMode.Undefined;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSSMeasureMode.AtMost;
|
||||
}
|
||||
} else if (node.style.overflow == CSSOverflow.Hidden) {
|
||||
if (heightMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) {
|
||||
childHeight = CSSConstants.Undefined;
|
||||
childHeightMeasureMode = CSSMeasureMode.Undefined;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSSMeasureMode.AtMost;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!float.IsNaN(availableInnerWidth) &&
|
||||
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
|
||||
widthMeasureMode == CSSMeasureMode.Exactly &&
|
||||
getAlignItem(node, child) == CSSAlign.Stretch) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (node.style.overflow == CSSOverflow.Hidden) {
|
||||
if (!float.IsNaN(availableInnerCrossDim) &&
|
||||
!(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) &&
|
||||
widthMeasureMode == CSSMeasureMode.Exactly &&
|
||||
getAlignItem(node, child) == CSSAlign.Stretch) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
@@ -723,56 +723,61 @@ 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]))));
|
||||
} else {
|
||||
|
||||
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
|
||||
childWidth = CSSConstants.UNDEFINED;
|
||||
childHeight = CSSConstants.UNDEFINED;
|
||||
childWidthMeasureMode = CSSMeasureMode.UNDEFINED;
|
||||
childHeightMeasureMode = CSSMeasureMode.UNDEFINED;
|
||||
|
||||
if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
|
||||
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;
|
||||
}
|
||||
if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// The W3C spec doesn't say anything about the 'overflow' property,
|
||||
// but all major browsers appear to implement the following logic.
|
||||
if (node.style.overflow == CSSOverflow.HIDDEN) {
|
||||
if (isMainAxisRow && Float.isNaN(childHeight) && !Float.isNaN(availableInnerHeight)) {
|
||||
childHeight = availableInnerHeight;
|
||||
// Main axis
|
||||
if (isMainAxisRow) {
|
||||
if (widthMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) {
|
||||
childWidth = CSSConstants.UNDEFINED;
|
||||
childWidthMeasureMode = CSSMeasureMode.UNDEFINED;
|
||||
} else {
|
||||
childWidth = availableInnerMainDim;
|
||||
childWidthMeasureMode = CSSMeasureMode.AT_MOST;
|
||||
}
|
||||
} else if (node.style.overflow == CSSOverflow.HIDDEN) {
|
||||
if (heightMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) {
|
||||
childHeight = CSSConstants.UNDEFINED;
|
||||
childHeightMeasureMode = CSSMeasureMode.UNDEFINED;
|
||||
} else {
|
||||
childHeight = availableInnerMainDim;
|
||||
childHeightMeasureMode = CSSMeasureMode.AT_MOST;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 &&
|
||||
!Float.isNaN(availableInnerWidth) &&
|
||||
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
|
||||
widthMeasureMode == CSSMeasureMode.EXACTLY &&
|
||||
getAlignItem(node, child) == CSSAlign.STRETCH) {
|
||||
childWidth = availableInnerWidth;
|
||||
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;
|
||||
// Cross axis
|
||||
if (isMainAxisRow) {
|
||||
if (node.style.overflow == CSSOverflow.HIDDEN) {
|
||||
if (!Float.isNaN(availableInnerCrossDim) &&
|
||||
!(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) &&
|
||||
widthMeasureMode == CSSMeasureMode.EXACTLY &&
|
||||
getAlignItem(node, child) == CSSAlign.STRETCH) {
|
||||
childWidth = availableInnerCrossDim;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measure the child
|
||||
|
@@ -34,20 +34,24 @@ public class LayoutEngineTest {
|
||||
width = 10000000;
|
||||
}
|
||||
measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH);
|
||||
measureOutput.height = TestConstants.SMALL_HEIGHT;
|
||||
measureOutput.height = TestConstants.SMALL_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT;
|
||||
} else if (testNode.context.equals(TestConstants.LONG_TEXT)) {
|
||||
if (widthMode == CSSMeasureMode.UNDEFINED) {
|
||||
width = 10000000;
|
||||
}
|
||||
measureOutput.width = width >= TestConstants.BIG_WIDTH ?
|
||||
TestConstants.BIG_WIDTH : Math.max(TestConstants.BIG_MIN_WIDTH, width);
|
||||
measureOutput.height = width >= TestConstants.BIG_WIDTH ?
|
||||
TestConstants.SMALL_HEIGHT : TestConstants.BIG_HEIGHT;
|
||||
measureOutput.width = Math.min(width, TestConstants.BIG_WIDTH);
|
||||
measureOutput.height = TestConstants.BIG_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT;
|
||||
} else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) {
|
||||
if (widthMode != CSSMeasureMode.UNDEFINED) {
|
||||
if (widthMode == CSSMeasureMode.EXACTLY) {
|
||||
measureOutput.width = width;
|
||||
measureOutput.height = width * 2;
|
||||
} else if (heightMode != CSSMeasureMode.UNDEFINED) {
|
||||
} else if (heightMode == CSSMeasureMode.EXACTLY) {
|
||||
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.height = height;
|
||||
} else {
|
||||
@@ -4446,7 +4450,7 @@ public class LayoutEngineTest {
|
||||
node_0.layout.position[POSITION_TOP] = 0;
|
||||
node_0.layout.position[POSITION_LEFT] = 0;
|
||||
node_0.layout.dimensions[DIMENSION_WIDTH] = 10;
|
||||
node_0.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
node_0.layout.dimensions[DIMENSION_HEIGHT] = 36;
|
||||
}
|
||||
|
||||
test("should layout node with text and width", root_node, root_layout);
|
||||
@@ -4834,7 +4838,7 @@ public class LayoutEngineTest {
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 0;
|
||||
node_2.layout.position[POSITION_LEFT] = 0;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 100;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 60;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 36;
|
||||
}
|
||||
}
|
||||
@@ -5030,7 +5034,7 @@ public class LayoutEngineTest {
|
||||
node_2.setMargin(Spacing.START, 20);
|
||||
node_2.setMargin(Spacing.END, 20);
|
||||
node_2.setMeasureFunction(sTestMeasureFunction);
|
||||
node_2.context = "loooooooooong with space";
|
||||
node_2.context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5056,7 +5060,7 @@ public class LayoutEngineTest {
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 20;
|
||||
node_2.layout.position[POSITION_LEFT] = 20;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 35;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
}
|
||||
}
|
||||
@@ -5089,7 +5093,7 @@ public class LayoutEngineTest {
|
||||
node_2.setMargin(Spacing.START, 20);
|
||||
node_2.setMargin(Spacing.END, 20);
|
||||
node_2.setMeasureFunction(sTestMeasureFunction);
|
||||
node_2.context = "loooooooooong with space";
|
||||
node_2.context = "small";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5114,8 +5118,8 @@ public class LayoutEngineTest {
|
||||
TestCSSNode node_2;
|
||||
node_2 = node_1.getChildAt(0);
|
||||
node_2.layout.position[POSITION_TOP] = 20;
|
||||
node_2.layout.position[POSITION_LEFT] = 8;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 172;
|
||||
node_2.layout.position[POSITION_LEFT] = 145;
|
||||
node_2.layout.dimensions[DIMENSION_WIDTH] = 35;
|
||||
node_2.layout.dimensions[DIMENSION_HEIGHT] = 18;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user