From 8779d942ea61a3eb9aa0296536a0234f702fda82 Mon Sep 17 00:00:00 2001 From: Adam Comella Date: Thu, 28 Apr 2016 17:07:34 -0700 Subject: [PATCH] Fix positioning of items with min/max width/height We found a case where a flexible item with a max width that was supposed to be centered was positioned in the wrong location. The problem was with our 2 pass approach for sizing flexible items with a min/max width/height. Items sized in the first pass were being double counted when calculating the remainingFreeSpace. Specifically, their sizes were being subtracted from remainingFreeSpace in both the first and second passes. I also noticed a second unrelated bug. We weren't correctly calculating deltaFreeSpace in the first pass. When calculating deltaFreeSpace, we need to take into account the flex basis like we do in the second pass. Consequently, in the first pass I changed this: deltaFreeSpace -= boundMainSize; To this: deltaFreeSpace -= boundMainSize - childFlexBasis; The problem there was that we'd end up double counting childFlexBasis in the remainingFreeSpace. --- dist/css-layout.h | 14 +- dist/css-layout.jar | Bin 16191 -> 16323 bytes dist/css-layout.js | 14 +- dist/css-layout.min.js | 2 +- dist/css-layout.min.js.map | 2 +- src/Layout.c | 14 +- src/Layout.js | 14 +- src/__tests__/Layout-test.c | 87 +++++++++ src/__tests__/Layout-test.js | 24 +++ .../LayoutEngineTest.cs | 165 ++++++++++++++---- src/csharp/Facebook.CSSLayout/LayoutEngine.cs | 14 +- .../com/facebook/csslayout/LayoutEngine.java | 14 +- .../facebook/csslayout/LayoutEngineTest.java | 165 ++++++++++++++---- 13 files changed, 411 insertions(+), 118 deletions(-) diff --git a/dist/css-layout.h b/dist/css-layout.h index 95eab64d..4e0e1511 100644 --- a/dist/css-layout.h +++ b/dist/css-layout.h @@ -1171,7 +1171,8 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab remainingFreeSpace = -sizeConsumedOnCurrentLine; } - float remainingFreeSpaceAfterFlex = remainingFreeSpace; + float originalRemainingFreeSpace = remainingFreeSpace; + float deltaFreeSpace = 0; if (!canSkipFlex) { float childFlexBasis; @@ -1194,7 +1195,6 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - float deltaFreeSpace = 0; float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -1213,7 +1213,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -1229,7 +1229,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -1241,9 +1241,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != NULL) { childFlexBasis = currentRelativeChild->layout.flex_basis; @@ -1267,7 +1267,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); @@ -1303,7 +1303,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/dist/css-layout.jar b/dist/css-layout.jar index 21cef567a1cd090fc626efb5b69189cfdcc76968..a13686964852c308a570cf5742ac435a08e608fc 100644 GIT binary patch delta 13152 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 PeZIervQR*Qf202oGq(X4 delta 13051 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 I{QqkI54gCY7XSbN diff --git a/dist/css-layout.js b/dist/css-layout.js index c5bf0095..43df9fae 100644 --- a/dist/css-layout.js +++ b/dist/css-layout.js @@ -935,7 +935,8 @@ var computeLayout = (function() { remainingFreeSpace = -sizeConsumedOnCurrentLine; } - var/*float*/ remainingFreeSpaceAfterFlex = remainingFreeSpace; + var/*float*/ originalRemainingFreeSpace = remainingFreeSpace; + var/*float*/ deltaFreeSpace = 0; if (!canSkipFlex) { var/*float*/ childFlexBasis; @@ -958,7 +959,6 @@ var computeLayout = (function() { // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - var/*float*/ deltaFreeSpace = 0; var/*float*/ deltaFlexShrinkScaledFactors = 0; var/*float*/ deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -977,7 +977,7 @@ var computeLayout = (function() { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -993,7 +993,7 @@ var computeLayout = (function() { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -1005,9 +1005,9 @@ var computeLayout = (function() { totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild !== undefined) { childFlexBasis = currentRelativeChild.layout.flexBasis; @@ -1031,7 +1031,7 @@ var computeLayout = (function() { } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); @@ -1067,7 +1067,7 @@ var computeLayout = (function() { } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/dist/css-layout.min.js b/dist/css-layout.min.js index 86e0108f..721c379f 100644 --- a/dist/css-layout.min.js +++ b/dist/css-layout.min.js @@ -1,2 +1,2 @@ -!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.computeLayout=b()}(this,function(){var a=function(){function a(b){if(b.layout&&!b.isDirty||(b.layout={width:void 0,height:void 0,top:0,left:0,right:0,bottom:0}),b.style||(b.style={}),b.children||(b.children=[]),b.style.measure&&b.children&&b.children.length)throw new Error("Using custom measure function is supported only for leaf nodes.");return b.children.forEach(a),b}function b(a){return void 0===a||Number.isNaN(a)}function c(a){return a===ca||a===da}function d(a){return a===ea||a===fa}function e(a){return void 0===a.style.flex?0:a.style.flex}function f(a){return V?!0:e(a)<=0}function g(a){return e(a)>0?e(a):0}function h(a){if(V){if(0!==e(a))return 1}else if(e(a)<0)return 1;return 0}function i(a,b){if(void 0!==a.style.marginStart&&c(b))return a.style.marginStart;var d=null;switch(b){case"row":d=a.style.marginLeft;break;case"row-reverse":d=a.style.marginRight;break;case"column":d=a.style.marginTop;break;case"column-reverse":d=a.style.marginBottom}return void 0!==d?d:void 0!==a.style.margin?a.style.margin:0}function j(a,b){if(void 0!==a.style.marginEnd&&c(b))return a.style.marginEnd;var d=null;switch(b){case"row":d=a.style.marginRight;break;case"row-reverse":d=a.style.marginLeft;break;case"column":d=a.style.marginBottom;break;case"column-reverse":d=a.style.marginTop}return null!=d?d:void 0!==a.style.margin?a.style.margin:0}function k(a,b){if(void 0!==a.style.paddingStart&&a.style.paddingStart>=0&&c(b))return a.style.paddingStart;var d=null;switch(b){case"row":d=a.style.paddingLeft;break;case"row-reverse":d=a.style.paddingRight;break;case"column":d=a.style.paddingTop;break;case"column-reverse":d=a.style.paddingBottom}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function l(a,b){if(void 0!==a.style.paddingEnd&&a.style.paddingEnd>=0&&c(b))return a.style.paddingEnd;var d=null;switch(b){case"row":d=a.style.paddingRight;break;case"row-reverse":d=a.style.paddingLeft;break;case"column":d=a.style.paddingBottom;break;case"column-reverse":d=a.style.paddingTop}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function m(a,b){if(void 0!==a.style.borderStartWidth&&a.style.borderStartWidth>=0&&c(b))return a.style.borderStartWidth;var d=null;switch(b){case"row":d=a.style.borderLeftWidth;break;case"row-reverse":d=a.style.borderRightWidth;break;case"column":d=a.style.borderTopWidth;break;case"column-reverse":d=a.style.borderBottomWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function n(a,b){if(void 0!==a.style.borderEndWidth&&a.style.borderEndWidth>=0&&c(b))return a.style.borderEndWidth;var d=null;switch(b){case"row":d=a.style.borderRightWidth;break;case"row-reverse":d=a.style.borderLeftWidth;break;case"column":d=a.style.borderBottomWidth;break;case"column-reverse":d=a.style.borderTopWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function o(a,b){return k(a,b)+m(a,b)}function p(a,b){return l(a,b)+n(a,b)}function q(a,b){return i(a,b)+j(a,b)}function r(a,b){return o(a,b)+p(a,b)}function s(a){return a.style.justifyContent?a.style.justifyContent:"flex-start"}function t(a){return a.style.alignContent?a.style.alignContent:"flex-start"}function u(a,b){return b.style.alignSelf?b.style.alignSelf:a.style.alignItems?a.style.alignItems:"stretch"}function v(a,b){if(b===ba){if(a===ca)return da;if(a===da)return ca}return a}function w(a,b){var c;return c=a.style.direction?a.style.direction:_,c===_&&(c=void 0===b?aa:b),c}function x(a){return a.style.flexDirection?a.style.flexDirection:ea}function y(a,b){return d(a)?v(ca,b):ea}function z(a){return a.style.position?a.style.position:pa}function A(a){return a.style.overflow?a.style.overflow:ra}function B(a){return z(a)===pa&&void 0!==a.style.flex&&0!==a.style.flex}function C(a){return"wrap"===a.style.flexWrap}function D(a,b){return a.layout[Aa[b]]+q(a,b)}function E(a,b){return void 0!==a.style[za[b]]&&a.style[za[b]]>=0}function F(a,b){return void 0!==a.layout[Aa[b]]&&a.layout[Aa[b]]>=0}function G(a,b){return void 0!==a.style[b]}function H(a){return void 0!==a.style.measure}function I(a,b){return void 0!==a.style[b]?a.style[b]:0}function J(a,b,c){var d={row:a.style.minWidth,"row-reverse":a.style.minWidth,column:a.style.minHeight,"column-reverse":a.style.minHeight}[b],e={row:a.style.maxWidth,"row-reverse":a.style.maxWidth,column:a.style.maxHeight,"column-reverse":a.style.maxHeight}[b],f=c;return void 0!==e&&e>=0&&f>e&&(f=e),void 0!==d&&d>=0&&d>f&&(f=d),f}function K(a,b){return b>a?a:b}function L(a,b){return a>b?a:b}function M(a,b,c){return L(J(a,b,c),r(a,b))}function N(a,b,c){var d=z(b)===qa?0:b.layout[Aa[c]];b.layout[xa[c]]=a.layout[Aa[c]]-d-b.layout[ya[c]]}function O(a,b){return void 0!==a.style[wa[b]]?I(a,wa[b]):-I(a,xa[b])}function P(a,b){var c=v(x(a),b),d=y(c,b);a.layout[wa[c]]=i(a,c)+O(a,c),a.layout[xa[c]]=j(a,c)+O(a,c),a.layout[wa[d]]=i(a,d)+O(a,d),a.layout[xa[d]]=j(a,d)+O(a,d)}function Q(a,b){if(!a)throw new Error(b)}function R(a,d,e,k,l,O,R){Q(b(d)?l===ta:!0,"availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED"),Q(b(e)?O===ta:!0,"availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED");var T=r(a,ca),V=r(a,ea),W=q(a,ca),_=q(a,ea),aa=w(a,k);if(a.layout.direction=aa,H(a)){var ba=d-W-T,ra=e-_-V;if(l===ua&&O===ua)a.layout.measuredWidth=M(a,ca,d-W),a.layout.measuredHeight=M(a,ea,e-_);else if(0>=ba)a.layout.measuredWidth=M(a,ca,0),a.layout.measuredHeight=M(a,ea,0);else{var za=a.style.measure(ba,l,ra,O);a.layout.measuredWidth=M(a,ca,l===ta||l===va?za.width+T:d-W),a.layout.measuredHeight=M(a,ea,O===ta||O===va?za.height+V:e-_)}}else{var Ba=a.children.length;if(0===Ba)return a.layout.measuredWidth=M(a,ca,l===ta||l===va?T:d-W),void(a.layout.measuredHeight=M(a,ea,O===ta||O===va?V:e-_));if(!R){if(l===va&&0>=d&&O===va&&0>=e)return a.layout.measuredWidth=M(a,ca,0),void(a.layout.measuredHeight=M(a,ea,0));if(l===va&&0>=d)return a.layout.measuredWidth=M(a,ca,0),void(a.layout.measuredHeight=M(a,ea,b(e)?0:e-_));if(O===va&&0>=e)return a.layout.measuredWidth=M(a,ca,b(d)?0:d-W),void(a.layout.measuredHeight=M(a,ea,0));if(l===ua&&O===ua)return a.layout.measuredWidth=M(a,ca,d-W),void(a.layout.measuredHeight=M(a,ea,e-_))}var Ca,Da,Ea,Fa,Ga,Ha,Ia=v(x(a),aa),Ja=y(Ia,aa),Ka=c(Ia),La=s(a),Ma=C(a),Na=void 0,Oa=void 0,Pa=o(a,Ia),Qa=p(a,Ia),Ra=o(a,Ja),Sa=r(a,Ia),Ta=r(a,Ja),Ua=Ka?l:O,Va=Ka?O:l,Wa=d-W-T,Xa=e-_-V,Ya=Ka?Wa:Xa,Za=Ka?Xa:Wa;for(Da=0;Ba>Da;Da++){if(Ca=a.children[Da],R){var $a=w(Ca,aa);P(Ca,$a)}z(Ca)===qa?(void 0===Na&&(Na=Ca),void 0!==Oa&&(Oa.nextChild=Ca),Oa=Ca,Ca.nextChild=void 0):Ka&&E(Ca,ca)?Ca.layout.flexBasis=L(Ca.style.width,r(Ca,ca)):!Ka&&E(Ca,ea)?Ca.layout.flexBasis=L(Ca.style.height,r(Ca,ea)):f(Ca)||b(Ya)?(Ea=U,Fa=U,Ga=ta,Ha=ta,E(Ca,ca)&&(Ea=Ca.style.width+q(Ca,ca),Ga=ua),E(Ca,ea)&&(Fa=Ca.style.height+q(Ca,ea),Ha=ua),Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=va),A(a)===sa&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=va),S(Ca,Ea,Fa,aa,Ga,Ha,!1,"measure"),Ca.layout.flexBasis=L(Ka?Ca.layout.measuredWidth:Ca.layout.measuredHeight,r(Ca,Ia))):Ca.layout.flexBasis=L(0,r(Ca,Ia))}for(var _a=0,ab=0,bb=0,cb=0,db=0;Ba>ab;){var eb=0,fb=0,gb=0,hb=0;Da=_a;for(var ib=void 0,jb=void 0;Ba>Da;){if(Ca=a.children[Da],Ca.lineIndex=bb,z(Ca)!==qa){var kb=Ca.layout.flexBasis+q(Ca,Ia);if(fb+kb>Ya&&Ma&&eb>0)break;fb+=kb,eb++,B(Ca)&&(gb+=g(Ca),hb+=h(Ca)*Ca.layout.flexBasis),void 0===ib&&(ib=Ca),void 0!==jb&&(jb.nextChild=Ca),jb=Ca,Ca.nextChild=void 0}Da++,ab++}var lb=!R&&Va===ua,mb=0,nb=0,ob=0;b(Ya)?0>fb&&(ob=-fb):ob=Ya-fb;var pb=ob;if(!lb){var qb,rb,sb,tb,ub,vb=0,wb=0,xb=0;for(jb=ib;void 0!==jb;)qb=jb.layout.flexBasis,0>ob?(rb=h(jb)*qb,0!==rb&&(tb=qb+ob/hb*rb,ub=M(jb,Ia,tb),tb!==ub&&(vb-=ub,wb-=rb))):ob>0&&(sb=g(jb),0!==sb&&(tb=qb+ob/gb*sb,ub=M(jb,Ia,tb),tb!==ub&&(vb-=ub,xb-=sb))),jb=jb.nextChild;for(hb+=wb,gb+=xb,ob+=vb,pb=ob,jb=ib;void 0!==jb;){qb=jb.layout.flexBasis;var yb=qb;0>ob?(rb=h(jb)*qb,0!==rb&&(yb=M(jb,Ia,qb+ob/hb*rb))):ob>0&&(sb=g(jb),0!==sb&&(yb=M(jb,Ia,qb+ob/gb*sb))),pb-=yb-qb,Ka?(Ea=yb+q(jb,ca),Ga=ua,E(jb,ea)?(Fa=jb.style.height+q(jb,ea),Ha=ua):(Fa=Za,Ha=b(Fa)?ta:va)):(Fa=yb+q(jb,ea),Ha=ua,E(jb,ca)?(Ea=jb.style.width+q(jb,ca),Ga=ua):(Ea=Za,Ga=b(Ea)?ta:va));var zb=!E(jb,Ja)&&u(a,jb)===oa;S(jb,Ea,Fa,aa,Ga,Ha,R&&!zb,"flex"),jb=jb.nextChild}}ob=pb,Ua===va&&(ob=0),La!==ga&&(La===ha?mb=ob/2:La===ia?mb=ob:La===ja?(ob=L(ob,0),nb=eb>1?ob/(eb-1):0):La===ka&&(nb=ob/eb,mb=nb/2));var Ab=Pa+mb,Bb=0;for(Da=_a;ab>Da;++Da)Ca=a.children[Da],z(Ca)===qa&&G(Ca,wa[Ia])?R&&(Ca.layout[ya[Ia]]=I(Ca,wa[Ia])+m(a,Ia)+i(Ca,Ia)):(R&&(Ca.layout[ya[Ia]]+=Ab),z(Ca)===pa&&(lb?(Ab+=nb+q(Ca,Ia)+Ca.layout.flexBasis,Bb=Za):(Ab+=nb+D(Ca,Ia),Bb=L(Bb,D(Ca,Ja)))));Ab+=Qa;var Cb=Za;if(Va!==ta&&Va!==va||(Cb=M(a,Ja,Bb+Ta)-Ta,Va===va&&(Cb=K(Cb,Za))),Ma||Va!==ua||(Bb=Za),Bb=M(a,Ja,Bb+Ta)-Ta,R)for(Da=_a;ab>Da;++Da)if(Ca=a.children[Da],z(Ca)===qa)G(Ca,wa[Ja])?Ca.layout[ya[Ja]]=I(Ca,wa[Ja])+m(a,Ja)+i(Ca,Ja):Ca.layout[ya[Ja]]=Ra+i(Ca,Ja);else{var Db=Ra,Eb=u(a,Ca);if(Eb===oa){Ea=Ca.layout.measuredWidth+q(Ca,ca),Fa=Ca.layout.measuredHeight+q(Ca,ea);var Fb=!1;Ka?(Fb=E(Ca,ea),Fa=Bb):(Fb=E(Ca,ca),Ea=Bb),Fb||(Ga=b(Ea)?ta:ua,Ha=b(Fa)?ta:ua,S(Ca,Ea,Fa,aa,Ga,Ha,!0,"stretch"))}else if(Eb!==la){var Gb=Cb-D(Ca,Ja);Db+=Eb===ma?Gb/2:Gb}Ca.layout[ya[Ja]]+=cb+Db}cb+=Bb,db=L(db,Ab),bb++,_a=ab,ab=_a}if(bb>1&&R&&!b(Za)){var Hb=Za-cb,Ib=0,Jb=Ra,Kb=t(a);Kb===na?Jb+=Hb:Kb===ma?Jb+=Hb/2:Kb===oa&&Za>cb&&(Ib=Hb/bb);var Lb=0;for(Da=0;bb>Da;++Da){var Mb,Nb=Lb,Ob=0;for(Mb=Nb;Ba>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===pa){if(Ca.lineIndex!==Da)break;F(Ca,Ja)&&(Ob=L(Ob,Ca.layout[Aa[Ja]]+q(Ca,Ja)))}if(Lb=Mb,Ob+=Ib,R)for(Mb=Nb;Lb>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===pa){var Pb=u(a,Ca);Pb===la?Ca.layout[ya[Ja]]=Jb+i(Ca,Ja):Pb===na?Ca.layout[ya[Ja]]=Jb+Ob-j(Ca,Ja)-Ca.layout[Aa[Ja]]:Pb===ma?(Fa=Ca.layout[Aa[Ja]],Ca.layout[ya[Ja]]=Jb+(Ob-Fa)/2):Pb===oa&&(Ca.layout[ya[Ja]]=Jb+i(Ca,Ja))}Jb+=Ob}}if(a.layout.measuredWidth=M(a,ca,d-W),a.layout.measuredHeight=M(a,ea,e-_),Ua===ta?a.layout[Aa[Ia]]=M(a,Ia,db):Ua===va&&(a.layout[Aa[Ia]]=L(K(Ya+Sa,J(a,Ia,db)),Sa)),Va===ta?a.layout[Aa[Ja]]=M(a,Ja,cb+Ta):Va===va&&(a.layout[Aa[Ja]]=L(K(Za+Ta,J(a,Ja,cb+Ta)),Ta)),R){var Qb=!1,Rb=!1;if(Ia!==da&&Ia!==fa||(Qb=!0),Ja!==da&&Ja!==fa||(Rb=!0),Qb||Rb)for(Da=0;Ba>Da;++Da)Ca=a.children[Da],Qb&&N(a,Ca,Ia),Rb&&N(a,Ca,Ja)}for(Oa=Na;void 0!==Oa;)R&&(Ea=U,Fa=U,E(Oa,ca)?Ea=Oa.style.width+q(Oa,ca):G(Oa,X)&&G(Oa,Z)&&(Ea=a.layout.measuredWidth-(m(a,ca)+n(a,ca))-(Oa.style[X]+Oa.style[Z]),Ea=M(Oa,ca,Ea)),E(Oa,ea)?Fa=Oa.style.height+q(Oa,ea):G(Oa,Y)&&G(Oa,$)&&(Fa=a.layout.measuredHeight-(m(a,ea)+n(a,ea))-(Oa.style[Y]+Oa.style[$]),Fa=M(Oa,ea,Fa)),(b(Ea)||b(Fa))&&(Ga=b(Ea)?ta:ua,Ha=b(Fa)?ta:ua,Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=va),A(a)===sa&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=va),S(Oa,Ea,Fa,aa,Ga,Ha,!1,"abs-measure"),Ea=Oa.layout.measuredWidth+q(Oa,ca),Fa=Oa.layout.measuredHeight+q(Oa,ea)),S(Oa,Ea,Fa,aa,ua,ua,!0,"abs-layout"),G(Oa,xa[ca])&&!G(Oa,wa[ca])&&(Oa.layout[wa[ca]]=a.layout[Aa[ca]]-Oa.layout[Aa[ca]]-I(Oa,xa[ca])),G(Oa,xa[ea])&&!G(Oa,wa[ea])&&(Oa.layout[wa[ea]]=a.layout[Aa[ea]]-Oa.layout[Aa[ea]]-I(Oa,xa[ea]))),Oa=Oa.nextChild}}function S(a,b,c,d,e,f,g,h){var i=a.layout,j=a.isDirty&&i.generationCount!==W||i.lastParentDirection!==d;j&&(void 0!==i.cachedMeasurements&&(i.cachedMeasurements=[]),void 0!==i.cachedLayout&&(i.cachedLayout.widthMeasureMode=void 0,i.cachedLayout.heightMeasureMode=void 0));var k;if(g)i.cachedLayout&&i.cachedLayout.availableWidth===b&&i.cachedLayout.availableHeight===c&&i.cachedLayout.widthMeasureMode===e&&i.cachedLayout.heightMeasureMode===f&&(k=i.cachedLayout);else if(i.cachedMeasurements)for(var l=0,m=i.cachedMeasurements.length;m>l;l++)if(i.cachedMeasurements[l].availableWidth===b&&i.cachedMeasurements[l].availableHeight===c&&i.cachedMeasurements[l].widthMeasureMode===e&&i.cachedMeasurements[l].heightMeasureMode===f){k=i.cachedMeasurements[l];break}if(j||void 0===k){if(R(a,b,c,d,e,f,g),i.lastParentDirection=d,void 0===k){var n;g?(void 0===i.cachedLayout&&(i.cachedLayout={}),n=i.cachedLayout):(void 0===i.cachedMeasurements&&(i.cachedMeasurements=[]),n={},i.cachedMeasurements.push(n)),n.availableWidth=b,n.availableHeight=c,n.widthMeasureMode=e,n.heightMeasureMode=f,n.computedWidth=i.measuredWidth,n.computedHeight=i.measuredHeight}}else i.measureWidth=k.computedWidth,i.measureHeight=k.computedHeight;return g&&(a.layout.width=a.layout.measuredWidth,a.layout.height=a.layout.measuredHeight,i.shouldUpdate=!0),i.generationCount=W,j||void 0===k}function T(a,c,d,e){W++,b(c)&&E(a,ca)&&(c=a.style.width+q(a,ca)),b(d)&&E(a,ea)&&(d=a.style.height+q(a,ea));var f=b(c)?ta:ua,g=b(d)?ta:ua;S(a,c,d,e,f,g,!0,"initial")&&P(a,a.layout.direction)}var U,V=!1,W=0,X="left",Y="top",Z="right",$="bottom",_="inherit",aa="ltr",ba="rtl",ca="row",da="row-reverse",ea="column",fa="column-reverse",ga="flex-start",ha="center",ia="flex-end",ja="space-between",ka="space-around",la="flex-start",ma="center",na="flex-end",oa="stretch",pa="relative",qa="absolute",ra="visible",sa="hidden",ta="undefined",ua="exactly",va="at-most",wa={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},xa={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},ya={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},za={row:"width","row-reverse":"width",column:"height","column-reverse":"height"},Aa={row:"measuredWidth","row-reverse":"measuredWidth",column:"measuredHeight","column-reverse":"measuredHeight"};return{layoutNodeImpl:R,computeLayout:T,fillNodes:a}}();return"object"==typeof exports&&(module.exports=a),function(b){a.fillNodes(b),a.computeLayout(b)}}); +!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.computeLayout=b()}(this,function(){var a=function(){function a(b){if(b.layout&&!b.isDirty||(b.layout={width:void 0,height:void 0,top:0,left:0,right:0,bottom:0}),b.style||(b.style={}),b.children||(b.children=[]),b.style.measure&&b.children&&b.children.length)throw new Error("Using custom measure function is supported only for leaf nodes.");return b.children.forEach(a),b}function b(a){return void 0===a||Number.isNaN(a)}function c(a){return a===ca||a===da}function d(a){return a===ea||a===fa}function e(a){return void 0===a.style.flex?0:a.style.flex}function f(a){return V?!0:e(a)<=0}function g(a){return e(a)>0?e(a):0}function h(a){if(V){if(0!==e(a))return 1}else if(e(a)<0)return 1;return 0}function i(a,b){if(void 0!==a.style.marginStart&&c(b))return a.style.marginStart;var d=null;switch(b){case"row":d=a.style.marginLeft;break;case"row-reverse":d=a.style.marginRight;break;case"column":d=a.style.marginTop;break;case"column-reverse":d=a.style.marginBottom}return void 0!==d?d:void 0!==a.style.margin?a.style.margin:0}function j(a,b){if(void 0!==a.style.marginEnd&&c(b))return a.style.marginEnd;var d=null;switch(b){case"row":d=a.style.marginRight;break;case"row-reverse":d=a.style.marginLeft;break;case"column":d=a.style.marginBottom;break;case"column-reverse":d=a.style.marginTop}return null!=d?d:void 0!==a.style.margin?a.style.margin:0}function k(a,b){if(void 0!==a.style.paddingStart&&a.style.paddingStart>=0&&c(b))return a.style.paddingStart;var d=null;switch(b){case"row":d=a.style.paddingLeft;break;case"row-reverse":d=a.style.paddingRight;break;case"column":d=a.style.paddingTop;break;case"column-reverse":d=a.style.paddingBottom}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function l(a,b){if(void 0!==a.style.paddingEnd&&a.style.paddingEnd>=0&&c(b))return a.style.paddingEnd;var d=null;switch(b){case"row":d=a.style.paddingRight;break;case"row-reverse":d=a.style.paddingLeft;break;case"column":d=a.style.paddingBottom;break;case"column-reverse":d=a.style.paddingTop}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function m(a,b){if(void 0!==a.style.borderStartWidth&&a.style.borderStartWidth>=0&&c(b))return a.style.borderStartWidth;var d=null;switch(b){case"row":d=a.style.borderLeftWidth;break;case"row-reverse":d=a.style.borderRightWidth;break;case"column":d=a.style.borderTopWidth;break;case"column-reverse":d=a.style.borderBottomWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function n(a,b){if(void 0!==a.style.borderEndWidth&&a.style.borderEndWidth>=0&&c(b))return a.style.borderEndWidth;var d=null;switch(b){case"row":d=a.style.borderRightWidth;break;case"row-reverse":d=a.style.borderLeftWidth;break;case"column":d=a.style.borderBottomWidth;break;case"column-reverse":d=a.style.borderTopWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function o(a,b){return k(a,b)+m(a,b)}function p(a,b){return l(a,b)+n(a,b)}function q(a,b){return i(a,b)+j(a,b)}function r(a,b){return o(a,b)+p(a,b)}function s(a){return a.style.justifyContent?a.style.justifyContent:"flex-start"}function t(a){return a.style.alignContent?a.style.alignContent:"flex-start"}function u(a,b){return b.style.alignSelf?b.style.alignSelf:a.style.alignItems?a.style.alignItems:"stretch"}function v(a,b){if(b===ba){if(a===ca)return da;if(a===da)return ca}return a}function w(a,b){var c;return c=a.style.direction?a.style.direction:_,c===_&&(c=void 0===b?aa:b),c}function x(a){return a.style.flexDirection?a.style.flexDirection:ea}function y(a,b){return d(a)?v(ca,b):ea}function z(a){return a.style.position?a.style.position:pa}function A(a){return a.style.overflow?a.style.overflow:ra}function B(a){return z(a)===pa&&void 0!==a.style.flex&&0!==a.style.flex}function C(a){return"wrap"===a.style.flexWrap}function D(a,b){return a.layout[Aa[b]]+q(a,b)}function E(a,b){return void 0!==a.style[za[b]]&&a.style[za[b]]>=0}function F(a,b){return void 0!==a.layout[Aa[b]]&&a.layout[Aa[b]]>=0}function G(a,b){return void 0!==a.style[b]}function H(a){return void 0!==a.style.measure}function I(a,b){return void 0!==a.style[b]?a.style[b]:0}function J(a,b,c){var d={row:a.style.minWidth,"row-reverse":a.style.minWidth,column:a.style.minHeight,"column-reverse":a.style.minHeight}[b],e={row:a.style.maxWidth,"row-reverse":a.style.maxWidth,column:a.style.maxHeight,"column-reverse":a.style.maxHeight}[b],f=c;return void 0!==e&&e>=0&&f>e&&(f=e),void 0!==d&&d>=0&&d>f&&(f=d),f}function K(a,b){return b>a?a:b}function L(a,b){return a>b?a:b}function M(a,b,c){return L(J(a,b,c),r(a,b))}function N(a,b,c){var d=z(b)===qa?0:b.layout[Aa[c]];b.layout[xa[c]]=a.layout[Aa[c]]-d-b.layout[ya[c]]}function O(a,b){return void 0!==a.style[wa[b]]?I(a,wa[b]):-I(a,xa[b])}function P(a,b){var c=v(x(a),b),d=y(c,b);a.layout[wa[c]]=i(a,c)+O(a,c),a.layout[xa[c]]=j(a,c)+O(a,c),a.layout[wa[d]]=i(a,d)+O(a,d),a.layout[xa[d]]=j(a,d)+O(a,d)}function Q(a,b){if(!a)throw new Error(b)}function R(a,d,e,k,l,O,R){Q(b(d)?l===ta:!0,"availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED"),Q(b(e)?O===ta:!0,"availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED");var T=r(a,ca),V=r(a,ea),W=q(a,ca),_=q(a,ea),aa=w(a,k);if(a.layout.direction=aa,H(a)){var ba=d-W-T,ra=e-_-V;if(l===ua&&O===ua)a.layout.measuredWidth=M(a,ca,d-W),a.layout.measuredHeight=M(a,ea,e-_);else if(0>=ba)a.layout.measuredWidth=M(a,ca,0),a.layout.measuredHeight=M(a,ea,0);else{var za=a.style.measure(ba,l,ra,O);a.layout.measuredWidth=M(a,ca,l===ta||l===va?za.width+T:d-W),a.layout.measuredHeight=M(a,ea,O===ta||O===va?za.height+V:e-_)}}else{var Ba=a.children.length;if(0===Ba)return a.layout.measuredWidth=M(a,ca,l===ta||l===va?T:d-W),void(a.layout.measuredHeight=M(a,ea,O===ta||O===va?V:e-_));if(!R){if(l===va&&0>=d&&O===va&&0>=e)return a.layout.measuredWidth=M(a,ca,0),void(a.layout.measuredHeight=M(a,ea,0));if(l===va&&0>=d)return a.layout.measuredWidth=M(a,ca,0),void(a.layout.measuredHeight=M(a,ea,b(e)?0:e-_));if(O===va&&0>=e)return a.layout.measuredWidth=M(a,ca,b(d)?0:d-W),void(a.layout.measuredHeight=M(a,ea,0));if(l===ua&&O===ua)return a.layout.measuredWidth=M(a,ca,d-W),void(a.layout.measuredHeight=M(a,ea,e-_))}var Ca,Da,Ea,Fa,Ga,Ha,Ia=v(x(a),aa),Ja=y(Ia,aa),Ka=c(Ia),La=s(a),Ma=C(a),Na=void 0,Oa=void 0,Pa=o(a,Ia),Qa=p(a,Ia),Ra=o(a,Ja),Sa=r(a,Ia),Ta=r(a,Ja),Ua=Ka?l:O,Va=Ka?O:l,Wa=d-W-T,Xa=e-_-V,Ya=Ka?Wa:Xa,Za=Ka?Xa:Wa;for(Da=0;Ba>Da;Da++){if(Ca=a.children[Da],R){var $a=w(Ca,aa);P(Ca,$a)}z(Ca)===qa?(void 0===Na&&(Na=Ca),void 0!==Oa&&(Oa.nextChild=Ca),Oa=Ca,Ca.nextChild=void 0):Ka&&E(Ca,ca)?Ca.layout.flexBasis=L(Ca.style.width,r(Ca,ca)):!Ka&&E(Ca,ea)?Ca.layout.flexBasis=L(Ca.style.height,r(Ca,ea)):f(Ca)||b(Ya)?(Ea=U,Fa=U,Ga=ta,Ha=ta,E(Ca,ca)&&(Ea=Ca.style.width+q(Ca,ca),Ga=ua),E(Ca,ea)&&(Fa=Ca.style.height+q(Ca,ea),Ha=ua),Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=va),A(a)===sa&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=va),S(Ca,Ea,Fa,aa,Ga,Ha,!1,"measure"),Ca.layout.flexBasis=L(Ka?Ca.layout.measuredWidth:Ca.layout.measuredHeight,r(Ca,Ia))):Ca.layout.flexBasis=L(0,r(Ca,Ia))}for(var _a=0,ab=0,bb=0,cb=0,db=0;Ba>ab;){var eb=0,fb=0,gb=0,hb=0;Da=_a;for(var ib=void 0,jb=void 0;Ba>Da;){if(Ca=a.children[Da],Ca.lineIndex=bb,z(Ca)!==qa){var kb=Ca.layout.flexBasis+q(Ca,Ia);if(fb+kb>Ya&&Ma&&eb>0)break;fb+=kb,eb++,B(Ca)&&(gb+=g(Ca),hb+=h(Ca)*Ca.layout.flexBasis),void 0===ib&&(ib=Ca),void 0!==jb&&(jb.nextChild=Ca),jb=Ca,Ca.nextChild=void 0}Da++,ab++}var lb=!R&&Va===ua,mb=0,nb=0,ob=0;b(Ya)?0>fb&&(ob=-fb):ob=Ya-fb;var pb=ob,qb=0;if(!lb){var rb,sb,tb,ub,vb,wb=0,xb=0;for(jb=ib;void 0!==jb;)rb=jb.layout.flexBasis,0>ob?(sb=h(jb)*rb,0!==sb&&(ub=rb+ob/hb*sb,vb=M(jb,Ia,ub),ub!==vb&&(qb-=vb-rb,wb-=sb))):ob>0&&(tb=g(jb),0!==tb&&(ub=rb+ob/gb*tb,vb=M(jb,Ia,ub),ub!==vb&&(qb-=vb-rb,xb-=tb))),jb=jb.nextChild;for(hb+=wb,gb+=xb,ob+=qb,qb=0,jb=ib;void 0!==jb;){rb=jb.layout.flexBasis;var yb=rb;0>ob?(sb=h(jb)*rb,0!==sb&&(yb=M(jb,Ia,rb+ob/hb*sb))):ob>0&&(tb=g(jb),0!==tb&&(yb=M(jb,Ia,rb+ob/gb*tb))),qb-=yb-rb,Ka?(Ea=yb+q(jb,ca),Ga=ua,E(jb,ea)?(Fa=jb.style.height+q(jb,ea),Ha=ua):(Fa=Za,Ha=b(Fa)?ta:va)):(Fa=yb+q(jb,ea),Ha=ua,E(jb,ca)?(Ea=jb.style.width+q(jb,ca),Ga=ua):(Ea=Za,Ga=b(Ea)?ta:va));var zb=!E(jb,Ja)&&u(a,jb)===oa;S(jb,Ea,Fa,aa,Ga,Ha,R&&!zb,"flex"),jb=jb.nextChild}}ob=pb+qb,Ua===va&&(ob=0),La!==ga&&(La===ha?mb=ob/2:La===ia?mb=ob:La===ja?(ob=L(ob,0),nb=eb>1?ob/(eb-1):0):La===ka&&(nb=ob/eb,mb=nb/2));var Ab=Pa+mb,Bb=0;for(Da=_a;ab>Da;++Da)Ca=a.children[Da],z(Ca)===qa&&G(Ca,wa[Ia])?R&&(Ca.layout[ya[Ia]]=I(Ca,wa[Ia])+m(a,Ia)+i(Ca,Ia)):(R&&(Ca.layout[ya[Ia]]+=Ab),z(Ca)===pa&&(lb?(Ab+=nb+q(Ca,Ia)+Ca.layout.flexBasis,Bb=Za):(Ab+=nb+D(Ca,Ia),Bb=L(Bb,D(Ca,Ja)))));Ab+=Qa;var Cb=Za;if(Va!==ta&&Va!==va||(Cb=M(a,Ja,Bb+Ta)-Ta,Va===va&&(Cb=K(Cb,Za))),Ma||Va!==ua||(Bb=Za),Bb=M(a,Ja,Bb+Ta)-Ta,R)for(Da=_a;ab>Da;++Da)if(Ca=a.children[Da],z(Ca)===qa)G(Ca,wa[Ja])?Ca.layout[ya[Ja]]=I(Ca,wa[Ja])+m(a,Ja)+i(Ca,Ja):Ca.layout[ya[Ja]]=Ra+i(Ca,Ja);else{var Db=Ra,Eb=u(a,Ca);if(Eb===oa){Ea=Ca.layout.measuredWidth+q(Ca,ca),Fa=Ca.layout.measuredHeight+q(Ca,ea);var Fb=!1;Ka?(Fb=E(Ca,ea),Fa=Bb):(Fb=E(Ca,ca),Ea=Bb),Fb||(Ga=b(Ea)?ta:ua,Ha=b(Fa)?ta:ua,S(Ca,Ea,Fa,aa,Ga,Ha,!0,"stretch"))}else if(Eb!==la){var Gb=Cb-D(Ca,Ja);Db+=Eb===ma?Gb/2:Gb}Ca.layout[ya[Ja]]+=cb+Db}cb+=Bb,db=L(db,Ab),bb++,_a=ab,ab=_a}if(bb>1&&R&&!b(Za)){var Hb=Za-cb,Ib=0,Jb=Ra,Kb=t(a);Kb===na?Jb+=Hb:Kb===ma?Jb+=Hb/2:Kb===oa&&Za>cb&&(Ib=Hb/bb);var Lb=0;for(Da=0;bb>Da;++Da){var Mb,Nb=Lb,Ob=0;for(Mb=Nb;Ba>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===pa){if(Ca.lineIndex!==Da)break;F(Ca,Ja)&&(Ob=L(Ob,Ca.layout[Aa[Ja]]+q(Ca,Ja)))}if(Lb=Mb,Ob+=Ib,R)for(Mb=Nb;Lb>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===pa){var Pb=u(a,Ca);Pb===la?Ca.layout[ya[Ja]]=Jb+i(Ca,Ja):Pb===na?Ca.layout[ya[Ja]]=Jb+Ob-j(Ca,Ja)-Ca.layout[Aa[Ja]]:Pb===ma?(Fa=Ca.layout[Aa[Ja]],Ca.layout[ya[Ja]]=Jb+(Ob-Fa)/2):Pb===oa&&(Ca.layout[ya[Ja]]=Jb+i(Ca,Ja))}Jb+=Ob}}if(a.layout.measuredWidth=M(a,ca,d-W),a.layout.measuredHeight=M(a,ea,e-_),Ua===ta?a.layout[Aa[Ia]]=M(a,Ia,db):Ua===va&&(a.layout[Aa[Ia]]=L(K(Ya+Sa,J(a,Ia,db)),Sa)),Va===ta?a.layout[Aa[Ja]]=M(a,Ja,cb+Ta):Va===va&&(a.layout[Aa[Ja]]=L(K(Za+Ta,J(a,Ja,cb+Ta)),Ta)),R){var Qb=!1,Rb=!1;if(Ia!==da&&Ia!==fa||(Qb=!0),Ja!==da&&Ja!==fa||(Rb=!0),Qb||Rb)for(Da=0;Ba>Da;++Da)Ca=a.children[Da],Qb&&N(a,Ca,Ia),Rb&&N(a,Ca,Ja)}for(Oa=Na;void 0!==Oa;)R&&(Ea=U,Fa=U,E(Oa,ca)?Ea=Oa.style.width+q(Oa,ca):G(Oa,X)&&G(Oa,Z)&&(Ea=a.layout.measuredWidth-(m(a,ca)+n(a,ca))-(Oa.style[X]+Oa.style[Z]),Ea=M(Oa,ca,Ea)),E(Oa,ea)?Fa=Oa.style.height+q(Oa,ea):G(Oa,Y)&&G(Oa,$)&&(Fa=a.layout.measuredHeight-(m(a,ea)+n(a,ea))-(Oa.style[Y]+Oa.style[$]),Fa=M(Oa,ea,Fa)),(b(Ea)||b(Fa))&&(Ga=b(Ea)?ta:ua,Ha=b(Fa)?ta:ua,Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=va),A(a)===sa&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=va),S(Oa,Ea,Fa,aa,Ga,Ha,!1,"abs-measure"),Ea=Oa.layout.measuredWidth+q(Oa,ca),Fa=Oa.layout.measuredHeight+q(Oa,ea)),S(Oa,Ea,Fa,aa,ua,ua,!0,"abs-layout"),G(Oa,xa[ca])&&!G(Oa,wa[ca])&&(Oa.layout[wa[ca]]=a.layout[Aa[ca]]-Oa.layout[Aa[ca]]-I(Oa,xa[ca])),G(Oa,xa[ea])&&!G(Oa,wa[ea])&&(Oa.layout[wa[ea]]=a.layout[Aa[ea]]-Oa.layout[Aa[ea]]-I(Oa,xa[ea]))),Oa=Oa.nextChild}}function S(a,b,c,d,e,f,g,h){var i=a.layout,j=a.isDirty&&i.generationCount!==W||i.lastParentDirection!==d;j&&(void 0!==i.cachedMeasurements&&(i.cachedMeasurements=[]),void 0!==i.cachedLayout&&(i.cachedLayout.widthMeasureMode=void 0,i.cachedLayout.heightMeasureMode=void 0));var k;if(g)i.cachedLayout&&i.cachedLayout.availableWidth===b&&i.cachedLayout.availableHeight===c&&i.cachedLayout.widthMeasureMode===e&&i.cachedLayout.heightMeasureMode===f&&(k=i.cachedLayout);else if(i.cachedMeasurements)for(var l=0,m=i.cachedMeasurements.length;m>l;l++)if(i.cachedMeasurements[l].availableWidth===b&&i.cachedMeasurements[l].availableHeight===c&&i.cachedMeasurements[l].widthMeasureMode===e&&i.cachedMeasurements[l].heightMeasureMode===f){k=i.cachedMeasurements[l];break}if(j||void 0===k){if(R(a,b,c,d,e,f,g),i.lastParentDirection=d,void 0===k){var n;g?(void 0===i.cachedLayout&&(i.cachedLayout={}),n=i.cachedLayout):(void 0===i.cachedMeasurements&&(i.cachedMeasurements=[]),n={},i.cachedMeasurements.push(n)),n.availableWidth=b,n.availableHeight=c,n.widthMeasureMode=e,n.heightMeasureMode=f,n.computedWidth=i.measuredWidth,n.computedHeight=i.measuredHeight}}else i.measureWidth=k.computedWidth,i.measureHeight=k.computedHeight;return g&&(a.layout.width=a.layout.measuredWidth,a.layout.height=a.layout.measuredHeight,i.shouldUpdate=!0),i.generationCount=W,j||void 0===k}function T(a,c,d,e){W++,b(c)&&E(a,ca)&&(c=a.style.width+q(a,ca)),b(d)&&E(a,ea)&&(d=a.style.height+q(a,ea));var f=b(c)?ta:ua,g=b(d)?ta:ua;S(a,c,d,e,f,g,!0,"initial")&&P(a,a.layout.direction)}var U,V=!1,W=0,X="left",Y="top",Z="right",$="bottom",_="inherit",aa="ltr",ba="rtl",ca="row",da="row-reverse",ea="column",fa="column-reverse",ga="flex-start",ha="center",ia="flex-end",ja="space-between",ka="space-around",la="flex-start",ma="center",na="flex-end",oa="stretch",pa="relative",qa="absolute",ra="visible",sa="hidden",ta="undefined",ua="exactly",va="at-most",wa={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},xa={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},ya={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},za={row:"width","row-reverse":"width",column:"height","column-reverse":"height"},Aa={row:"measuredWidth","row-reverse":"measuredWidth",column:"measuredHeight","column-reverse":"measuredHeight"};return{layoutNodeImpl:R,computeLayout:T,fillNodes:a}}();return"object"==typeof exports&&(module.exports=a),function(b){a.fillNodes(b),a.computeLayout(b)}}); //# sourceMappingURL=css-layout.min.js.map \ No newline at end of file diff --git a/dist/css-layout.min.js.map b/dist/css-layout.min.js.map index 58ab8daa..4f9fb2e9 100644 --- a/dist/css-layout.min.js.map +++ b/dist/css-layout.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["css-layout.js"],"names":["root","factory","define","amd","exports","module","computeLayout","this","fillNodes","node","layout","isDirty","width","undefined","height","top","left","right","bottom","style","children","measure","length","Error","forEach","isUndefined","value","Number","isNaN","isRowDirection","flexDirection","CSS_FLEX_DIRECTION_ROW","CSS_FLEX_DIRECTION_ROW_REVERSE","isColumnDirection","CSS_FLEX_DIRECTION_COLUMN","CSS_FLEX_DIRECTION_COLUMN_REVERSE","getFlex","flex","isFlexBasisAuto","POSITIVE_FLEX_IS_AUTO","getFlexGrowFactor","getFlexShrinkFactor","getLeadingMargin","axis","marginStart","marginLeft","marginRight","marginTop","marginBottom","margin","getTrailingMargin","marginEnd","getLeadingPadding","paddingStart","paddingLeft","paddingRight","paddingTop","paddingBottom","padding","getTrailingPadding","paddingEnd","getLeadingBorder","borderStartWidth","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth","borderWidth","getTrailingBorder","borderEndWidth","getLeadingPaddingAndBorder","getTrailingPaddingAndBorder","getMarginAxis","getPaddingAndBorderAxis","getJustifyContent","justifyContent","getAlignContent","alignContent","getAlignItem","child","alignSelf","alignItems","resolveAxis","direction","CSS_DIRECTION_RTL","resolveDirection","parentDirection","CSS_DIRECTION_INHERIT","CSS_DIRECTION_LTR","getFlexDirection","getCrossFlexDirection","getPositionType","position","CSS_POSITION_RELATIVE","getOverflow","overflow","CSS_OVERFLOW_VISIBLE","isFlex","isFlexWrap","flexWrap","getDimWithMargin","measuredDim","isStyleDimDefined","dim","isLayoutDimDefined","isPosDefined","pos","isMeasureDefined","getPosition","boundAxisWithinMinAndMax","min","row","minWidth","row-reverse","column","minHeight","column-reverse","max","maxWidth","maxHeight","boundValue","fminf","a","b","fmaxf","boundAxis","setTrailingPosition","size","CSS_POSITION_ABSOLUTE","trailing","getRelativePosition","leading","setPosition","mainAxis","crossAxis","assert","condition","message","layoutNodeImpl","availableWidth","availableHeight","widthMeasureMode","heightMeasureMode","performLayout","CSS_MEASURE_MODE_UNDEFINED","paddingAndBorderAxisRow","paddingAndBorderAxisColumn","marginAxisRow","marginAxisColumn","innerWidth","innerHeight","CSS_MEASURE_MODE_EXACTLY","measuredWidth","measuredHeight","measureDim","CSS_MEASURE_MODE_AT_MOST","childCount","i","childWidth","childHeight","childWidthMeasureMode","childHeightMeasureMode","isMainAxisRow","isNodeFlexWrap","firstAbsoluteChild","currentAbsoluteChild","leadingPaddingAndBorderMain","trailingPaddingAndBorderMain","leadingPaddingAndBorderCross","paddingAndBorderAxisMain","paddingAndBorderAxisCross","measureModeMainDim","measureModeCrossDim","availableInnerWidth","availableInnerHeight","availableInnerMainDim","availableInnerCrossDim","childDirection","nextChild","flexBasis","CSS_UNDEFINED","CSS_OVERFLOW_HIDDEN","layoutNodeInternal","startOfLineIndex","endOfLineIndex","lineCount","totalLineCrossDim","maxLineMainDim","itemsOnLine","sizeConsumedOnCurrentLine","totalFlexGrowFactors","totalFlexShrinkScaledFactors","firstRelativeChild","currentRelativeChild","lineIndex","outerFlexBasis","canSkipFlex","leadingMainDim","betweenMainDim","remainingFreeSpace","remainingFreeSpaceAfterFlex","childFlexBasis","flexShrinkScaledFactor","flexGrowFactor","baseMainSize","boundMainSize","deltaFreeSpace","deltaFlexShrinkScaledFactors","deltaFlexGrowFactors","updatedMainSize","requiresStretchLayout","CSS_ALIGN_STRETCH","CSS_JUSTIFY_FLEX_START","CSS_JUSTIFY_CENTER","CSS_JUSTIFY_FLEX_END","CSS_JUSTIFY_SPACE_BETWEEN","CSS_JUSTIFY_SPACE_AROUND","mainDim","crossDim","containerCrossAxis","leadingCrossDim","alignItem","isCrossSizeDefinite","CSS_ALIGN_FLEX_START","remainingCrossDim","CSS_ALIGN_CENTER","remainingAlignContentDim","crossDimLead","currentLead","CSS_ALIGN_FLEX_END","endIndex","j","startIndex","lineHeight","alignContentAlignItem","needsMainTrailingPos","needsCrossTrailingPos","CSS_LEFT","CSS_RIGHT","CSS_TOP","CSS_BOTTOM","reason","needToVisitNode","generationCount","gCurrentGenerationCount","lastParentDirection","cachedMeasurements","cachedLayout","cachedResults","len","newCacheEntry","push","computedWidth","computedHeight","measureWidth","measureHeight","shouldUpdate","layoutNode"],"mappings":"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","file":"css-layout.min.js","sourcesContent":["// UMD (Universal Module Definition)\n// See https://github.com/umdjs/umd for reference\n//\n// This file uses the following specific UMD implementation:\n// https://github.com/umdjs/umd/blob/master/templates/returnExports.js\n(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.computeLayout = factory();\n }\n}(this, function() {\n /**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nvar computeLayout = (function() {\n \n var POSITIVE_FLEX_IS_AUTO = false;\n \n var gCurrentGenerationCount = 0;\n \n var CSS_UNDEFINED;\n \n var CSS_LEFT = 'left';\n var CSS_TOP = 'top';\n var CSS_RIGHT = 'right';\n var CSS_BOTTOM = 'bottom';\n \n var CSS_DIRECTION_INHERIT = 'inherit';\n var CSS_DIRECTION_LTR = 'ltr';\n var CSS_DIRECTION_RTL = 'rtl';\n\n var CSS_FLEX_DIRECTION_ROW = 'row';\n var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';\n var CSS_FLEX_DIRECTION_COLUMN = 'column';\n var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';\n\n var CSS_JUSTIFY_FLEX_START = 'flex-start';\n var CSS_JUSTIFY_CENTER = 'center';\n var CSS_JUSTIFY_FLEX_END = 'flex-end';\n var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';\n var CSS_JUSTIFY_SPACE_AROUND = 'space-around';\n\n var CSS_ALIGN_FLEX_START = 'flex-start';\n var CSS_ALIGN_CENTER = 'center';\n var CSS_ALIGN_FLEX_END = 'flex-end';\n var CSS_ALIGN_STRETCH = 'stretch';\n\n var CSS_POSITION_RELATIVE = 'relative';\n var CSS_POSITION_ABSOLUTE = 'absolute';\n \n var CSS_OVERFLOW_VISIBLE = 'visible';\n var CSS_OVERFLOW_HIDDEN = 'hidden';\n \n var CSS_MEASURE_MODE_UNDEFINED = 'undefined';\n var CSS_MEASURE_MODE_EXACTLY = 'exactly';\n var CSS_MEASURE_MODE_AT_MOST = 'at-most';\n\n var leading = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var trailing = {\n 'row': 'right',\n 'row-reverse': 'left',\n 'column': 'bottom',\n 'column-reverse': 'top'\n };\n var pos = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var dim = {\n 'row': 'width',\n 'row-reverse': 'width',\n 'column': 'height',\n 'column-reverse': 'height'\n };\n var measuredDim = {\n 'row': 'measuredWidth',\n 'row-reverse': 'measuredWidth',\n 'column': 'measuredHeight',\n 'column-reverse': 'measuredHeight'\n };\n\n // When transpiled to Java / C the node type has layout, children and style\n // properties. For the JavaScript version this function adds these properties\n // if they don't already exist.\n function fillNodes(node) {\n if (!node.layout || node.isDirty) {\n node.layout = {\n width: undefined,\n height: undefined,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n };\n }\n\n if (!node.style) {\n node.style = {};\n }\n\n if (!node.children) {\n node.children = [];\n }\n\n if (node.style.measure && node.children && node.children.length) {\n throw new Error('Using custom measure function is supported only for leaf nodes.');\n }\n\n node.children.forEach(fillNodes);\n return node;\n }\n\n function isUndefined(value) {\n return value === undefined || Number.isNaN(value);\n }\n\n function isRowDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_ROW ||\n flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;\n }\n\n function isColumnDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_COLUMN ||\n flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;\n }\n \n function getFlex(node) {\n if (node.style.flex === undefined) {\n return 0;\n }\n return node.style.flex;\n }\n \n function isFlexBasisAuto(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // All flex values are auto.\n return true;\n } else {\n // A flex value > 0 implies a basis of zero.\n return getFlex(node) <= 0;\n }\n }\n \n function getFlexGrowFactor(node) {\n // Flex grow is implied by positive values for flex.\n if (getFlex(node) > 0) {\n return getFlex(node);\n }\n return 0;\n }\n \n function getFlexShrinkFactor(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // A flex shrink factor of 1 is implied by non-zero values for flex.\n if (getFlex(node) !== 0) {\n return 1;\n }\n } else {\n // A flex shrink factor of 1 is implied by negative values for flex.\n if (getFlex(node) < 0) {\n return 1;\n }\n }\n return 0;\n }\n\n function getLeadingMargin(node, axis) {\n if (node.style.marginStart !== undefined && isRowDirection(axis)) {\n return node.style.marginStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginLeft; break;\n case 'row-reverse': value = node.style.marginRight; break;\n case 'column': value = node.style.marginTop; break;\n case 'column-reverse': value = node.style.marginBottom; break;\n }\n\n if (value !== undefined) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getTrailingMargin(node, axis) {\n if (node.style.marginEnd !== undefined && isRowDirection(axis)) {\n return node.style.marginEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginRight; break;\n case 'row-reverse': value = node.style.marginLeft; break;\n case 'column': value = node.style.marginBottom; break;\n case 'column-reverse': value = node.style.marginTop; break;\n }\n\n if (value != null) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getLeadingPadding(node, axis) {\n if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0\n && isRowDirection(axis)) {\n return node.style.paddingStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingLeft; break;\n case 'row-reverse': value = node.style.paddingRight; break;\n case 'column': value = node.style.paddingTop; break;\n case 'column-reverse': value = node.style.paddingBottom; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getTrailingPadding(node, axis) {\n if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0\n && isRowDirection(axis)) {\n return node.style.paddingEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingRight; break;\n case 'row-reverse': value = node.style.paddingLeft; break;\n case 'column': value = node.style.paddingBottom; break;\n case 'column-reverse': value = node.style.paddingTop; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getLeadingBorder(node, axis) {\n if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderStartWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderLeftWidth; break;\n case 'row-reverse': value = node.style.borderRightWidth; break;\n case 'column': value = node.style.borderTopWidth; break;\n case 'column-reverse': value = node.style.borderBottomWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getTrailingBorder(node, axis) {\n if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderEndWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderRightWidth; break;\n case 'row-reverse': value = node.style.borderLeftWidth; break;\n case 'column': value = node.style.borderBottomWidth; break;\n case 'column-reverse': value = node.style.borderTopWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getLeadingPaddingAndBorder(node, axis) {\n return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);\n }\n\n function getTrailingPaddingAndBorder(node, axis) {\n return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);\n }\n\n function getMarginAxis(node, axis) {\n return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);\n }\n\n function getPaddingAndBorderAxis(node, axis) {\n return getLeadingPaddingAndBorder(node, axis) +\n getTrailingPaddingAndBorder(node, axis);\n }\n\n function getJustifyContent(node) {\n if (node.style.justifyContent) {\n return node.style.justifyContent;\n }\n return 'flex-start';\n }\n\n function getAlignContent(node) {\n if (node.style.alignContent) {\n return node.style.alignContent;\n }\n return 'flex-start';\n }\n\n function getAlignItem(node, child) {\n if (child.style.alignSelf) {\n return child.style.alignSelf;\n }\n if (node.style.alignItems) {\n return node.style.alignItems;\n }\n return 'stretch';\n }\n\n function resolveAxis(axis, direction) {\n if (direction === CSS_DIRECTION_RTL) {\n if (axis === CSS_FLEX_DIRECTION_ROW) {\n return CSS_FLEX_DIRECTION_ROW_REVERSE;\n } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {\n return CSS_FLEX_DIRECTION_ROW;\n }\n }\n\n return axis;\n }\n\n function resolveDirection(node, parentDirection) {\n var direction;\n if (node.style.direction) {\n direction = node.style.direction;\n } else {\n direction = CSS_DIRECTION_INHERIT;\n }\n\n if (direction === CSS_DIRECTION_INHERIT) {\n direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection);\n }\n\n return direction;\n }\n\n function getFlexDirection(node) {\n if (node.style.flexDirection) {\n return node.style.flexDirection;\n }\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n\n function getCrossFlexDirection(flexDirection, direction) {\n if (isColumnDirection(flexDirection)) {\n return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);\n } else {\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n }\n\n function getPositionType(node) {\n if (node.style.position) {\n return node.style.position;\n }\n return CSS_POSITION_RELATIVE;\n }\n \n function getOverflow(node) {\n if (node.style.overflow) {\n return node.style.overflow;\n }\n return CSS_OVERFLOW_VISIBLE;\n }\n\n function isFlex(node) {\n return (\n getPositionType(node) === CSS_POSITION_RELATIVE &&\n node.style.flex !== undefined && node.style.flex !== 0\n );\n }\n\n function isFlexWrap(node) {\n return node.style.flexWrap === 'wrap';\n }\n\n function getDimWithMargin(node, axis) {\n return node.layout[measuredDim[axis]] + getMarginAxis(node, axis);\n }\n \n function isStyleDimDefined(node, axis) { \n return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;\n }\n \n function isLayoutDimDefined(node, axis) { \n return node.layout[measuredDim[axis]] !== undefined && node.layout[measuredDim[axis]] >= 0;\n }\n\n function isPosDefined(node, pos) {\n return node.style[pos] !== undefined;\n }\n\n function isMeasureDefined(node) {\n return node.style.measure !== undefined;\n }\n\n function getPosition(node, pos) {\n if (node.style[pos] !== undefined) {\n return node.style[pos];\n }\n return 0;\n }\n \n function boundAxisWithinMinAndMax(node, axis, value) {\n var min = {\n 'row': node.style.minWidth,\n 'row-reverse': node.style.minWidth,\n 'column': node.style.minHeight,\n 'column-reverse': node.style.minHeight\n }[axis];\n\n var max = {\n 'row': node.style.maxWidth,\n 'row-reverse': node.style.maxWidth,\n 'column': node.style.maxHeight,\n 'column-reverse': node.style.maxHeight\n }[axis];\n\n var boundValue = value;\n if (max !== undefined && max >= 0 && boundValue > max) {\n boundValue = max;\n }\n if (min !== undefined && min >= 0 && boundValue < min) {\n boundValue = min;\n }\n return boundValue;\n }\n \n function fminf(a, b) {\n if (a < b) {\n return a;\n }\n return b;\n }\n\n function fmaxf(a, b) {\n if (a > b) {\n return a;\n }\n return b;\n }\n \n // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the\n // padding and border amount.\n function boundAxis(node, axis, value) {\n return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis));\n }\n\n function setTrailingPosition(node, child, axis) {\n var size = (getPositionType(child) === CSS_POSITION_ABSOLUTE) ?\n 0 :\n child.layout[measuredDim[axis]];\n child.layout[trailing[axis]] = node.layout[measuredDim[axis]] - size - child.layout[pos[axis]];\n }\n\n // If both left and right are defined, then use left. Otherwise return\n // +left or -right depending on which is defined.\n function getRelativePosition(node, axis) {\n if (node.style[leading[axis]] !== undefined) {\n return getPosition(node, leading[axis]);\n }\n return -getPosition(node, trailing[axis]);\n }\n \n function setPosition(node, direction) {\n var mainAxis = resolveAxis(getFlexDirection(node), direction);\n var crossAxis = getCrossFlexDirection(mainAxis, direction);\n \n node.layout[leading[mainAxis]] = getLeadingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[leading[crossAxis]] = getLeadingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n node.layout[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n }\n \n function assert(condition, message) {\n if (!condition) {\n throw new Error(message);\n }\n }\n \n //\n // This is the main routine that implements a subset of the flexbox layout algorithm\n // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/.\n //\n // Limitations of this algorithm, compared to the full standard:\n // * Display property is always assumed to be 'flex' except for Text nodes, which\n // are assumed to be 'inline-flex'.\n // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are\n // stacked in document order.\n // * The 'order' property is not supported. The order of flex items is always defined\n // by document order.\n // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse'\n // and 'hidden' are not supported.\n // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The\n // rarely-used 'wrap-reverse' is not supported.\n // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and\n // flexBasis, this algorithm supports only the three most common combinations:\n // flex: 0 is equiavlent to flex: 0 0 auto\n // flex: n (where n is a positive value) is equivalent to flex: n 1 auto\n // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0\n // This is faster because the content doesn't need to be measured, but it's\n // less flexible because the basis is always 0 and can't be overriden with\n // the width/height attributes.\n // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto\n // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel\n // values, and the default value is 0.\n // * The 'baseline' value is not supported for alignItems and alignSelf properties.\n // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be\n // specified as pixel values, not as percentages.\n // * There is no support for calculation of dimensions based on intrinsic aspect ratios\n // (e.g. images).\n // * There is no support for forced breaks.\n // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text).\n //\n // Deviations from standard:\n // * Section 4.5 of the spec indicates that all flex items have a default minimum\n // main size. For text blocks, for example, this is the width of the widest word. \n // Calculating the minimum width is expensive, so we forego it and assume a default \n // minimum main size of 0.\n // * Min/Max sizes in the main axis are not honored when resolving flexible lengths.\n // * The spec indicates that the default value for 'flexDirection' is 'row', but\n // the algorithm below assumes a default of 'column'.\n //\n // Input parameters:\n // - node: current node to be sized and layed out\n // - availableWidth & availableHeight: available size to be used for sizing the node\n // or CSS_UNDEFINED if the size is not available; interpretation depends on layout\n // flags\n // - parentDirection: the inline (text) direction within the parent (left-to-right or\n // right-to-left)\n // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation)\n // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation)\n // - performLayout: specifies whether the caller is interested in just the dimensions\n // of the node or it requires the entire node and its subtree to be layed out\n // (with final positions)\n //\n // Details:\n // This routine is called recursively to lay out subtrees of flexbox elements. It uses the\n // information in node.style, which is treated as a read-only input. It is responsible for\n // setting the layout.direction and layout.measured_dimensions fields for the input node as well\n // as the layout.position and layout.line_index fields for its child nodes. The\n // layout.measured_dimensions field includes any border or padding for the node but does\n // not include margins.\n //\n // The spec describes four different layout modes: \"fill available\", \"max content\", \"min content\",\n // and \"fit content\". Of these, we don't use \"min content\" because we don't support default\n // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode\n // from the spec (https://www.w3.org/TR/css3-sizing/#terms):\n // - CSS_MEASURE_MODE_UNDEFINED: max content\n // - CSS_MEASURE_MODE_EXACTLY: fill available\n // - CSS_MEASURE_MODE_AT_MOST: fit content\n // \n // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of\n // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension.\n //\n function layoutNodeImpl(node, availableWidth, availableHeight, /*css_direction_t*/parentDirection, widthMeasureMode, heightMeasureMode, performLayout) {\n assert(isUndefined(availableWidth) ? widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n assert(isUndefined(availableHeight) ? heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n \n var/*float*/ paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n var/*float*/ marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // Set the resolved resolution in the node's layout.\n var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);\n node.layout.direction = direction;\n\n // For content (text) nodes, determine the dimensions based on the text contents.\n if (isMeasureDefined(node)) {\n var/*float*/ innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n \n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n\n // Don't bother sizing the text if both dimensions are already defined.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n } else if (innerWidth <= 0) {\n\n // Don't bother sizing the text if there's no horizontal space.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n } else {\n\n // Measure the text under the current constraints.\n var/*css_dim_t*/ measureDim = node.style.measure(\n /*(c)!node->context,*/\n /*(java)!layoutContext.measureOutput,*/\n innerWidth,\n widthMeasureMode,\n innerHeight,\n heightMeasureMode\n );\n\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.width + paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.height + paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n }\n \n return;\n }\n\n // For nodes with no children, use the available values if they were provided, or\n // the minimum size as indicated by the padding and border sizes.\n var/*int*/ childCount = node.children.length;\n if (childCount === 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n return;\n }\n\n // If we're not being asked to perform a full layout, we can handle a number of common\n // cases here without incurring the cost of the remaining function.\n if (!performLayout) {\n // If we're being asked to size the content with an at most constraint but there is no available width,\n // the measurement will always be zero.\n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 &&\n heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n \n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn));\n return;\n }\n\n if (heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow));\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n \n // If we're being asked to use an exact width/height, there's no need to measure the children.\n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n return;\n }\n }\n\n // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM\n var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction);\n var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction);\n var/*bool*/ isMainAxisRow = isRowDirection(mainAxis);\n var/*css_justify_t*/ justifyContent = getJustifyContent(node);\n var/*bool*/ isNodeFlexWrap = isFlexWrap(node);\n\n var/*css_node_t**/ firstAbsoluteChild = undefined;\n var/*css_node_t**/ currentAbsoluteChild = undefined;\n\n var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);\n var/*float*/ trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis);\n var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);\n var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);\n var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);\n \n var/*css_measure_mode_t*/ measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;\n var/*css_measure_mode_t*/ measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;\n\n // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS\n var/*float*/ availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n var/*float*/ availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;\n var/*float*/ availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;\n\n // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM\n var/*css_node_t**/ child;\n var/*int*/ i;\n var/*float*/ childWidth;\n var/*float*/ childHeight;\n var/*css_measure_mode_t*/ childWidthMeasureMode;\n var/*css_measure_mode_t*/ childHeightMeasureMode;\n for (i = 0; i < childCount; i++) {\n child = node.children[i];\n\n if (performLayout) {\n // Set the initial position (relative to the parent).\n var/*css_direction_t*/ childDirection = resolveDirection(child, direction);\n setPosition(child, childDirection);\n }\n \n // Absolute-positioned children don't participate in flex layout. Add them\n // to a list that we can process later.\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n\n // Store a private linked list of absolutely positioned children\n // so that we can efficiently traverse them later.\n if (firstAbsoluteChild === undefined) {\n firstAbsoluteChild = child;\n }\n if (currentAbsoluteChild !== undefined) {\n currentAbsoluteChild.nextChild = child;\n }\n currentAbsoluteChild = child;\n child.nextChild = undefined;\n } else {\n \n if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n \n // The width is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.width, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW));\n } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n \n // The height is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.height, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN));\n } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) {\n \n // If the basis isn't 'auto', it is assumed to be zero.\n child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));\n } else {\n \n // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n \n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n \n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n // Measure the child\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'measure');\n \n child.layout.flexBasis = fmaxf(isMainAxisRow ? child.layout.measuredWidth : child.layout.measuredHeight, getPaddingAndBorderAxis(child, mainAxis));\n }\n }\n }\n\n // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES\n \n // Indexes of children that represent the first and last items in the line.\n var/*int*/ startOfLineIndex = 0;\n var/*int*/ endOfLineIndex = 0;\n \n // Number of lines.\n var/*int*/ lineCount = 0;\n \n // Accumulated cross dimensions of all lines so far.\n var/*float*/ totalLineCrossDim = 0;\n\n // Max main dimension of all the lines.\n var/*float*/ maxLineMainDim = 0;\n\n while (endOfLineIndex < childCount) {\n \n // Number of items on the currently line. May be different than the difference\n // between start and end indicates because we skip over absolute-positioned items.\n var/*int*/ itemsOnLine = 0;\n\n // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin\n // of all the children on the current line. This will be used in order to\n // either set the dimensions of the node if none already exist or to compute\n // the remaining space left for the flexible children.\n var/*float*/ sizeConsumedOnCurrentLine = 0;\n\n var/*float*/ totalFlexGrowFactors = 0;\n var/*float*/ totalFlexShrinkScaledFactors = 0;\n\n i = startOfLineIndex;\n\n // Maintain a linked list of the child nodes that can shrink and/or grow.\n var/*css_node_t**/ firstRelativeChild = undefined;\n var/*css_node_t**/ currentRelativeChild = undefined;\n\n // Add items to the current line until it's full or we run out of items.\n while (i < childCount) {\n child = node.children[i];\n child.lineIndex = lineCount;\n\n if (getPositionType(child) !== CSS_POSITION_ABSOLUTE) {\n var/*float*/ outerFlexBasis = child.layout.flexBasis + getMarginAxis(child, mainAxis);\n \n // If this is a multi-line flow and this item pushes us over the available size, we've\n // hit the end of the current line. Break out of the loop and lay out the current line.\n if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) {\n break;\n }\n\n sizeConsumedOnCurrentLine += outerFlexBasis;\n itemsOnLine++;\n\n if (isFlex(child)) {\n totalFlexGrowFactors += getFlexGrowFactor(child);\n \n // Unlike the grow factor, the shrink factor is scaled relative to the child\n // dimension.\n totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis;\n }\n\n // Store a private linked list of children that need to be layed out.\n if (firstRelativeChild === undefined) {\n firstRelativeChild = child;\n }\n if (currentRelativeChild !== undefined) {\n currentRelativeChild.nextChild = child;\n }\n currentRelativeChild = child;\n child.nextChild = undefined;\n }\n \n i++;\n endOfLineIndex++;\n }\n \n // If we don't need to measure the cross axis, we can skip the entire flex step.\n var/*bool*/ canSkipFlex = !performLayout && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY;\n\n // In order to position the elements in the main axis, we have two\n // controls. The space between the beginning and the first element\n // and the space between each two elements.\n var/*float*/ leadingMainDim = 0;\n var/*float*/ betweenMainDim = 0;\n\n // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS\n // Calculate the remaining available space that needs to be allocated.\n // If the main dimension size isn't known, it is computed based on\n // the line length, so there's no more space left to distribute.\n var/*float*/ remainingFreeSpace = 0;\n if (!isUndefined(availableInnerMainDim)) {\n remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;\n } else if (sizeConsumedOnCurrentLine < 0) {\n // availableInnerMainDim is indefinite which means the node is being sized based on its content.\n // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for\n // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.\n remainingFreeSpace = -sizeConsumedOnCurrentLine;\n }\n \n var/*float*/ remainingFreeSpaceAfterFlex = remainingFreeSpace;\n\n if (!canSkipFlex) {\n var/*float*/ childFlexBasis;\n var/*float*/ flexShrinkScaledFactor;\n var/*float*/ flexGrowFactor;\n var/*float*/ baseMainSize;\n var/*float*/ boundMainSize;\n \n // Do two passes over the flex items to figure out how to distribute the remaining space.\n // The first pass finds the items whose min/max constraints trigger, freezes them at those\n // sizes, and excludes those sizes from the remaining space. The second pass sets the size\n // of each flexible item. It distributes the remaining space amongst the items whose min/max\n // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing\n // their min/max constraints to trigger again. \n //\n // This two pass approach for resolving min/max constraints deviates from the spec. The\n // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process\n // that needs to be repeated a variable number of times. The algorithm implemented here\n // won't handle all cases but it was simpler to implement and it mitigates performance\n // concerns because we know exactly how many passes it'll do.\n \n // First pass: detect the flex items whose min/max constraints trigger\n var/*float*/ deltaFreeSpace = 0;\n var/*float*/ deltaFlexShrinkScaledFactors = 0;\n var/*float*/ deltaFlexGrowFactors = 0;\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n \n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize;\n deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor;\n }\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize;\n deltaFlexGrowFactors -= flexGrowFactor;\n }\n }\n }\n \n currentRelativeChild = currentRelativeChild.nextChild;\n }\n \n totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors;\n totalFlexGrowFactors += deltaFlexGrowFactors;\n remainingFreeSpace += deltaFreeSpace;\n remainingFreeSpaceAfterFlex = remainingFreeSpace;\n \n // Second pass: resolve the sizes of the flexible items\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n var/*float*/ updatedMainSize = childFlexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n \n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor);\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor);\n }\n }\n \n remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis;\n \n if (isMainAxisRow) {\n childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n \n if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childHeight = currentRelativeChild.style.height + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n } else {\n childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n \n if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childWidth = currentRelativeChild.style.width + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n }\n \n var/*bool*/ requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) &&\n getAlignItem(node, currentRelativeChild) === CSS_ALIGN_STRETCH;\n\n // Recursively call the layout algorithm for this child with the updated main size.\n layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, 'flex');\n\n currentRelativeChild = currentRelativeChild.nextChild;\n }\n }\n \n remainingFreeSpace = remainingFreeSpaceAfterFlex;\n\n // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION\n\n // At this point, all the children have their dimensions set in the main axis.\n // Their dimensions are also set in the cross axis with the exception of items\n // that are aligned 'stretch'. We need to compute these stretch values and\n // set the final positions.\n\n // If we are using \"at most\" rules in the main axis, we won't distribute\n // any remaining space at this point.\n if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n remainingFreeSpace = 0;\n }\n\n // Use justifyContent to figure out how to allocate the remaining space\n // available in the main axis.\n if (justifyContent !== CSS_JUSTIFY_FLEX_START) {\n if (justifyContent === CSS_JUSTIFY_CENTER) {\n leadingMainDim = remainingFreeSpace / 2;\n } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {\n leadingMainDim = remainingFreeSpace;\n } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {\n remainingFreeSpace = fmaxf(remainingFreeSpace, 0);\n if (itemsOnLine > 1) {\n betweenMainDim = remainingFreeSpace / (itemsOnLine - 1);\n } else {\n betweenMainDim = 0;\n }\n } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {\n // Space on the edges is half of the space between elements\n betweenMainDim = remainingFreeSpace / itemsOnLine;\n leadingMainDim = betweenMainDim / 2;\n }\n }\n\n var/*float*/ mainDim = leadingPaddingAndBorderMain + leadingMainDim;\n var/*float*/ crossDim = 0;\n\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[mainAxis])) {\n if (performLayout) {\n // In case the child is position absolute and has left/top being\n // defined, we override the position to whatever the user said\n // (and margin/border).\n child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) +\n getLeadingBorder(node, mainAxis) +\n getLeadingMargin(child, mainAxis);\n }\n } else {\n if (performLayout) {\n // If the child is position absolute (without top/left) or relative,\n // we put it at the current accumulated offset.\n child.layout[pos[mainAxis]] += mainDim;\n }\n \n // Now that we placed the element, we need to update the variables.\n // We need to do that only for relative elements. Absolute elements\n // do not take part in that phase.\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n if (canSkipFlex) {\n // If we skipped the flex step, then we can't rely on the measuredDims because\n // they weren't computed. This means we can't call getDimWithMargin.\n mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child.layout.flexBasis;\n crossDim = availableInnerCrossDim;\n } else {\n // The main dimension is the sum of all the elements dimension plus\n // the spacing.\n mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);\n \n // The cross dimension is the max of the elements dimension since there\n // can only be one element in that cross dimension.\n crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis));\n }\n }\n }\n }\n\n mainDim += trailingPaddingAndBorderMain;\n \n var/*float*/ containerCrossAxis = availableInnerCrossDim;\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n // Compute the cross axis from the max cross dimension of the children.\n containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n \n if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim);\n }\n }\n\n // If there's no flex wrap, the cross dimension is defined by the container.\n if (!isNodeFlexWrap && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY) {\n crossDim = availableInnerCrossDim;\n }\n\n // Clamp to the min/max size specified on the container.\n crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n\n // STEP 7: CROSS-AXIS ALIGNMENT\n // We can skip child alignment if we're just measuring the container.\n if (performLayout) {\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n // If the child is absolutely positioned and has a top/left/bottom/right\n // set, override all the previously computed positions to set it correctly.\n if (isPosDefined(child, leading[crossAxis])) {\n child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +\n getLeadingBorder(node, crossAxis) +\n getLeadingMargin(child, crossAxis);\n } else {\n child.layout[pos[crossAxis]] = leadingPaddingAndBorderCross +\n getLeadingMargin(child, crossAxis);\n }\n } else {\n var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross;\n\n // For a relative children, we're either using alignItems (parent) or\n // alignSelf (child) in order to determine the position in the cross axis\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n \n // If the child uses align stretch, we need to lay it out one more time, this time\n // forcing the cross-axis size to be the computed cross size for the current line.\n if (alignItem === CSS_ALIGN_STRETCH) {\n childWidth = child.layout.measuredWidth + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childHeight = child.layout.measuredHeight + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n var/*bool*/ isCrossSizeDefinite = false;\n \n if (isMainAxisRow) {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeight = crossDim;\n } else {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW);\n childWidth = crossDim;\n }\n \n // If the child defines a definite size for its cross axis, there's no need to stretch.\n if (!isCrossSizeDefinite) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, 'stretch');\n }\n } else if (alignItem !== CSS_ALIGN_FLEX_START) {\n var/*float*/ remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis);\n\n if (alignItem === CSS_ALIGN_CENTER) {\n leadingCrossDim += remainingCrossDim / 2;\n } else { // CSS_ALIGN_FLEX_END\n leadingCrossDim += remainingCrossDim;\n }\n }\n\n // And we apply the position\n child.layout[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim;\n }\n }\n }\n\n totalLineCrossDim += crossDim;\n maxLineMainDim = fmaxf(maxLineMainDim, mainDim);\n\n // Reset variables for new line.\n lineCount++;\n startOfLineIndex = endOfLineIndex;\n endOfLineIndex = startOfLineIndex;\n }\n\n // STEP 8: MULTI-LINE CONTENT ALIGNMENT\n if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) {\n var/*float*/ remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;\n\n var/*float*/ crossDimLead = 0;\n var/*float*/ currentLead = leadingPaddingAndBorderCross;\n\n var/*css_align_t*/ alignContent = getAlignContent(node);\n if (alignContent === CSS_ALIGN_FLEX_END) {\n currentLead += remainingAlignContentDim;\n } else if (alignContent === CSS_ALIGN_CENTER) {\n currentLead += remainingAlignContentDim / 2;\n } else if (alignContent === CSS_ALIGN_STRETCH) {\n if (availableInnerCrossDim > totalLineCrossDim) {\n crossDimLead = (remainingAlignContentDim / lineCount);\n }\n }\n\n var/*int*/ endIndex = 0;\n for (i = 0; i < lineCount; ++i) {\n var/*int*/ startIndex = endIndex;\n var/*int*/ j;\n\n // compute the line's height and find the endIndex\n var/*float*/ lineHeight = 0;\n for (j = startIndex; j < childCount; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n if (child.lineIndex !== i) {\n break;\n }\n if (isLayoutDimDefined(child, crossAxis)) {\n lineHeight = fmaxf(lineHeight,\n child.layout[measuredDim[crossAxis]] + getMarginAxis(child, crossAxis));\n }\n }\n endIndex = j;\n lineHeight += crossDimLead;\n\n if (performLayout) {\n for (j = startIndex; j < endIndex; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n\n var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child);\n if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {\n child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[measuredDim[crossAxis]];\n } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {\n childHeight = child.layout[measuredDim[crossAxis]];\n child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;\n } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n // TODO(prenaux): Correctly set the height of items with indefinite\n // (auto) crossAxis dimension.\n }\n }\n }\n\n currentLead += lineHeight;\n }\n }\n\n // STEP 9: COMPUTING FINAL DIMENSIONS\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n\n // If the user didn't specify a width or height for the node, set the\n // dimensions based on the children.\n if (measureModeMainDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim);\n } else if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[mainAxis]] = fmaxf(\n fminf(availableInnerMainDim + paddingAndBorderAxisMain,\n boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)),\n paddingAndBorderAxisMain);\n }\n\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross);\n } else if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[crossAxis]] = fmaxf(\n fminf(availableInnerCrossDim + paddingAndBorderAxisCross,\n boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)),\n paddingAndBorderAxisCross);\n }\n \n // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN\n if (performLayout) {\n var/*bool*/ needsMainTrailingPos = false;\n var/*bool*/ needsCrossTrailingPos = false;\n\n if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsMainTrailingPos = true;\n }\n\n if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsCrossTrailingPos = true;\n }\n\n // Set trailing position if necessary.\n if (needsMainTrailingPos || needsCrossTrailingPos) {\n for (i = 0; i < childCount; ++i) {\n child = node.children[i];\n\n if (needsMainTrailingPos) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n if (needsCrossTrailingPos) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n }\n }\n \n // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN\n currentAbsoluteChild = firstAbsoluteChild;\n while (currentAbsoluteChild !== undefined) {\n // Now that we know the bounds of the container, perform layout again on the\n // absolutely-positioned children.\n if (performLayout) {\n\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n\n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = currentAbsoluteChild.style.width + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n } else {\n // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) {\n childWidth = node.layout.measuredWidth -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) -\n (currentAbsoluteChild.style[CSS_LEFT] + currentAbsoluteChild.style[CSS_RIGHT]);\n childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth);\n }\n }\n \n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = currentAbsoluteChild.style.height + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n } else {\n // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) {\n childHeight = node.layout.measuredHeight -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) -\n (currentAbsoluteChild.style[CSS_TOP] + currentAbsoluteChild.style[CSS_BOTTOM]);\n childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight);\n }\n }\n\n // If we're still missing one or the other dimension, measure the content.\n if (isUndefined(childWidth) || isUndefined(childHeight)) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n \n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'abs-measure');\n childWidth = currentAbsoluteChild.layout.measuredWidth + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n childHeight = currentAbsoluteChild.layout.measuredHeight + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n }\n \n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, 'abs-layout');\n \n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_ROW]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]);\n }\n \n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_COLUMN]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]);\n }\n }\n\n currentAbsoluteChild = currentAbsoluteChild.nextChild;\n }\n }\n \n //\n // This is a wrapper around the layoutNodeImpl function. It determines\n // whether the layout request is redundant and can be skipped.\n //\n // Parameters:\n // Input parameters are the same as layoutNodeImpl (see above)\n // Return parameter is true if layout was performed, false if skipped\n //\n function layoutNodeInternal(node, availableWidth, availableHeight, parentDirection,\n widthMeasureMode, heightMeasureMode, performLayout, reason) {\n var layout = node.layout;\n\n var needToVisitNode = (node.isDirty && layout.generationCount !== gCurrentGenerationCount) ||\n layout.lastParentDirection !== parentDirection;\n\n if (needToVisitNode) {\n // Invalidate the cached results.\n if (layout.cachedMeasurements !== undefined) {\n layout.cachedMeasurements = []; \n }\n if (layout.cachedLayout !== undefined) {\n layout.cachedLayout.widthMeasureMode = undefined;\n layout.cachedLayout.heightMeasureMode = undefined;\n }\n }\n\n var cachedResults;\n \n // Determine whether the results are already cached. We maintain a separate\n // cache for layouts and measurements. A layout operation modifies the positions\n // and dimensions for nodes in the subtree. The algorithm assumes that each node\n // gets layed out a maximum of one time per tree layout, but multiple measurements\n // may be required to resolve all of the flex dimensions.\n if (performLayout) {\n if (layout.cachedLayout &&\n layout.cachedLayout.availableWidth === availableWidth &&\n layout.cachedLayout.availableHeight === availableHeight &&\n layout.cachedLayout.widthMeasureMode === widthMeasureMode &&\n layout.cachedLayout.heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedLayout;\n }\n } else if (layout.cachedMeasurements) {\n for (var i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (layout.cachedMeasurements[i].availableWidth === availableWidth &&\n layout.cachedMeasurements[i].availableHeight === availableHeight &&\n layout.cachedMeasurements[i].widthMeasureMode === widthMeasureMode &&\n layout.cachedMeasurements[i].heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n \n if (!needToVisitNode && cachedResults !== undefined) {\n layout.measureWidth = cachedResults.computedWidth;\n layout.measureHeight = cachedResults.computedHeight;\n } else {\n layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout);\n layout.lastParentDirection = parentDirection;\n \n if (cachedResults === undefined) {\n var newCacheEntry;\n if (performLayout) {\n // Use the single layout cache entry.\n if (layout.cachedLayout === undefined) {\n layout.cachedLayout = {};\n }\n newCacheEntry = layout.cachedLayout;\n } else {\n // Allocate a new measurement cache entry.\n if (layout.cachedMeasurements === undefined) {\n layout.cachedMeasurements = [];\n }\n newCacheEntry = {};\n layout.cachedMeasurements.push(newCacheEntry);\n }\n \n newCacheEntry.availableWidth = availableWidth;\n newCacheEntry.availableHeight = availableHeight;\n newCacheEntry.widthMeasureMode = widthMeasureMode;\n newCacheEntry.heightMeasureMode = heightMeasureMode;\n newCacheEntry.computedWidth = layout.measuredWidth;\n newCacheEntry.computedHeight = layout.measuredHeight;\n }\n }\n \n if (performLayout) {\n node.layout.width = node.layout.measuredWidth;\n node.layout.height = node.layout.measuredHeight;\n layout.shouldUpdate = true;\n }\n \n layout.generationCount = gCurrentGenerationCount;\n return (needToVisitNode || cachedResults === undefined);\n }\n \n function layoutNode(node, availableWidth, availableHeight, parentDirection) {\n // Increment the generation count. This will force the recursive routine to visit\n // all dirty nodes at least once. Subsequent visits will be skipped if the input\n // parameters don't change.\n gCurrentGenerationCount++;\n \n // If the caller didn't specify a height/width, use the dimensions\n // specified in the style.\n if (isUndefined(availableWidth) && isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {\n availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n }\n if (isUndefined(availableHeight) && isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n }\n \n var widthMeasureMode = isUndefined(availableWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n var heightMeasureMode = isUndefined(availableHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n \n if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, 'initial')) {\n setPosition(node, node.layout.direction);\n }\n }\n\n return {\n layoutNodeImpl: layoutNodeImpl,\n computeLayout: layoutNode,\n fillNodes: fillNodes\n };\n})();\n\n// This module export is only used for the purposes of unit testing this file. When\n// the library is packaged this file is included within css-layout.js which forms\n// the public API.\nif (typeof exports === 'object') {\n module.exports = computeLayout;\n}\n\n\n return function(node) {\n /*eslint-disable */\n // disabling ESLint because this code relies on the above include\n computeLayout.fillNodes(node);\n computeLayout.computeLayout(node);\n /*eslint-enable */\n };\n}));\n"]} \ No newline at end of file +{"version":3,"sources":["css-layout.js"],"names":["root","factory","define","amd","exports","module","computeLayout","this","fillNodes","node","layout","isDirty","width","undefined","height","top","left","right","bottom","style","children","measure","length","Error","forEach","isUndefined","value","Number","isNaN","isRowDirection","flexDirection","CSS_FLEX_DIRECTION_ROW","CSS_FLEX_DIRECTION_ROW_REVERSE","isColumnDirection","CSS_FLEX_DIRECTION_COLUMN","CSS_FLEX_DIRECTION_COLUMN_REVERSE","getFlex","flex","isFlexBasisAuto","POSITIVE_FLEX_IS_AUTO","getFlexGrowFactor","getFlexShrinkFactor","getLeadingMargin","axis","marginStart","marginLeft","marginRight","marginTop","marginBottom","margin","getTrailingMargin","marginEnd","getLeadingPadding","paddingStart","paddingLeft","paddingRight","paddingTop","paddingBottom","padding","getTrailingPadding","paddingEnd","getLeadingBorder","borderStartWidth","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth","borderWidth","getTrailingBorder","borderEndWidth","getLeadingPaddingAndBorder","getTrailingPaddingAndBorder","getMarginAxis","getPaddingAndBorderAxis","getJustifyContent","justifyContent","getAlignContent","alignContent","getAlignItem","child","alignSelf","alignItems","resolveAxis","direction","CSS_DIRECTION_RTL","resolveDirection","parentDirection","CSS_DIRECTION_INHERIT","CSS_DIRECTION_LTR","getFlexDirection","getCrossFlexDirection","getPositionType","position","CSS_POSITION_RELATIVE","getOverflow","overflow","CSS_OVERFLOW_VISIBLE","isFlex","isFlexWrap","flexWrap","getDimWithMargin","measuredDim","isStyleDimDefined","dim","isLayoutDimDefined","isPosDefined","pos","isMeasureDefined","getPosition","boundAxisWithinMinAndMax","min","row","minWidth","row-reverse","column","minHeight","column-reverse","max","maxWidth","maxHeight","boundValue","fminf","a","b","fmaxf","boundAxis","setTrailingPosition","size","CSS_POSITION_ABSOLUTE","trailing","getRelativePosition","leading","setPosition","mainAxis","crossAxis","assert","condition","message","layoutNodeImpl","availableWidth","availableHeight","widthMeasureMode","heightMeasureMode","performLayout","CSS_MEASURE_MODE_UNDEFINED","paddingAndBorderAxisRow","paddingAndBorderAxisColumn","marginAxisRow","marginAxisColumn","innerWidth","innerHeight","CSS_MEASURE_MODE_EXACTLY","measuredWidth","measuredHeight","measureDim","CSS_MEASURE_MODE_AT_MOST","childCount","i","childWidth","childHeight","childWidthMeasureMode","childHeightMeasureMode","isMainAxisRow","isNodeFlexWrap","firstAbsoluteChild","currentAbsoluteChild","leadingPaddingAndBorderMain","trailingPaddingAndBorderMain","leadingPaddingAndBorderCross","paddingAndBorderAxisMain","paddingAndBorderAxisCross","measureModeMainDim","measureModeCrossDim","availableInnerWidth","availableInnerHeight","availableInnerMainDim","availableInnerCrossDim","childDirection","nextChild","flexBasis","CSS_UNDEFINED","CSS_OVERFLOW_HIDDEN","layoutNodeInternal","startOfLineIndex","endOfLineIndex","lineCount","totalLineCrossDim","maxLineMainDim","itemsOnLine","sizeConsumedOnCurrentLine","totalFlexGrowFactors","totalFlexShrinkScaledFactors","firstRelativeChild","currentRelativeChild","lineIndex","outerFlexBasis","canSkipFlex","leadingMainDim","betweenMainDim","remainingFreeSpace","originalRemainingFreeSpace","deltaFreeSpace","childFlexBasis","flexShrinkScaledFactor","flexGrowFactor","baseMainSize","boundMainSize","deltaFlexShrinkScaledFactors","deltaFlexGrowFactors","updatedMainSize","requiresStretchLayout","CSS_ALIGN_STRETCH","CSS_JUSTIFY_FLEX_START","CSS_JUSTIFY_CENTER","CSS_JUSTIFY_FLEX_END","CSS_JUSTIFY_SPACE_BETWEEN","CSS_JUSTIFY_SPACE_AROUND","mainDim","crossDim","containerCrossAxis","leadingCrossDim","alignItem","isCrossSizeDefinite","CSS_ALIGN_FLEX_START","remainingCrossDim","CSS_ALIGN_CENTER","remainingAlignContentDim","crossDimLead","currentLead","CSS_ALIGN_FLEX_END","endIndex","j","startIndex","lineHeight","alignContentAlignItem","needsMainTrailingPos","needsCrossTrailingPos","CSS_LEFT","CSS_RIGHT","CSS_TOP","CSS_BOTTOM","reason","needToVisitNode","generationCount","gCurrentGenerationCount","lastParentDirection","cachedMeasurements","cachedLayout","cachedResults","len","newCacheEntry","push","computedWidth","computedHeight","measureWidth","measureHeight","shouldUpdate","layoutNode"],"mappings":"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","file":"css-layout.min.js","sourcesContent":["// UMD (Universal Module Definition)\n// See https://github.com/umdjs/umd for reference\n//\n// This file uses the following specific UMD implementation:\n// https://github.com/umdjs/umd/blob/master/templates/returnExports.js\n(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.computeLayout = factory();\n }\n}(this, function() {\n /**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nvar computeLayout = (function() {\n \n var POSITIVE_FLEX_IS_AUTO = false;\n \n var gCurrentGenerationCount = 0;\n \n var CSS_UNDEFINED;\n \n var CSS_LEFT = 'left';\n var CSS_TOP = 'top';\n var CSS_RIGHT = 'right';\n var CSS_BOTTOM = 'bottom';\n \n var CSS_DIRECTION_INHERIT = 'inherit';\n var CSS_DIRECTION_LTR = 'ltr';\n var CSS_DIRECTION_RTL = 'rtl';\n\n var CSS_FLEX_DIRECTION_ROW = 'row';\n var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';\n var CSS_FLEX_DIRECTION_COLUMN = 'column';\n var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';\n\n var CSS_JUSTIFY_FLEX_START = 'flex-start';\n var CSS_JUSTIFY_CENTER = 'center';\n var CSS_JUSTIFY_FLEX_END = 'flex-end';\n var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';\n var CSS_JUSTIFY_SPACE_AROUND = 'space-around';\n\n var CSS_ALIGN_FLEX_START = 'flex-start';\n var CSS_ALIGN_CENTER = 'center';\n var CSS_ALIGN_FLEX_END = 'flex-end';\n var CSS_ALIGN_STRETCH = 'stretch';\n\n var CSS_POSITION_RELATIVE = 'relative';\n var CSS_POSITION_ABSOLUTE = 'absolute';\n \n var CSS_OVERFLOW_VISIBLE = 'visible';\n var CSS_OVERFLOW_HIDDEN = 'hidden';\n \n var CSS_MEASURE_MODE_UNDEFINED = 'undefined';\n var CSS_MEASURE_MODE_EXACTLY = 'exactly';\n var CSS_MEASURE_MODE_AT_MOST = 'at-most';\n\n var leading = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var trailing = {\n 'row': 'right',\n 'row-reverse': 'left',\n 'column': 'bottom',\n 'column-reverse': 'top'\n };\n var pos = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var dim = {\n 'row': 'width',\n 'row-reverse': 'width',\n 'column': 'height',\n 'column-reverse': 'height'\n };\n var measuredDim = {\n 'row': 'measuredWidth',\n 'row-reverse': 'measuredWidth',\n 'column': 'measuredHeight',\n 'column-reverse': 'measuredHeight'\n };\n\n // When transpiled to Java / C the node type has layout, children and style\n // properties. For the JavaScript version this function adds these properties\n // if they don't already exist.\n function fillNodes(node) {\n if (!node.layout || node.isDirty) {\n node.layout = {\n width: undefined,\n height: undefined,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n };\n }\n\n if (!node.style) {\n node.style = {};\n }\n\n if (!node.children) {\n node.children = [];\n }\n\n if (node.style.measure && node.children && node.children.length) {\n throw new Error('Using custom measure function is supported only for leaf nodes.');\n }\n\n node.children.forEach(fillNodes);\n return node;\n }\n\n function isUndefined(value) {\n return value === undefined || Number.isNaN(value);\n }\n\n function isRowDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_ROW ||\n flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;\n }\n\n function isColumnDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_COLUMN ||\n flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;\n }\n \n function getFlex(node) {\n if (node.style.flex === undefined) {\n return 0;\n }\n return node.style.flex;\n }\n \n function isFlexBasisAuto(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // All flex values are auto.\n return true;\n } else {\n // A flex value > 0 implies a basis of zero.\n return getFlex(node) <= 0;\n }\n }\n \n function getFlexGrowFactor(node) {\n // Flex grow is implied by positive values for flex.\n if (getFlex(node) > 0) {\n return getFlex(node);\n }\n return 0;\n }\n \n function getFlexShrinkFactor(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // A flex shrink factor of 1 is implied by non-zero values for flex.\n if (getFlex(node) !== 0) {\n return 1;\n }\n } else {\n // A flex shrink factor of 1 is implied by negative values for flex.\n if (getFlex(node) < 0) {\n return 1;\n }\n }\n return 0;\n }\n\n function getLeadingMargin(node, axis) {\n if (node.style.marginStart !== undefined && isRowDirection(axis)) {\n return node.style.marginStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginLeft; break;\n case 'row-reverse': value = node.style.marginRight; break;\n case 'column': value = node.style.marginTop; break;\n case 'column-reverse': value = node.style.marginBottom; break;\n }\n\n if (value !== undefined) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getTrailingMargin(node, axis) {\n if (node.style.marginEnd !== undefined && isRowDirection(axis)) {\n return node.style.marginEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginRight; break;\n case 'row-reverse': value = node.style.marginLeft; break;\n case 'column': value = node.style.marginBottom; break;\n case 'column-reverse': value = node.style.marginTop; break;\n }\n\n if (value != null) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getLeadingPadding(node, axis) {\n if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0\n && isRowDirection(axis)) {\n return node.style.paddingStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingLeft; break;\n case 'row-reverse': value = node.style.paddingRight; break;\n case 'column': value = node.style.paddingTop; break;\n case 'column-reverse': value = node.style.paddingBottom; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getTrailingPadding(node, axis) {\n if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0\n && isRowDirection(axis)) {\n return node.style.paddingEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingRight; break;\n case 'row-reverse': value = node.style.paddingLeft; break;\n case 'column': value = node.style.paddingBottom; break;\n case 'column-reverse': value = node.style.paddingTop; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getLeadingBorder(node, axis) {\n if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderStartWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderLeftWidth; break;\n case 'row-reverse': value = node.style.borderRightWidth; break;\n case 'column': value = node.style.borderTopWidth; break;\n case 'column-reverse': value = node.style.borderBottomWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getTrailingBorder(node, axis) {\n if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderEndWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderRightWidth; break;\n case 'row-reverse': value = node.style.borderLeftWidth; break;\n case 'column': value = node.style.borderBottomWidth; break;\n case 'column-reverse': value = node.style.borderTopWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getLeadingPaddingAndBorder(node, axis) {\n return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);\n }\n\n function getTrailingPaddingAndBorder(node, axis) {\n return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);\n }\n\n function getMarginAxis(node, axis) {\n return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);\n }\n\n function getPaddingAndBorderAxis(node, axis) {\n return getLeadingPaddingAndBorder(node, axis) +\n getTrailingPaddingAndBorder(node, axis);\n }\n\n function getJustifyContent(node) {\n if (node.style.justifyContent) {\n return node.style.justifyContent;\n }\n return 'flex-start';\n }\n\n function getAlignContent(node) {\n if (node.style.alignContent) {\n return node.style.alignContent;\n }\n return 'flex-start';\n }\n\n function getAlignItem(node, child) {\n if (child.style.alignSelf) {\n return child.style.alignSelf;\n }\n if (node.style.alignItems) {\n return node.style.alignItems;\n }\n return 'stretch';\n }\n\n function resolveAxis(axis, direction) {\n if (direction === CSS_DIRECTION_RTL) {\n if (axis === CSS_FLEX_DIRECTION_ROW) {\n return CSS_FLEX_DIRECTION_ROW_REVERSE;\n } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {\n return CSS_FLEX_DIRECTION_ROW;\n }\n }\n\n return axis;\n }\n\n function resolveDirection(node, parentDirection) {\n var direction;\n if (node.style.direction) {\n direction = node.style.direction;\n } else {\n direction = CSS_DIRECTION_INHERIT;\n }\n\n if (direction === CSS_DIRECTION_INHERIT) {\n direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection);\n }\n\n return direction;\n }\n\n function getFlexDirection(node) {\n if (node.style.flexDirection) {\n return node.style.flexDirection;\n }\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n\n function getCrossFlexDirection(flexDirection, direction) {\n if (isColumnDirection(flexDirection)) {\n return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);\n } else {\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n }\n\n function getPositionType(node) {\n if (node.style.position) {\n return node.style.position;\n }\n return CSS_POSITION_RELATIVE;\n }\n \n function getOverflow(node) {\n if (node.style.overflow) {\n return node.style.overflow;\n }\n return CSS_OVERFLOW_VISIBLE;\n }\n\n function isFlex(node) {\n return (\n getPositionType(node) === CSS_POSITION_RELATIVE &&\n node.style.flex !== undefined && node.style.flex !== 0\n );\n }\n\n function isFlexWrap(node) {\n return node.style.flexWrap === 'wrap';\n }\n\n function getDimWithMargin(node, axis) {\n return node.layout[measuredDim[axis]] + getMarginAxis(node, axis);\n }\n \n function isStyleDimDefined(node, axis) { \n return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;\n }\n \n function isLayoutDimDefined(node, axis) { \n return node.layout[measuredDim[axis]] !== undefined && node.layout[measuredDim[axis]] >= 0;\n }\n\n function isPosDefined(node, pos) {\n return node.style[pos] !== undefined;\n }\n\n function isMeasureDefined(node) {\n return node.style.measure !== undefined;\n }\n\n function getPosition(node, pos) {\n if (node.style[pos] !== undefined) {\n return node.style[pos];\n }\n return 0;\n }\n \n function boundAxisWithinMinAndMax(node, axis, value) {\n var min = {\n 'row': node.style.minWidth,\n 'row-reverse': node.style.minWidth,\n 'column': node.style.minHeight,\n 'column-reverse': node.style.minHeight\n }[axis];\n\n var max = {\n 'row': node.style.maxWidth,\n 'row-reverse': node.style.maxWidth,\n 'column': node.style.maxHeight,\n 'column-reverse': node.style.maxHeight\n }[axis];\n\n var boundValue = value;\n if (max !== undefined && max >= 0 && boundValue > max) {\n boundValue = max;\n }\n if (min !== undefined && min >= 0 && boundValue < min) {\n boundValue = min;\n }\n return boundValue;\n }\n \n function fminf(a, b) {\n if (a < b) {\n return a;\n }\n return b;\n }\n\n function fmaxf(a, b) {\n if (a > b) {\n return a;\n }\n return b;\n }\n \n // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the\n // padding and border amount.\n function boundAxis(node, axis, value) {\n return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis));\n }\n\n function setTrailingPosition(node, child, axis) {\n var size = (getPositionType(child) === CSS_POSITION_ABSOLUTE) ?\n 0 :\n child.layout[measuredDim[axis]];\n child.layout[trailing[axis]] = node.layout[measuredDim[axis]] - size - child.layout[pos[axis]];\n }\n\n // If both left and right are defined, then use left. Otherwise return\n // +left or -right depending on which is defined.\n function getRelativePosition(node, axis) {\n if (node.style[leading[axis]] !== undefined) {\n return getPosition(node, leading[axis]);\n }\n return -getPosition(node, trailing[axis]);\n }\n \n function setPosition(node, direction) {\n var mainAxis = resolveAxis(getFlexDirection(node), direction);\n var crossAxis = getCrossFlexDirection(mainAxis, direction);\n \n node.layout[leading[mainAxis]] = getLeadingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[leading[crossAxis]] = getLeadingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n node.layout[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n }\n \n function assert(condition, message) {\n if (!condition) {\n throw new Error(message);\n }\n }\n \n //\n // This is the main routine that implements a subset of the flexbox layout algorithm\n // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/.\n //\n // Limitations of this algorithm, compared to the full standard:\n // * Display property is always assumed to be 'flex' except for Text nodes, which\n // are assumed to be 'inline-flex'.\n // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are\n // stacked in document order.\n // * The 'order' property is not supported. The order of flex items is always defined\n // by document order.\n // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse'\n // and 'hidden' are not supported.\n // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The\n // rarely-used 'wrap-reverse' is not supported.\n // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and\n // flexBasis, this algorithm supports only the three most common combinations:\n // flex: 0 is equiavlent to flex: 0 0 auto\n // flex: n (where n is a positive value) is equivalent to flex: n 1 auto\n // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0\n // This is faster because the content doesn't need to be measured, but it's\n // less flexible because the basis is always 0 and can't be overriden with\n // the width/height attributes.\n // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto\n // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel\n // values, and the default value is 0.\n // * The 'baseline' value is not supported for alignItems and alignSelf properties.\n // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be\n // specified as pixel values, not as percentages.\n // * There is no support for calculation of dimensions based on intrinsic aspect ratios\n // (e.g. images).\n // * There is no support for forced breaks.\n // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text).\n //\n // Deviations from standard:\n // * Section 4.5 of the spec indicates that all flex items have a default minimum\n // main size. For text blocks, for example, this is the width of the widest word. \n // Calculating the minimum width is expensive, so we forego it and assume a default \n // minimum main size of 0.\n // * Min/Max sizes in the main axis are not honored when resolving flexible lengths.\n // * The spec indicates that the default value for 'flexDirection' is 'row', but\n // the algorithm below assumes a default of 'column'.\n //\n // Input parameters:\n // - node: current node to be sized and layed out\n // - availableWidth & availableHeight: available size to be used for sizing the node\n // or CSS_UNDEFINED if the size is not available; interpretation depends on layout\n // flags\n // - parentDirection: the inline (text) direction within the parent (left-to-right or\n // right-to-left)\n // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation)\n // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation)\n // - performLayout: specifies whether the caller is interested in just the dimensions\n // of the node or it requires the entire node and its subtree to be layed out\n // (with final positions)\n //\n // Details:\n // This routine is called recursively to lay out subtrees of flexbox elements. It uses the\n // information in node.style, which is treated as a read-only input. It is responsible for\n // setting the layout.direction and layout.measured_dimensions fields for the input node as well\n // as the layout.position and layout.line_index fields for its child nodes. The\n // layout.measured_dimensions field includes any border or padding for the node but does\n // not include margins.\n //\n // The spec describes four different layout modes: \"fill available\", \"max content\", \"min content\",\n // and \"fit content\". Of these, we don't use \"min content\" because we don't support default\n // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode\n // from the spec (https://www.w3.org/TR/css3-sizing/#terms):\n // - CSS_MEASURE_MODE_UNDEFINED: max content\n // - CSS_MEASURE_MODE_EXACTLY: fill available\n // - CSS_MEASURE_MODE_AT_MOST: fit content\n // \n // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of\n // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension.\n //\n function layoutNodeImpl(node, availableWidth, availableHeight, /*css_direction_t*/parentDirection, widthMeasureMode, heightMeasureMode, performLayout) {\n assert(isUndefined(availableWidth) ? widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n assert(isUndefined(availableHeight) ? heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n \n var/*float*/ paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n var/*float*/ marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // Set the resolved resolution in the node's layout.\n var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);\n node.layout.direction = direction;\n\n // For content (text) nodes, determine the dimensions based on the text contents.\n if (isMeasureDefined(node)) {\n var/*float*/ innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n \n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n\n // Don't bother sizing the text if both dimensions are already defined.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n } else if (innerWidth <= 0) {\n\n // Don't bother sizing the text if there's no horizontal space.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n } else {\n\n // Measure the text under the current constraints.\n var/*css_dim_t*/ measureDim = node.style.measure(\n /*(c)!node->context,*/\n /*(java)!layoutContext.measureOutput,*/\n innerWidth,\n widthMeasureMode,\n innerHeight,\n heightMeasureMode\n );\n\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.width + paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.height + paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n }\n \n return;\n }\n\n // For nodes with no children, use the available values if they were provided, or\n // the minimum size as indicated by the padding and border sizes.\n var/*int*/ childCount = node.children.length;\n if (childCount === 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n return;\n }\n\n // If we're not being asked to perform a full layout, we can handle a number of common\n // cases here without incurring the cost of the remaining function.\n if (!performLayout) {\n // If we're being asked to size the content with an at most constraint but there is no available width,\n // the measurement will always be zero.\n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 &&\n heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n \n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn));\n return;\n }\n\n if (heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow));\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n \n // If we're being asked to use an exact width/height, there's no need to measure the children.\n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n return;\n }\n }\n\n // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM\n var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction);\n var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction);\n var/*bool*/ isMainAxisRow = isRowDirection(mainAxis);\n var/*css_justify_t*/ justifyContent = getJustifyContent(node);\n var/*bool*/ isNodeFlexWrap = isFlexWrap(node);\n\n var/*css_node_t**/ firstAbsoluteChild = undefined;\n var/*css_node_t**/ currentAbsoluteChild = undefined;\n\n var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);\n var/*float*/ trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis);\n var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);\n var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);\n var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);\n \n var/*css_measure_mode_t*/ measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;\n var/*css_measure_mode_t*/ measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;\n\n // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS\n var/*float*/ availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n var/*float*/ availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;\n var/*float*/ availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;\n\n // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM\n var/*css_node_t**/ child;\n var/*int*/ i;\n var/*float*/ childWidth;\n var/*float*/ childHeight;\n var/*css_measure_mode_t*/ childWidthMeasureMode;\n var/*css_measure_mode_t*/ childHeightMeasureMode;\n for (i = 0; i < childCount; i++) {\n child = node.children[i];\n\n if (performLayout) {\n // Set the initial position (relative to the parent).\n var/*css_direction_t*/ childDirection = resolveDirection(child, direction);\n setPosition(child, childDirection);\n }\n \n // Absolute-positioned children don't participate in flex layout. Add them\n // to a list that we can process later.\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n\n // Store a private linked list of absolutely positioned children\n // so that we can efficiently traverse them later.\n if (firstAbsoluteChild === undefined) {\n firstAbsoluteChild = child;\n }\n if (currentAbsoluteChild !== undefined) {\n currentAbsoluteChild.nextChild = child;\n }\n currentAbsoluteChild = child;\n child.nextChild = undefined;\n } else {\n \n if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n \n // The width is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.width, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW));\n } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n \n // The height is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.height, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN));\n } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) {\n \n // If the basis isn't 'auto', it is assumed to be zero.\n child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));\n } else {\n \n // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n \n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n \n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n // Measure the child\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'measure');\n \n child.layout.flexBasis = fmaxf(isMainAxisRow ? child.layout.measuredWidth : child.layout.measuredHeight, getPaddingAndBorderAxis(child, mainAxis));\n }\n }\n }\n\n // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES\n \n // Indexes of children that represent the first and last items in the line.\n var/*int*/ startOfLineIndex = 0;\n var/*int*/ endOfLineIndex = 0;\n \n // Number of lines.\n var/*int*/ lineCount = 0;\n \n // Accumulated cross dimensions of all lines so far.\n var/*float*/ totalLineCrossDim = 0;\n\n // Max main dimension of all the lines.\n var/*float*/ maxLineMainDim = 0;\n\n while (endOfLineIndex < childCount) {\n \n // Number of items on the currently line. May be different than the difference\n // between start and end indicates because we skip over absolute-positioned items.\n var/*int*/ itemsOnLine = 0;\n\n // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin\n // of all the children on the current line. This will be used in order to\n // either set the dimensions of the node if none already exist or to compute\n // the remaining space left for the flexible children.\n var/*float*/ sizeConsumedOnCurrentLine = 0;\n\n var/*float*/ totalFlexGrowFactors = 0;\n var/*float*/ totalFlexShrinkScaledFactors = 0;\n\n i = startOfLineIndex;\n\n // Maintain a linked list of the child nodes that can shrink and/or grow.\n var/*css_node_t**/ firstRelativeChild = undefined;\n var/*css_node_t**/ currentRelativeChild = undefined;\n\n // Add items to the current line until it's full or we run out of items.\n while (i < childCount) {\n child = node.children[i];\n child.lineIndex = lineCount;\n\n if (getPositionType(child) !== CSS_POSITION_ABSOLUTE) {\n var/*float*/ outerFlexBasis = child.layout.flexBasis + getMarginAxis(child, mainAxis);\n \n // If this is a multi-line flow and this item pushes us over the available size, we've\n // hit the end of the current line. Break out of the loop and lay out the current line.\n if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) {\n break;\n }\n\n sizeConsumedOnCurrentLine += outerFlexBasis;\n itemsOnLine++;\n\n if (isFlex(child)) {\n totalFlexGrowFactors += getFlexGrowFactor(child);\n \n // Unlike the grow factor, the shrink factor is scaled relative to the child\n // dimension.\n totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis;\n }\n\n // Store a private linked list of children that need to be layed out.\n if (firstRelativeChild === undefined) {\n firstRelativeChild = child;\n }\n if (currentRelativeChild !== undefined) {\n currentRelativeChild.nextChild = child;\n }\n currentRelativeChild = child;\n child.nextChild = undefined;\n }\n \n i++;\n endOfLineIndex++;\n }\n \n // If we don't need to measure the cross axis, we can skip the entire flex step.\n var/*bool*/ canSkipFlex = !performLayout && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY;\n\n // In order to position the elements in the main axis, we have two\n // controls. The space between the beginning and the first element\n // and the space between each two elements.\n var/*float*/ leadingMainDim = 0;\n var/*float*/ betweenMainDim = 0;\n\n // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS\n // Calculate the remaining available space that needs to be allocated.\n // If the main dimension size isn't known, it is computed based on\n // the line length, so there's no more space left to distribute.\n var/*float*/ remainingFreeSpace = 0;\n if (!isUndefined(availableInnerMainDim)) {\n remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;\n } else if (sizeConsumedOnCurrentLine < 0) {\n // availableInnerMainDim is indefinite which means the node is being sized based on its content.\n // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for\n // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.\n remainingFreeSpace = -sizeConsumedOnCurrentLine;\n }\n \n var/*float*/ originalRemainingFreeSpace = remainingFreeSpace;\n var/*float*/ deltaFreeSpace = 0;\n\n if (!canSkipFlex) {\n var/*float*/ childFlexBasis;\n var/*float*/ flexShrinkScaledFactor;\n var/*float*/ flexGrowFactor;\n var/*float*/ baseMainSize;\n var/*float*/ boundMainSize;\n \n // Do two passes over the flex items to figure out how to distribute the remaining space.\n // The first pass finds the items whose min/max constraints trigger, freezes them at those\n // sizes, and excludes those sizes from the remaining space. The second pass sets the size\n // of each flexible item. It distributes the remaining space amongst the items whose min/max\n // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing\n // their min/max constraints to trigger again. \n //\n // This two pass approach for resolving min/max constraints deviates from the spec. The\n // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process\n // that needs to be repeated a variable number of times. The algorithm implemented here\n // won't handle all cases but it was simpler to implement and it mitigates performance\n // concerns because we know exactly how many passes it'll do.\n \n // First pass: detect the flex items whose min/max constraints trigger\n var/*float*/ deltaFlexShrinkScaledFactors = 0;\n var/*float*/ deltaFlexGrowFactors = 0;\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n \n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize - childFlexBasis;\n deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor;\n }\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize - childFlexBasis;\n deltaFlexGrowFactors -= flexGrowFactor;\n }\n }\n }\n \n currentRelativeChild = currentRelativeChild.nextChild;\n }\n \n totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors;\n totalFlexGrowFactors += deltaFlexGrowFactors;\n remainingFreeSpace += deltaFreeSpace;\n \n // Second pass: resolve the sizes of the flexible items\n deltaFreeSpace = 0;\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n var/*float*/ updatedMainSize = childFlexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n \n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor);\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor);\n }\n }\n \n deltaFreeSpace -= updatedMainSize - childFlexBasis;\n \n if (isMainAxisRow) {\n childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n \n if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childHeight = currentRelativeChild.style.height + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n } else {\n childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n \n if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childWidth = currentRelativeChild.style.width + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n }\n \n var/*bool*/ requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) &&\n getAlignItem(node, currentRelativeChild) === CSS_ALIGN_STRETCH;\n\n // Recursively call the layout algorithm for this child with the updated main size.\n layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, 'flex');\n\n currentRelativeChild = currentRelativeChild.nextChild;\n }\n }\n \n remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace;\n\n // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION\n\n // At this point, all the children have their dimensions set in the main axis.\n // Their dimensions are also set in the cross axis with the exception of items\n // that are aligned 'stretch'. We need to compute these stretch values and\n // set the final positions.\n\n // If we are using \"at most\" rules in the main axis, we won't distribute\n // any remaining space at this point.\n if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n remainingFreeSpace = 0;\n }\n\n // Use justifyContent to figure out how to allocate the remaining space\n // available in the main axis.\n if (justifyContent !== CSS_JUSTIFY_FLEX_START) {\n if (justifyContent === CSS_JUSTIFY_CENTER) {\n leadingMainDim = remainingFreeSpace / 2;\n } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {\n leadingMainDim = remainingFreeSpace;\n } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {\n remainingFreeSpace = fmaxf(remainingFreeSpace, 0);\n if (itemsOnLine > 1) {\n betweenMainDim = remainingFreeSpace / (itemsOnLine - 1);\n } else {\n betweenMainDim = 0;\n }\n } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {\n // Space on the edges is half of the space between elements\n betweenMainDim = remainingFreeSpace / itemsOnLine;\n leadingMainDim = betweenMainDim / 2;\n }\n }\n\n var/*float*/ mainDim = leadingPaddingAndBorderMain + leadingMainDim;\n var/*float*/ crossDim = 0;\n\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[mainAxis])) {\n if (performLayout) {\n // In case the child is position absolute and has left/top being\n // defined, we override the position to whatever the user said\n // (and margin/border).\n child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) +\n getLeadingBorder(node, mainAxis) +\n getLeadingMargin(child, mainAxis);\n }\n } else {\n if (performLayout) {\n // If the child is position absolute (without top/left) or relative,\n // we put it at the current accumulated offset.\n child.layout[pos[mainAxis]] += mainDim;\n }\n \n // Now that we placed the element, we need to update the variables.\n // We need to do that only for relative elements. Absolute elements\n // do not take part in that phase.\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n if (canSkipFlex) {\n // If we skipped the flex step, then we can't rely on the measuredDims because\n // they weren't computed. This means we can't call getDimWithMargin.\n mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child.layout.flexBasis;\n crossDim = availableInnerCrossDim;\n } else {\n // The main dimension is the sum of all the elements dimension plus\n // the spacing.\n mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);\n \n // The cross dimension is the max of the elements dimension since there\n // can only be one element in that cross dimension.\n crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis));\n }\n }\n }\n }\n\n mainDim += trailingPaddingAndBorderMain;\n \n var/*float*/ containerCrossAxis = availableInnerCrossDim;\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n // Compute the cross axis from the max cross dimension of the children.\n containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n \n if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim);\n }\n }\n\n // If there's no flex wrap, the cross dimension is defined by the container.\n if (!isNodeFlexWrap && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY) {\n crossDim = availableInnerCrossDim;\n }\n\n // Clamp to the min/max size specified on the container.\n crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n\n // STEP 7: CROSS-AXIS ALIGNMENT\n // We can skip child alignment if we're just measuring the container.\n if (performLayout) {\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n // If the child is absolutely positioned and has a top/left/bottom/right\n // set, override all the previously computed positions to set it correctly.\n if (isPosDefined(child, leading[crossAxis])) {\n child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +\n getLeadingBorder(node, crossAxis) +\n getLeadingMargin(child, crossAxis);\n } else {\n child.layout[pos[crossAxis]] = leadingPaddingAndBorderCross +\n getLeadingMargin(child, crossAxis);\n }\n } else {\n var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross;\n\n // For a relative children, we're either using alignItems (parent) or\n // alignSelf (child) in order to determine the position in the cross axis\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n \n // If the child uses align stretch, we need to lay it out one more time, this time\n // forcing the cross-axis size to be the computed cross size for the current line.\n if (alignItem === CSS_ALIGN_STRETCH) {\n childWidth = child.layout.measuredWidth + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childHeight = child.layout.measuredHeight + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n var/*bool*/ isCrossSizeDefinite = false;\n \n if (isMainAxisRow) {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeight = crossDim;\n } else {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW);\n childWidth = crossDim;\n }\n \n // If the child defines a definite size for its cross axis, there's no need to stretch.\n if (!isCrossSizeDefinite) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, 'stretch');\n }\n } else if (alignItem !== CSS_ALIGN_FLEX_START) {\n var/*float*/ remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis);\n\n if (alignItem === CSS_ALIGN_CENTER) {\n leadingCrossDim += remainingCrossDim / 2;\n } else { // CSS_ALIGN_FLEX_END\n leadingCrossDim += remainingCrossDim;\n }\n }\n\n // And we apply the position\n child.layout[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim;\n }\n }\n }\n\n totalLineCrossDim += crossDim;\n maxLineMainDim = fmaxf(maxLineMainDim, mainDim);\n\n // Reset variables for new line.\n lineCount++;\n startOfLineIndex = endOfLineIndex;\n endOfLineIndex = startOfLineIndex;\n }\n\n // STEP 8: MULTI-LINE CONTENT ALIGNMENT\n if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) {\n var/*float*/ remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;\n\n var/*float*/ crossDimLead = 0;\n var/*float*/ currentLead = leadingPaddingAndBorderCross;\n\n var/*css_align_t*/ alignContent = getAlignContent(node);\n if (alignContent === CSS_ALIGN_FLEX_END) {\n currentLead += remainingAlignContentDim;\n } else if (alignContent === CSS_ALIGN_CENTER) {\n currentLead += remainingAlignContentDim / 2;\n } else if (alignContent === CSS_ALIGN_STRETCH) {\n if (availableInnerCrossDim > totalLineCrossDim) {\n crossDimLead = (remainingAlignContentDim / lineCount);\n }\n }\n\n var/*int*/ endIndex = 0;\n for (i = 0; i < lineCount; ++i) {\n var/*int*/ startIndex = endIndex;\n var/*int*/ j;\n\n // compute the line's height and find the endIndex\n var/*float*/ lineHeight = 0;\n for (j = startIndex; j < childCount; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n if (child.lineIndex !== i) {\n break;\n }\n if (isLayoutDimDefined(child, crossAxis)) {\n lineHeight = fmaxf(lineHeight,\n child.layout[measuredDim[crossAxis]] + getMarginAxis(child, crossAxis));\n }\n }\n endIndex = j;\n lineHeight += crossDimLead;\n\n if (performLayout) {\n for (j = startIndex; j < endIndex; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n\n var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child);\n if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {\n child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[measuredDim[crossAxis]];\n } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {\n childHeight = child.layout[measuredDim[crossAxis]];\n child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;\n } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n // TODO(prenaux): Correctly set the height of items with indefinite\n // (auto) crossAxis dimension.\n }\n }\n }\n\n currentLead += lineHeight;\n }\n }\n\n // STEP 9: COMPUTING FINAL DIMENSIONS\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n\n // If the user didn't specify a width or height for the node, set the\n // dimensions based on the children.\n if (measureModeMainDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim);\n } else if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[mainAxis]] = fmaxf(\n fminf(availableInnerMainDim + paddingAndBorderAxisMain,\n boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)),\n paddingAndBorderAxisMain);\n }\n\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross);\n } else if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[crossAxis]] = fmaxf(\n fminf(availableInnerCrossDim + paddingAndBorderAxisCross,\n boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)),\n paddingAndBorderAxisCross);\n }\n \n // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN\n if (performLayout) {\n var/*bool*/ needsMainTrailingPos = false;\n var/*bool*/ needsCrossTrailingPos = false;\n\n if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsMainTrailingPos = true;\n }\n\n if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsCrossTrailingPos = true;\n }\n\n // Set trailing position if necessary.\n if (needsMainTrailingPos || needsCrossTrailingPos) {\n for (i = 0; i < childCount; ++i) {\n child = node.children[i];\n\n if (needsMainTrailingPos) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n if (needsCrossTrailingPos) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n }\n }\n \n // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN\n currentAbsoluteChild = firstAbsoluteChild;\n while (currentAbsoluteChild !== undefined) {\n // Now that we know the bounds of the container, perform layout again on the\n // absolutely-positioned children.\n if (performLayout) {\n\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n\n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = currentAbsoluteChild.style.width + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n } else {\n // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) {\n childWidth = node.layout.measuredWidth -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) -\n (currentAbsoluteChild.style[CSS_LEFT] + currentAbsoluteChild.style[CSS_RIGHT]);\n childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth);\n }\n }\n \n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = currentAbsoluteChild.style.height + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n } else {\n // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) {\n childHeight = node.layout.measuredHeight -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) -\n (currentAbsoluteChild.style[CSS_TOP] + currentAbsoluteChild.style[CSS_BOTTOM]);\n childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight);\n }\n }\n\n // If we're still missing one or the other dimension, measure the content.\n if (isUndefined(childWidth) || isUndefined(childHeight)) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n \n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'abs-measure');\n childWidth = currentAbsoluteChild.layout.measuredWidth + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n childHeight = currentAbsoluteChild.layout.measuredHeight + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n }\n \n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, 'abs-layout');\n \n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_ROW]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]);\n }\n \n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_COLUMN]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]);\n }\n }\n\n currentAbsoluteChild = currentAbsoluteChild.nextChild;\n }\n }\n \n //\n // This is a wrapper around the layoutNodeImpl function. It determines\n // whether the layout request is redundant and can be skipped.\n //\n // Parameters:\n // Input parameters are the same as layoutNodeImpl (see above)\n // Return parameter is true if layout was performed, false if skipped\n //\n function layoutNodeInternal(node, availableWidth, availableHeight, parentDirection,\n widthMeasureMode, heightMeasureMode, performLayout, reason) {\n var layout = node.layout;\n\n var needToVisitNode = (node.isDirty && layout.generationCount !== gCurrentGenerationCount) ||\n layout.lastParentDirection !== parentDirection;\n\n if (needToVisitNode) {\n // Invalidate the cached results.\n if (layout.cachedMeasurements !== undefined) {\n layout.cachedMeasurements = []; \n }\n if (layout.cachedLayout !== undefined) {\n layout.cachedLayout.widthMeasureMode = undefined;\n layout.cachedLayout.heightMeasureMode = undefined;\n }\n }\n\n var cachedResults;\n \n // Determine whether the results are already cached. We maintain a separate\n // cache for layouts and measurements. A layout operation modifies the positions\n // and dimensions for nodes in the subtree. The algorithm assumes that each node\n // gets layed out a maximum of one time per tree layout, but multiple measurements\n // may be required to resolve all of the flex dimensions.\n if (performLayout) {\n if (layout.cachedLayout &&\n layout.cachedLayout.availableWidth === availableWidth &&\n layout.cachedLayout.availableHeight === availableHeight &&\n layout.cachedLayout.widthMeasureMode === widthMeasureMode &&\n layout.cachedLayout.heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedLayout;\n }\n } else if (layout.cachedMeasurements) {\n for (var i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (layout.cachedMeasurements[i].availableWidth === availableWidth &&\n layout.cachedMeasurements[i].availableHeight === availableHeight &&\n layout.cachedMeasurements[i].widthMeasureMode === widthMeasureMode &&\n layout.cachedMeasurements[i].heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n \n if (!needToVisitNode && cachedResults !== undefined) {\n layout.measureWidth = cachedResults.computedWidth;\n layout.measureHeight = cachedResults.computedHeight;\n } else {\n layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout);\n layout.lastParentDirection = parentDirection;\n \n if (cachedResults === undefined) {\n var newCacheEntry;\n if (performLayout) {\n // Use the single layout cache entry.\n if (layout.cachedLayout === undefined) {\n layout.cachedLayout = {};\n }\n newCacheEntry = layout.cachedLayout;\n } else {\n // Allocate a new measurement cache entry.\n if (layout.cachedMeasurements === undefined) {\n layout.cachedMeasurements = [];\n }\n newCacheEntry = {};\n layout.cachedMeasurements.push(newCacheEntry);\n }\n \n newCacheEntry.availableWidth = availableWidth;\n newCacheEntry.availableHeight = availableHeight;\n newCacheEntry.widthMeasureMode = widthMeasureMode;\n newCacheEntry.heightMeasureMode = heightMeasureMode;\n newCacheEntry.computedWidth = layout.measuredWidth;\n newCacheEntry.computedHeight = layout.measuredHeight;\n }\n }\n \n if (performLayout) {\n node.layout.width = node.layout.measuredWidth;\n node.layout.height = node.layout.measuredHeight;\n layout.shouldUpdate = true;\n }\n \n layout.generationCount = gCurrentGenerationCount;\n return (needToVisitNode || cachedResults === undefined);\n }\n \n function layoutNode(node, availableWidth, availableHeight, parentDirection) {\n // Increment the generation count. This will force the recursive routine to visit\n // all dirty nodes at least once. Subsequent visits will be skipped if the input\n // parameters don't change.\n gCurrentGenerationCount++;\n \n // If the caller didn't specify a height/width, use the dimensions\n // specified in the style.\n if (isUndefined(availableWidth) && isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {\n availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n }\n if (isUndefined(availableHeight) && isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n }\n \n var widthMeasureMode = isUndefined(availableWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n var heightMeasureMode = isUndefined(availableHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n \n if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, 'initial')) {\n setPosition(node, node.layout.direction);\n }\n }\n\n return {\n layoutNodeImpl: layoutNodeImpl,\n computeLayout: layoutNode,\n fillNodes: fillNodes\n };\n})();\n\n// This module export is only used for the purposes of unit testing this file. When\n// the library is packaged this file is included within css-layout.js which forms\n// the public API.\nif (typeof exports === 'object') {\n module.exports = computeLayout;\n}\n\n\n return function(node) {\n /*eslint-disable */\n // disabling ESLint because this code relies on the above include\n computeLayout.fillNodes(node);\n computeLayout.computeLayout(node);\n /*eslint-enable */\n };\n}));\n"]} \ No newline at end of file diff --git a/src/Layout.c b/src/Layout.c index 52acc085..b001efab 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -966,7 +966,8 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab remainingFreeSpace = -sizeConsumedOnCurrentLine; } - float remainingFreeSpaceAfterFlex = remainingFreeSpace; + float originalRemainingFreeSpace = remainingFreeSpace; + float deltaFreeSpace = 0; if (!canSkipFlex) { float childFlexBasis; @@ -989,7 +990,6 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - float deltaFreeSpace = 0; float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -1008,7 +1008,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -1024,7 +1024,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -1036,9 +1036,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != NULL) { childFlexBasis = currentRelativeChild->layout.flex_basis; @@ -1062,7 +1062,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); @@ -1098,7 +1098,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/src/Layout.js b/src/Layout.js index 72a68360..056ac0d9 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -916,7 +916,8 @@ var computeLayout = (function() { remainingFreeSpace = -sizeConsumedOnCurrentLine; } - var/*float*/ remainingFreeSpaceAfterFlex = remainingFreeSpace; + var/*float*/ originalRemainingFreeSpace = remainingFreeSpace; + var/*float*/ deltaFreeSpace = 0; if (!canSkipFlex) { var/*float*/ childFlexBasis; @@ -939,7 +940,6 @@ var computeLayout = (function() { // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - var/*float*/ deltaFreeSpace = 0; var/*float*/ deltaFlexShrinkScaledFactors = 0; var/*float*/ deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -958,7 +958,7 @@ var computeLayout = (function() { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -974,7 +974,7 @@ var computeLayout = (function() { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -986,9 +986,9 @@ var computeLayout = (function() { totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild !== undefined) { childFlexBasis = currentRelativeChild.layout.flexBasis; @@ -1012,7 +1012,7 @@ var computeLayout = (function() { } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); @@ -1048,7 +1048,7 @@ var computeLayout = (function() { } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 7a9b913d..18fe70dc 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -6923,6 +6923,93 @@ int main() test("should layout node with position absolute, top and left and min bounds", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.justify_content = CSS_JUSTIFY_CENTER; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + 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.flex = 1; + node_1->style.dimensions[CSS_HEIGHT] = 1000; + node_1->style.maxDimensions[CSS_WIDTH] = 600; + } + } + + 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] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + 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] = 200; + node_1->layout.dimensions[CSS_WIDTH] = 600; + node_1->layout.dimensions[CSS_HEIGHT] = 1000; + } + } + + test("should center flexible item with max size", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 1000; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 1000; + node_1->style.maxDimensions[CSS_WIDTH] = 200; + } + } + + 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] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + 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] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 800; + node_1->layout.dimensions[CSS_HEIGHT] = 1000; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 800; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 1000; + } + } + + test("should correctly size flexible items with flex basis and a max width", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index d7edb768..738fd40c 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -2151,6 +2151,30 @@ describe('Layout', function() { ]} ); }); + + it('should center flexible item with max size', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'row', justifyContent: 'center'}, children: [ + {style: {flex: 1, maxWidth: 600, height: 1000}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 600, height: 1000, top: 0, left: 200} + ]} + ); + }); + + it('should correctly size flexible items with flex basis and a max width', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'row'}, children: [ + {style: {flex: 1, width: 100, height: 1000}}, + {style: {flex: 1, width: 100, maxWidth: 200, height: 1000}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 800, height: 1000, top: 0, left: 0}, + {width: 200, height: 1000, top: 0, left: 800} + ]} + ); + }); xit('should layout node with a nested sibling child with width', function() { testLayout( diff --git a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs index 63fb0c9d..4950f230 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs @@ -7362,6 +7362,97 @@ public class LayoutEngineTest [Test] public void TestCase168() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.Row; + node_0.style.justifyContent = CSSJustify.Center; + node_0.style.dimensions[DIMENSION_WIDTH] = 1000; + node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1.style.maxWidth = 600; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 200; + node_1.layout.dimensions[DIMENSION_WIDTH] = 600; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + } + } + + test("should center flexible item with max size", root_node, root_layout); + } + + [Test] + public void TestCase169() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.Row; + node_0.style.dimensions[DIMENSION_WIDTH] = 1000; + node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_WIDTH] = 100; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_WIDTH] = 100; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1.style.maxWidth = 200; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 800; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + node_1 = node_0.getChildAt(1); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 800; + node_1.layout.dimensions[DIMENSION_WIDTH] = 200; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + } + } + + test("should correctly size flexible items with flex basis and a max width", root_node, root_layout); + } + + [Test] + public void TestCase170() { TestCSSNode root_node = new TestCSSNode(); { @@ -7427,7 +7518,7 @@ public class LayoutEngineTest } [Test] - public void TestCase169() + public void TestCase171() { TestCSSNode root_node = new TestCSSNode(); { @@ -7499,7 +7590,7 @@ public class LayoutEngineTest } [Test] - public void TestCase170() + public void TestCase172() { TestCSSNode root_node = new TestCSSNode(); { @@ -7561,7 +7652,7 @@ public class LayoutEngineTest } [Test] - public void TestCase171() + public void TestCase173() { TestCSSNode root_node = new TestCSSNode(); { @@ -7655,7 +7746,7 @@ public class LayoutEngineTest } [Test] - public void TestCase172() + public void TestCase174() { TestCSSNode root_node = new TestCSSNode(); { @@ -7736,7 +7827,7 @@ public class LayoutEngineTest } [Test] - public void TestCase173() + public void TestCase175() { TestCSSNode root_node = new TestCSSNode(); { @@ -7776,7 +7867,7 @@ public class LayoutEngineTest } [Test] - public void TestCase174() + public void TestCase176() { TestCSSNode root_node = new TestCSSNode(); { @@ -7816,7 +7907,7 @@ public class LayoutEngineTest } [Test] - public void TestCase175() + public void TestCase177() { TestCSSNode root_node = new TestCSSNode(); { @@ -7856,7 +7947,7 @@ public class LayoutEngineTest } [Test] - public void TestCase176() + public void TestCase178() { TestCSSNode root_node = new TestCSSNode(); { @@ -7894,7 +7985,7 @@ public class LayoutEngineTest } [Test] - public void TestCase177() + public void TestCase179() { TestCSSNode root_node = new TestCSSNode(); { @@ -7933,7 +8024,7 @@ public class LayoutEngineTest } [Test] - public void TestCase178() + public void TestCase180() { TestCSSNode root_node = new TestCSSNode(); { @@ -7971,7 +8062,7 @@ public class LayoutEngineTest } [Test] - public void TestCase179() + public void TestCase181() { TestCSSNode root_node = new TestCSSNode(); { @@ -8010,7 +8101,7 @@ public class LayoutEngineTest } [Test] - public void TestCase180() + public void TestCase182() { TestCSSNode root_node = new TestCSSNode(); { @@ -8048,7 +8139,7 @@ public class LayoutEngineTest } [Test] - public void TestCase181() + public void TestCase183() { TestCSSNode root_node = new TestCSSNode(); { @@ -8087,7 +8178,7 @@ public class LayoutEngineTest } [Test] - public void TestCase182() + public void TestCase184() { TestCSSNode root_node = new TestCSSNode(); { @@ -8123,7 +8214,7 @@ public class LayoutEngineTest } [Test] - public void TestCase183() + public void TestCase185() { TestCSSNode root_node = new TestCSSNode(); { @@ -8191,7 +8282,7 @@ public class LayoutEngineTest } [Test] - public void TestCase184() + public void TestCase186() { TestCSSNode root_node = new TestCSSNode(); { @@ -8268,7 +8359,7 @@ public class LayoutEngineTest } [Test] - public void TestCase185() + public void TestCase187() { TestCSSNode root_node = new TestCSSNode(); { @@ -8340,7 +8431,7 @@ public class LayoutEngineTest } [Test] - public void TestCase186() + public void TestCase188() { TestCSSNode root_node = new TestCSSNode(); { @@ -8393,7 +8484,7 @@ public class LayoutEngineTest } [Test] - public void TestCase187() + public void TestCase189() { TestCSSNode root_node = new TestCSSNode(); { @@ -8483,7 +8574,7 @@ public class LayoutEngineTest } [Test] - public void TestCase188() + public void TestCase190() { TestCSSNode root_node = new TestCSSNode(); { @@ -8537,7 +8628,7 @@ public class LayoutEngineTest } [Test] - public void TestCase189() + public void TestCase191() { TestCSSNode root_node = new TestCSSNode(); { @@ -8591,7 +8682,7 @@ public class LayoutEngineTest } [Test] - public void TestCase190() + public void TestCase192() { TestCSSNode root_node = new TestCSSNode(); { @@ -8661,7 +8752,7 @@ public class LayoutEngineTest } [Test] - public void TestCase191() + public void TestCase193() { TestCSSNode root_node = new TestCSSNode(); { @@ -8731,7 +8822,7 @@ public class LayoutEngineTest } [Test] - public void TestCase192() + public void TestCase194() { TestCSSNode root_node = new TestCSSNode(); { @@ -8787,7 +8878,7 @@ public class LayoutEngineTest } [Test] - public void TestCase193() + public void TestCase195() { TestCSSNode root_node = new TestCSSNode(); { @@ -8842,7 +8933,7 @@ public class LayoutEngineTest } [Test] - public void TestCase194() + public void TestCase196() { TestCSSNode root_node = new TestCSSNode(); { @@ -8897,7 +8988,7 @@ public class LayoutEngineTest } [Test] - public void TestCase195() + public void TestCase197() { TestCSSNode root_node = new TestCSSNode(); { @@ -8968,7 +9059,7 @@ public class LayoutEngineTest } [Test] - public void TestCase196() + public void TestCase198() { TestCSSNode root_node = new TestCSSNode(); { @@ -9039,7 +9130,7 @@ public class LayoutEngineTest } [Test] - public void TestCase197() + public void TestCase199() { TestCSSNode root_node = new TestCSSNode(); { @@ -9096,7 +9187,7 @@ public class LayoutEngineTest } [Test] - public void TestCase198() + public void TestCase200() { TestCSSNode root_node = new TestCSSNode(); { @@ -9152,7 +9243,7 @@ public class LayoutEngineTest } [Test] - public void TestCase199() + public void TestCase201() { TestCSSNode root_node = new TestCSSNode(); { @@ -9208,7 +9299,7 @@ public class LayoutEngineTest } [Test] - public void TestCase200() + public void TestCase202() { TestCSSNode root_node = new TestCSSNode(); { @@ -9280,7 +9371,7 @@ public class LayoutEngineTest } [Test] - public void TestCase201() + public void TestCase203() { TestCSSNode root_node = new TestCSSNode(); { @@ -9352,7 +9443,7 @@ public class LayoutEngineTest } [Test] - public void TestCase202() + public void TestCase204() { TestCSSNode root_node = new TestCSSNode(); { @@ -9411,7 +9502,7 @@ public class LayoutEngineTest } [Test] - public void TestCase203() + public void TestCase205() { TestCSSNode root_node = new TestCSSNode(); { @@ -9484,7 +9575,7 @@ public class LayoutEngineTest } [Test] - public void TestCase204() + public void TestCase206() { TestCSSNode root_node = new TestCSSNode(); { @@ -9558,7 +9649,7 @@ public class LayoutEngineTest } [Test] - public void TestCase205() + public void TestCase207() { TestCSSNode root_node = new TestCSSNode(); { diff --git a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs index 175ec525..3d9924e5 100644 --- a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs +++ b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs @@ -784,7 +784,8 @@ namespace Facebook.CSSLayout remainingFreeSpace = -sizeConsumedOnCurrentLine; } - float remainingFreeSpaceAfterFlex = remainingFreeSpace; + float originalRemainingFreeSpace = remainingFreeSpace; + float deltaFreeSpace = 0; if (!canSkipFlex) { float childFlexBasis; @@ -807,7 +808,6 @@ namespace Facebook.CSSLayout // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - float deltaFreeSpace = 0; float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -826,7 +826,7 @@ namespace Facebook.CSSLayout // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -842,7 +842,7 @@ namespace Facebook.CSSLayout // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -854,9 +854,9 @@ namespace Facebook.CSSLayout totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != null) { childFlexBasis = currentRelativeChild.layout.flexBasis; @@ -880,7 +880,7 @@ namespace Facebook.CSSLayout } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); @@ -916,7 +916,7 @@ namespace Facebook.CSSLayout } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 92965141..fa9c35ef 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -751,7 +751,8 @@ public class LayoutEngine { remainingFreeSpace = -sizeConsumedOnCurrentLine; } - float remainingFreeSpaceAfterFlex = remainingFreeSpace; + float originalRemainingFreeSpace = remainingFreeSpace; + float deltaFreeSpace = 0; if (!canSkipFlex) { float childFlexBasis; @@ -774,7 +775,6 @@ public class LayoutEngine { // concerns because we know exactly how many passes it'll do. // First pass: detect the flex items whose min/max constraints trigger - float deltaFreeSpace = 0; float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; @@ -793,7 +793,7 @@ public class LayoutEngine { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; } } @@ -809,7 +809,7 @@ public class LayoutEngine { // By excluding this item's size and flex factor from remaining, this item's // min/max constraints should also trigger in the second pass resulting in the // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize; + deltaFreeSpace -= boundMainSize - childFlexBasis; deltaFlexGrowFactors -= flexGrowFactor; } } @@ -821,9 +821,9 @@ public class LayoutEngine { totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - remainingFreeSpaceAfterFlex = remainingFreeSpace; // Second pass: resolve the sizes of the flexible items + deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != null) { childFlexBasis = currentRelativeChild.layout.flexBasis; @@ -847,7 +847,7 @@ public class LayoutEngine { } } - remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis; + deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { childWidth = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); @@ -883,7 +883,7 @@ public class LayoutEngine { } } - remainingFreeSpace = remainingFreeSpaceAfterFlex; + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index 54560437..4337dc20 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -7365,6 +7365,97 @@ public class LayoutEngineTest { @Test public void testCase168() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.justifyContent = CSSJustify.CENTER; + node_0.style.dimensions[DIMENSION_WIDTH] = 1000; + node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1.style.maxWidth = 600; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 200; + node_1.layout.dimensions[DIMENSION_WIDTH] = 600; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + } + } + + test("should center flexible item with max size", root_node, root_layout); + } + + @Test + public void testCase169() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.dimensions[DIMENSION_WIDTH] = 1000; + node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_WIDTH] = 100; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.dimensions[DIMENSION_WIDTH] = 100; + node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; + node_1.style.maxWidth = 200; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 800; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + node_1 = node_0.getChildAt(1); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 800; + node_1.layout.dimensions[DIMENSION_WIDTH] = 200; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; + } + } + + test("should correctly size flexible items with flex basis and a max width", root_node, root_layout); + } + + @Test + public void testCase170() { TestCSSNode root_node = new TestCSSNode(); { @@ -7430,7 +7521,7 @@ public class LayoutEngineTest { } @Test - public void testCase169() + public void testCase171() { TestCSSNode root_node = new TestCSSNode(); { @@ -7502,7 +7593,7 @@ public class LayoutEngineTest { } @Test - public void testCase170() + public void testCase172() { TestCSSNode root_node = new TestCSSNode(); { @@ -7564,7 +7655,7 @@ public class LayoutEngineTest { } @Test - public void testCase171() + public void testCase173() { TestCSSNode root_node = new TestCSSNode(); { @@ -7658,7 +7749,7 @@ public class LayoutEngineTest { } @Test - public void testCase172() + public void testCase174() { TestCSSNode root_node = new TestCSSNode(); { @@ -7739,7 +7830,7 @@ public class LayoutEngineTest { } @Test - public void testCase173() + public void testCase175() { TestCSSNode root_node = new TestCSSNode(); { @@ -7779,7 +7870,7 @@ public class LayoutEngineTest { } @Test - public void testCase174() + public void testCase176() { TestCSSNode root_node = new TestCSSNode(); { @@ -7819,7 +7910,7 @@ public class LayoutEngineTest { } @Test - public void testCase175() + public void testCase177() { TestCSSNode root_node = new TestCSSNode(); { @@ -7859,7 +7950,7 @@ public class LayoutEngineTest { } @Test - public void testCase176() + public void testCase178() { TestCSSNode root_node = new TestCSSNode(); { @@ -7897,7 +7988,7 @@ public class LayoutEngineTest { } @Test - public void testCase177() + public void testCase179() { TestCSSNode root_node = new TestCSSNode(); { @@ -7936,7 +8027,7 @@ public class LayoutEngineTest { } @Test - public void testCase178() + public void testCase180() { TestCSSNode root_node = new TestCSSNode(); { @@ -7974,7 +8065,7 @@ public class LayoutEngineTest { } @Test - public void testCase179() + public void testCase181() { TestCSSNode root_node = new TestCSSNode(); { @@ -8013,7 +8104,7 @@ public class LayoutEngineTest { } @Test - public void testCase180() + public void testCase182() { TestCSSNode root_node = new TestCSSNode(); { @@ -8051,7 +8142,7 @@ public class LayoutEngineTest { } @Test - public void testCase181() + public void testCase183() { TestCSSNode root_node = new TestCSSNode(); { @@ -8090,7 +8181,7 @@ public class LayoutEngineTest { } @Test - public void testCase182() + public void testCase184() { TestCSSNode root_node = new TestCSSNode(); { @@ -8126,7 +8217,7 @@ public class LayoutEngineTest { } @Test - public void testCase183() + public void testCase185() { TestCSSNode root_node = new TestCSSNode(); { @@ -8194,7 +8285,7 @@ public class LayoutEngineTest { } @Test - public void testCase184() + public void testCase186() { TestCSSNode root_node = new TestCSSNode(); { @@ -8271,7 +8362,7 @@ public class LayoutEngineTest { } @Test - public void testCase185() + public void testCase187() { TestCSSNode root_node = new TestCSSNode(); { @@ -8343,7 +8434,7 @@ public class LayoutEngineTest { } @Test - public void testCase186() + public void testCase188() { TestCSSNode root_node = new TestCSSNode(); { @@ -8396,7 +8487,7 @@ public class LayoutEngineTest { } @Test - public void testCase187() + public void testCase189() { TestCSSNode root_node = new TestCSSNode(); { @@ -8486,7 +8577,7 @@ public class LayoutEngineTest { } @Test - public void testCase188() + public void testCase190() { TestCSSNode root_node = new TestCSSNode(); { @@ -8540,7 +8631,7 @@ public class LayoutEngineTest { } @Test - public void testCase189() + public void testCase191() { TestCSSNode root_node = new TestCSSNode(); { @@ -8594,7 +8685,7 @@ public class LayoutEngineTest { } @Test - public void testCase190() + public void testCase192() { TestCSSNode root_node = new TestCSSNode(); { @@ -8664,7 +8755,7 @@ public class LayoutEngineTest { } @Test - public void testCase191() + public void testCase193() { TestCSSNode root_node = new TestCSSNode(); { @@ -8734,7 +8825,7 @@ public class LayoutEngineTest { } @Test - public void testCase192() + public void testCase194() { TestCSSNode root_node = new TestCSSNode(); { @@ -8790,7 +8881,7 @@ public class LayoutEngineTest { } @Test - public void testCase193() + public void testCase195() { TestCSSNode root_node = new TestCSSNode(); { @@ -8845,7 +8936,7 @@ public class LayoutEngineTest { } @Test - public void testCase194() + public void testCase196() { TestCSSNode root_node = new TestCSSNode(); { @@ -8900,7 +8991,7 @@ public class LayoutEngineTest { } @Test - public void testCase195() + public void testCase197() { TestCSSNode root_node = new TestCSSNode(); { @@ -8971,7 +9062,7 @@ public class LayoutEngineTest { } @Test - public void testCase196() + public void testCase198() { TestCSSNode root_node = new TestCSSNode(); { @@ -9042,7 +9133,7 @@ public class LayoutEngineTest { } @Test - public void testCase197() + public void testCase199() { TestCSSNode root_node = new TestCSSNode(); { @@ -9099,7 +9190,7 @@ public class LayoutEngineTest { } @Test - public void testCase198() + public void testCase200() { TestCSSNode root_node = new TestCSSNode(); { @@ -9155,7 +9246,7 @@ public class LayoutEngineTest { } @Test - public void testCase199() + public void testCase201() { TestCSSNode root_node = new TestCSSNode(); { @@ -9211,7 +9302,7 @@ public class LayoutEngineTest { } @Test - public void testCase200() + public void testCase202() { TestCSSNode root_node = new TestCSSNode(); { @@ -9283,7 +9374,7 @@ public class LayoutEngineTest { } @Test - public void testCase201() + public void testCase203() { TestCSSNode root_node = new TestCSSNode(); { @@ -9355,7 +9446,7 @@ public class LayoutEngineTest { } @Test - public void testCase202() + public void testCase204() { TestCSSNode root_node = new TestCSSNode(); { @@ -9414,7 +9505,7 @@ public class LayoutEngineTest { } @Test - public void testCase203() + public void testCase205() { TestCSSNode root_node = new TestCSSNode(); { @@ -9487,7 +9578,7 @@ public class LayoutEngineTest { } @Test - public void testCase204() + public void testCase206() { TestCSSNode root_node = new TestCSSNode(); { @@ -9561,7 +9652,7 @@ public class LayoutEngineTest { } @Test - public void testCase205() + public void testCase207() { TestCSSNode root_node = new TestCSSNode(); {