diff --git a/src/Layout.c b/src/Layout.c index 7f991790..6118b2e6 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -691,6 +691,16 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { ); } } + for (int ii = 0; ii < 2; ii++) { + css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + if (isPosDefined(child, trailing[axis]) && + !isPosDefined(child, leading[axis])) { + child->layout.position[leading[axis]] = + node->layout.dimensions[dim[axis]] - + child->layout.dimensions[dim[axis]] - + getPosition(child, trailing[axis]); + } + } } } /** END_GENERATED **/ diff --git a/src/Layout.js b/src/Layout.js index 16c567a2..cf229c72 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -566,6 +566,16 @@ var computeLayout = (function() { ); } } + for (var/*int*/ ii = 0; ii < 2; ii++) { + var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + if (isPosDefined(child, trailing[axis]) && + !isPosDefined(child, leading[axis])) { + child.layout[leading[axis]] = + node.layout[dim[axis]] - + child.layout[dim[axis]] - + getPosition(child, trailing[axis]); + } + } } } }; diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 9b310fac..89d926bd 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -3170,7 +3170,6 @@ int main() css_node_t *root_node = new_test_css_node(); { css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; node_0->style.dimensions[CSS_HEIGHT] = 100; init_css_node_children(node_0, 1); { @@ -3187,7 +3186,7 @@ int main() 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] = 100; + node_0->layout.dimensions[CSS_WIDTH] = 0; node_0->layout.dimensions[CSS_HEIGHT] = 100; init_css_node_children(node_0, 1); { @@ -3200,7 +3199,7 @@ int main() } } - test("should layout with position: absolute, bottom", root_node, root_layout); + test("should calculate height properly with position: absolute top and bottom", root_node, root_layout); } { @@ -3258,6 +3257,218 @@ int main() test("should layout with complicated position: absolute and justifyContent: center combo", root_node, root_layout); } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.position[CSS_BOTTOM] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should calculate top properly with position: absolute bottom", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_WIDTH] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.position[CSS_RIGHT] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 100; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 100; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should calcluate left properly with position: absolute right", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.dimensions[CSS_HEIGHT] = 10; + node_1->style.position[CSS_BOTTOM] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 90; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 10; + } + } + + test("should calculate top properly with position: absolute bottom and height", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_WIDTH] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.dimensions[CSS_WIDTH] = 10; + node_1->style.position[CSS_RIGHT] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 100; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 90; + node_1->layout.dimensions[CSS_WIDTH] = 10; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should calcluate left properly with position: absolute right and width", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.dimensions[CSS_HEIGHT] = 10; + node_1->style.position[CSS_BOTTOM] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = -10; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 10; + } + } + + test("should calcluate top properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.dimensions[CSS_WIDTH] = 10; + node_1->style.position[CSS_RIGHT] = 0; + } + } + + css_node_t *root_layout = new_test_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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = -10; + node_1->layout.dimensions[CSS_WIDTH] = 10; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should calcluate left properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); + } /** END_GENERATED **/ return tests_finished(); } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 89eee5f3..37a051ba 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -955,30 +955,12 @@ describe('Layout', function() { ); }); - xit('should layout text with alignItems: stretch', function() { + it('should calculate height properly with position: absolute top and bottom', function() { testLayout( - {style: {width: 80, padding: 7, alignItems: 'stretch', measure: text(texts.big)}}, - {width: 80, height: 68, top: 0, left: 0} - ); - }); - - xit('should layout node with text and position absolute', function() { - testLayout( - {style: {}, children: [ - {style: {measure: text(texts.big)}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 100, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ); - }); - - it('should layout with position: absolute, bottom', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ + {style: {height: 100}, children: [ {style: {position: 'absolute', top: 0, bottom: 20}} ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 100, top: 0, left: 0, children: [ {width: 0, height: 80, top: 0, left: 0} ]} ); @@ -999,5 +981,89 @@ describe('Layout', function() { ); }); + it('should calculate top properly with position: absolute bottom', function() { + testLayout( + {style: {height: 100}, children: [ + {style: {position: 'absolute', bottom: 0}} + ]}, + {width: 0, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 100, left: 0} + ]} + ); + }); + + it('should calcluate left properly with position: absolute right', function() { + testLayout( + {style: {width: 100}, children: [ + {style: {position: 'absolute', right: 0}} + ]}, + {width: 100, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 0, left: 100} + ]} + ); + }); + + it('should calculate top properly with position: absolute bottom and height', function() { + testLayout( + {style: {height: 100}, children: [ + {style: {height: 10, position: 'absolute', bottom: 0}} + ]}, + {width: 0, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 10, top: 90, left: 0} + ]} + ); + }); + + it('should calcluate left properly with position: absolute right and width', function() { + testLayout( + {style: {width: 100}, children: [ + {style: {width: 10, position: 'absolute', right: 0}} + ]}, + {width: 100, height: 0, top: 0, left: 0, children: [ + {width: 10, height: 0, top: 0, left: 90} + ]} + ); + }); + + it('should calcluate top properly with position: absolute right, width, and no parent dimensions', function() { + testLayout( + {style: {}, children: [ + {style: {height: 10, position: 'absolute', bottom: 0}} + ]}, + {width: 0, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 10, top: -10, left: 0} + ]} + ); + }); + + it('should calcluate left properly with position: absolute right, width, and no parent dimensions', function() { + testLayout( + {style: {}, children: [ + {style: {width: 10, position: 'absolute', right: 0}} + ]}, + {width: 0, height: 0, top: 0, left: 0, children: [ + {width: 10, height: 0, top: 0, left: -10} + ]} + ); + }); + + xit('should layout text with alignItems: stretch', function() { + testLayout( + {style: {width: 80, padding: 7, alignItems: 'stretch', measure: text(texts.big)}}, + {width: 80, height: 68, top: 0, left: 0} + ); + }); + + xit('should layout node with text and position absolute', function() { + testLayout( + {style: {}, children: [ + {style: {measure: text(texts.big)}} + ]}, + {width: 0, height: 0, top: 0, left: 0, children: [ + {width: 100, height: textSizes.bigHeight, top: 0, left: 0} + ]} + ); + }); + });