diff --git a/spec/LayoutSpec.js b/spec/LayoutSpec.js index c540a2c4..9110dd92 100755 --- a/spec/LayoutSpec.js +++ b/spec/LayoutSpec.js @@ -36,6 +36,7 @@ function computeDOMLayout(node) { transfer(div, node, 'height', 'px'); transfer(div, node, 'margin', 'px'); transfer(div, node, 'flexDirection'); + transfer(div, node, 'flex'); parent.appendChild(div); (node.children || []).forEach(function(child) { renderNode(div, child); @@ -68,11 +69,24 @@ function computeDOMLayout(node) { return layout; } +function nameLayout(name, layout) { + var namedLayout = {name: name}; + for (var key in layout) { + namedLayout[key] = layout[key]; + } + return namedLayout; +} + +function testNamedLayout(name, layoutA, layoutB) { + expect(nameLayout(name, layoutA)) + .toEqual(nameLayout(name, layoutB)); +} + function testLayout(node, expectedLayout) { var layout = computeLayout(node); var domLayout = computeDOMLayout(node); - expect(expectedLayout).toEqual(domLayout); - expect(layout).toEqual(domLayout); + testNamedLayout('expected-dom', expectedLayout, domLayout); + testNamedLayout('layout-dom', layout, domLayout); } describe('Layout', function() { @@ -193,5 +207,21 @@ describe('Layout', function() { ] }); }); + + it('should layout node with flex', function() { + testLayout({ + style: {width: 1000, height: 1000}, + children: [ + {style: {width: 100, height: 200}}, + {style: {width: 100, flex: 1}} + ] + }, { + width: 1000, height: 1000, top: 0, left: 0, + children: [ + {width: 100, height: 200, top: 0, left: 0}, + {width: 100, height: 800, top: 200, left: 0} + ] + }); + }); }); diff --git a/src/Layout.js b/src/Layout.js index c1afb4bd..6662730f 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -3,10 +3,10 @@ function computeLayout(node) { function fillNodes(node) { node.layout = { - top: undefined, - left: undefined, width: undefined, - height: undefined + height: undefined, + top: 0, + left: 0 }; (node.children || []).forEach(fillNodes); } @@ -45,13 +45,30 @@ function computeLayout(node) { node.layout[dim[mainAxis]] = node.style[dim[mainAxis]]; } + var fixedChildren = []; + var flexibleChildren = []; + var mainContentDim = 0; + (node.children || []).forEach(function(child) { + if (child.style.flex) { + flexibleChildren.push(child); + } else { + fixedChildren.push(child); + layoutNode(child); + mainContentDim += child.layout[dim[mainAxis]]; + } + }); + + var flexibleMainDim = + (node.layout[dim[mainAxis]] - mainContentDim) / flexibleChildren.length; + flexibleChildren.forEach(function(child) { + layoutNode(child); + child.layout[dim[mainAxis]] = flexibleMainDim; + }); + var mainPos = 0; var children = []; (node.children || []).forEach(function(child) { - child.layout[pos[mainAxis]] = mainPos; - child.layout[pos[crossAxis]] = 0; - layoutNode(child); - + child.layout[pos[mainAxis]] += mainPos; mainPos += child.layout[dim[mainAxis]] + 2 * getMargin(child); });