From 57874a1a9e84c8e3069c1d961e67f3a68da6ca2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Sj=C3=B6lander?= Date: Wed, 13 Jul 2016 10:42:03 +0100 Subject: [PATCH] Revert "Correctly size cross axis when measuring flex basis" --- .gitignore | 1 - TestResult.xml | 2 +- dist/css-layout.h | 87 +++++++++--------- dist/css-layout.jar | Bin 16343 -> 16324 bytes dist/css-layout.js | 87 +++++++++--------- dist/css-layout.min.js | 2 +- dist/css-layout.min.js.map | 2 +- src/Layout-test-utils.c | 16 +--- src/Layout-test-utils.js | 17 ++-- src/Layout.c | 87 +++++++++--------- src/Layout.js | 87 +++++++++--------- src/__tests__/Layout-test.c | 14 +-- src/__tests__/Layout-test.js | 16 ++-- .../LayoutEngineTest.cs | 45 ++++----- src/csharp/Facebook.CSSLayout/LayoutEngine.cs | 87 +++++++++--------- .../com/facebook/csslayout/LayoutEngine.java | 87 +++++++++--------- .../facebook/csslayout/LayoutEngineTest.java | 32 +++---- 17 files changed, 307 insertions(+), 362 deletions(-) diff --git a/.gitignore b/.gitignore index 4fdad226..b7fd170c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ a.out /lib/ /node_modules/ npm-debug.log -TestResult.xml diff --git a/TestResult.xml b/TestResult.xml index 66a6b6b0..a2bb5a16 100644 --- a/TestResult.xml +++ b/TestResult.xml @@ -1,6 +1,6 @@ - + diff --git a/dist/css-layout.h b/dist/css-layout.h index f949aed2..44160d61 100644 --- a/dist/css-layout.h +++ b/dist/css-layout.h @@ -1032,61 +1032,56 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSS_UNDEFINED; childHeight = CSS_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childWidth = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childHeight = CSS_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childHeight = availableInnerMainDim; + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { + childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { + childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { + if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; } } - // Cross axis - if (isMainAxisRow) { - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - } else { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !isUndefined(availableInnerWidth) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && + widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isMainAxisRow && + !isUndefined(availableInnerHeight) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && + heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; } // Measure the child diff --git a/dist/css-layout.jar b/dist/css-layout.jar index a57e8feac7fc296ec7edea6e093d2b676137e809..0e00efe75bcda0b4c0c7f8a4a818a5942a7cfd57 100644 GIT binary patch delta 13316 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 OsTU-HNaY9m*ZvR8Z+>(D delta 13314 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 diff --git a/dist/css-layout.js b/dist/css-layout.js index fcc10d87..5dc93990 100644 --- a/dist/css-layout.js +++ b/dist/css-layout.js @@ -795,61 +795,56 @@ var computeLayout = (function() { child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSS_UNDEFINED; childHeight = CSS_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childWidth = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childHeight = CSS_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childHeight = availableInnerMainDim; + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { + childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { + childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { + if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; } } - // Cross axis - if (isMainAxisRow) { - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - } else { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !isUndefined(availableInnerWidth) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && + widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isMainAxisRow && + !isUndefined(availableInnerHeight) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && + heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; } // Measure the child diff --git a/dist/css-layout.min.js b/dist/css-layout.min.js index 2c459252..e4a5f417 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===da||a===ea}function d(a){return a===fa||a===ga}function e(a){return void 0===a.style.flex?0:a.style.flex}function f(a){return W?!0:e(a)<=0}function g(a){return e(a)>0?e(a):0}function h(a){if(W){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===ca){if(a===da)return ea;if(a===ea)return da}return a}function w(a,b){var c;return c=a.style.direction?a.style.direction:aa,c===aa&&(c=void 0===b?ba:b),c}function x(a){return a.style.flexDirection?a.style.flexDirection:fa}function y(a,b){return d(a)?v(da,b):fa}function z(a){return a.style.position?a.style.position:qa}function A(a){return a.style.overflow?a.style.overflow:sa}function B(a){return z(a)===qa&&void 0!==a.style.flex&&0!==a.style.flex}function C(a){return"wrap"===a.style.flexWrap}function D(a,b){return a.layout[Ba[b]]+q(a,b)}function E(a,b){return void 0!==a.style[Aa[b]]&&a.style[Aa[b]]>=0}function F(a,b){return void 0!==a.layout[Ba[b]]&&a.layout[Ba[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)===ra?0:b.layout[Ba[c]];b.layout[ya[c]]=a.layout[Ba[c]]-d-b.layout[za[c]]}function O(a,b){return void 0!==a.style[xa[b]]?I(a,xa[b]):-I(a,ya[b])}function P(a,b){var c=v(x(a),b),d=y(c,b);a.layout[xa[c]]=i(a,c)+O(a,c),a.layout[ya[c]]=j(a,c)+O(a,c),a.layout[xa[d]]=i(a,d)+O(a,d),a.layout[ya[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===ua:!0,"availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED"),Q(b(e)?O===ua:!0,"availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED");var S=r(a,da),U=r(a,fa),W=q(a,da),X=q(a,fa),aa=w(a,k);if(a.layout.direction=aa,H(a)){var ba=d-W-S,ca=e-X-U;if(l===va&&O===va)a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X);else if(0>=ba||0>=ca)a.layout.measuredWidth=M(a,da,0),a.layout.measuredHeight=M(a,fa,0);else{var sa=a.style.measure(ba,l,ca,O);a.layout.measuredWidth=M(a,da,l===ua||l===wa?sa.width+S:d-W),a.layout.measuredHeight=M(a,fa,O===ua||O===wa?sa.height+U:e-X)}}else{var Aa=a.children.length;if(0===Aa)return a.layout.measuredWidth=M(a,da,l===ua||l===wa?S:d-W),void(a.layout.measuredHeight=M(a,fa,O===ua||O===wa?U:e-X));if(!R){if(l===wa&&0>=d&&O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,0));if(l===wa&&0>=d)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,b(e)?0:e-X));if(O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,b(d)?0:d-W),void(a.layout.measuredHeight=M(a,fa,0));if(l===va&&O===va)return a.layout.measuredWidth=M(a,da,d-W),void(a.layout.measuredHeight=M(a,fa,e-X))}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-S,Xa=e-X-U,Ya=Ka?Wa:Xa,Za=Ka?Xa:Wa;for(Da=0;Aa>Da;Da++){if(Ca=a.children[Da],R){var $a=w(Ca,aa);P(Ca,$a)}z(Ca)===ra?(void 0===Na&&(Na=Ca),void 0!==Oa&&(Oa.nextChild=Ca),Oa=Ca,Ca.nextChild=void 0):Ka&&E(Ca,da)?Ca.layout.flexBasis=L(Ca.style.width,r(Ca,da)):!Ka&&E(Ca,fa)?Ca.layout.flexBasis=L(Ca.style.height,r(Ca,fa)):f(Ca)||b(Ya)?(Ea=V,Fa=V,Ga=ua,Ha=ua,Ka?l==ua||b(Ya)?(Ea=V,Ga=ua):(Ea=Ya,Ga=wa):A(a)===ta&&(O==ua||b(Ya)?(Fa=V,Ha=ua):(Fa=Ya,Ha=wa)),Ka?A(a)===ta&&(b(Za)||E(Ca,fa)||O!=va||u(a,Ca)!=pa?E(Ca,fa)?(Fa=Ca.style.height+q(Ca,fa),Ha=va):(Fa=Za,Ha=b(Fa)?ua:wa):(Fa=Za,Ha=va)):b(Za)||E(Ca,da)||l!=va||u(a,Ca)!=pa?E(Ca,da)?(Ea=Ca.style.width+q(Ca,da),Ga=va):(Ea=Za,Ga=b(Ea)?ua:wa):(Ea=Za,Ga=va),T(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;Aa>ab;){var eb=0,fb=0,gb=0,hb=0;Da=_a;for(var ib=void 0,jb=void 0;Aa>Da;){if(Ca=a.children[Da],Ca.lineIndex=bb,z(Ca)!==ra){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===va,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,da),Ga=va,b(Za)||E(jb,fa)||O!=va||u(a,jb)!=pa?E(jb,fa)?(Fa=jb.style.height+q(jb,fa),Ha=va):(Fa=Za,Ha=b(Fa)?ua:wa):(Fa=Za,Ha=va)):(Fa=yb+q(jb,fa),Ha=va,b(Za)||E(jb,da)||l!=va||u(a,jb)!=pa?E(jb,da)?(Ea=jb.style.width+q(jb,da),Ga=va):(Ea=Za,Ga=b(Ea)?ua:wa):(Ea=Za,Ga=va));var zb=!E(jb,Ja)&&u(a,jb)===pa;T(jb,Ea,Fa,aa,Ga,Ha,R&&!zb,"flex"),jb=jb.nextChild}}ob=pb+qb,Ua===wa&&(ob=0),La!==ha&&(La===ia?mb=ob/2:La===ja?mb=ob:La===ka?(ob=L(ob,0),nb=eb>1?ob/(eb-1):0):La===la&&(nb=ob/eb,mb=nb/2));var Ab=Pa+mb,Bb=0;for(Da=_a;ab>Da;++Da)Ca=a.children[Da],z(Ca)===ra&&G(Ca,xa[Ia])?R&&(Ca.layout[za[Ia]]=I(Ca,xa[Ia])+m(a,Ia)+i(Ca,Ia)):(R&&(Ca.layout[za[Ia]]+=Ab),z(Ca)===qa&&(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===ua||Va===wa)&&(Cb=M(a,Ja,Bb+Ta)-Ta,Va===wa&&(Cb=K(Cb,Za))),Ma||Va!==va||(Bb=Za),Bb=M(a,Ja,Bb+Ta)-Ta,R)for(Da=_a;ab>Da;++Da)if(Ca=a.children[Da],z(Ca)===ra)G(Ca,xa[Ja])?Ca.layout[za[Ja]]=I(Ca,xa[Ja])+m(a,Ja)+i(Ca,Ja):Ca.layout[za[Ja]]=Ra+i(Ca,Ja);else{var Db=Ra,Eb=u(a,Ca);if(Eb===pa){Ea=Ca.layout.measuredWidth+q(Ca,da),Fa=Ca.layout.measuredHeight+q(Ca,fa);var Fb=!1;Ka?(Fb=E(Ca,fa),Fa=Bb):(Fb=E(Ca,da),Ea=Bb),Fb||(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,T(Ca,Ea,Fa,aa,Ga,Ha,!0,"stretch"))}else if(Eb!==ma){var Gb=Cb-D(Ca,Ja);Db+=Eb===na?Gb/2:Gb}Ca.layout[za[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===oa?Jb+=Hb:Kb===na?Jb+=Hb/2:Kb===pa&&Za>cb&&(Ib=Hb/bb);var Lb=0;for(Da=0;bb>Da;++Da){var Mb,Nb=Lb,Ob=0;for(Mb=Nb;Aa>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){if(Ca.lineIndex!==Da)break;F(Ca,Ja)&&(Ob=L(Ob,Ca.layout[Ba[Ja]]+q(Ca,Ja)))}if(Lb=Mb,Ob+=Ib,R)for(Mb=Nb;Lb>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){var Pb=u(a,Ca);Pb===ma?Ca.layout[za[Ja]]=Jb+i(Ca,Ja):Pb===oa?Ca.layout[za[Ja]]=Jb+Ob-j(Ca,Ja)-Ca.layout[Ba[Ja]]:Pb===na?(Fa=Ca.layout[Ba[Ja]],Ca.layout[za[Ja]]=Jb+(Ob-Fa)/2):Pb===pa&&(Ca.layout[za[Ja]]=Jb+i(Ca,Ja))}Jb+=Ob}}if(a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X),Ua===ua?a.layout[Ba[Ia]]=M(a,Ia,db):Ua===wa&&(a.layout[Ba[Ia]]=L(K(Ya+Sa,J(a,Ia,db)),Sa)),Va===ua?a.layout[Ba[Ja]]=M(a,Ja,cb+Ta):Va===wa&&(a.layout[Ba[Ja]]=L(K(Za+Ta,J(a,Ja,cb+Ta)),Ta)),R){var Qb=!1,Rb=!1;if((Ia===ea||Ia===ga)&&(Qb=!0),(Ja===ea||Ja===ga)&&(Rb=!0),Qb||Rb)for(Da=0;Aa>Da;++Da)Ca=a.children[Da],Qb&&N(a,Ca,Ia),Rb&&N(a,Ca,Ja)}for(Oa=Na;void 0!==Oa;)R&&(Ea=V,Fa=V,E(Oa,da)?Ea=Oa.style.width+q(Oa,da):G(Oa,Y)&&G(Oa,$)&&(Ea=a.layout.measuredWidth-(m(a,da)+n(a,da))-(Oa.style[Y]+Oa.style[$]),Ea=M(Oa,da,Ea)),E(Oa,fa)?Fa=Oa.style.height+q(Oa,fa):G(Oa,Z)&&G(Oa,_)&&(Fa=a.layout.measuredHeight-(m(a,fa)+n(a,fa))-(Oa.style[Z]+Oa.style[_]),Fa=M(Oa,fa,Fa)),(b(Ea)||b(Fa))&&(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=wa),A(a)===ta&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=wa),T(Oa,Ea,Fa,aa,Ga,Ha,!1,"abs-measure"),Ea=Oa.layout.measuredWidth+q(Oa,da),Fa=Oa.layout.measuredHeight+q(Oa,fa)),T(Oa,Ea,Fa,aa,va,va,!0,"abs-layout"),G(Oa,ya[da])&&!G(Oa,xa[da])&&(Oa.layout[xa[da]]=a.layout[Ba[da]]-Oa.layout[Ba[da]]-I(Oa,ya[da])),G(Oa,ya[fa])&&!G(Oa,xa[fa])&&(Oa.layout[xa[fa]]=a.layout[Ba[fa]]-Oa.layout[Ba[fa]]-I(Oa,ya[fa]))),Oa=Oa.nextChild}}function S(a,b,c,d,e,f,g,h){var i=h.heightMeasureMode==ua&&g==ua||h.heightMeasureMode==g&&h.availableHeight==c,j=h.widthMeasureMode==ua&&f==ua||h.widthMeasureMode==f&&h.availableWidth==b;if(i&&j)return!0;var k=h.heightMeasureMode==ua&&g==wa&&h.computedHeight<=c-e||g==va&&h.computedHeight==c-e;if(j&&k)return!0;var l=h.widthMeasureMode==ua&&f==wa&&h.computedWidth<=b-d||f==va&&h.computedWidth==b-d;if(i&&l)return!0;if(k&&l)return!0;if(a){if(j)return g==ua?!0:g==wa&&h.computedHeightk;k++)if(S(a.isTextNode,b,c,n,o,e,f,i.cachedMeasurements[k])){m=i.cachedMeasurements[k];break}}else if(g)i.cachedLayout&&i.cachedLayout.availableWidth===b&&i.cachedLayout.availableHeight===c&&i.cachedLayout.widthMeasureMode===e&&i.cachedLayout.heightMeasureMode===f&&(m=i.cachedLayout);else if(i.cachedMeasurements)for(k=0,l=i.cachedMeasurements.length;l>k;k++)if(i.cachedMeasurements[k].availableWidth===b&&i.cachedMeasurements[k].availableHeight===c&&i.cachedMeasurements[k].widthMeasureMode===e&&i.cachedMeasurements[k].heightMeasureMode===f){m=i.cachedMeasurements[k];break}if(j||void 0===m){if(R(a,b,c,d,e,f,g),i.lastParentDirection=d,void 0===m){var p;g?(void 0===i.cachedLayout&&(i.cachedLayout={}),p=i.cachedLayout):(void 0===i.cachedMeasurements&&(i.cachedMeasurements=[]),p={},i.cachedMeasurements.push(p)),p.availableWidth=b,p.availableHeight=c,p.widthMeasureMode=e,p.heightMeasureMode=f,p.computedWidth=i.measuredWidth,p.computedHeight=i.measuredHeight}}else i.measureWidth=m.computedWidth,i.measureHeight=m.computedHeight;return g&&(a.layout.width=a.layout.measuredWidth,a.layout.height=a.layout.measuredHeight,i.shouldUpdate=!0),i.generationCount=X,j||void 0===m}function U(a,c,d,e){X++;var f=ua,g=ua;b(c)?E(a,da)?(c=a.style.width+q(a,da),f=va):a.style.maxWidth>=0&&(c=a.style.maxWidth,f=wa):f=va,b(d)?E(a,fa)?(d=a.style.height+q(a,fa),g=va):a.style.maxHeight>=0&&(d=a.style.maxHeight,g=wa):g=va,T(a,c,d,e,f,g,!0,"initial")&&P(a,a.layout.direction)}var V,W=!1,X=0,Y="left",Z="top",$="right",_="bottom",aa="inherit",ba="ltr",ca="rtl",da="row",ea="row-reverse",fa="column",ga="column-reverse",ha="flex-start",ia="center",ja="flex-end",ka="space-between",la="space-around",ma="flex-start",na="center",oa="flex-end",pa="stretch",qa="relative",ra="absolute",sa="visible",ta="hidden",ua="undefined",va="exactly",wa="at-most",xa={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},ya={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},za={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},Aa={row:"width","row-reverse":"width",column:"height","column-reverse":"height"},Ba={row:"measuredWidth","row-reverse":"measuredWidth",column:"measuredHeight","column-reverse":"measuredHeight"};return{layoutNodeImpl:R,computeLayout:U,fillNodes:a,canUseCachedMeasurement:S}}();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===da||a===ea}function d(a){return a===fa||a===ga}function e(a){return void 0===a.style.flex?0:a.style.flex}function f(a){return W?!0:e(a)<=0}function g(a){return e(a)>0?e(a):0}function h(a){if(W){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===ca){if(a===da)return ea;if(a===ea)return da}return a}function w(a,b){var c;return c=a.style.direction?a.style.direction:aa,c===aa&&(c=void 0===b?ba:b),c}function x(a){return a.style.flexDirection?a.style.flexDirection:fa}function y(a,b){return d(a)?v(da,b):fa}function z(a){return a.style.position?a.style.position:qa}function A(a){return a.style.overflow?a.style.overflow:sa}function B(a){return z(a)===qa&&void 0!==a.style.flex&&0!==a.style.flex}function C(a){return"wrap"===a.style.flexWrap}function D(a,b){return a.layout[Ba[b]]+q(a,b)}function E(a,b){return void 0!==a.style[Aa[b]]&&a.style[Aa[b]]>=0}function F(a,b){return void 0!==a.layout[Ba[b]]&&a.layout[Ba[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)===ra?0:b.layout[Ba[c]];b.layout[ya[c]]=a.layout[Ba[c]]-d-b.layout[za[c]]}function O(a,b){return void 0!==a.style[xa[b]]?I(a,xa[b]):-I(a,ya[b])}function P(a,b){var c=v(x(a),b),d=y(c,b);a.layout[xa[c]]=i(a,c)+O(a,c),a.layout[ya[c]]=j(a,c)+O(a,c),a.layout[xa[d]]=i(a,d)+O(a,d),a.layout[ya[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===ua:!0,"availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED"),Q(b(e)?O===ua:!0,"availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED");var S=r(a,da),U=r(a,fa),W=q(a,da),X=q(a,fa),aa=w(a,k);if(a.layout.direction=aa,H(a)){var ba=d-W-S,ca=e-X-U;if(l===va&&O===va)a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X);else if(0>=ba||0>=ca)a.layout.measuredWidth=M(a,da,0),a.layout.measuredHeight=M(a,fa,0);else{var sa=a.style.measure(ba,l,ca,O);a.layout.measuredWidth=M(a,da,l===ua||l===wa?sa.width+S:d-W),a.layout.measuredHeight=M(a,fa,O===ua||O===wa?sa.height+U:e-X)}}else{var Aa=a.children.length;if(0===Aa)return a.layout.measuredWidth=M(a,da,l===ua||l===wa?S:d-W),void(a.layout.measuredHeight=M(a,fa,O===ua||O===wa?U:e-X));if(!R){if(l===wa&&0>=d&&O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,0));if(l===wa&&0>=d)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,b(e)?0:e-X));if(O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,b(d)?0:d-W),void(a.layout.measuredHeight=M(a,fa,0));if(l===va&&O===va)return a.layout.measuredWidth=M(a,da,d-W),void(a.layout.measuredHeight=M(a,fa,e-X))}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-S,Xa=e-X-U,Ya=Ka?Wa:Xa,Za=Ka?Xa:Wa;for(Da=0;Aa>Da;Da++){if(Ca=a.children[Da],R){var $a=w(Ca,aa);P(Ca,$a)}z(Ca)===ra?(void 0===Na&&(Na=Ca),void 0!==Oa&&(Oa.nextChild=Ca),Oa=Ca,Ca.nextChild=void 0):Ka&&E(Ca,da)?Ca.layout.flexBasis=L(Ca.style.width,r(Ca,da)):!Ka&&E(Ca,fa)?Ca.layout.flexBasis=L(Ca.style.height,r(Ca,fa)):f(Ca)||b(Ya)?(Ea=V,Fa=V,Ga=ua,Ha=ua,E(Ca,da)&&(Ea=Ca.style.width+q(Ca,da),Ga=va),E(Ca,fa)&&(Fa=Ca.style.height+q(Ca,fa),Ha=va),Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=wa),A(a)===ta&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=wa),Ka||b(Wa)||E(Ca,da)||l!=va||u(a,Ca)!=pa||(Ea=Wa,Ga=va),!Ka||b(Xa)||E(Ca,fa)||O!=va||u(a,Ca)!=pa||(Fa=Xa,Ha=va),T(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;Aa>ab;){var eb=0,fb=0,gb=0,hb=0;Da=_a;for(var ib=void 0,jb=void 0;Aa>Da;){if(Ca=a.children[Da],Ca.lineIndex=bb,z(Ca)!==ra){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===va,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,da),Ga=va,b(Za)||E(jb,fa)||O!=va||u(a,jb)!=pa?E(jb,fa)?(Fa=jb.style.height+q(jb,fa),Ha=va):(Fa=Za,Ha=b(Fa)?ua:wa):(Fa=Za,Ha=va)):(Fa=yb+q(jb,fa),Ha=va,b(Za)||E(jb,da)||l!=va||u(a,jb)!=pa?E(jb,da)?(Ea=jb.style.width+q(jb,da),Ga=va):(Ea=Za,Ga=b(Ea)?ua:wa):(Ea=Za,Ga=va));var zb=!E(jb,Ja)&&u(a,jb)===pa;T(jb,Ea,Fa,aa,Ga,Ha,R&&!zb,"flex"),jb=jb.nextChild}}ob=pb+qb,Ua===wa&&(ob=0),La!==ha&&(La===ia?mb=ob/2:La===ja?mb=ob:La===ka?(ob=L(ob,0),nb=eb>1?ob/(eb-1):0):La===la&&(nb=ob/eb,mb=nb/2));var Ab=Pa+mb,Bb=0;for(Da=_a;ab>Da;++Da)Ca=a.children[Da],z(Ca)===ra&&G(Ca,xa[Ia])?R&&(Ca.layout[za[Ia]]=I(Ca,xa[Ia])+m(a,Ia)+i(Ca,Ia)):(R&&(Ca.layout[za[Ia]]+=Ab),z(Ca)===qa&&(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===ua||Va===wa)&&(Cb=M(a,Ja,Bb+Ta)-Ta,Va===wa&&(Cb=K(Cb,Za))),Ma||Va!==va||(Bb=Za),Bb=M(a,Ja,Bb+Ta)-Ta,R)for(Da=_a;ab>Da;++Da)if(Ca=a.children[Da],z(Ca)===ra)G(Ca,xa[Ja])?Ca.layout[za[Ja]]=I(Ca,xa[Ja])+m(a,Ja)+i(Ca,Ja):Ca.layout[za[Ja]]=Ra+i(Ca,Ja);else{var Db=Ra,Eb=u(a,Ca);if(Eb===pa){Ea=Ca.layout.measuredWidth+q(Ca,da),Fa=Ca.layout.measuredHeight+q(Ca,fa);var Fb=!1;Ka?(Fb=E(Ca,fa),Fa=Bb):(Fb=E(Ca,da),Ea=Bb),Fb||(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,T(Ca,Ea,Fa,aa,Ga,Ha,!0,"stretch"))}else if(Eb!==ma){var Gb=Cb-D(Ca,Ja);Db+=Eb===na?Gb/2:Gb}Ca.layout[za[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===oa?Jb+=Hb:Kb===na?Jb+=Hb/2:Kb===pa&&Za>cb&&(Ib=Hb/bb);var Lb=0;for(Da=0;bb>Da;++Da){var Mb,Nb=Lb,Ob=0;for(Mb=Nb;Aa>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){if(Ca.lineIndex!==Da)break;F(Ca,Ja)&&(Ob=L(Ob,Ca.layout[Ba[Ja]]+q(Ca,Ja)))}if(Lb=Mb,Ob+=Ib,R)for(Mb=Nb;Lb>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){var Pb=u(a,Ca);Pb===ma?Ca.layout[za[Ja]]=Jb+i(Ca,Ja):Pb===oa?Ca.layout[za[Ja]]=Jb+Ob-j(Ca,Ja)-Ca.layout[Ba[Ja]]:Pb===na?(Fa=Ca.layout[Ba[Ja]],Ca.layout[za[Ja]]=Jb+(Ob-Fa)/2):Pb===pa&&(Ca.layout[za[Ja]]=Jb+i(Ca,Ja))}Jb+=Ob}}if(a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X),Ua===ua?a.layout[Ba[Ia]]=M(a,Ia,db):Ua===wa&&(a.layout[Ba[Ia]]=L(K(Ya+Sa,J(a,Ia,db)),Sa)),Va===ua?a.layout[Ba[Ja]]=M(a,Ja,cb+Ta):Va===wa&&(a.layout[Ba[Ja]]=L(K(Za+Ta,J(a,Ja,cb+Ta)),Ta)),R){var Qb=!1,Rb=!1;if((Ia===ea||Ia===ga)&&(Qb=!0),(Ja===ea||Ja===ga)&&(Rb=!0),Qb||Rb)for(Da=0;Aa>Da;++Da)Ca=a.children[Da],Qb&&N(a,Ca,Ia),Rb&&N(a,Ca,Ja)}for(Oa=Na;void 0!==Oa;)R&&(Ea=V,Fa=V,E(Oa,da)?Ea=Oa.style.width+q(Oa,da):G(Oa,Y)&&G(Oa,$)&&(Ea=a.layout.measuredWidth-(m(a,da)+n(a,da))-(Oa.style[Y]+Oa.style[$]),Ea=M(Oa,da,Ea)),E(Oa,fa)?Fa=Oa.style.height+q(Oa,fa):G(Oa,Z)&&G(Oa,_)&&(Fa=a.layout.measuredHeight-(m(a,fa)+n(a,fa))-(Oa.style[Z]+Oa.style[_]),Fa=M(Oa,fa,Fa)),(b(Ea)||b(Fa))&&(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=wa),A(a)===ta&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=wa),T(Oa,Ea,Fa,aa,Ga,Ha,!1,"abs-measure"),Ea=Oa.layout.measuredWidth+q(Oa,da),Fa=Oa.layout.measuredHeight+q(Oa,fa)),T(Oa,Ea,Fa,aa,va,va,!0,"abs-layout"),G(Oa,ya[da])&&!G(Oa,xa[da])&&(Oa.layout[xa[da]]=a.layout[Ba[da]]-Oa.layout[Ba[da]]-I(Oa,ya[da])),G(Oa,ya[fa])&&!G(Oa,xa[fa])&&(Oa.layout[xa[fa]]=a.layout[Ba[fa]]-Oa.layout[Ba[fa]]-I(Oa,ya[fa]))),Oa=Oa.nextChild}}function S(a,b,c,d,e,f,g,h){var i=h.heightMeasureMode==ua&&g==ua||h.heightMeasureMode==g&&h.availableHeight==c,j=h.widthMeasureMode==ua&&f==ua||h.widthMeasureMode==f&&h.availableWidth==b;if(i&&j)return!0;var k=h.heightMeasureMode==ua&&g==wa&&h.computedHeight<=c-e||g==va&&h.computedHeight==c-e;if(j&&k)return!0;var l=h.widthMeasureMode==ua&&f==wa&&h.computedWidth<=b-d||f==va&&h.computedWidth==b-d;if(i&&l)return!0;if(k&&l)return!0;if(a){if(j)return g==ua?!0:g==wa&&h.computedHeightk;k++)if(S(a.isTextNode,b,c,n,o,e,f,i.cachedMeasurements[k])){m=i.cachedMeasurements[k];break}}else if(g)i.cachedLayout&&i.cachedLayout.availableWidth===b&&i.cachedLayout.availableHeight===c&&i.cachedLayout.widthMeasureMode===e&&i.cachedLayout.heightMeasureMode===f&&(m=i.cachedLayout);else if(i.cachedMeasurements)for(k=0,l=i.cachedMeasurements.length;l>k;k++)if(i.cachedMeasurements[k].availableWidth===b&&i.cachedMeasurements[k].availableHeight===c&&i.cachedMeasurements[k].widthMeasureMode===e&&i.cachedMeasurements[k].heightMeasureMode===f){m=i.cachedMeasurements[k];break}if(j||void 0===m){if(R(a,b,c,d,e,f,g),i.lastParentDirection=d,void 0===m){var p;g?(void 0===i.cachedLayout&&(i.cachedLayout={}),p=i.cachedLayout):(void 0===i.cachedMeasurements&&(i.cachedMeasurements=[]),p={},i.cachedMeasurements.push(p)),p.availableWidth=b,p.availableHeight=c,p.widthMeasureMode=e,p.heightMeasureMode=f,p.computedWidth=i.measuredWidth,p.computedHeight=i.measuredHeight}}else i.measureWidth=m.computedWidth,i.measureHeight=m.computedHeight;return g&&(a.layout.width=a.layout.measuredWidth,a.layout.height=a.layout.measuredHeight,i.shouldUpdate=!0),i.generationCount=X,j||void 0===m}function U(a,c,d,e){X++;var f=ua,g=ua;b(c)?E(a,da)?(c=a.style.width+q(a,da),f=va):a.style.maxWidth>=0&&(c=a.style.maxWidth,f=wa):f=va,b(d)?E(a,fa)?(d=a.style.height+q(a,fa),g=va):a.style.maxHeight>=0&&(d=a.style.maxHeight,g=wa):g=va,T(a,c,d,e,f,g,!0,"initial")&&P(a,a.layout.direction)}var V,W=!1,X=0,Y="left",Z="top",$="right",_="bottom",aa="inherit",ba="ltr",ca="rtl",da="row",ea="row-reverse",fa="column",ga="column-reverse",ha="flex-start",ia="center",ja="flex-end",ka="space-between",la="space-around",ma="flex-start",na="center",oa="flex-end",pa="stretch",qa="relative",ra="absolute",sa="visible",ta="hidden",ua="undefined",va="exactly",wa="at-most",xa={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},ya={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},za={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},Aa={row:"width","row-reverse":"width",column:"height","column-reverse":"height"},Ba={row:"measuredWidth","row-reverse":"measuredWidth",column:"measuredHeight","column-reverse":"measuredHeight"};return{layoutNodeImpl:R,computeLayout:U,fillNodes:a,canUseCachedMeasurement:S}}();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 108c6792..d7beff52 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","CSS_ALIGN_STRETCH","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_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","canUseCachedMeasurement","isTextNode","marginRow","marginColumn","cachedLayout","isHeightSame","isWidthSame","isHeightValid","computedHeight","isWidthValid","computedWidth","reason","needToVisitNode","generationCount","gCurrentGenerationCount","lastParentDirection","cachedMeasurements","len","cachedResults","newCacheEntry","push","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 || innerHeight <= 0) {\n\n // Don't bother sizing the text if there's no horizontal or vertical 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 childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n\n // Main axis\n if (isMainAxisRow) {\n if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {\n childWidth = CSS_UNDEFINED;\n childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n } else {\n childWidth = availableInnerMainDim;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n } else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) {\n childHeight = CSS_UNDEFINED;\n childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n } else {\n childHeight = availableInnerMainDim;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n // Cross axis\n if (isMainAxisRow) {\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n }\n } else {\n if (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\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 (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else 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 (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else 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 function canUseCachedMeasurement(\n isTextNode,\n availableWidth,\n availableHeight,\n marginRow,\n marginColumn,\n widthMeasureMode,\n heightMeasureMode,\n cachedLayout) {\n\n var isHeightSame =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.heightMeasureMode == heightMeasureMode && cachedLayout.availableHeight == availableHeight);\n\n var isWidthSame =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.widthMeasureMode == widthMeasureMode && cachedLayout.availableWidth == availableWidth);\n\n if (isHeightSame && isWidthSame) {\n return true;\n }\n\n var isHeightValid =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) ||\n (heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedHeight == (availableHeight - marginColumn));\n\n if (isWidthSame && isHeightValid) {\n return true;\n }\n\n var isWidthValid =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) ||\n (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedWidth == (availableWidth - marginRow));\n\n if (isHeightSame && isWidthValid) {\n return true;\n }\n\n if (isHeightValid && isWidthValid) {\n return true;\n }\n\n // We know this to be text so we can apply some more specialized heuristics.\n if (isTextNode) {\n if (isWidthSame) {\n if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n // Width is the same and height is not restricted. Re-use cahced value.\n return true;\n }\n\n if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedHeight < (availableHeight - marginColumn)) {\n // Width is the same and height restriction is greater than the cached height. Re-use cached value.\n return true;\n }\n\n // Width is the same but height restriction imposes smaller height than previously measured.\n // Update the cached value to respect the new height restriction.\n cachedLayout.computedHeight = availableHeight - marginColumn;\n return true;\n }\n\n if (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED ||\n (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedWidth <= (availableWidth - marginRow))) {\n // Previsouly this text was measured with no width restriction, if width is now restricted\n // but to a larger value than the previsouly measured width we can re-use the measurement\n // as we know it will fit.\n return true;\n }\n }\n }\n\n return false;\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 i;\n var len;\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 // We handle nodes with measure functions specially here because they are the most\n // expensive to measure, so it's worth avoiding redundant measurements if at all possible.\n if (isMeasureDefined(node)) {\n var marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // First, try to use the layout cache.\n if (layout.cachedLayout &&\n canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedLayout)) {\n cachedResults = layout.cachedLayout;\n } else if (layout.cachedMeasurements) {\n // Try to use the measurement cache.\n for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n } else 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 (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 var widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n var heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n\n if (!isUndefined(availableWidth)) {\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {\n availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxWidth >= 0.0) {\n availableWidth = node.style.maxWidth;\n widthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n if (!isUndefined(availableHeight)) {\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxHeight >= 0.0) {\n availableHeight = node.style.maxHeight;\n heightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\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 canUseCachedMeasurement: canUseCachedMeasurement\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","CSS_ALIGN_STRETCH","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_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","canUseCachedMeasurement","isTextNode","marginRow","marginColumn","cachedLayout","isHeightSame","isWidthSame","isHeightValid","computedHeight","isWidthValid","computedWidth","reason","needToVisitNode","generationCount","gCurrentGenerationCount","lastParentDirection","cachedMeasurements","len","cachedResults","newCacheEntry","push","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 || innerHeight <= 0) {\n\n // Don't bother sizing the text if there's no horizontal or vertical 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 // If child has no defined size in the cross axis and is set to stretch, set the cross\n // axis to be measured exactly with the available inner width\n if (!isMainAxisRow &&\n !isUndefined(availableInnerWidth) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n if (isMainAxisRow &&\n !isUndefined(availableInnerHeight) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\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 (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else 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 (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else 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 function canUseCachedMeasurement(\n isTextNode,\n availableWidth,\n availableHeight,\n marginRow,\n marginColumn,\n widthMeasureMode,\n heightMeasureMode,\n cachedLayout) {\n\n var isHeightSame =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.heightMeasureMode == heightMeasureMode && cachedLayout.availableHeight == availableHeight);\n\n var isWidthSame =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.widthMeasureMode == widthMeasureMode && cachedLayout.availableWidth == availableWidth);\n\n if (isHeightSame && isWidthSame) {\n return true;\n }\n\n var isHeightValid =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) ||\n (heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedHeight == (availableHeight - marginColumn));\n\n if (isWidthSame && isHeightValid) {\n return true;\n }\n\n var isWidthValid =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) ||\n (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedWidth == (availableWidth - marginRow));\n\n if (isHeightSame && isWidthValid) {\n return true;\n }\n\n if (isHeightValid && isWidthValid) {\n return true;\n }\n\n // We know this to be text so we can apply some more specialized heuristics.\n if (isTextNode) {\n if (isWidthSame) {\n if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n // Width is the same and height is not restricted. Re-use cahced value.\n return true;\n }\n\n if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedHeight < (availableHeight - marginColumn)) {\n // Width is the same and height restriction is greater than the cached height. Re-use cached value.\n return true;\n }\n\n // Width is the same but height restriction imposes smaller height than previously measured.\n // Update the cached value to respect the new height restriction.\n cachedLayout.computedHeight = availableHeight - marginColumn;\n return true;\n }\n\n if (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED ||\n (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedWidth <= (availableWidth - marginRow))) {\n // Previsouly this text was measured with no width restriction, if width is now restricted\n // but to a larger value than the previsouly measured width we can re-use the measurement\n // as we know it will fit.\n return true;\n }\n }\n }\n\n return false;\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 i;\n var len;\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 // We handle nodes with measure functions specially here because they are the most\n // expensive to measure, so it's worth avoiding redundant measurements if at all possible.\n if (isMeasureDefined(node)) {\n var marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // First, try to use the layout cache.\n if (layout.cachedLayout &&\n canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedLayout)) {\n cachedResults = layout.cachedLayout;\n } else if (layout.cachedMeasurements) {\n // Try to use the measurement cache.\n for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n } else 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 (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 var widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n var heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n\n if (!isUndefined(availableWidth)) {\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {\n availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxWidth >= 0.0) {\n availableWidth = node.style.maxWidth;\n widthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n if (!isUndefined(availableHeight)) {\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxHeight >= 0.0) {\n availableHeight = node.style.maxHeight;\n heightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\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 canUseCachedMeasurement: canUseCachedMeasurement\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-test-utils.c b/src/Layout-test-utils.c index 4e63488d..06237650 100644 --- a/src/Layout-test-utils.c +++ b/src/Layout-test-utils.c @@ -90,29 +90,23 @@ css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, floa width = 1000000; } dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width); - dim.dimensions[CSS_HEIGHT] = SMALL_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; + dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT; return dim; } if (strcmp(text, LONG_TEXT) == 0) { if (widthMode == CSS_MEASURE_MODE_UNDEFINED) { width = 1000000; } - dim.dimensions[CSS_WIDTH] = fminf(BIG_WIDTH, width); - dim.dimensions[CSS_HEIGHT] = BIG_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; + dim.dimensions[CSS_WIDTH] = width >= BIG_WIDTH ? BIG_WIDTH : fmaxf(BIG_MIN_WIDTH, width); + dim.dimensions[CSS_HEIGHT] = width >= BIG_WIDTH ? SMALL_HEIGHT : BIG_HEIGHT; return dim; } if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) { - if (widthMode == CSS_MEASURE_MODE_EXACTLY) { + if (widthMode != CSS_MEASURE_MODE_UNDEFINED) { dim.dimensions[CSS_WIDTH] = width; dim.dimensions[CSS_HEIGHT] = width * 2; - } else if (heightMode == CSS_MEASURE_MODE_EXACTLY) { - dim.dimensions[CSS_WIDTH] = height * 2; - dim.dimensions[CSS_HEIGHT] = height; - } else if (widthMode == CSS_MEASURE_MODE_AT_MOST) { - dim.dimensions[CSS_WIDTH] = width; - dim.dimensions[CSS_HEIGHT] = width * 2; - } else if (heightMode == CSS_MEASURE_MODE_AT_MOST) { + } else if (heightMode != CSS_MEASURE_MODE_UNDEFINED) { dim.dimensions[CSS_WIDTH] = height * 2; dim.dimensions[CSS_HEIGHT] = height; } else { diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index 05e09a7c..6d9e6b1e 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -548,14 +548,15 @@ var layoutTestUtils = (function() { if (text === texts.small) { return { width: Math.min(textSizes.smallWidth, width), - height: textSizes.smallWidth > width ? textSizes.bigHeight : textSizes.smallHeight + height: textSizes.smallHeight }; } if (text === texts.big) { - return { - width: Math.min(textSizes.bigWidth, width), - height: textSizes.bigWidth > width ? textSizes.bigHeight : textSizes.smallHeight + var res = { + width: width >= textSizes.bigWidth ? textSizes.bigWidth : Math.max(textSizes.bigMinWidth, width), + height: width >= textSizes.bigWidth ? textSizes.smallHeight : textSizes.bigHeight }; + return res; } }; // Name of the function is used in DOM tests as a text in the measured node @@ -565,13 +566,9 @@ var layoutTestUtils = (function() { }, measureWithRatio2: function() { var fn = function(width, widthMode, height, heightMode) { - if (widthMode === 'exactly') { + if (widthMode !== 'undefined') { height = width * 2; - } else if (heightMode === 'exactly') { - width = height * 2; - } else if (widthMode === 'at-most') { - height = width * 2; - } else if (heightMode === 'at-most') { + } else if (heightMode !== 'undefined') { width = height * 2; } else { // This should be Infinity, but it would be pain to transpile, diff --git a/src/Layout.c b/src/Layout.c index e14d77d0..a8e12f85 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -826,61 +826,56 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSS_UNDEFINED; childHeight = CSS_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childWidth = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } else if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childHeight = CSS_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childHeight = availableInnerMainDim; + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { + childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { + childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { + if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; } } - // Cross axis - if (isMainAxisRow) { - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - } else { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !isUndefined(availableInnerWidth) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && + widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isMainAxisRow && + !isUndefined(availableInnerHeight) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && + heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; } // Measure the child diff --git a/src/Layout.js b/src/Layout.js index 962d0b61..ea4d4b20 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -776,61 +776,56 @@ var computeLayout = (function() { child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSS_UNDEFINED; childHeight = CSS_UNDEFINED; childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childWidth = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } else if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || isUndefined(availableInnerMainDim)) { - childHeight = CSS_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - } else { - childHeight = availableInnerMainDim; + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { + childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { + childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { + if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; } } - // Cross axis - if (isMainAxisRow) { - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - } else { - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !isUndefined(availableInnerWidth) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && + widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + } + if (isMainAxisRow && + !isUndefined(availableInnerHeight) && + !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && + heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && + getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; } // Measure the child diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index f3575f66..18fe70dc 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -4140,7 +4140,7 @@ int main() node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_LEFT] = 0; node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 36; + node_0->layout.dimensions[CSS_HEIGHT] = 18; } test("should layout node with text and width", root_node, root_layout); @@ -4512,7 +4512,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 0; node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 60; + node_2->layout.dimensions[CSS_WIDTH] = 100; node_2->layout.dimensions[CSS_HEIGHT] = 36; } } @@ -4698,7 +4698,7 @@ int main() node_2->style.margin[CSS_START] = 20; node_2->style.margin[CSS_END] = 20; node_2->measure = measure; - node_2->context = "small"; + node_2->context = "loooooooooong with space"; } } } @@ -4724,7 +4724,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 20; node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 35; + node_2->layout.dimensions[CSS_WIDTH] = 172; node_2->layout.dimensions[CSS_HEIGHT] = 18; } } @@ -4755,7 +4755,7 @@ int main() node_2->style.margin[CSS_START] = 20; node_2->style.margin[CSS_END] = 20; node_2->measure = measure; - node_2->context = "small"; + node_2->context = "loooooooooong with space"; } } } @@ -4780,8 +4780,8 @@ int main() css_node_t *node_2; node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 20; - node_2->layout.position[CSS_LEFT] = 145; - node_2->layout.dimensions[CSS_WIDTH] = 35; + node_2->layout.position[CSS_LEFT] = 8; + node_2->layout.dimensions[CSS_WIDTH] = 172; node_2->layout.dimensions[CSS_HEIGHT] = 18; } } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 0b3ea803..7599fd36 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -1403,7 +1403,7 @@ describe('Layout', function() { it('should layout node with text and width', function() { testLayout( {style: {measure: text(texts.small), width: 10}}, - {width: 10, height: textSizes.bigHeight, top: 0, left: 0} + {width: 10, height: textSizes.smallHeight, top: 0, left: 0} ); }); @@ -1508,8 +1508,10 @@ describe('Layout', function() { ]} ]}, {width: 100, height: 40 + textSizes.bigHeight, top: 0, left: 0, children: [ - {width: 60, height: textSizes.bigHeight, top: 20, left: 20, children: [ - {width: 60, height: textSizes.bigHeight, top: 0, left: 0} + // In the flexbox engine implementation, min width of text is not supported so we max + // out at the amount of available space (60) + {width: Math.min(60, textSizes.bigMinWidth), height: textSizes.bigHeight, top: 20, left: 20, children: [ + {width: textSizes.bigMinWidth, height: textSizes.bigHeight, top: 0, left: 0} ]} ]} ); @@ -1567,12 +1569,12 @@ describe('Layout', function() { testLayout( {style: {}, children: [ {style: {width: 200, flexDirection: 'row'}, children: [ - {style: {margin: 20, measure: text(texts.small)}} + {style: {margin: 20, measure: text(texts.big)}} ]} ]}, {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 20} + {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 20} ]} ]} ); @@ -1582,12 +1584,12 @@ describe('Layout', function() { testLayout( {style: { direction: 'rtl' }, children: [ {style: {width: 200, flexDirection: 'row'}, children: [ - {style: {margin: 20, measure: text(texts.small)}} + {style: {margin: 20, measure: text(texts.big)}} ]} ]}, {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: textSizes.smallWidth, height: textSizes.smallHeight, top: 20, left: 200 - 20 - textSizes.smallWidth} + {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 8} ]} ]} ); diff --git a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs index dd9d8161..4950f230 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs @@ -32,36 +32,23 @@ public class LayoutEngineTest if (widthMode == CSSMeasureMode.Undefined) { width = 10000000; } - - float textHeight = TestConstants.SMALL_HEIGHT; - if (TestConstants.SMALL_WIDTH > width) { - textHeight = TestConstants.BIG_HEIGHT; - } - return new MeasureOutput( Math.Min(width, TestConstants.SMALL_WIDTH), - textHeight); + TestConstants.SMALL_HEIGHT); } else if (testNode.context.Equals(TestConstants.LONG_TEXT)) { if (widthMode == CSSMeasureMode.Undefined) { width = 10000000; } - - float textHeight = TestConstants.SMALL_HEIGHT; - if (TestConstants.BIG_WIDTH > width) { - textHeight = TestConstants.BIG_HEIGHT; - } - - return new MeasureOutput( - Math.Min(width, TestConstants.BIG_WIDTH), - textHeight); + return new MeasureOutput(width >= TestConstants.BIG_WIDTH + ? TestConstants.BIG_WIDTH + : Math.Max(TestConstants.BIG_MIN_WIDTH, width), + width >= TestConstants.BIG_WIDTH + ? TestConstants.SMALL_HEIGHT + : TestConstants.BIG_HEIGHT); } else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) { - if (widthMode == CSSMeasureMode.Exactly) { + if (widthMode != CSSMeasureMode.Undefined) { return new MeasureOutput(width, width * 2); - } else if (heightMode == CSSMeasureMode.Exactly) { - return new MeasureOutput(height * 2, height); - } else if (widthMode == CSSMeasureMode.AtMost) { - return new MeasureOutput(width, width * 2); - } else if (heightMode == CSSMeasureMode.AtMost) { + } else if (heightMode != CSSMeasureMode.Undefined) { return new MeasureOutput(height * 2, height); } else { return new MeasureOutput(99999, 99999); @@ -4456,7 +4443,7 @@ public class LayoutEngineTest node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; } test("should layout node with text and width", root_node, root_layout); @@ -4844,7 +4831,7 @@ public class LayoutEngineTest node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 60; + node_2.layout.dimensions[DIMENSION_WIDTH] = 100; node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; } } @@ -5040,7 +5027,7 @@ public class LayoutEngineTest node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "small"; + node_2.context = "loooooooooong with space"; } } } @@ -5066,7 +5053,7 @@ public class LayoutEngineTest node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 35; + node_2.layout.dimensions[DIMENSION_WIDTH] = 172; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; } } @@ -5099,7 +5086,7 @@ public class LayoutEngineTest node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "small"; + node_2.context = "loooooooooong with space"; } } } @@ -5124,8 +5111,8 @@ public class LayoutEngineTest TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 145; - node_2.layout.dimensions[DIMENSION_WIDTH] = 35; + node_2.layout.position[POSITION_LEFT] = 8; + node_2.layout.dimensions[DIMENSION_WIDTH] = 172; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; } } diff --git a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs index dbb20083..d50b20f1 100644 --- a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs +++ b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs @@ -762,61 +762,56 @@ namespace Facebook.CSSLayout child.layout.flexBasis = Math.Max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSSConstants.Undefined; childHeight = CSSConstants.Undefined; childWidthMeasureMode = CSSMeasureMode.Undefined; childHeightMeasureMode = CSSMeasureMode.Undefined; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) { - childWidth = CSSConstants.Undefined; - childWidthMeasureMode = CSSMeasureMode.Undefined; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSSMeasureMode.AtMost; - } - } else if (node.style.overflow == CSSOverflow.Hidden) { - if (heightMeasureMode == CSSMeasureMode.Undefined || float.IsNaN(availableInnerMainDim)) { - childHeight = CSSConstants.Undefined; - childHeightMeasureMode = CSSMeasureMode.Undefined; - } else { - childHeight = availableInnerMainDim; + if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { + childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); + childWidthMeasureMode = CSSMeasureMode.Exactly; + } + if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); + childHeightMeasureMode = CSSMeasureMode.Exactly; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && float.IsNaN(childWidth) && !float.IsNaN(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSSMeasureMode.AtMost; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (node.style.overflow == CSSOverflow.Hidden) { + if (isMainAxisRow && float.IsNaN(childHeight) && !float.IsNaN(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSSMeasureMode.AtMost; } } - // Cross axis - if (isMainAxisRow) { - if (node.style.overflow == CSSOverflow.Hidden) { - if (!float.IsNaN(availableInnerCrossDim) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && - heightMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, child) == CSSAlign.Stretch) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSSMeasureMode.Exactly; - } else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = float.IsNaN(childHeight) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost; - } else { - childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - childHeightMeasureMode = CSSMeasureMode.Exactly; - } - } - } else { - if (!float.IsNaN(availableInnerCrossDim) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && - widthMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, child) == CSSAlign.Stretch) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSSMeasureMode.Exactly; - } else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = float.IsNaN(childWidth) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost; - } else { - childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childWidthMeasureMode = CSSMeasureMode.Exactly; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !float.IsNaN(availableInnerWidth) && + !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && + widthMeasureMode == CSSMeasureMode.Exactly && + getAlignItem(node, child) == CSSAlign.Stretch) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSSMeasureMode.Exactly; + } + if (isMainAxisRow && + !float.IsNaN(availableInnerHeight) && + !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && + heightMeasureMode == CSSMeasureMode.Exactly && + getAlignItem(node, child) == CSSAlign.Stretch) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSSMeasureMode.Exactly; } // Measure the child diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index f71c6b0b..7649f0b2 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -723,61 +723,56 @@ public class LayoutEngine { child.layout.flexBasis = Math.max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSSConstants.UNDEFINED; childHeight = CSSConstants.UNDEFINED; childWidthMeasureMode = CSSMeasureMode.UNDEFINED; childHeightMeasureMode = CSSMeasureMode.UNDEFINED; - // Main axis - if (isMainAxisRow) { - if (widthMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) { - childWidth = CSSConstants.UNDEFINED; - childWidthMeasureMode = CSSMeasureMode.UNDEFINED; - } else { - childWidth = availableInnerMainDim; - childWidthMeasureMode = CSSMeasureMode.AT_MOST; - } - } else if (node.style.overflow == CSSOverflow.HIDDEN) { - if (heightMeasureMode == CSSMeasureMode.UNDEFINED || Float.isNaN(availableInnerMainDim)) { - childHeight = CSSConstants.UNDEFINED; - childHeightMeasureMode = CSSMeasureMode.UNDEFINED; - } else { - childHeight = availableInnerMainDim; + if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { + childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); + childWidthMeasureMode = CSSMeasureMode.EXACTLY; + } + if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); + childHeightMeasureMode = CSSMeasureMode.EXACTLY; + } + + // According to the spec, if the main size is not definite and the + // child's inline axis is parallel to the main axis (i.e. it's + // horizontal), the child should be sized using "UNDEFINED" in + // the main size. Otherwise use "AT_MOST" in the cross axis. + if (!isMainAxisRow && Float.isNaN(childWidth) && !Float.isNaN(availableInnerWidth)) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSSMeasureMode.AT_MOST; + } + + // The W3C spec doesn't say anything about the 'overflow' property, + // but all major browsers appear to implement the following logic. + if (node.style.overflow == CSSOverflow.HIDDEN) { + if (isMainAxisRow && Float.isNaN(childHeight) && !Float.isNaN(availableInnerHeight)) { + childHeight = availableInnerHeight; childHeightMeasureMode = CSSMeasureMode.AT_MOST; } } - // Cross axis - if (isMainAxisRow) { - if (node.style.overflow == CSSOverflow.HIDDEN) { - if (!Float.isNaN(availableInnerCrossDim) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && - heightMeasureMode == CSSMeasureMode.EXACTLY && - getAlignItem(node, child) == CSSAlign.STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSSMeasureMode.EXACTLY; - } else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = Float.isNaN(childHeight) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST; - } else { - childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - childHeightMeasureMode = CSSMeasureMode.EXACTLY; - } - } - } else { - if (!Float.isNaN(availableInnerCrossDim) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && - widthMeasureMode == CSSMeasureMode.EXACTLY && - getAlignItem(node, child) == CSSAlign.STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSSMeasureMode.EXACTLY; - } else if (!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = Float.isNaN(childWidth) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST; - } else { - childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childWidthMeasureMode = CSSMeasureMode.EXACTLY; - } + // If child has no defined size in the cross axis and is set to stretch, set the cross + // axis to be measured exactly with the available inner width + if (!isMainAxisRow && + !Float.isNaN(availableInnerWidth) && + !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && + widthMeasureMode == CSSMeasureMode.EXACTLY && + getAlignItem(node, child) == CSSAlign.STRETCH) { + childWidth = availableInnerWidth; + childWidthMeasureMode = CSSMeasureMode.EXACTLY; + } + if (isMainAxisRow && + !Float.isNaN(availableInnerHeight) && + !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && + heightMeasureMode == CSSMeasureMode.EXACTLY && + getAlignItem(node, child) == CSSAlign.STRETCH) { + childHeight = availableInnerHeight; + childHeightMeasureMode = CSSMeasureMode.EXACTLY; } // Measure the child diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index c9c703c4..4337dc20 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -34,24 +34,20 @@ public class LayoutEngineTest { width = 10000000; } measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH); - measureOutput.height = TestConstants.SMALL_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; + measureOutput.height = TestConstants.SMALL_HEIGHT; } else if (testNode.context.equals(TestConstants.LONG_TEXT)) { if (widthMode == CSSMeasureMode.UNDEFINED) { width = 10000000; } - measureOutput.width = Math.min(width, TestConstants.BIG_WIDTH); - measureOutput.height = TestConstants.BIG_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; + measureOutput.width = width >= TestConstants.BIG_WIDTH ? + TestConstants.BIG_WIDTH : Math.max(TestConstants.BIG_MIN_WIDTH, width); + measureOutput.height = width >= TestConstants.BIG_WIDTH ? + TestConstants.SMALL_HEIGHT : TestConstants.BIG_HEIGHT; } else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) { - if (widthMode == CSSMeasureMode.EXACTLY) { + if (widthMode != CSSMeasureMode.UNDEFINED) { measureOutput.width = width; measureOutput.height = width * 2; - } else if (heightMode == CSSMeasureMode.EXACTLY) { - measureOutput.width = height * 2; - measureOutput.height = height; - } else if (widthMode == CSSMeasureMode.AT_MOST) { - measureOutput.width = width; - measureOutput.height = width * 2; - } else if (heightMode == CSSMeasureMode.AT_MOST) { + } else if (heightMode != CSSMeasureMode.UNDEFINED) { measureOutput.width = height * 2; measureOutput.height = height; } else { @@ -4450,7 +4446,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; } test("should layout node with text and width", root_node, root_layout); @@ -4838,7 +4834,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 60; + node_2.layout.dimensions[DIMENSION_WIDTH] = 100; node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; } } @@ -5034,7 +5030,7 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "small"; + node_2.context = "loooooooooong with space"; } } } @@ -5060,7 +5056,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 35; + node_2.layout.dimensions[DIMENSION_WIDTH] = 172; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; } } @@ -5093,7 +5089,7 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "small"; + node_2.context = "loooooooooong with space"; } } } @@ -5118,8 +5114,8 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 145; - node_2.layout.dimensions[DIMENSION_WIDTH] = 35; + node_2.layout.position[POSITION_LEFT] = 8; + node_2.layout.dimensions[DIMENSION_WIDTH] = 172; node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; } }