diff --git a/src/Layout.c b/src/Layout.c index 069e52c3..fb2cf409 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -364,6 +364,25 @@ void layoutNode(css_node_t *node) { return; } + // Pre-fill cross axis dimensions when the child is using stretch before + // we call the recursive layout pass + for (int i = 0; i < node->children_count; ++i) { + css_node_t* child = &node->children[i]; + if (getAlignItem(node, child) == CSS_ALIGN_STRETCH && + getPositionType(child) == CSS_POSITION_RELATIVE && + !isUndefined(node->layout.dimensions[dim[crossAxis]]) && + !isDimDefined(child, crossAxis) && + !isPosDefined(child, leading[crossAxis])) { + child->layout.dimensions[dim[crossAxis]] = fmaxf( + node->layout.dimensions[dim[crossAxis]] - + getPaddingAndBorderAxis(node, crossAxis) - + getMarginAxis(child, crossAxis), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, crossAxis) + ); + } + } + // Layout non flexible children and count children by type // mainContentDim is accumulation of the dimensions and margin of all the diff --git a/src/Layout.js b/src/Layout.js index 48803b2a..4627a920 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -242,6 +242,25 @@ var computeLayout = (function() { return; } + // Pre-fill cross axis dimensions when the child is using stretch before + // we call the recursive layout pass + for (var/*int*/ i = 0; i < node.children.length; ++i) { + var/*css_node_t**/ child = node.children[i]; + if (getAlignItem(node, child) === CSS_ALIGN_STRETCH && + getPositionType(child) === CSS_POSITION_RELATIVE && + !isUndefined(node.layout[dim[crossAxis]]) && + !isDimDefined(child, crossAxis) && + !isPosDefined(child, leading[crossAxis])) { + child.layout[dim[crossAxis]] = fmaxf( + node.layout[dim[crossAxis]] - + getPaddingAndBorderAxis(node, crossAxis) - + getMarginAxis(child, crossAxis), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, crossAxis) + ); + } + } + // Layout non flexible children and count children by type // mainContentDim is accumulation of the dimensions and margin of all the diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index a21865eb..958c2937 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -2563,6 +2563,55 @@ int main() test("should layout node with text and position absolute", root_node, root_layout); } + { + css_node_t *root_node = new_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_WIDTH] = 300; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = &node_0->children[0]; + node_1->style.align_self = CSS_ALIGN_STRETCH; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = &node_1->children[0]; + node_2->style.align_self = CSS_ALIGN_STRETCH; + } + } + } + + css_node_t *root_layout = new_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = &node_0->children[0]; + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 300; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = &node_1->children[0]; + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 0; + node_2->layout.dimensions[CSS_WIDTH] = 300; + node_2->layout.dimensions[CSS_HEIGHT] = 0; + } + } + } + + test("should layout node with nested alignSelf: stretch", root_node, root_layout); + } + { css_node_t *root_node = new_css_node(); { diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 5134b66d..01f0ff65 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -777,7 +777,20 @@ describe('Layout', function() { ) }); - + it('should layout node with nested alignSelf: stretch', function() { + testLayout( + {style: {width: 300}, children: [ + {style: {alignSelf: 'stretch'}, children: [ + {style: {alignSelf: 'stretch'}} + ]} + ]}, + {width: 300, height: 0, top: 0, left: 0, children: [ + {width: 300, height: 0, top: 0, left: 0, children: [ + {width: 300, height: 0, top: 0, left: 0} + ]} + ]} + ); + }); it('should layout randomly', function() { function RNG(seed) {