From f2aa5ba6041de619b98b47052bc178fc7cec5095 Mon Sep 17 00:00:00 2001 From: Martin Kralik Date: Tue, 17 Nov 2015 18:50:42 +0000 Subject: [PATCH] passing height to the measure function This diff: * adds height as another parameter passed to the measure function, computed the same way width is * adds tests for this extension, which has involved adding a new measure function to all of js, c, java and c# tests --- dist/css-layout.h | 56 ++- dist/css-layout.jar | Bin 13871 -> 14260 bytes dist/css-layout.js | 55 ++- dist/css-layout.min.js | 2 +- dist/css-layout.min.js.map | 2 +- src/CSharpTranspiler.js | 2 +- src/JavaTranspiler.js | 2 +- src/Layout-test-utils.c | 28 +- src/Layout-test-utils.h | 2 +- src/Layout-test-utils.js | 28 +- src/Layout.c | 51 ++- src/Layout.h | 5 +- src/Layout.js | 55 ++- src/__tests__/Layout-test.c | 152 ++++++++ src/__tests__/Layout-test.js | 61 +++ .../Facebook.CSSLayout.Tests/CSSNodeTest.cs | 4 +- .../LayoutCachingTest.cs | 60 +-- .../LayoutEngineTest.cs | 363 +++++++++++++----- .../Facebook.CSSLayout.Tests/TestConstants.cs | 1 + src/csharp/Facebook.CSSLayout/CSSNode.cs | 12 +- .../Facebook.CSSLayout/CachedCSSLayout.cs | 1 + src/csharp/Facebook.CSSLayout/LayoutEngine.cs | 58 ++- .../src/com/facebook/csslayout/CSSNode.java | 8 +- .../facebook/csslayout/CachedCSSLayout.java | 1 + .../com/facebook/csslayout/LayoutEngine.java | 58 ++- .../facebook/csslayout/LayoutCachingTest.java | 2 +- .../facebook/csslayout/LayoutEngineTest.java | 351 ++++++++++++----- .../com/facebook/csslayout/TestConstants.java | 1 + src/transpile.js | 12 +- 29 files changed, 1139 insertions(+), 294 deletions(-) diff --git a/dist/css-layout.h b/dist/css-layout.h index 8f45b31e8d1..bc5909a8984 100644 --- a/dist/css-layout.h +++ b/dist/css-layout.h @@ -95,6 +95,7 @@ typedef struct { bool should_update; float last_requested_dimensions[2]; float last_parent_max_width; + float last_parent_max_height; float last_dimensions[2]; float last_position[2]; css_direction_t last_direction; @@ -143,7 +144,7 @@ struct css_node { css_node_t* next_absolute_child; css_node_t* next_flex_child; - css_dim_t (*measure)(void *context, float width); + css_dim_t (*measure)(void *context, float width, float height); void (*print)(void *context); struct css_node* (*get_child)(void *context, int i); bool (*is_dirty)(void *context); @@ -165,7 +166,7 @@ typedef enum { void print_css_node(css_node_t *node, css_print_options_t options); // Function that computes the layout! -void layoutNode(css_node_t *node, float maxWidth, css_direction_t parentDirection); +void layoutNode(css_node_t *node, float maxWidth, float maxHeight, css_direction_t parentDirection); bool isUndefined(float value); #endif @@ -249,6 +250,7 @@ void init_css_node(css_node_t *node) { node->layout.last_requested_dimensions[CSS_WIDTH] = -1; node->layout.last_requested_dimensions[CSS_HEIGHT] = -1; node->layout.last_parent_max_width = -1; + node->layout.last_parent_max_height = -1; node->layout.last_direction = (css_direction_t)-1; node->layout.should_update = true; } @@ -689,7 +691,7 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { return -getPosition(node, trailing[axis]); } -static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { +static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { /** START_GENERATED **/ css_direction_t direction = resolveDirection(node, parentDirection); css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); @@ -718,6 +720,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // invocations during the layout calculation. int childCount = node->children_count; float paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); if (isMeasureDefined(node)) { bool isResolvedRowDimDefined = !isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); @@ -733,6 +736,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } width -= paddingAndBorderAxisResolvedRow; + float height = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + height = node->style.dimensions[CSS_HEIGHT]; + } else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]])) { + height = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]; + } else { + height = parentMaxHeight - + getMarginAxis(node, resolvedRowAxis); + } + height -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. @@ -745,7 +759,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction css_dim_t measureDim = node->measure( node->context, - width + width, + height ); if (isRowUndefined) { node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + @@ -753,7 +768,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } if (isColumnUndefined) { node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + paddingAndBorderAxisColumn; } } if (childCount == 0) { @@ -834,6 +849,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction float crossDim = 0; float maxWidth; + float maxHeight; for (i = startLine; i < childCount; ++i) { child = node->get_child(node->context, i); child->line_index = linesCount; @@ -914,6 +930,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } else { maxWidth = CSS_UNDEFINED; + maxHeight = CSS_UNDEFINED; + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - @@ -923,11 +941,20 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + } else { + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(child, maxWidth, direction); + layoutNode(child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -1057,9 +1084,18 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(currentFlexChild, maxWidth, direction); + layoutNode(currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild->next_flex_child; @@ -1378,7 +1414,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction /** END_GENERATED **/ } -void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { +void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { css_layout_t *layout = &node->layout; css_direction_t direction = node->style.direction; layout->should_update = true; @@ -1388,6 +1424,7 @@ void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDi eq(layout->last_requested_dimensions[CSS_WIDTH], layout->dimensions[CSS_WIDTH]) && eq(layout->last_requested_dimensions[CSS_HEIGHT], layout->dimensions[CSS_HEIGHT]) && eq(layout->last_parent_max_width, parentMaxWidth); + eq(layout->last_parent_max_height, parentMaxHeight); eq(layout->last_direction, direction); if (skipLayout) { @@ -1399,9 +1436,10 @@ void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDi layout->last_requested_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_requested_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; layout->last_parent_max_width = parentMaxWidth; + layout->last_parent_max_height = parentMaxHeight; layout->last_direction = direction; - layoutNodeImpl(node, parentMaxWidth, parentDirection); + layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection); layout->last_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; diff --git a/dist/css-layout.jar b/dist/css-layout.jar index a13f3846330a9eb5aa42c686c2d65b536e0dfbcf..5d2d133407ef349f833ff3057f47f87acfa2805c 100644 GIT binary patch delta 12989 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 delta 12601 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,*/ /*(java)!layoutContext.measureOutput,*/ - width + width, + height ); if (isRowUndefined) { node.layout.width = measureDim.width + @@ -521,7 +539,7 @@ var computeLayout = (function() { } if (isColumnUndefined) { node.layout.height = measureDim.height + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + paddingAndBorderAxisColumn; } } if (childCount === 0) { @@ -602,6 +620,7 @@ var computeLayout = (function() { var/*float*/ crossDim = 0; var/*float*/ maxWidth; + var/*float*/ maxHeight; for (i = startLine; i < childCount; ++i) { child = node.children[i]; child.lineIndex = linesCount; @@ -682,6 +701,8 @@ var computeLayout = (function() { } else { maxWidth = CSS_UNDEFINED; + maxHeight = CSS_UNDEFINED; + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout[dim[resolvedRowAxis]] - @@ -691,11 +712,20 @@ var computeLayout = (function() { getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + } else { + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout === 0) { - layoutNode(/*(java)!layoutContext, */child, maxWidth, direction); + layoutNode(/*(java)!layoutContext, */child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -825,9 +855,18 @@ var computeLayout = (function() { getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction); + layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild.nextFlexChild; @@ -1145,7 +1184,7 @@ var computeLayout = (function() { } } - function layoutNode(node, parentMaxWidth, parentDirection) { + function layoutNode(node, parentMaxWidth, parentMaxHeight, parentDirection) { node.shouldUpdate = true; var direction = node.style.direction || CSS_DIRECTION_LTR; @@ -1155,6 +1194,7 @@ var computeLayout = (function() { node.lastLayout.requestedHeight === node.layout.height && node.lastLayout.requestedWidth === node.layout.width && node.lastLayout.parentMaxWidth === parentMaxWidth && + node.lastLayout.parentMaxHeight === parentMaxHeight && node.lastLayout.direction === direction; if (skipLayout) { @@ -1170,6 +1210,7 @@ var computeLayout = (function() { node.lastLayout.requestedWidth = node.layout.width; node.lastLayout.requestedHeight = node.layout.height; node.lastLayout.parentMaxWidth = parentMaxWidth; + node.lastLayout.parentMaxHeight = parentMaxHeight; node.lastLayout.direction = direction; // Reset child layouts @@ -1180,7 +1221,7 @@ var computeLayout = (function() { child.layout.left = 0; }); - layoutNodeImpl(node, parentMaxWidth, parentDirection); + layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection); node.lastLayout.width = node.layout.width; node.lastLayout.height = node.layout.height; diff --git a/dist/css-layout.min.js b/dist/css-layout.min.js index 3e4ddf0eda9..8a227ceb04f 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){return(!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.children.forEach(a),b}function b(a){return void 0===a}function c(a){return a===P||a===Q}function d(a){return a===R||a===S}function e(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 f(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 g(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 h(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 i(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 j(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 k(a,b){return g(a,b)+i(a,b)}function l(a,b){return h(a,b)+j(a,b)}function m(a,b){return i(a,b)+j(a,b)}function n(a,b){return e(a,b)+f(a,b)}function o(a,b){return k(a,b)+l(a,b)}function p(a){return a.style.justifyContent?a.style.justifyContent:"flex-start"}function q(a){return a.style.alignContent?a.style.alignContent:"flex-start"}function r(a,b){return b.style.alignSelf?b.style.alignSelf:a.style.alignItems?a.style.alignItems:"stretch"}function s(a,b){if(b===O){if(a===P)return Q;if(a===Q)return P}return a}function t(a,b){var c;return c=a.style.direction?a.style.direction:M,c===M&&(c=void 0===b?N:b),c}function u(a){return a.style.flexDirection?a.style.flexDirection:R}function v(a,b){return d(a)?s(P,b):R}function w(a){return a.style.position?a.style.position:"relative"}function x(a){return w(a)===aa&&a.style.flex>0}function y(a){return"wrap"===a.style.flexWrap}function z(a,b){return a.layout[fa[b]]+n(a,b)}function A(a,b){return void 0!==a.style[fa[b]]&&a.style[fa[b]]>=0}function B(a,b){return void 0!==a.style[b]}function C(a){return void 0!==a.style.measure}function D(a,b){return void 0!==a.style[b]?a.style[b]:0}function E(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 F(a,b){return a>b?a:b}function G(a,b){void 0===a.layout[fa[b]]&&A(a,b)&&(a.layout[fa[b]]=F(E(a,b,a.style[fa[b]]),o(a,b)))}function H(a,b,c){b.layout[da[c]]=a.layout[fa[c]]-b.layout[fa[c]]-b.layout[ea[c]]}function I(a,b){return void 0!==a.style[ca[b]]?D(a,ca[b]):-D(a,da[b])}function J(a,d,g){var h=t(a,g),j=s(u(a),h),J=v(j,h),M=s(P,h);G(a,j),G(a,J),a.layout.direction=h,a.layout[ca[j]]+=e(a,j)+I(a,j),a.layout[da[j]]+=f(a,j)+I(a,j),a.layout[ca[J]]+=e(a,J)+I(a,J),a.layout[da[J]]+=f(a,J)+I(a,J);var N=a.children.length,O=o(a,M);if(C(a)){var ga=!b(a.layout[fa[M]]),ha=L;ha=A(a,M)?a.style.width:ga?a.layout[fa[M]]:d-n(a,M),ha-=O;var ia=!A(a,M)&&!ga,ja=!A(a,R)&&b(a.layout[fa[R]]);if(ia||ja){var ka=a.style.measure(ha);ia&&(a.layout.width=ka.width+O),ja&&(a.layout.height=ka.height+o(a,R))}if(0===N)return}var la,ma,na,oa,pa=y(a),qa=p(a),ra=k(a,j),sa=k(a,J),ta=o(a,j),ua=o(a,J),va=!b(a.layout[fa[j]]),wa=!b(a.layout[fa[J]]),xa=c(j),ya=null,za=null,Aa=L;va&&(Aa=a.layout[fa[j]]-ta);for(var Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0;N>Ca;){var Ha,Ia=0,Ja=0,Ka=0,La=0,Ma=va&&qa===T||!va&&qa!==U,Na=Ma?N:Ba,Oa=!0,Pa=N,Qa=null,Ra=null,Sa=ra,Ta=0;for(la=Ba;N>la;++la){na=a.children[la],na.lineIndex=Ga,na.nextAbsoluteChild=null,na.nextFlexChild=null;var Ua=r(a,na);if(Ua===_&&w(na)===aa&&wa&&!A(na,J))na.layout[fa[J]]=F(E(na,J,a.layout[fa[J]]-ua-n(na,J)),o(na,J));else if(w(na)===ba)for(null===ya&&(ya=na),null!==za&&(za.nextAbsoluteChild=na),za=na,ma=0;2>ma;ma++)oa=0!==ma?P:R,!b(a.layout[fa[oa]])&&!A(na,oa)&&B(na,ca[oa])&&B(na,da[oa])&&(na.layout[fa[oa]]=F(E(na,oa,a.layout[fa[oa]]-o(a,oa)-n(na,oa)-D(na,ca[oa])-D(na,da[oa])),o(na,oa)));var Va=0;if(va&&x(na)?(Ja++,Ka+=na.style.flex,null===Qa&&(Qa=na),null!==Ra&&(Ra.nextFlexChild=na),Ra=na,Va=o(na,j)+n(na,j)):(Ha=L,xa||(Ha=A(a,M)?a.layout[fa[M]]-O:d-n(a,M)-O),0===Da&&K(na,Ha,h),w(na)===aa&&(La++,Va=z(na,j))),pa&&va&&Ia+Va>Aa&&la!==Ba){La--,Da=1;break}Ma&&(w(na)!==aa||x(na))&&(Ma=!1,Na=la),Oa&&(w(na)!==aa||Ua!==_&&Ua!==Y||b(na.layout[fa[J]]))&&(Oa=!1,Pa=la),Ma&&(na.layout[ea[j]]+=Sa,va&&H(a,na,j),Sa+=z(na,j),Ta=F(Ta,E(na,J,z(na,J)))),Oa&&(na.layout[ea[J]]+=Ea+sa,wa&&H(a,na,J)),Da=0,Ia+=Va,Ca=la+1}var Wa=0,Xa=0,Ya=0;if(Ya=va?Aa-Ia:F(Ia,0)-Ia,0!==Ja){var Za,$a,_a=Ya/Ka;for(Ra=Qa;null!==Ra;)Za=_a*Ra.style.flex+o(Ra,j),$a=E(Ra,j,Za),Za!==$a&&(Ya-=$a,Ka-=Ra.style.flex),Ra=Ra.nextFlexChild;for(_a=Ya/Ka,0>_a&&(_a=0),Ra=Qa;null!==Ra;)Ra.layout[fa[j]]=E(Ra,j,_a*Ra.style.flex+o(Ra,j)),Ha=L,A(a,M)?Ha=a.layout[fa[M]]-O:xa||(Ha=d-n(a,M)-O),K(Ra,Ha,h),na=Ra,Ra=Ra.nextFlexChild,na.nextFlexChild=null}else qa!==T&&(qa===U?Wa=Ya/2:qa===V?Wa=Ya:qa===W?(Ya=F(Ya,0),Xa=Ja+La-1!==0?Ya/(Ja+La-1):0):qa===X&&(Xa=Ya/(Ja+La),Wa=Xa/2));for(Sa+=Wa,la=Na;Ca>la;++la)na=a.children[la],w(na)===ba&&B(na,ca[j])?na.layout[ea[j]]=D(na,ca[j])+i(a,j)+e(na,j):(na.layout[ea[j]]+=Sa,va&&H(a,na,j),w(na)===aa&&(Sa+=Xa+z(na,j),Ta=F(Ta,E(na,J,z(na,J)))));var ab=a.layout[fa[J]];for(wa||(ab=F(E(a,J,Ta+ua),ua)),la=Pa;Ca>la;++la)if(na=a.children[la],w(na)===ba&&B(na,ca[J]))na.layout[ea[J]]=D(na,ca[J])+i(a,J)+e(na,J);else{var bb=sa;if(w(na)===aa){var Ua=r(a,na);if(Ua===_)b(na.layout[fa[J]])&&(na.layout[fa[J]]=F(E(na,J,ab-ua-n(na,J)),o(na,J)));else if(Ua!==Y){var cb=ab-ua-z(na,J);bb+=Ua===Z?cb/2:cb}}na.layout[ea[J]]+=Ea+bb,wa&&H(a,na,J)}Ea+=Ta,Fa=F(Fa,Sa),Ga+=1,Ba=Ca}if(Ga>1&&wa){var db=a.layout[fa[J]]-ua,eb=db-Ea,fb=0,gb=sa,hb=q(a);hb===$?gb+=eb:hb===Z?gb+=eb/2:hb===_&&db>Ea&&(fb=eb/Ga);var ib=0;for(la=0;Ga>la;++la){var jb=ib,kb=0;for(ma=jb;N>ma;++ma)if(na=a.children[ma],w(na)===aa){if(na.lineIndex!==la)break;b(na.layout[fa[J]])||(kb=F(kb,na.layout[fa[J]]+n(na,J)))}for(ib=ma,kb+=fb,ma=jb;ib>ma;++ma)if(na=a.children[ma],w(na)===aa){var lb=r(a,na);if(lb===Y)na.layout[ea[J]]=gb+e(na,J);else if(lb===$)na.layout[ea[J]]=gb+kb-f(na,J)-na.layout[fa[J]];else if(lb===Z){var mb=na.layout[fa[J]];na.layout[ea[J]]=gb+(kb-mb)/2}else lb===_&&(na.layout[ea[J]]=gb+e(na,J))}gb+=kb}}var nb=!1,ob=!1;if(va||(a.layout[fa[j]]=F(E(a,j,Fa+l(a,j)),ta),(j===Q||j===S)&&(nb=!0)),wa||(a.layout[fa[J]]=F(E(a,J,Ea+ua),ua),(J===Q||J===S)&&(ob=!0)),nb||ob)for(la=0;N>la;++la)na=a.children[la],nb&&H(a,na,j),ob&&H(a,na,J);for(za=ya;null!==za;){for(ma=0;2>ma;ma++)oa=0!==ma?P:R,!b(a.layout[fa[oa]])&&!A(za,oa)&&B(za,ca[oa])&&B(za,da[oa])&&(za.layout[fa[oa]]=F(E(za,oa,a.layout[fa[oa]]-m(a,oa)-n(za,oa)-D(za,ca[oa])-D(za,da[oa])),o(za,oa))),B(za,da[oa])&&!B(za,ca[oa])&&(za.layout[ca[oa]]=a.layout[fa[oa]]-za.layout[fa[oa]]-D(za,da[oa]));na=za,za=za.nextAbsoluteChild,na.nextAbsoluteChild=null}}function K(a,b,c){a.shouldUpdate=!0;var d=a.style.direction||N,e=!a.isDirty&&a.lastLayout&&a.lastLayout.requestedHeight===a.layout.height&&a.lastLayout.requestedWidth===a.layout.width&&a.lastLayout.parentMaxWidth===b&&a.lastLayout.direction===d;e?(a.layout.width=a.lastLayout.width,a.layout.height=a.lastLayout.height,a.layout.top=a.lastLayout.top,a.layout.left=a.lastLayout.left):(a.lastLayout||(a.lastLayout={}),a.lastLayout.requestedWidth=a.layout.width,a.lastLayout.requestedHeight=a.layout.height,a.lastLayout.parentMaxWidth=b,a.lastLayout.direction=d,a.children.forEach(function(a){a.layout.width=void 0,a.layout.height=void 0,a.layout.top=0,a.layout.left=0}),J(a,b,c),a.lastLayout.width=a.layout.width,a.lastLayout.height=a.layout.height,a.lastLayout.top=a.layout.top,a.lastLayout.left=a.layout.left)}var L,M="inherit",N="ltr",O="rtl",P="row",Q="row-reverse",R="column",S="column-reverse",T="flex-start",U="center",V="flex-end",W="space-between",X="space-around",Y="flex-start",Z="center",$="flex-end",_="stretch",aa="relative",ba="absolute",ca={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},da={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},ea={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},fa={row:"width","row-reverse":"width",column:"height","column-reverse":"height"};return{layoutNodeImpl:J,computeLayout:K,fillNodes:a}}();return"object"==typeof exports&&(module.exports=a),function(b){a.fillNodes(b),a.computeLayout(b)}}); +!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.computeLayout=b()}(this,function(){var a=function(){function a(b){if((!b.layout||b.isDirty)&&(b.layout={width:void 0,height:void 0,top:0,left:0,right:0,bottom:0}),b.style||(b.style={}),b.children||(b.children=[]),b.style.measure&&b.children&&b.children.length)throw new Error("Using custom measure function is supported only for leaf nodes.");return b.children.forEach(a),b}function b(a){return void 0===a}function c(a){return a===P||a===Q}function d(a){return a===R||a===S}function e(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 f(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 g(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 h(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 i(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 j(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 k(a,b){return g(a,b)+i(a,b)}function l(a,b){return h(a,b)+j(a,b)}function m(a,b){return i(a,b)+j(a,b)}function n(a,b){return e(a,b)+f(a,b)}function o(a,b){return k(a,b)+l(a,b)}function p(a){return a.style.justifyContent?a.style.justifyContent:"flex-start"}function q(a){return a.style.alignContent?a.style.alignContent:"flex-start"}function r(a,b){return b.style.alignSelf?b.style.alignSelf:a.style.alignItems?a.style.alignItems:"stretch"}function s(a,b){if(b===O){if(a===P)return Q;if(a===Q)return P}return a}function t(a,b){var c;return c=a.style.direction?a.style.direction:M,c===M&&(c=void 0===b?N:b),c}function u(a){return a.style.flexDirection?a.style.flexDirection:R}function v(a,b){return d(a)?s(P,b):R}function w(a){return a.style.position?a.style.position:"relative"}function x(a){return w(a)===aa&&a.style.flex>0}function y(a){return"wrap"===a.style.flexWrap}function z(a,b){return a.layout[fa[b]]+n(a,b)}function A(a,b){return void 0!==a.style[fa[b]]&&a.style[fa[b]]>=0}function B(a,b){return void 0!==a.style[b]}function C(a){return void 0!==a.style.measure}function D(a,b){return void 0!==a.style[b]?a.style[b]:0}function E(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 F(a,b){return a>b?a:b}function G(a,b){void 0===a.layout[fa[b]]&&A(a,b)&&(a.layout[fa[b]]=F(E(a,b,a.style[fa[b]]),o(a,b)))}function H(a,b,c){b.layout[da[c]]=a.layout[fa[c]]-b.layout[fa[c]]-b.layout[ea[c]]}function I(a,b){return void 0!==a.style[ca[b]]?D(a,ca[b]):-D(a,da[b])}function J(a,d,g,h){var j=t(a,h),J=s(u(a),j),M=v(J,j),N=s(P,j);G(a,J),G(a,M),a.layout.direction=j,a.layout[ca[J]]+=e(a,J)+I(a,J),a.layout[da[J]]+=f(a,J)+I(a,J),a.layout[ca[M]]+=e(a,M)+I(a,M),a.layout[da[M]]+=f(a,M)+I(a,M);var O=a.children.length,ga=o(a,N),ha=o(a,R);if(C(a)){var ia=!b(a.layout[fa[N]]),ja=L;ja=A(a,N)?a.style.width:ia?a.layout[fa[N]]:d-n(a,N),ja-=ga;var ka=L;ka=A(a,R)?a.style.height:b(a.layout[fa[R]])?g-n(a,N):a.layout[fa[R]],ka-=o(a,R);var la=!A(a,N)&&!ia,ma=!A(a,R)&&b(a.layout[fa[R]]);if(la||ma){var na=a.style.measure(ja,ka);la&&(a.layout.width=na.width+ga),ma&&(a.layout.height=na.height+ha)}if(0===O)return}var oa,pa,qa,ra,sa=y(a),ta=p(a),ua=k(a,J),va=k(a,M),wa=o(a,J),xa=o(a,M),ya=!b(a.layout[fa[J]]),za=!b(a.layout[fa[M]]),Aa=c(J),Ba=null,Ca=null,Da=L;ya&&(Da=a.layout[fa[J]]-wa);for(var Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0;O>Fa;){var Ka,La,Ma=0,Na=0,Oa=0,Pa=0,Qa=ya&&ta===T||!ya&&ta!==U,Ra=Qa?O:Ea,Sa=!0,Ta=O,Ua=null,Va=null,Wa=ua,Xa=0;for(oa=Ea;O>oa;++oa){qa=a.children[oa],qa.lineIndex=Ja,qa.nextAbsoluteChild=null,qa.nextFlexChild=null;var Ya=r(a,qa);if(Ya===_&&w(qa)===aa&&za&&!A(qa,M))qa.layout[fa[M]]=F(E(qa,M,a.layout[fa[M]]-xa-n(qa,M)),o(qa,M));else if(w(qa)===ba)for(null===Ba&&(Ba=qa),null!==Ca&&(Ca.nextAbsoluteChild=qa),Ca=qa,pa=0;2>pa;pa++)ra=0!==pa?P:R,!b(a.layout[fa[ra]])&&!A(qa,ra)&&B(qa,ca[ra])&&B(qa,da[ra])&&(qa.layout[fa[ra]]=F(E(qa,ra,a.layout[fa[ra]]-o(a,ra)-n(qa,ra)-D(qa,ca[ra])-D(qa,da[ra])),o(qa,ra)));var Za=0;if(ya&&x(qa)?(Na++,Oa+=qa.style.flex,null===Ua&&(Ua=qa),null!==Va&&(Va.nextFlexChild=qa),Va=qa,Za=o(qa,J)+n(qa,J)):(Ka=L,La=L,Aa?La=A(a,R)?a.layout[fa[R]]-ha:g-n(a,R)-ha:Ka=A(a,N)?a.layout[fa[N]]-ga:d-n(a,N)-ga,0===Ga&&K(qa,Ka,La,j),w(qa)===aa&&(Pa++,Za=z(qa,J))),sa&&ya&&Ma+Za>Da&&oa!==Ea){Pa--,Ga=1;break}Qa&&(w(qa)!==aa||x(qa))&&(Qa=!1,Ra=oa),Sa&&(w(qa)!==aa||Ya!==_&&Ya!==Y||b(qa.layout[fa[M]]))&&(Sa=!1,Ta=oa),Qa&&(qa.layout[ea[J]]+=Wa,ya&&H(a,qa,J),Wa+=z(qa,J),Xa=F(Xa,E(qa,M,z(qa,M)))),Sa&&(qa.layout[ea[M]]+=Ha+va,za&&H(a,qa,M)),Ga=0,Ma+=Za,Fa=oa+1}var $a=0,_a=0,ab=0;if(ab=ya?Da-Ma:F(Ma,0)-Ma,0!==Na){var bb,cb,db=ab/Oa;for(Va=Ua;null!==Va;)bb=db*Va.style.flex+o(Va,J),cb=E(Va,J,bb),bb!==cb&&(ab-=cb,Oa-=Va.style.flex),Va=Va.nextFlexChild;for(db=ab/Oa,0>db&&(db=0),Va=Ua;null!==Va;)Va.layout[fa[J]]=E(Va,J,db*Va.style.flex+o(Va,J)),Ka=L,A(a,N)?Ka=a.layout[fa[N]]-ga:Aa||(Ka=d-n(a,N)-ga),La=L,A(a,R)?La=a.layout[fa[R]]-ha:Aa&&(La=g-n(a,R)-ha),K(Va,Ka,La,j),qa=Va,Va=Va.nextFlexChild,qa.nextFlexChild=null}else ta!==T&&(ta===U?$a=ab/2:ta===V?$a=ab:ta===W?(ab=F(ab,0),_a=Na+Pa-1!==0?ab/(Na+Pa-1):0):ta===X&&(_a=ab/(Na+Pa),$a=_a/2));for(Wa+=$a,oa=Ra;Fa>oa;++oa)qa=a.children[oa],w(qa)===ba&&B(qa,ca[J])?qa.layout[ea[J]]=D(qa,ca[J])+i(a,J)+e(qa,J):(qa.layout[ea[J]]+=Wa,ya&&H(a,qa,J),w(qa)===aa&&(Wa+=_a+z(qa,J),Xa=F(Xa,E(qa,M,z(qa,M)))));var eb=a.layout[fa[M]];for(za||(eb=F(E(a,M,Xa+xa),xa)),oa=Ta;Fa>oa;++oa)if(qa=a.children[oa],w(qa)===ba&&B(qa,ca[M]))qa.layout[ea[M]]=D(qa,ca[M])+i(a,M)+e(qa,M);else{var fb=va;if(w(qa)===aa){var Ya=r(a,qa);if(Ya===_)b(qa.layout[fa[M]])&&(qa.layout[fa[M]]=F(E(qa,M,eb-xa-n(qa,M)),o(qa,M)));else if(Ya!==Y){var gb=eb-xa-z(qa,M);fb+=Ya===Z?gb/2:gb}}qa.layout[ea[M]]+=Ha+fb,za&&H(a,qa,M)}Ha+=Xa,Ia=F(Ia,Wa),Ja+=1,Ea=Fa}if(Ja>1&&za){var hb=a.layout[fa[M]]-xa,ib=hb-Ha,jb=0,kb=va,lb=q(a);lb===$?kb+=ib:lb===Z?kb+=ib/2:lb===_&&hb>Ha&&(jb=ib/Ja);var mb=0;for(oa=0;Ja>oa;++oa){var nb=mb,ob=0;for(pa=nb;O>pa;++pa)if(qa=a.children[pa],w(qa)===aa){if(qa.lineIndex!==oa)break;b(qa.layout[fa[M]])||(ob=F(ob,qa.layout[fa[M]]+n(qa,M)))}for(mb=pa,ob+=jb,pa=nb;mb>pa;++pa)if(qa=a.children[pa],w(qa)===aa){var pb=r(a,qa);if(pb===Y)qa.layout[ea[M]]=kb+e(qa,M);else if(pb===$)qa.layout[ea[M]]=kb+ob-f(qa,M)-qa.layout[fa[M]];else if(pb===Z){var qb=qa.layout[fa[M]];qa.layout[ea[M]]=kb+(ob-qb)/2}else pb===_&&(qa.layout[ea[M]]=kb+e(qa,M))}kb+=ob}}var rb=!1,sb=!1;if(ya||(a.layout[fa[J]]=F(E(a,J,Ia+l(a,J)),wa),(J===Q||J===S)&&(rb=!0)),za||(a.layout[fa[M]]=F(E(a,M,Ha+xa),xa),(M===Q||M===S)&&(sb=!0)),rb||sb)for(oa=0;O>oa;++oa)qa=a.children[oa],rb&&H(a,qa,J),sb&&H(a,qa,M);for(Ca=Ba;null!==Ca;){for(pa=0;2>pa;pa++)ra=0!==pa?P:R,!b(a.layout[fa[ra]])&&!A(Ca,ra)&&B(Ca,ca[ra])&&B(Ca,da[ra])&&(Ca.layout[fa[ra]]=F(E(Ca,ra,a.layout[fa[ra]]-m(a,ra)-n(Ca,ra)-D(Ca,ca[ra])-D(Ca,da[ra])),o(Ca,ra))),B(Ca,da[ra])&&!B(Ca,ca[ra])&&(Ca.layout[ca[ra]]=a.layout[fa[ra]]-Ca.layout[fa[ra]]-D(Ca,da[ra]));qa=Ca,Ca=Ca.nextAbsoluteChild,qa.nextAbsoluteChild=null}}function K(a,b,c,d){a.shouldUpdate=!0;var e=a.style.direction||N,f=!a.isDirty&&a.lastLayout&&a.lastLayout.requestedHeight===a.layout.height&&a.lastLayout.requestedWidth===a.layout.width&&a.lastLayout.parentMaxWidth===b&&a.lastLayout.parentMaxHeight===c&&a.lastLayout.direction===e;f?(a.layout.width=a.lastLayout.width,a.layout.height=a.lastLayout.height,a.layout.top=a.lastLayout.top,a.layout.left=a.lastLayout.left):(a.lastLayout||(a.lastLayout={}),a.lastLayout.requestedWidth=a.layout.width,a.lastLayout.requestedHeight=a.layout.height,a.lastLayout.parentMaxWidth=b,a.lastLayout.parentMaxHeight=c,a.lastLayout.direction=e,a.children.forEach(function(a){a.layout.width=void 0,a.layout.height=void 0,a.layout.top=0,a.layout.left=0}),J(a,b,c,d),a.lastLayout.width=a.layout.width,a.lastLayout.height=a.layout.height,a.lastLayout.top=a.layout.top,a.lastLayout.left=a.layout.left)}var L,M="inherit",N="ltr",O="rtl",P="row",Q="row-reverse",R="column",S="column-reverse",T="flex-start",U="center",V="flex-end",W="space-between",X="space-around",Y="flex-start",Z="center",$="flex-end",_="stretch",aa="relative",ba="absolute",ca={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},da={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},ea={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},fa={row:"width","row-reverse":"width",column:"height","column-reverse":"height"};return{layoutNodeImpl:J,computeLayout:K,fillNodes:a}}();return"object"==typeof exports&&(module.exports=a),function(b){a.fillNodes(b),a.computeLayout(b)}}); //# sourceMappingURL=css-layout.min.js.map \ No newline at end of file diff --git a/dist/css-layout.min.js.map b/dist/css-layout.min.js.map index 25972b30327..e231ca755d6 100644 --- a/dist/css-layout.min.js.map +++ b/dist/css-layout.min.js.map @@ -1 +1 @@ -{"version":3,"file":"css-layout.min.js","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","forEach","isUndefined","value","isRowDirection","flexDirection","CSS_FLEX_DIRECTION_ROW","CSS_FLEX_DIRECTION_ROW_REVERSE","isColumnDirection","CSS_FLEX_DIRECTION_COLUMN","CSS_FLEX_DIRECTION_COLUMN_REVERSE","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","getBorderAxis","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","isFlex","CSS_POSITION_RELATIVE","flex","isFlexWrap","flexWrap","getDimWithMargin","dim","isDimDefined","isPosDefined","pos","isMeasureDefined","measure","getPosition","boundAxis","min","row","minWidth","row-reverse","column","minHeight","column-reverse","max","maxWidth","maxHeight","boundValue","fmaxf","a","b","setDimensionFromStyle","setTrailingPosition","trailing","getRelativePosition","leading","layoutNodeImpl","parentMaxWidth","mainAxis","crossAxis","resolvedRowAxis","childCount","length","paddingAndBorderAxisResolvedRow","isResolvedRowDimDefined","CSS_UNDEFINED","isRowUndefined","isColumnUndefined","measureDim","i","ii","isNodeFlexWrap","leadingPaddingAndBorderMain","leadingPaddingAndBorderCross","paddingAndBorderAxisMain","paddingAndBorderAxisCross","isMainDimDefined","isCrossDimDefined","isMainRowDirection","firstAbsoluteChild","currentAbsoluteChild","definedMainDim","startLine","endLine","alreadyComputedNextLayout","linesCrossDim","linesMainDim","linesCount","mainContentDim","flexibleChildrenCount","totalFlexible","nonFlexibleChildrenCount","isSimpleStackMain","CSS_JUSTIFY_FLEX_START","CSS_JUSTIFY_CENTER","firstComplexMain","isSimpleStackCross","firstComplexCross","firstFlexChild","currentFlexChild","mainDim","crossDim","lineIndex","nextAbsoluteChild","nextFlexChild","alignItem","CSS_ALIGN_STRETCH","CSS_POSITION_ABSOLUTE","nextContentDim","layoutNode","CSS_ALIGN_FLEX_START","leadingMainDim","betweenMainDim","remainingMainDim","baseMainDim","boundMainDim","flexibleMainDim","CSS_JUSTIFY_FLEX_END","CSS_JUSTIFY_SPACE_BETWEEN","CSS_JUSTIFY_SPACE_AROUND","containerCrossAxis","leadingCrossDim","remainingCrossDim","CSS_ALIGN_CENTER","nodeCrossAxisInnerSize","remainingAlignContentDim","crossDimLead","currentLead","CSS_ALIGN_FLEX_END","endIndex","startIndex","lineHeight","alignContentAlignItem","childHeight","needsMainTrailingPos","needsCrossTrailingPos","shouldUpdate","skipLayout","lastLayout","requestedHeight","requestedWidth"],"mappings":"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","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/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 CSS_UNDEFINED;\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 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\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 node.children.forEach(fillNodes);\n return node;\n }\n\n function isUndefined(value) {\n return value === undefined;\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 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 getBorderAxis(node, axis) {\n return getLeadingBorder(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 'relative';\n }\n\n function isFlex(node) {\n return (\n getPositionType(node) === CSS_POSITION_RELATIVE &&\n 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[dim[axis]] + getMarginAxis(node, axis);\n }\n\n function isDimDefined(node, axis) {\n return node.style[dim[axis]] !== undefined && node.style[dim[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 boundAxis(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 fmaxf(a, b) {\n if (a > b) {\n return a;\n }\n return b;\n }\n\n // When the user specifically sets a value for width or height\n function setDimensionFromStyle(node, axis) {\n // The parent already computed us a width or height. We just skip it\n if (node.layout[dim[axis]] !== undefined) {\n return;\n }\n // We only run if there's a width or height defined\n if (!isDimDefined(node, axis)) {\n return;\n }\n\n // The dimensions can never be smaller than the padding and border\n node.layout[dim[axis]] = fmaxf(\n boundAxis(node, axis, node.style[dim[axis]]),\n getPaddingAndBorderAxis(node, axis)\n );\n }\n\n function setTrailingPosition(node, child, axis) {\n child.layout[trailing[axis]] = node.layout[dim[axis]] -\n child.layout[dim[axis]] - 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 layoutNodeImpl(node, parentMaxWidth, /*css_direction_t*/parentDirection) {\n var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);\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/*(c)!css_flex_direction_t*//*(java)!int*/ resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);\n\n // Handle width and height style attributes\n setDimensionFromStyle(node, mainAxis);\n setDimensionFromStyle(node, crossAxis);\n\n // Set the resolved resolution in the node's layout\n node.layout.direction = direction;\n\n // The position is set by the parent, but we need to complete it with a\n // delta composed of the margin and left/top/right/bottom\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 // Inline immutable values from the target node to avoid excessive method\n // invocations during the layout calculation.\n var/*int*/ childCount = node.children.length;\n var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis);\n\n if (isMeasureDefined(node)) {\n var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]);\n\n var/*float*/ width = CSS_UNDEFINED;\n if (isDimDefined(node, resolvedRowAxis)) {\n width = node.style.width;\n } else if (isResolvedRowDimDefined) {\n width = node.layout[dim[resolvedRowAxis]];\n } else {\n width = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis);\n }\n width -= paddingAndBorderAxisResolvedRow;\n\n // We only need to give a dimension for the text if we haven't got any\n // for it computed yet. It can either be from the style attribute or because\n // the element is flexible.\n var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined;\n var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) &&\n isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]);\n\n // Let's not measure the text if we already know both dimensions\n if (isRowUndefined || isColumnUndefined) {\n var/*css_dim_t*/ measureDim = node.style.measure(\n /*(c)!node->context,*/\n /*(java)!layoutContext.measureOutput,*/\n width\n );\n if (isRowUndefined) {\n node.layout.width = measureDim.width +\n paddingAndBorderAxisResolvedRow;\n }\n if (isColumnUndefined) {\n node.layout.height = measureDim.height +\n getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n }\n }\n if (childCount === 0) {\n return;\n }\n }\n\n var/*bool*/ isNodeFlexWrap = isFlexWrap(node);\n\n var/*css_justify_t*/ justifyContent = getJustifyContent(node);\n\n var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(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/*bool*/ isMainDimDefined = !isUndefined(node.layout[dim[mainAxis]]);\n var/*bool*/ isCrossDimDefined = !isUndefined(node.layout[dim[crossAxis]]);\n var/*bool*/ isMainRowDirection = isRowDirection(mainAxis);\n\n var/*int*/ i;\n var/*int*/ ii;\n var/*css_node_t**/ child;\n var/*(c)!css_flex_direction_t*//*(java)!int*/ axis;\n\n var/*css_node_t**/ firstAbsoluteChild = null;\n var/*css_node_t**/ currentAbsoluteChild = null;\n\n var/*float*/ definedMainDim = CSS_UNDEFINED;\n if (isMainDimDefined) {\n definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain;\n }\n\n // We want to execute the next two loops one per line with flex-wrap\n var/*int*/ startLine = 0;\n var/*int*/ endLine = 0;\n // var/*int*/ nextOffset = 0;\n var/*int*/ alreadyComputedNextLayout = 0;\n // We aggregate the total dimensions of the container in those two variables\n var/*float*/ linesCrossDim = 0;\n var/*float*/ linesMainDim = 0;\n var/*int*/ linesCount = 0;\n while (endLine < childCount) {\n // Layout non flexible children and count children by type\n\n // mainContentDim is accumulation of the dimensions and margin of all the\n // non flexible children. This will be used in order to either set the\n // dimensions of the node if none already exist, or to compute the\n // remaining space left for the flexible children.\n var/*float*/ mainContentDim = 0;\n\n // There are three kind of children, non flexible, flexible and absolute.\n // We need to know how many there are in order to distribute the space.\n var/*int*/ flexibleChildrenCount = 0;\n var/*float*/ totalFlexible = 0;\n var/*int*/ nonFlexibleChildrenCount = 0;\n\n // Use the line loop to position children in the main axis for as long\n // as they are using a simple stacking behaviour. Children that are\n // immediately stacked in the initial loop will not be touched again\n // in .\n var/*bool*/ isSimpleStackMain =\n (isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START) ||\n (!isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER);\n var/*int*/ firstComplexMain = (isSimpleStackMain ? childCount : startLine);\n\n // Use the initial line loop to position children in the cross axis for\n // as long as they are relatively positioned with alignment STRETCH or\n // FLEX_START. Children that are immediately stacked in the initial loop\n // will not be touched again in .\n var/*bool*/ isSimpleStackCross = true;\n var/*int*/ firstComplexCross = childCount;\n\n var/*css_node_t**/ firstFlexChild = null;\n var/*css_node_t**/ currentFlexChild = null;\n\n var/*float*/ mainDim = leadingPaddingAndBorderMain;\n var/*float*/ crossDim = 0;\n\n var/*float*/ maxWidth;\n for (i = startLine; i < childCount; ++i) {\n child = node.children[i];\n child.lineIndex = linesCount;\n\n child.nextAbsoluteChild = null;\n child.nextFlexChild = null;\n\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n\n // Pre-fill cross axis dimensions when the child is using stretch before\n // we call the recursive layout pass\n if (alignItem === CSS_ALIGN_STRETCH &&\n getPositionType(child) === CSS_POSITION_RELATIVE &&\n isCrossDimDefined &&\n !isDimDefined(child, crossAxis)) {\n child.layout[dim[crossAxis]] = fmaxf(\n boundAxis(child, crossAxis, node.layout[dim[crossAxis]] -\n paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, crossAxis)\n );\n } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n // Store a private linked list of absolutely positioned children\n // so that we can efficiently traverse them later.\n if (firstAbsoluteChild === null) {\n firstAbsoluteChild = child;\n }\n if (currentAbsoluteChild !== null) {\n currentAbsoluteChild.nextAbsoluteChild = child;\n }\n currentAbsoluteChild = child;\n\n // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both\n // left and right or top and bottom).\n for (ii = 0; ii < 2; ii++) {\n axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;\n if (!isUndefined(node.layout[dim[axis]]) &&\n !isDimDefined(child, axis) &&\n isPosDefined(child, leading[axis]) &&\n isPosDefined(child, trailing[axis])) {\n child.layout[dim[axis]] = fmaxf(\n boundAxis(child, axis, node.layout[dim[axis]] -\n getPaddingAndBorderAxis(node, axis) -\n getMarginAxis(child, axis) -\n getPosition(child, leading[axis]) -\n getPosition(child, trailing[axis])),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, axis)\n );\n }\n }\n }\n\n var/*float*/ nextContentDim = 0;\n\n // It only makes sense to consider a child flexible if we have a computed\n // dimension for the node.\n if (isMainDimDefined && isFlex(child)) {\n flexibleChildrenCount++;\n totalFlexible += child.style.flex;\n\n // Store a private linked list of flexible children so that we can\n // efficiently traverse them later.\n if (firstFlexChild === null) {\n firstFlexChild = child;\n }\n if (currentFlexChild !== null) {\n currentFlexChild.nextFlexChild = child;\n }\n currentFlexChild = child;\n\n // Even if we don't know its exact size yet, we already know the padding,\n // border and margin. We'll use this partial information, which represents\n // the smallest possible size for the child, to compute the remaining\n // available space.\n nextContentDim = getPaddingAndBorderAxis(child, mainAxis) +\n getMarginAxis(child, mainAxis);\n\n } else {\n maxWidth = CSS_UNDEFINED;\n if (!isMainRowDirection) {\n if (isDimDefined(node, resolvedRowAxis)) {\n maxWidth = node.layout[dim[resolvedRowAxis]] -\n paddingAndBorderAxisResolvedRow;\n } else {\n maxWidth = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis) -\n paddingAndBorderAxisResolvedRow;\n }\n }\n\n // This is the main recursive call. We layout non flexible children.\n if (alreadyComputedNextLayout === 0) {\n layoutNode(/*(java)!layoutContext, */child, maxWidth, direction);\n }\n\n // Absolute positioned elements do not take part of the layout, so we\n // don't use them to compute mainContentDim\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n nonFlexibleChildrenCount++;\n // At this point we know the final size and margin of the element.\n nextContentDim = getDimWithMargin(child, mainAxis);\n }\n }\n\n // The element we are about to add would make us go to the next line\n if (isNodeFlexWrap &&\n isMainDimDefined &&\n mainContentDim + nextContentDim > definedMainDim &&\n // If there's only one element, then it's bigger than the content\n // and needs its own line\n i !== startLine) {\n nonFlexibleChildrenCount--;\n alreadyComputedNextLayout = 1;\n break;\n }\n\n // Disable simple stacking in the main axis for the current line as\n // we found a non-trivial child. The remaining children will be laid out\n // in .\n if (isSimpleStackMain &&\n (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) {\n isSimpleStackMain = false;\n firstComplexMain = i;\n }\n\n // Disable simple stacking in the cross axis for the current line as\n // we found a non-trivial child. The remaining children will be laid out\n // in .\n if (isSimpleStackCross &&\n (getPositionType(child) !== CSS_POSITION_RELATIVE ||\n (alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START) ||\n isUndefined(child.layout[dim[crossAxis]]))) {\n isSimpleStackCross = false;\n firstComplexCross = i;\n }\n\n if (isSimpleStackMain) {\n child.layout[pos[mainAxis]] += mainDim;\n if (isMainDimDefined) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n mainDim += getDimWithMargin(child, mainAxis);\n crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));\n }\n\n if (isSimpleStackCross) {\n child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross;\n if (isCrossDimDefined) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n\n alreadyComputedNextLayout = 0;\n mainContentDim += nextContentDim;\n endLine = i + 1;\n }\n\n // Layout flexible children and allocate empty space\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 // The remaining available space that needs to be allocated\n var/*float*/ remainingMainDim = 0;\n if (isMainDimDefined) {\n remainingMainDim = definedMainDim - mainContentDim;\n } else {\n remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim;\n }\n\n // If there are flexible children in the mix, they are going to fill the\n // remaining space\n if (flexibleChildrenCount !== 0) {\n var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible;\n var/*float*/ baseMainDim;\n var/*float*/ boundMainDim;\n\n // If the flex share of remaining space doesn't meet min/max bounds,\n // remove this child from flex calculations.\n currentFlexChild = firstFlexChild;\n while (currentFlexChild !== null) {\n baseMainDim = flexibleMainDim * currentFlexChild.style.flex +\n getPaddingAndBorderAxis(currentFlexChild, mainAxis);\n boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim);\n\n if (baseMainDim !== boundMainDim) {\n remainingMainDim -= boundMainDim;\n totalFlexible -= currentFlexChild.style.flex;\n }\n\n currentFlexChild = currentFlexChild.nextFlexChild;\n }\n flexibleMainDim = remainingMainDim / totalFlexible;\n\n // The non flexible children can overflow the container, in this case\n // we should just assume that there is no space available.\n if (flexibleMainDim < 0) {\n flexibleMainDim = 0;\n }\n\n currentFlexChild = firstFlexChild;\n while (currentFlexChild !== null) {\n // At this point we know the final size of the element in the main\n // dimension\n currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis,\n flexibleMainDim * currentFlexChild.style.flex +\n getPaddingAndBorderAxis(currentFlexChild, mainAxis)\n );\n\n maxWidth = CSS_UNDEFINED;\n if (isDimDefined(node, resolvedRowAxis)) {\n maxWidth = node.layout[dim[resolvedRowAxis]] -\n paddingAndBorderAxisResolvedRow;\n } else if (!isMainRowDirection) {\n maxWidth = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis) -\n paddingAndBorderAxisResolvedRow;\n }\n\n // And we recursively call the layout algorithm for this child\n layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction);\n\n child = currentFlexChild;\n currentFlexChild = currentFlexChild.nextFlexChild;\n child.nextFlexChild = null;\n }\n\n // We use justifyContent to figure out how to allocate the remaining\n // space available\n } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) {\n if (justifyContent === CSS_JUSTIFY_CENTER) {\n leadingMainDim = remainingMainDim / 2;\n } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {\n leadingMainDim = remainingMainDim;\n } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {\n remainingMainDim = fmaxf(remainingMainDim, 0);\n if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) {\n betweenMainDim = remainingMainDim /\n (flexibleChildrenCount + nonFlexibleChildrenCount - 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 = remainingMainDim /\n (flexibleChildrenCount + nonFlexibleChildrenCount);\n leadingMainDim = betweenMainDim / 2;\n }\n }\n\n // Position elements in the main axis and compute dimensions\n\n // At this point, all the children have their dimensions set. We need to\n // find their position. In order to do that, we accumulate data in\n // variables that are also useful to compute the total dimensions of the\n // container!\n mainDim += leadingMainDim;\n\n for (i = firstComplexMain; i < endLine; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[mainAxis])) {\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 } else {\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 // Define the trailing position accordingly.\n if (isMainDimDefined) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n // Now that we placed the element, we need to update the variables\n // We only need to do that for relative elements. Absolute elements\n // do not take part in that phase.\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n // The main dimension is the sum of all the elements dimension plus\n // the spacing.\n mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);\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, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));\n }\n }\n }\n\n var/*float*/ containerCrossAxis = node.layout[dim[crossAxis]];\n if (!isCrossDimDefined) {\n containerCrossAxis = fmaxf(\n // For the cross dim, we add both sides at the end because the value\n // is aggregate via a max function. Intermediate negative values\n // can mess this computation otherwise\n boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross),\n paddingAndBorderAxisCross\n );\n }\n\n // Position elements in the cross axis\n for (i = firstComplexCross; i < endLine; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[crossAxis])) {\n // In case the child is absolutely positionned and has a\n // top/left/bottom/right being set, we override all the previously\n // computed positions to set it correctly.\n child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +\n getLeadingBorder(node, crossAxis) +\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 if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n /*eslint-disable */\n // This variable is intentionally re-defined as the code is transpiled to a block scope language\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n /*eslint-enable */\n if (alignItem === CSS_ALIGN_STRETCH) {\n // You can only stretch if the dimension has not already been set\n // previously.\n if (isUndefined(child.layout[dim[crossAxis]])) {\n child.layout[dim[crossAxis]] = fmaxf(\n boundAxis(child, crossAxis, containerCrossAxis -\n paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, crossAxis)\n );\n }\n } else if (alignItem !== CSS_ALIGN_FLEX_START) {\n // The remaining space between the parent dimensions+padding and child\n // dimensions+margin.\n var/*float*/ remainingCrossDim = containerCrossAxis -\n paddingAndBorderAxisCross - 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\n // And we apply the position\n child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim;\n\n // Define the trailing position accordingly.\n if (isCrossDimDefined) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n }\n\n linesCrossDim += crossDim;\n linesMainDim = fmaxf(linesMainDim, mainDim);\n linesCount += 1;\n startLine = endLine;\n }\n\n // \n //\n // Note(prenaux): More than one line, we need to layout the crossAxis\n // according to alignContent.\n //\n // Note that we could probably remove and handle the one line case\n // here too, but for the moment this is safer since it won't interfere with\n // previously working code.\n //\n // See specs:\n // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm\n // section 9.4\n //\n if (linesCount > 1 && isCrossDimDefined) {\n var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] -\n paddingAndBorderAxisCross;\n var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim;\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 (nodeCrossAxisInnerSize > linesCrossDim) {\n crossDimLead = (remainingAlignContentDim / linesCount);\n }\n }\n\n var/*int*/ endIndex = 0;\n for (i = 0; i < linesCount; ++i) {\n var/*int*/ startIndex = endIndex;\n\n // compute the line's height and find the endIndex\n var/*float*/ lineHeight = 0;\n for (ii = startIndex; ii < childCount; ++ii) {\n child = node.children[ii];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n if (child.lineIndex !== i) {\n break;\n }\n if (!isUndefined(child.layout[dim[crossAxis]])) {\n lineHeight = fmaxf(\n lineHeight,\n child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis)\n );\n }\n }\n endIndex = ii;\n lineHeight += crossDimLead;\n\n for (ii = startIndex; ii < endIndex; ++ii) {\n child = node.children[ii];\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[dim[crossAxis]];\n } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {\n var/*float*/ childHeight = child.layout[dim[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 undefined\n // (auto) crossAxis dimension.\n }\n }\n\n currentLead += lineHeight;\n }\n }\n\n var/*bool*/ needsMainTrailingPos = false;\n var/*bool*/ needsCrossTrailingPos = false;\n\n // If the user didn't specify a width or height, and it has not been set\n // by the container, then we set it via the children.\n if (!isMainDimDefined) {\n node.layout[dim[mainAxis]] = fmaxf(\n // We're missing the last padding at this point to get the final\n // dimension\n boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)),\n // We can never assign a width smaller than the padding and borders\n paddingAndBorderAxisMain\n );\n\n if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsMainTrailingPos = true;\n }\n }\n\n if (!isCrossDimDefined) {\n node.layout[dim[crossAxis]] = fmaxf(\n // For the cross dim, we add both sides at the end because the value\n // is aggregate via a max function. Intermediate negative values\n // can mess this computation otherwise\n boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross),\n paddingAndBorderAxisCross\n );\n\n if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsCrossTrailingPos = true;\n }\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 // Calculate dimensions for absolutely positioned elements\n currentAbsoluteChild = firstAbsoluteChild;\n while (currentAbsoluteChild !== null) {\n // Pre-fill dimensions when using absolute position and both offsets for\n // the axis are defined (either both left and right or top and bottom).\n for (ii = 0; ii < 2; ii++) {\n axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;\n\n if (!isUndefined(node.layout[dim[axis]]) &&\n !isDimDefined(currentAbsoluteChild, axis) &&\n isPosDefined(currentAbsoluteChild, leading[axis]) &&\n isPosDefined(currentAbsoluteChild, trailing[axis])) {\n currentAbsoluteChild.layout[dim[axis]] = fmaxf(\n boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] -\n getBorderAxis(node, axis) -\n getMarginAxis(currentAbsoluteChild, axis) -\n getPosition(currentAbsoluteChild, leading[axis]) -\n getPosition(currentAbsoluteChild, trailing[axis])\n ),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(currentAbsoluteChild, axis)\n );\n }\n\n if (isPosDefined(currentAbsoluteChild, trailing[axis]) &&\n !isPosDefined(currentAbsoluteChild, leading[axis])) {\n currentAbsoluteChild.layout[leading[axis]] =\n node.layout[dim[axis]] -\n currentAbsoluteChild.layout[dim[axis]] -\n getPosition(currentAbsoluteChild, trailing[axis]);\n }\n }\n\n child = currentAbsoluteChild;\n currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild;\n child.nextAbsoluteChild = null;\n }\n }\n\n function layoutNode(node, parentMaxWidth, parentDirection) {\n node.shouldUpdate = true;\n\n var direction = node.style.direction || CSS_DIRECTION_LTR;\n var skipLayout =\n !node.isDirty &&\n node.lastLayout &&\n node.lastLayout.requestedHeight === node.layout.height &&\n node.lastLayout.requestedWidth === node.layout.width &&\n node.lastLayout.parentMaxWidth === parentMaxWidth &&\n node.lastLayout.direction === direction;\n\n if (skipLayout) {\n node.layout.width = node.lastLayout.width;\n node.layout.height = node.lastLayout.height;\n node.layout.top = node.lastLayout.top;\n node.layout.left = node.lastLayout.left;\n } else {\n if (!node.lastLayout) {\n node.lastLayout = {};\n }\n\n node.lastLayout.requestedWidth = node.layout.width;\n node.lastLayout.requestedHeight = node.layout.height;\n node.lastLayout.parentMaxWidth = parentMaxWidth;\n node.lastLayout.direction = direction;\n\n // Reset child layouts\n node.children.forEach(function(child) {\n child.layout.width = undefined;\n child.layout.height = undefined;\n child.layout.top = 0;\n child.layout.left = 0;\n });\n\n layoutNodeImpl(node, parentMaxWidth, parentDirection);\n\n node.lastLayout.width = node.layout.width;\n node.lastLayout.height = node.layout.height;\n node.lastLayout.top = node.layout.top;\n node.lastLayout.left = node.layout.left;\n }\n }\n\n return {\n layoutNodeImpl: layoutNodeImpl,\n computeLayout: layoutNode,\n fillNodes: fillNodes\n };\n})();\n\n// This module export is only used for the purposes of unit testing this file. When\n// the library is packaged this file is included within css-layout.js which forms\n// the public API.\nif (typeof exports === 'object') {\n module.exports = computeLayout;\n}\n\n\n return function(node) {\n /*eslint-disable */\n // disabling ESLint because this code relies on the above include\n computeLayout.fillNodes(node);\n computeLayout.computeLayout(node);\n /*eslint-enable */\n };\n}));\n"]} \ No newline at end of file +{"version":3,"sources":["css-layout.js"],"names":["root","factory","define","amd","exports","module","computeLayout","this","fillNodes","node","layout","isDirty","width","undefined","height","top","left","right","bottom","style","children","measure","length","Error","forEach","isUndefined","value","isRowDirection","flexDirection","CSS_FLEX_DIRECTION_ROW","CSS_FLEX_DIRECTION_ROW_REVERSE","isColumnDirection","CSS_FLEX_DIRECTION_COLUMN","CSS_FLEX_DIRECTION_COLUMN_REVERSE","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","getBorderAxis","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","isFlex","CSS_POSITION_RELATIVE","flex","isFlexWrap","flexWrap","getDimWithMargin","dim","isDimDefined","isPosDefined","pos","isMeasureDefined","getPosition","boundAxis","min","row","minWidth","row-reverse","column","minHeight","column-reverse","max","maxWidth","maxHeight","boundValue","fmaxf","a","b","setDimensionFromStyle","setTrailingPosition","trailing","getRelativePosition","leading","layoutNodeImpl","parentMaxWidth","parentMaxHeight","mainAxis","crossAxis","resolvedRowAxis","childCount","paddingAndBorderAxisResolvedRow","paddingAndBorderAxisColumn","isResolvedRowDimDefined","CSS_UNDEFINED","isRowUndefined","isColumnUndefined","measureDim","i","ii","isNodeFlexWrap","leadingPaddingAndBorderMain","leadingPaddingAndBorderCross","paddingAndBorderAxisMain","paddingAndBorderAxisCross","isMainDimDefined","isCrossDimDefined","isMainRowDirection","firstAbsoluteChild","currentAbsoluteChild","definedMainDim","startLine","endLine","alreadyComputedNextLayout","linesCrossDim","linesMainDim","linesCount","mainContentDim","flexibleChildrenCount","totalFlexible","nonFlexibleChildrenCount","isSimpleStackMain","CSS_JUSTIFY_FLEX_START","CSS_JUSTIFY_CENTER","firstComplexMain","isSimpleStackCross","firstComplexCross","firstFlexChild","currentFlexChild","mainDim","crossDim","lineIndex","nextAbsoluteChild","nextFlexChild","alignItem","CSS_ALIGN_STRETCH","CSS_POSITION_ABSOLUTE","nextContentDim","layoutNode","CSS_ALIGN_FLEX_START","leadingMainDim","betweenMainDim","remainingMainDim","baseMainDim","boundMainDim","flexibleMainDim","CSS_JUSTIFY_FLEX_END","CSS_JUSTIFY_SPACE_BETWEEN","CSS_JUSTIFY_SPACE_AROUND","containerCrossAxis","leadingCrossDim","remainingCrossDim","CSS_ALIGN_CENTER","nodeCrossAxisInnerSize","remainingAlignContentDim","crossDimLead","currentLead","CSS_ALIGN_FLEX_END","endIndex","startIndex","lineHeight","alignContentAlignItem","childHeight","needsMainTrailingPos","needsCrossTrailingPos","shouldUpdate","skipLayout","lastLayout","requestedHeight","requestedWidth"],"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/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 CSS_UNDEFINED;\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 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\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;\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 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 getBorderAxis(node, axis) {\n return getLeadingBorder(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 'relative';\n }\n\n function isFlex(node) {\n return (\n getPositionType(node) === CSS_POSITION_RELATIVE &&\n 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[dim[axis]] + getMarginAxis(node, axis);\n }\n\n function isDimDefined(node, axis) {\n return node.style[dim[axis]] !== undefined && node.style[dim[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 boundAxis(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 fmaxf(a, b) {\n if (a > b) {\n return a;\n }\n return b;\n }\n\n // When the user specifically sets a value for width or height\n function setDimensionFromStyle(node, axis) {\n // The parent already computed us a width or height. We just skip it\n if (node.layout[dim[axis]] !== undefined) {\n return;\n }\n // We only run if there's a width or height defined\n if (!isDimDefined(node, axis)) {\n return;\n }\n\n // The dimensions can never be smaller than the padding and border\n node.layout[dim[axis]] = fmaxf(\n boundAxis(node, axis, node.style[dim[axis]]),\n getPaddingAndBorderAxis(node, axis)\n );\n }\n\n function setTrailingPosition(node, child, axis) {\n child.layout[trailing[axis]] = node.layout[dim[axis]] -\n child.layout[dim[axis]] - 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 layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, /*css_direction_t*/parentDirection) {\n var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);\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/*(c)!css_flex_direction_t*//*(java)!int*/ resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);\n\n // Handle width and height style attributes\n setDimensionFromStyle(node, mainAxis);\n setDimensionFromStyle(node, crossAxis);\n\n // Set the resolved resolution in the node's layout\n node.layout.direction = direction;\n\n // The position is set by the parent, but we need to complete it with a\n // delta composed of the margin and left/top/right/bottom\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 // Inline immutable values from the target node to avoid excessive method\n // invocations during the layout calculation.\n var/*int*/ childCount = node.children.length;\n var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis);\n var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n if (isMeasureDefined(node)) {\n var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]);\n\n var/*float*/ width = CSS_UNDEFINED;\n if (isDimDefined(node, resolvedRowAxis)) {\n width = node.style.width;\n } else if (isResolvedRowDimDefined) {\n width = node.layout[dim[resolvedRowAxis]];\n } else {\n width = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis);\n }\n width -= paddingAndBorderAxisResolvedRow;\n\n var/*float*/ height = CSS_UNDEFINED;\n if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n height = node.style.height;\n } else if (!isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]])) {\n height = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]];\n } else {\n height = parentMaxHeight -\n getMarginAxis(node, resolvedRowAxis);\n }\n height -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // We only need to give a dimension for the text if we haven't got any\n // for it computed yet. It can either be from the style attribute or because\n // the element is flexible.\n var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined;\n var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) &&\n isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]);\n\n // Let's not measure the text if we already know both dimensions\n if (isRowUndefined || isColumnUndefined) {\n var/*css_dim_t*/ measureDim = node.style.measure(\n /*(c)!node->context,*/\n /*(java)!layoutContext.measureOutput,*/\n width,\n height\n );\n if (isRowUndefined) {\n node.layout.width = measureDim.width +\n paddingAndBorderAxisResolvedRow;\n }\n if (isColumnUndefined) {\n node.layout.height = measureDim.height +\n paddingAndBorderAxisColumn;\n }\n }\n if (childCount === 0) {\n return;\n }\n }\n\n var/*bool*/ isNodeFlexWrap = isFlexWrap(node);\n\n var/*css_justify_t*/ justifyContent = getJustifyContent(node);\n\n var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(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/*bool*/ isMainDimDefined = !isUndefined(node.layout[dim[mainAxis]]);\n var/*bool*/ isCrossDimDefined = !isUndefined(node.layout[dim[crossAxis]]);\n var/*bool*/ isMainRowDirection = isRowDirection(mainAxis);\n\n var/*int*/ i;\n var/*int*/ ii;\n var/*css_node_t**/ child;\n var/*(c)!css_flex_direction_t*//*(java)!int*/ axis;\n\n var/*css_node_t**/ firstAbsoluteChild = null;\n var/*css_node_t**/ currentAbsoluteChild = null;\n\n var/*float*/ definedMainDim = CSS_UNDEFINED;\n if (isMainDimDefined) {\n definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain;\n }\n\n // We want to execute the next two loops one per line with flex-wrap\n var/*int*/ startLine = 0;\n var/*int*/ endLine = 0;\n // var/*int*/ nextOffset = 0;\n var/*int*/ alreadyComputedNextLayout = 0;\n // We aggregate the total dimensions of the container in those two variables\n var/*float*/ linesCrossDim = 0;\n var/*float*/ linesMainDim = 0;\n var/*int*/ linesCount = 0;\n while (endLine < childCount) {\n // Layout non flexible children and count children by type\n\n // mainContentDim is accumulation of the dimensions and margin of all the\n // non flexible children. This will be used in order to either set the\n // dimensions of the node if none already exist, or to compute the\n // remaining space left for the flexible children.\n var/*float*/ mainContentDim = 0;\n\n // There are three kind of children, non flexible, flexible and absolute.\n // We need to know how many there are in order to distribute the space.\n var/*int*/ flexibleChildrenCount = 0;\n var/*float*/ totalFlexible = 0;\n var/*int*/ nonFlexibleChildrenCount = 0;\n\n // Use the line loop to position children in the main axis for as long\n // as they are using a simple stacking behaviour. Children that are\n // immediately stacked in the initial loop will not be touched again\n // in .\n var/*bool*/ isSimpleStackMain =\n (isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START) ||\n (!isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER);\n var/*int*/ firstComplexMain = (isSimpleStackMain ? childCount : startLine);\n\n // Use the initial line loop to position children in the cross axis for\n // as long as they are relatively positioned with alignment STRETCH or\n // FLEX_START. Children that are immediately stacked in the initial loop\n // will not be touched again in .\n var/*bool*/ isSimpleStackCross = true;\n var/*int*/ firstComplexCross = childCount;\n\n var/*css_node_t**/ firstFlexChild = null;\n var/*css_node_t**/ currentFlexChild = null;\n\n var/*float*/ mainDim = leadingPaddingAndBorderMain;\n var/*float*/ crossDim = 0;\n\n var/*float*/ maxWidth;\n var/*float*/ maxHeight;\n for (i = startLine; i < childCount; ++i) {\n child = node.children[i];\n child.lineIndex = linesCount;\n\n child.nextAbsoluteChild = null;\n child.nextFlexChild = null;\n\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n\n // Pre-fill cross axis dimensions when the child is using stretch before\n // we call the recursive layout pass\n if (alignItem === CSS_ALIGN_STRETCH &&\n getPositionType(child) === CSS_POSITION_RELATIVE &&\n isCrossDimDefined &&\n !isDimDefined(child, crossAxis)) {\n child.layout[dim[crossAxis]] = fmaxf(\n boundAxis(child, crossAxis, node.layout[dim[crossAxis]] -\n paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, crossAxis)\n );\n } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n // Store a private linked list of absolutely positioned children\n // so that we can efficiently traverse them later.\n if (firstAbsoluteChild === null) {\n firstAbsoluteChild = child;\n }\n if (currentAbsoluteChild !== null) {\n currentAbsoluteChild.nextAbsoluteChild = child;\n }\n currentAbsoluteChild = child;\n\n // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both\n // left and right or top and bottom).\n for (ii = 0; ii < 2; ii++) {\n axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;\n if (!isUndefined(node.layout[dim[axis]]) &&\n !isDimDefined(child, axis) &&\n isPosDefined(child, leading[axis]) &&\n isPosDefined(child, trailing[axis])) {\n child.layout[dim[axis]] = fmaxf(\n boundAxis(child, axis, node.layout[dim[axis]] -\n getPaddingAndBorderAxis(node, axis) -\n getMarginAxis(child, axis) -\n getPosition(child, leading[axis]) -\n getPosition(child, trailing[axis])),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, axis)\n );\n }\n }\n }\n\n var/*float*/ nextContentDim = 0;\n\n // It only makes sense to consider a child flexible if we have a computed\n // dimension for the node.\n if (isMainDimDefined && isFlex(child)) {\n flexibleChildrenCount++;\n totalFlexible += child.style.flex;\n\n // Store a private linked list of flexible children so that we can\n // efficiently traverse them later.\n if (firstFlexChild === null) {\n firstFlexChild = child;\n }\n if (currentFlexChild !== null) {\n currentFlexChild.nextFlexChild = child;\n }\n currentFlexChild = child;\n\n // Even if we don't know its exact size yet, we already know the padding,\n // border and margin. We'll use this partial information, which represents\n // the smallest possible size for the child, to compute the remaining\n // available space.\n nextContentDim = getPaddingAndBorderAxis(child, mainAxis) +\n getMarginAxis(child, mainAxis);\n\n } else {\n maxWidth = CSS_UNDEFINED;\n maxHeight = CSS_UNDEFINED;\n\n if (!isMainRowDirection) {\n if (isDimDefined(node, resolvedRowAxis)) {\n maxWidth = node.layout[dim[resolvedRowAxis]] -\n paddingAndBorderAxisResolvedRow;\n } else {\n maxWidth = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis) -\n paddingAndBorderAxisResolvedRow;\n }\n } else {\n if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] -\n paddingAndBorderAxisColumn;\n } else {\n maxHeight = parentMaxHeight -\n getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) -\n paddingAndBorderAxisColumn;\n }\n }\n\n // This is the main recursive call. We layout non flexible children.\n if (alreadyComputedNextLayout === 0) {\n layoutNode(/*(java)!layoutContext, */child, maxWidth, maxHeight, direction);\n }\n\n // Absolute positioned elements do not take part of the layout, so we\n // don't use them to compute mainContentDim\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n nonFlexibleChildrenCount++;\n // At this point we know the final size and margin of the element.\n nextContentDim = getDimWithMargin(child, mainAxis);\n }\n }\n\n // The element we are about to add would make us go to the next line\n if (isNodeFlexWrap &&\n isMainDimDefined &&\n mainContentDim + nextContentDim > definedMainDim &&\n // If there's only one element, then it's bigger than the content\n // and needs its own line\n i !== startLine) {\n nonFlexibleChildrenCount--;\n alreadyComputedNextLayout = 1;\n break;\n }\n\n // Disable simple stacking in the main axis for the current line as\n // we found a non-trivial child. The remaining children will be laid out\n // in .\n if (isSimpleStackMain &&\n (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) {\n isSimpleStackMain = false;\n firstComplexMain = i;\n }\n\n // Disable simple stacking in the cross axis for the current line as\n // we found a non-trivial child. The remaining children will be laid out\n // in .\n if (isSimpleStackCross &&\n (getPositionType(child) !== CSS_POSITION_RELATIVE ||\n (alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START) ||\n isUndefined(child.layout[dim[crossAxis]]))) {\n isSimpleStackCross = false;\n firstComplexCross = i;\n }\n\n if (isSimpleStackMain) {\n child.layout[pos[mainAxis]] += mainDim;\n if (isMainDimDefined) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n mainDim += getDimWithMargin(child, mainAxis);\n crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));\n }\n\n if (isSimpleStackCross) {\n child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross;\n if (isCrossDimDefined) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n\n alreadyComputedNextLayout = 0;\n mainContentDim += nextContentDim;\n endLine = i + 1;\n }\n\n // Layout flexible children and allocate empty space\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 // The remaining available space that needs to be allocated\n var/*float*/ remainingMainDim = 0;\n if (isMainDimDefined) {\n remainingMainDim = definedMainDim - mainContentDim;\n } else {\n remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim;\n }\n\n // If there are flexible children in the mix, they are going to fill the\n // remaining space\n if (flexibleChildrenCount !== 0) {\n var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible;\n var/*float*/ baseMainDim;\n var/*float*/ boundMainDim;\n\n // If the flex share of remaining space doesn't meet min/max bounds,\n // remove this child from flex calculations.\n currentFlexChild = firstFlexChild;\n while (currentFlexChild !== null) {\n baseMainDim = flexibleMainDim * currentFlexChild.style.flex +\n getPaddingAndBorderAxis(currentFlexChild, mainAxis);\n boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim);\n\n if (baseMainDim !== boundMainDim) {\n remainingMainDim -= boundMainDim;\n totalFlexible -= currentFlexChild.style.flex;\n }\n\n currentFlexChild = currentFlexChild.nextFlexChild;\n }\n flexibleMainDim = remainingMainDim / totalFlexible;\n\n // The non flexible children can overflow the container, in this case\n // we should just assume that there is no space available.\n if (flexibleMainDim < 0) {\n flexibleMainDim = 0;\n }\n\n currentFlexChild = firstFlexChild;\n while (currentFlexChild !== null) {\n // At this point we know the final size of the element in the main\n // dimension\n currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis,\n flexibleMainDim * currentFlexChild.style.flex +\n getPaddingAndBorderAxis(currentFlexChild, mainAxis)\n );\n\n maxWidth = CSS_UNDEFINED;\n if (isDimDefined(node, resolvedRowAxis)) {\n maxWidth = node.layout[dim[resolvedRowAxis]] -\n paddingAndBorderAxisResolvedRow;\n } else if (!isMainRowDirection) {\n maxWidth = parentMaxWidth -\n getMarginAxis(node, resolvedRowAxis) -\n paddingAndBorderAxisResolvedRow;\n }\n maxHeight = CSS_UNDEFINED;\n if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] -\n paddingAndBorderAxisColumn;\n } else if (isMainRowDirection) {\n maxHeight = parentMaxHeight -\n getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) -\n paddingAndBorderAxisColumn;\n }\n\n // And we recursively call the layout algorithm for this child\n layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, maxHeight, direction);\n\n child = currentFlexChild;\n currentFlexChild = currentFlexChild.nextFlexChild;\n child.nextFlexChild = null;\n }\n\n // We use justifyContent to figure out how to allocate the remaining\n // space available\n } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) {\n if (justifyContent === CSS_JUSTIFY_CENTER) {\n leadingMainDim = remainingMainDim / 2;\n } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {\n leadingMainDim = remainingMainDim;\n } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {\n remainingMainDim = fmaxf(remainingMainDim, 0);\n if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) {\n betweenMainDim = remainingMainDim /\n (flexibleChildrenCount + nonFlexibleChildrenCount - 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 = remainingMainDim /\n (flexibleChildrenCount + nonFlexibleChildrenCount);\n leadingMainDim = betweenMainDim / 2;\n }\n }\n\n // Position elements in the main axis and compute dimensions\n\n // At this point, all the children have their dimensions set. We need to\n // find their position. In order to do that, we accumulate data in\n // variables that are also useful to compute the total dimensions of the\n // container!\n mainDim += leadingMainDim;\n\n for (i = firstComplexMain; i < endLine; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[mainAxis])) {\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 } else {\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 // Define the trailing position accordingly.\n if (isMainDimDefined) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n // Now that we placed the element, we need to update the variables\n // We only need to do that for relative elements. Absolute elements\n // do not take part in that phase.\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n // The main dimension is the sum of all the elements dimension plus\n // the spacing.\n mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);\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, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));\n }\n }\n }\n\n var/*float*/ containerCrossAxis = node.layout[dim[crossAxis]];\n if (!isCrossDimDefined) {\n containerCrossAxis = fmaxf(\n // For the cross dim, we add both sides at the end because the value\n // is aggregate via a max function. Intermediate negative values\n // can mess this computation otherwise\n boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross),\n paddingAndBorderAxisCross\n );\n }\n\n // Position elements in the cross axis\n for (i = firstComplexCross; i < endLine; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[crossAxis])) {\n // In case the child is absolutely positionned and has a\n // top/left/bottom/right being set, we override all the previously\n // computed positions to set it correctly.\n child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +\n getLeadingBorder(node, crossAxis) +\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 if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n /*eslint-disable */\n // This variable is intentionally re-defined as the code is transpiled to a block scope language\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n /*eslint-enable */\n if (alignItem === CSS_ALIGN_STRETCH) {\n // You can only stretch if the dimension has not already been set\n // previously.\n if (isUndefined(child.layout[dim[crossAxis]])) {\n child.layout[dim[crossAxis]] = fmaxf(\n boundAxis(child, crossAxis, containerCrossAxis -\n paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(child, crossAxis)\n );\n }\n } else if (alignItem !== CSS_ALIGN_FLEX_START) {\n // The remaining space between the parent dimensions+padding and child\n // dimensions+margin.\n var/*float*/ remainingCrossDim = containerCrossAxis -\n paddingAndBorderAxisCross - 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\n // And we apply the position\n child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim;\n\n // Define the trailing position accordingly.\n if (isCrossDimDefined) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n }\n\n linesCrossDim += crossDim;\n linesMainDim = fmaxf(linesMainDim, mainDim);\n linesCount += 1;\n startLine = endLine;\n }\n\n // \n //\n // Note(prenaux): More than one line, we need to layout the crossAxis\n // according to alignContent.\n //\n // Note that we could probably remove and handle the one line case\n // here too, but for the moment this is safer since it won't interfere with\n // previously working code.\n //\n // See specs:\n // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm\n // section 9.4\n //\n if (linesCount > 1 && isCrossDimDefined) {\n var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] -\n paddingAndBorderAxisCross;\n var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim;\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 (nodeCrossAxisInnerSize > linesCrossDim) {\n crossDimLead = (remainingAlignContentDim / linesCount);\n }\n }\n\n var/*int*/ endIndex = 0;\n for (i = 0; i < linesCount; ++i) {\n var/*int*/ startIndex = endIndex;\n\n // compute the line's height and find the endIndex\n var/*float*/ lineHeight = 0;\n for (ii = startIndex; ii < childCount; ++ii) {\n child = node.children[ii];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n if (child.lineIndex !== i) {\n break;\n }\n if (!isUndefined(child.layout[dim[crossAxis]])) {\n lineHeight = fmaxf(\n lineHeight,\n child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis)\n );\n }\n }\n endIndex = ii;\n lineHeight += crossDimLead;\n\n for (ii = startIndex; ii < endIndex; ++ii) {\n child = node.children[ii];\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[dim[crossAxis]];\n } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {\n var/*float*/ childHeight = child.layout[dim[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 undefined\n // (auto) crossAxis dimension.\n }\n }\n\n currentLead += lineHeight;\n }\n }\n\n var/*bool*/ needsMainTrailingPos = false;\n var/*bool*/ needsCrossTrailingPos = false;\n\n // If the user didn't specify a width or height, and it has not been set\n // by the container, then we set it via the children.\n if (!isMainDimDefined) {\n node.layout[dim[mainAxis]] = fmaxf(\n // We're missing the last padding at this point to get the final\n // dimension\n boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)),\n // We can never assign a width smaller than the padding and borders\n paddingAndBorderAxisMain\n );\n\n if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsMainTrailingPos = true;\n }\n }\n\n if (!isCrossDimDefined) {\n node.layout[dim[crossAxis]] = fmaxf(\n // For the cross dim, we add both sides at the end because the value\n // is aggregate via a max function. Intermediate negative values\n // can mess this computation otherwise\n boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross),\n paddingAndBorderAxisCross\n );\n\n if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsCrossTrailingPos = true;\n }\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 // Calculate dimensions for absolutely positioned elements\n currentAbsoluteChild = firstAbsoluteChild;\n while (currentAbsoluteChild !== null) {\n // Pre-fill dimensions when using absolute position and both offsets for\n // the axis are defined (either both left and right or top and bottom).\n for (ii = 0; ii < 2; ii++) {\n axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;\n\n if (!isUndefined(node.layout[dim[axis]]) &&\n !isDimDefined(currentAbsoluteChild, axis) &&\n isPosDefined(currentAbsoluteChild, leading[axis]) &&\n isPosDefined(currentAbsoluteChild, trailing[axis])) {\n currentAbsoluteChild.layout[dim[axis]] = fmaxf(\n boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] -\n getBorderAxis(node, axis) -\n getMarginAxis(currentAbsoluteChild, axis) -\n getPosition(currentAbsoluteChild, leading[axis]) -\n getPosition(currentAbsoluteChild, trailing[axis])\n ),\n // You never want to go smaller than padding\n getPaddingAndBorderAxis(currentAbsoluteChild, axis)\n );\n }\n\n if (isPosDefined(currentAbsoluteChild, trailing[axis]) &&\n !isPosDefined(currentAbsoluteChild, leading[axis])) {\n currentAbsoluteChild.layout[leading[axis]] =\n node.layout[dim[axis]] -\n currentAbsoluteChild.layout[dim[axis]] -\n getPosition(currentAbsoluteChild, trailing[axis]);\n }\n }\n\n child = currentAbsoluteChild;\n currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild;\n child.nextAbsoluteChild = null;\n }\n }\n\n function layoutNode(node, parentMaxWidth, parentMaxHeight, parentDirection) {\n node.shouldUpdate = true;\n\n var direction = node.style.direction || CSS_DIRECTION_LTR;\n var skipLayout =\n !node.isDirty &&\n node.lastLayout &&\n node.lastLayout.requestedHeight === node.layout.height &&\n node.lastLayout.requestedWidth === node.layout.width &&\n node.lastLayout.parentMaxWidth === parentMaxWidth &&\n node.lastLayout.parentMaxHeight === parentMaxHeight &&\n node.lastLayout.direction === direction;\n\n if (skipLayout) {\n node.layout.width = node.lastLayout.width;\n node.layout.height = node.lastLayout.height;\n node.layout.top = node.lastLayout.top;\n node.layout.left = node.lastLayout.left;\n } else {\n if (!node.lastLayout) {\n node.lastLayout = {};\n }\n\n node.lastLayout.requestedWidth = node.layout.width;\n node.lastLayout.requestedHeight = node.layout.height;\n node.lastLayout.parentMaxWidth = parentMaxWidth;\n node.lastLayout.parentMaxHeight = parentMaxHeight;\n node.lastLayout.direction = direction;\n\n // Reset child layouts\n node.children.forEach(function(child) {\n child.layout.width = undefined;\n child.layout.height = undefined;\n child.layout.top = 0;\n child.layout.left = 0;\n });\n\n layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection);\n\n node.lastLayout.width = node.layout.width;\n node.lastLayout.height = node.layout.height;\n node.lastLayout.top = node.layout.top;\n node.lastLayout.left = node.layout.left;\n }\n }\n\n return {\n layoutNodeImpl: layoutNodeImpl,\n computeLayout: layoutNode,\n fillNodes: fillNodes\n };\n})();\n\n// This module export is only used for the purposes of unit testing this file. When\n// the library is packaged this file is included within css-layout.js which forms\n// the public API.\nif (typeof exports === 'object') {\n module.exports = computeLayout;\n}\n\n\n return function(node) {\n /*eslint-disable */\n // disabling ESLint because this code relies on the above include\n computeLayout.fillNodes(node);\n computeLayout.computeLayout(node);\n /*eslint-enable */\n };\n}));\n"]} \ No newline at end of file diff --git a/src/CSharpTranspiler.js b/src/CSharpTranspiler.js index 1e3dfa8552f..fdc9ce47e4c 100644 --- a/src/CSharpTranspiler.js +++ b/src/CSharpTranspiler.js @@ -108,7 +108,7 @@ function __transpileSingleTestToCSharp(code) { function(str, match1, match2, match3) { return 'style.' + match1 + match2.toUpperCase() + match3; }) - .replace(/(\w+)\.measure\s+=\s+.+/, '$1.setMeasureFunction(sTestMeasureFunction);') + .replace(/(\w+)\.measure\s+=\s+.+/g, '$1.setMeasureFunction(sTestMeasureFunction);') // additional case conversions diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index 4e129bd0290..f7244fe966c 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -101,7 +101,7 @@ function __transpileSingleTestToJava(code) { function(str, match1, match2, match3) { return 'style.' + match1 + match2.toUpperCase() + match3; }) - .replace(/(\w+)\.measure\s+=\s+.+/, '$1.setMeasureFunction(sTestMeasureFunction);'); + .replace(/(\w+)\.measure\s+=\s+.+/g, '$1.setMeasureFunction(sTestMeasureFunction);'); } function indent(code) { diff --git a/src/Layout-test-utils.c b/src/Layout-test-utils.c index c1dd9e6eb41..95922e3f632 100644 --- a/src/Layout-test-utils.c +++ b/src/Layout-test-utils.c @@ -33,6 +33,7 @@ __forceinline const float fminf(const float a, const float b) { #define BIG_MIN_WIDTH 100 #define SMALL_TEXT "small" #define LONG_TEXT "loooooooooong with space" +#define MEASURE_WITH_RATIO_2 "measureWithRatio2" /** END_GENERATED **/ typedef struct failed_test_t { @@ -80,23 +81,40 @@ static bool are_layout_equal(css_node_t *a, css_node_t *b) { return true; } -css_dim_t measure(void *context, float width) { +css_dim_t measure(void *context, float width, float height) { const char *text = (const char *)context; css_dim_t dim; - if (width != width) { - width = 1000000; - } if (strcmp(text, SMALL_TEXT) == 0) { + if (width != width) { + width = 1000000; + } dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width); dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT; return dim; } if (strcmp(text, LONG_TEXT) == 0) { + if (width != width) { + width = 1000000; + } 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 (width > 0) { + dim.dimensions[CSS_WIDTH] = width; + dim.dimensions[CSS_HEIGHT] = width * 2; + } else if (height > 0) { + dim.dimensions[CSS_WIDTH] = height * 2; + dim.dimensions[CSS_HEIGHT] = height; + } else { + dim.dimensions[CSS_WIDTH] = 99999; + dim.dimensions[CSS_HEIGHT] = 99999; + } + return dim; + } + // Should not go here dim.dimensions[CSS_WIDTH] = CSS_UNDEFINED; dim.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; @@ -106,7 +124,7 @@ css_dim_t measure(void *context, float width) { static int test_ran_count = 0; void test(const char *name, css_node_t *style, css_node_t *expected_layout) { ++test_ran_count; - layoutNode(style, CSS_UNDEFINED, (css_direction_t)-1); + layoutNode(style, CSS_UNDEFINED, CSS_UNDEFINED, (css_direction_t)-1); if (!are_layout_equal(style, expected_layout)) { printf("%sF%s", "\x1B[31m", "\x1B[0m"); diff --git a/src/Layout-test-utils.h b/src/Layout-test-utils.h index 73569ccee99..0bcb3be2ced 100644 --- a/src/Layout-test-utils.h +++ b/src/Layout-test-utils.h @@ -13,6 +13,6 @@ void test(const char *name, css_node_t *style, css_node_t *expected_layout); int tests_finished(void); -css_dim_t measure(void *context, float width); +css_dim_t measure(void *context, float width, float height); void init_css_node_children(css_node_t *node, int children_count); css_node_t *new_test_css_node(void); diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index 2a79f1dcd93..4108e67ff9a 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -471,6 +471,12 @@ var layoutTestUtils = (function() { inplaceRoundNumbersInObject(domLayout); testNamedLayout('layout-dom', layout, domLayout); }, + testLayoutAgainstExpectedOnly: function(node, expectedLayout) { + var layout = computeCSSLayout(node); + inplaceRoundNumbersInObject(layout); + inplaceRoundNumbersInObject(expectedLayout); + testNamedLayout('expected-dom', expectedLayout, layout); + }, testFillNodes: testFillNodes, testExtractNodes: testExtractNodes, testRandomLayout: function(node) { @@ -488,7 +494,7 @@ var layoutTestUtils = (function() { computeDOMLayout: computeDOMLayout, reduceTest: reduceTest, text: function(text) { - var fn = function(width) { + var fn = function(width, height) { if (width === undefined || isNaN(width)) { width = Infinity; } @@ -510,8 +516,28 @@ var layoutTestUtils = (function() { return res; } }; + // Name of the function is used in DOM tests as a text in the measured node + // and as a way to tell different measure functions apart in transpiled tests fn.toString = function() { return text; }; return fn; + }, + measureWithRatio2: function() { + var fn = function(width, height) { + if (width > 0) { + height = width * 2; + } else if (height > 0) { + width = height * 2; + } else { + // This should be Infinity, but it would be pain to transpile, + // so let's just go with big numbers. + height = 99999; + width = 99999; + } + return {width: width, height: height}; + }; + // This is necessary for transpiled tests, see previous comment + fn.toString = function() { return 'measureWithRatio2'; }; + return fn; } }; })(); diff --git a/src/Layout.c b/src/Layout.c index 9242a885f2f..40f723a6712 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -76,6 +76,7 @@ void init_css_node(css_node_t *node) { node->layout.last_requested_dimensions[CSS_WIDTH] = -1; node->layout.last_requested_dimensions[CSS_HEIGHT] = -1; node->layout.last_parent_max_width = -1; + node->layout.last_parent_max_height = -1; node->layout.last_direction = (css_direction_t)-1; node->layout.should_update = true; } @@ -516,7 +517,7 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { return -getPosition(node, trailing[axis]); } -static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { +static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { /** START_GENERATED **/ css_direction_t direction = resolveDirection(node, parentDirection); css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); @@ -545,6 +546,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // invocations during the layout calculation. int childCount = node->children_count; float paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); if (isMeasureDefined(node)) { bool isResolvedRowDimDefined = !isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); @@ -560,6 +562,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } width -= paddingAndBorderAxisResolvedRow; + float height = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + height = node->style.dimensions[CSS_HEIGHT]; + } else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]])) { + height = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]; + } else { + height = parentMaxHeight - + getMarginAxis(node, resolvedRowAxis); + } + height -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. @@ -572,7 +585,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction css_dim_t measureDim = node->measure( node->context, - width + width, + height ); if (isRowUndefined) { node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + @@ -580,7 +594,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } if (isColumnUndefined) { node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + paddingAndBorderAxisColumn; } } if (childCount == 0) { @@ -661,6 +675,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction float crossDim = 0; float maxWidth; + float maxHeight; for (i = startLine; i < childCount; ++i) { child = node->get_child(node->context, i); child->line_index = linesCount; @@ -741,6 +756,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } else { maxWidth = CSS_UNDEFINED; + maxHeight = CSS_UNDEFINED; + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - @@ -750,11 +767,20 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + } else { + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(child, maxWidth, direction); + layoutNode(child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -884,9 +910,18 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(currentFlexChild, maxWidth, direction); + layoutNode(currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild->next_flex_child; @@ -1205,7 +1240,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction /** END_GENERATED **/ } -void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { +void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, css_direction_t parentDirection) { css_layout_t *layout = &node->layout; css_direction_t direction = node->style.direction; layout->should_update = true; @@ -1215,6 +1250,7 @@ void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDi eq(layout->last_requested_dimensions[CSS_WIDTH], layout->dimensions[CSS_WIDTH]) && eq(layout->last_requested_dimensions[CSS_HEIGHT], layout->dimensions[CSS_HEIGHT]) && eq(layout->last_parent_max_width, parentMaxWidth); + eq(layout->last_parent_max_height, parentMaxHeight); eq(layout->last_direction, direction); if (skipLayout) { @@ -1226,9 +1262,10 @@ void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDi layout->last_requested_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_requested_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; layout->last_parent_max_width = parentMaxWidth; + layout->last_parent_max_height = parentMaxHeight; layout->last_direction = direction; - layoutNodeImpl(node, parentMaxWidth, parentDirection); + layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection); layout->last_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; diff --git a/src/Layout.h b/src/Layout.h index 535fa7347cd..6ad53e04196 100644 --- a/src/Layout.h +++ b/src/Layout.h @@ -91,6 +91,7 @@ typedef struct { bool should_update; float last_requested_dimensions[2]; float last_parent_max_width; + float last_parent_max_height; float last_dimensions[2]; float last_position[2]; css_direction_t last_direction; @@ -139,7 +140,7 @@ struct css_node { css_node_t* next_absolute_child; css_node_t* next_flex_child; - css_dim_t (*measure)(void *context, float width); + css_dim_t (*measure)(void *context, float width, float height); void (*print)(void *context); struct css_node* (*get_child)(void *context, int i); bool (*is_dirty)(void *context); @@ -161,7 +162,7 @@ typedef enum { void print_css_node(css_node_t *node, css_print_options_t options); // Function that computes the layout! -void layoutNode(css_node_t *node, float maxWidth, css_direction_t parentDirection); +void layoutNode(css_node_t *node, float maxWidth, float maxHeight, css_direction_t parentDirection); bool isUndefined(float value); #endif diff --git a/src/Layout.js b/src/Layout.js index 15e3fbcfa05..525bab7faa8 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -81,6 +81,11 @@ var computeLayout = (function() { if (!node.children) { node.children = []; } + + if (node.style.measure && node.children && node.children.length) { + throw new Error('Using custom measure function is supported only for leaf nodes.'); + } + node.children.forEach(fillNodes); return node; } @@ -439,7 +444,7 @@ var computeLayout = (function() { return -getPosition(node, trailing[axis]); } - function layoutNodeImpl(node, parentMaxWidth, /*css_direction_t*/parentDirection) { + function layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, /*css_direction_t*/parentDirection) { var/*css_direction_t*/ direction = resolveDirection(node, parentDirection); var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction); var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction); @@ -467,6 +472,7 @@ var computeLayout = (function() { // invocations during the layout calculation. var/*int*/ childCount = node.children.length; var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); if (isMeasureDefined(node)) { var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]); @@ -482,6 +488,17 @@ var computeLayout = (function() { } width -= paddingAndBorderAxisResolvedRow; + var/*float*/ height = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + height = node.style.height; + } else if (!isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]])) { + height = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]; + } else { + height = parentMaxHeight - + getMarginAxis(node, resolvedRowAxis); + } + height -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. @@ -494,7 +511,8 @@ var computeLayout = (function() { var/*css_dim_t*/ measureDim = node.style.measure( /*(c)!node->context,*/ /*(java)!layoutContext.measureOutput,*/ - width + width, + height ); if (isRowUndefined) { node.layout.width = measureDim.width + @@ -502,7 +520,7 @@ var computeLayout = (function() { } if (isColumnUndefined) { node.layout.height = measureDim.height + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); + paddingAndBorderAxisColumn; } } if (childCount === 0) { @@ -583,6 +601,7 @@ var computeLayout = (function() { var/*float*/ crossDim = 0; var/*float*/ maxWidth; + var/*float*/ maxHeight; for (i = startLine; i < childCount; ++i) { child = node.children[i]; child.lineIndex = linesCount; @@ -663,6 +682,8 @@ var computeLayout = (function() { } else { maxWidth = CSS_UNDEFINED; + maxHeight = CSS_UNDEFINED; + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout[dim[resolvedRowAxis]] - @@ -672,11 +693,20 @@ var computeLayout = (function() { getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + } else { + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout === 0) { - layoutNode(/*(java)!layoutContext, */child, maxWidth, direction); + layoutNode(/*(java)!layoutContext, */child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -806,9 +836,18 @@ var computeLayout = (function() { getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { + maxHeight = node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction); + layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild.nextFlexChild; @@ -1126,7 +1165,7 @@ var computeLayout = (function() { } } - function layoutNode(node, parentMaxWidth, parentDirection) { + function layoutNode(node, parentMaxWidth, parentMaxHeight, parentDirection) { node.shouldUpdate = true; var direction = node.style.direction || CSS_DIRECTION_LTR; @@ -1136,6 +1175,7 @@ var computeLayout = (function() { node.lastLayout.requestedHeight === node.layout.height && node.lastLayout.requestedWidth === node.layout.width && node.lastLayout.parentMaxWidth === parentMaxWidth && + node.lastLayout.parentMaxHeight === parentMaxHeight && node.lastLayout.direction === direction; if (skipLayout) { @@ -1151,6 +1191,7 @@ var computeLayout = (function() { node.lastLayout.requestedWidth = node.layout.width; node.lastLayout.requestedHeight = node.layout.height; node.lastLayout.parentMaxWidth = parentMaxWidth; + node.lastLayout.parentMaxHeight = parentMaxHeight; node.lastLayout.direction = direction; // Reset child layouts @@ -1161,7 +1202,7 @@ var computeLayout = (function() { child.layout.left = 0; }); - layoutNodeImpl(node, parentMaxWidth, parentDirection); + layoutNodeImpl(node, parentMaxWidth, parentMaxHeight, parentDirection); node.lastLayout.width = node.layout.width; node.lastLayout.height = node.layout.height; diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 85079d44319..ef0db773e57 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -3972,6 +3972,158 @@ int main() test("should layout node with just text", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_WIDTH] = 100; + node_0->measure = measure; + node_0->context = "measureWithRatio2"; + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 100; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + } + + test("should layout node with fixed width and custom measure function", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_HEIGHT] = 100; + node_0->measure = measure; + node_0->context = "measureWithRatio2"; + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 200; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + } + + test("should layout node with fixed height and custom measure function", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.dimensions[CSS_WIDTH] = 100; + node_0->style.dimensions[CSS_HEIGHT] = 100; + node_0->measure = measure; + node_0->context = "measureWithRatio2"; + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 100; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + } + + test("should layout node with fixed height and fixed width, ignoring custom measure function", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->measure = measure; + node_0->context = "measureWithRatio2"; + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 99999; + node_0->layout.dimensions[CSS_HEIGHT] = 99999; + } + + test("should layout node with no fixed dimension and custom measure function", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; + node_0->style.dimensions[CSS_WIDTH] = 320; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->measure = measure; + node_1->context = "measureWithRatio2"; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_1->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->measure = measure; + node_2->context = "measureWithRatio2"; + node_2 = node_1->get_child(node_1->context, 1); + node_2->measure = measure; + node_2->context = "measureWithRatio2"; + } + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 320; + node_0->layout.dimensions[CSS_HEIGHT] = 740; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 320; + node_1->layout.dimensions[CSS_HEIGHT] = 640; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 640; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 320; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + 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] = 200; + node_2->layout.dimensions[CSS_HEIGHT] = 100; + node_2 = node_1->get_child(node_1->context, 1); + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 200; + node_2->layout.dimensions[CSS_WIDTH] = 200; + node_2->layout.dimensions[CSS_HEIGHT] = 100; + } + } + } + + test("should layout node with nested stacks and custom measure function", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 5134b53c343..31d39551491 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -10,10 +10,12 @@ var testLayout = layoutTestUtils.testLayout; var testLayoutAgainstDomOnly = layoutTestUtils.testLayoutAgainstDomOnly; +var testLayoutAgainstExpectedOnly = layoutTestUtils.testLayoutAgainstExpectedOnly; var testFillNodes = layoutTestUtils.testFillNodes; var text = layoutTestUtils.text; var texts = layoutTestUtils.texts; var textSizes = layoutTestUtils.textSizes; +var measureWithRatio2 = layoutTestUtils.measureWithRatio2(); describe('Javascript Only', function() { it('should fill root node with layout, style, and children', function() { @@ -1192,6 +1194,65 @@ describe('Layout', function() { ); }); + it('should layout node with fixed width and custom measure function', function() { + testLayoutAgainstExpectedOnly( + {style: { + measure: measureWithRatio2, + width: 100 + }}, + {width: 100, height: 200, top: 0, left: 0} + ); + }); + + it('should layout node with fixed height and custom measure function', function() { + testLayoutAgainstExpectedOnly( + {style: { + measure: measureWithRatio2, + height: 100 + }}, + {width: 200, height: 100, top: 0, left: 0} + ); + }); + + it('should layout node with fixed height and fixed width, ignoring custom measure function', function() { + testLayoutAgainstExpectedOnly( + {style: { + measure: measureWithRatio2, + width: 100, + height: 100 + }}, + {width: 100, height: 100, top: 0, left: 0} + ); + }); + + it('should layout node with no fixed dimension and custom measure function', function() { + testLayoutAgainstExpectedOnly( + {style: { + measure: measureWithRatio2, + }}, + {width: 99999, height: 99999, top: 0, left: 0} + ); + }); + + it('should layout node with nested stacks and custom measure function', function() { + testLayoutAgainstExpectedOnly( + {style: {width: 320, flexDirection: 'column'}, children: [ + {style: {measure: measureWithRatio2}}, + {style: {height: 100, flexDirection: 'row'}, children: [ + {style: {measure: measureWithRatio2}}, + {style: {measure: measureWithRatio2}} + ]}, + ]}, + {width: 320, height: 740, top: 0, left: 0, children: [ + {width: 320, height: 640, top: 0, left: 0}, + {width: 320, height: 100, top: 640, left: 0, children: [ + {width: 200, height: 100, top: 0, left: 0}, + {width: 200, height: 100, top: 0, left: 200} + ]}, + ]} + ); + }); + it('should layout node with text and width', function() { testLayout( {style: {measure: text(texts.small), width: 10}}, diff --git a/src/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs b/src/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs index 37a4c9fcc72..87e9991beb6 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs @@ -24,7 +24,7 @@ public void testAddChildGetParent() CSSNode parent = new CSSNode(); CSSNode child = new CSSNode(); - Assert.Null(child.getParent()); + Assert.IsNull(child.getParent()); Assert.AreEqual(0, parent.getChildCount()); parent.addChildAt(child, 0); @@ -35,7 +35,7 @@ public void testAddChildGetParent() parent.removeChildAt(0); - Assert.Null(child.getParent()); + Assert.IsNull(child.getParent()); Assert.AreEqual(0, parent.getChildCount()); } diff --git a/src/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs b/src/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs index 503de5476e1..7c260eff1b6 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs @@ -54,7 +54,7 @@ public void testCachesFullTree() markLayoutAppliedForTree(root); root.calculateLayout(); - Assert.True(root.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); assertTreeHasNewLayout(false, c0); assertTreeHasNewLayout(false, c1); } @@ -81,14 +81,14 @@ public void testInvalidatesCacheWhenChildAdded() c0.addChildAt(c0c1, 1); root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.True(c0c1.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsTrue(c0c1.HasNewLayout); - Assert.True(c0c0.HasNewLayout); - Assert.True(c1.HasNewLayout); + Assert.IsTrue(c0c0.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); - Assert.False(c1c0.HasNewLayout); + Assert.IsFalse(c1c0.HasNewLayout); } [Test] @@ -108,11 +108,11 @@ public void testInvalidatesCacheWhenEnumPropertyChanges() c1.AlignSelf = CSSAlign.Center; root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c1.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.False(c0c0.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsFalse(c0c0.HasNewLayout); } [Test] @@ -132,11 +132,11 @@ public void testInvalidatesCacheWhenFloatPropertyChanges() c1.SetMargin(CSSSpacingType.Left, 10); root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c1.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.False(c0c0.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsFalse(c0c0.HasNewLayout); } [Test] @@ -158,12 +158,12 @@ public void testInvalidatesFullTreeWhenParentWidthChanges() c0.Height = 200; root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.True(c0c0.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsTrue(c0c0.HasNewLayout); - Assert.True(c1.HasNewLayout); - Assert.False(c1c0.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); + Assert.IsFalse(c1c0.HasNewLayout); } [Test] @@ -184,7 +184,7 @@ public void testDoesNotInvalidateCacheWhenPropertyIsTheSame() root.Width = 200; root.calculateLayout(); - Assert.True(root.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); assertTreeHasNewLayout(false, c0); assertTreeHasNewLayout(false, c1); } @@ -206,10 +206,10 @@ public void testInvalidateCacheWhenHeightChangesPosition() c0.Height = 100; root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.True(c1.HasNewLayout); - Assert.False(c1c0.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); + Assert.IsFalse(c1c0.HasNewLayout); } [Test] @@ -226,15 +226,15 @@ public void testInvalidatesOnNewMeasureFunction() root.calculateLayout(); markLayoutAppliedForTree(root); - c1.setMeasureFunction((node, width) => new MeasureOutput(100, 20)); + c1.setMeasureFunction((node, width, height) => new MeasureOutput(100, 20)); root.calculateLayout(); - Assert.True(root.HasNewLayout); - Assert.True(c1.HasNewLayout); + Assert.IsTrue(root.HasNewLayout); + Assert.IsTrue(c1.HasNewLayout); - Assert.True(c0.HasNewLayout); - Assert.False(c0c0.HasNewLayout); + Assert.IsTrue(c0.HasNewLayout); + Assert.IsFalse(c0c0.HasNewLayout); } } } diff --git a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs index 3fadb61b829..6ef73899189 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs @@ -12,7 +12,7 @@ namespace Facebook.CSSLayout.Tests { - + /** * Tests for {@link LayoutEngine} */ @@ -24,27 +24,35 @@ public class LayoutEngineTest const int POSITION_BOTTOM = CSSLayout.POSITION_BOTTOM; const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT; const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH; - - static readonly MeasureFunction sTestMeasureFunction = (node, width) => - { - if (CSSConstants.IsUndefined(width)) { - width = 10000000; - } + static readonly MeasureFunction sTestMeasureFunction = (node, width, height) => + { TestCSSNode testNode = (TestCSSNode) node; - if (testNode.context.Equals(TestConstants.SMALL_TEXT)) - { + if (testNode.context.Equals(TestConstants.SMALL_TEXT)) { + if (CSSConstants.IsUndefined(width)) { + width = 10000000; + } return new MeasureOutput( Math.Min(width, TestConstants.SMALL_WIDTH), TestConstants.SMALL_HEIGHT); - } else if (testNode.context.Equals(TestConstants.LONG_TEXT)) - { + } else if (testNode.context.Equals(TestConstants.LONG_TEXT)) { + if (CSSConstants.IsUndefined(width)) { + width = 10000000; + } 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 (width > 0) { + return new MeasureOutput(width, width * 2); + } else if (height > 0) { + return new MeasureOutput(height * 2, height); + } else { + return new MeasureOutput(99999, 99999); + } } else { throw new Exception("Got unknown test: " + testNode.context); } @@ -71,8 +79,8 @@ private static void addChildren(TestCSSNode node, int numChildren) { } private static void assertLayoutsEqual(String message, CSSNode actual, CSSNode expected) { - Assert.True( - areLayoutsEqual(actual, expected), + Assert.IsTrue( + areLayoutsEqual(actual, expected), message + "\nActual:\n" + actual.ToString() + "\nExpected:\n" + expected.ToString() ); } @@ -4249,6 +4257,168 @@ public void TestCase94() [Test] public void TestCase95() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_WIDTH] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 100; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; + } + + test("should layout node with fixed width and custom measure function", root_node, root_layout); + } + + [Test] + public void TestCase96() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_HEIGHT] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 200; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + + test("should layout node with fixed height and custom measure function", root_node, root_layout); + } + + [Test] + public void TestCase97() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_WIDTH] = 100; + node_0.style.dimensions[DIMENSION_HEIGHT] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 100; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + + test("should layout node with fixed height and fixed width, ignoring custom measure function", root_node, root_layout); + } + + [Test] + public void TestCase98() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 99999; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 99999; + } + + test("should layout node with no fixed dimension and custom measure function", root_node, root_layout); + } + + [Test] + public void TestCase99() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.Column; + node_0.style.dimensions[DIMENSION_WIDTH] = 320; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.setMeasureFunction(sTestMeasureFunction); + node_1.context = "measureWithRatio2"; + node_1 = node_0.getChildAt(1); + node_1.style.flexDirection = CSSFlexDirection.Row; + node_1.style.dimensions[DIMENSION_HEIGHT] = 100; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "measureWithRatio2"; + node_2 = node_1.getChildAt(1); + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "measureWithRatio2"; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 320; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 740; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 320; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 640; + node_1 = node_0.getChildAt(1); + node_1.layout.position[POSITION_TOP] = 640; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 320; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; + addChildren(node_1, 2); + { + TestCSSNode node_2; + 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] = 200; + node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; + node_2 = node_1.getChildAt(1); + node_2.layout.position[POSITION_TOP] = 0; + node_2.layout.position[POSITION_LEFT] = 200; + node_2.layout.dimensions[DIMENSION_WIDTH] = 200; + node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + } + } + + test("should layout node with nested stacks and custom measure function", root_node, root_layout); + } + + [Test] + public void TestCase100() { TestCSSNode root_node = new TestCSSNode(); { @@ -4271,7 +4441,7 @@ public void TestCase95() } [Test] - public void TestCase96() + public void TestCase101() { TestCSSNode root_node = new TestCSSNode(); { @@ -4293,7 +4463,7 @@ public void TestCase96() } [Test] - public void TestCase97() + public void TestCase102() { TestCSSNode root_node = new TestCSSNode(); { @@ -4344,7 +4514,7 @@ public void TestCase97() } [Test] - public void TestCase98() + public void TestCase103() { TestCSSNode root_node = new TestCSSNode(); { @@ -4397,7 +4567,7 @@ public void TestCase98() } [Test] - public void TestCase99() + public void TestCase104() { TestCSSNode root_node = new TestCSSNode(); { @@ -4451,7 +4621,7 @@ public void TestCase99() } [Test] - public void TestCase100() + public void TestCase105() { TestCSSNode root_node = new TestCSSNode(); { @@ -4504,7 +4674,7 @@ public void TestCase100() } [Test] - public void TestCase101() + public void TestCase106() { TestCSSNode root_node = new TestCSSNode(); { @@ -4558,7 +4728,7 @@ public void TestCase101() } [Test] - public void TestCase102() + public void TestCase107() { TestCSSNode root_node = new TestCSSNode(); { @@ -4597,7 +4767,7 @@ public void TestCase102() } [Test] - public void TestCase103() + public void TestCase108() { TestCSSNode root_node = new TestCSSNode(); { @@ -4662,7 +4832,7 @@ public void TestCase103() } [Test] - public void TestCase104() + public void TestCase109() { TestCSSNode root_node = new TestCSSNode(); { @@ -4705,7 +4875,7 @@ public void TestCase104() } [Test] - public void TestCase105() + public void TestCase110() { TestCSSNode root_node = new TestCSSNode(); { @@ -4749,7 +4919,7 @@ public void TestCase105() } [Test] - public void TestCase106() + public void TestCase111() { TestCSSNode root_node = new TestCSSNode(); { @@ -4787,7 +4957,7 @@ public void TestCase106() } [Test] - public void TestCase107() + public void TestCase112() { TestCSSNode root_node = new TestCSSNode(); { @@ -4826,7 +4996,7 @@ public void TestCase107() } [Test] - public void TestCase108() + public void TestCase113() { TestCSSNode root_node = new TestCSSNode(); { @@ -4884,7 +5054,7 @@ public void TestCase108() } [Test] - public void TestCase109() + public void TestCase114() { TestCSSNode root_node = new TestCSSNode(); { @@ -4943,7 +5113,7 @@ public void TestCase109() } [Test] - public void TestCase110() + public void TestCase115() { TestCSSNode root_node = new TestCSSNode(); { @@ -5000,7 +5170,7 @@ public void TestCase110() } [Test] - public void TestCase111() + public void TestCase116() { TestCSSNode root_node = new TestCSSNode(); { @@ -5041,7 +5211,7 @@ public void TestCase111() } [Test] - public void TestCase112() + public void TestCase117() { TestCSSNode root_node = new TestCSSNode(); { @@ -5088,7 +5258,7 @@ public void TestCase112() } [Test] - public void TestCase113() + public void TestCase118() { TestCSSNode root_node = new TestCSSNode(); { @@ -5136,7 +5306,7 @@ public void TestCase113() } [Test] - public void TestCase114() + public void TestCase119() { TestCSSNode root_node = new TestCSSNode(); { @@ -5184,7 +5354,7 @@ public void TestCase114() } [Test] - public void TestCase115() + public void TestCase120() { TestCSSNode root_node = new TestCSSNode(); { @@ -5229,7 +5399,7 @@ public void TestCase115() } [Test] - public void TestCase116() + public void TestCase121() { TestCSSNode root_node = new TestCSSNode(); { @@ -5267,7 +5437,7 @@ public void TestCase116() } [Test] - public void TestCase117() + public void TestCase122() { TestCSSNode root_node = new TestCSSNode(); { @@ -5325,7 +5495,7 @@ public void TestCase117() } [Test] - public void TestCase118() + public void TestCase123() { TestCSSNode root_node = new TestCSSNode(); { @@ -5362,7 +5532,7 @@ public void TestCase118() } [Test] - public void TestCase119() + public void TestCase124() { TestCSSNode root_node = new TestCSSNode(); { @@ -5399,7 +5569,7 @@ public void TestCase119() } [Test] - public void TestCase120() + public void TestCase125() { TestCSSNode root_node = new TestCSSNode(); { @@ -5437,7 +5607,7 @@ public void TestCase120() } [Test] - public void TestCase121() + public void TestCase126() { TestCSSNode root_node = new TestCSSNode(); { @@ -5475,7 +5645,7 @@ public void TestCase121() } [Test] - public void TestCase122() + public void TestCase127() { TestCSSNode root_node = new TestCSSNode(); { @@ -5512,7 +5682,7 @@ public void TestCase122() } [Test] - public void TestCase123() + public void TestCase128() { TestCSSNode root_node = new TestCSSNode(); { @@ -5549,7 +5719,7 @@ public void TestCase123() } [Test] - public void TestCase124() + public void TestCase129() { TestCSSNode root_node = new TestCSSNode(); { @@ -5585,7 +5755,7 @@ public void TestCase124() } [Test] - public void TestCase125() + public void TestCase130() { TestCSSNode root_node = new TestCSSNode(); { @@ -5621,7 +5791,7 @@ public void TestCase125() } [Test] - public void TestCase126() + public void TestCase131() { TestCSSNode root_node = new TestCSSNode(); { @@ -5657,7 +5827,7 @@ public void TestCase126() } [Test] - public void TestCase127() + public void TestCase132() { TestCSSNode root_node = new TestCSSNode(); { @@ -5693,7 +5863,7 @@ public void TestCase127() } [Test] - public void TestCase128() + public void TestCase133() { TestCSSNode root_node = new TestCSSNode(); { @@ -5743,7 +5913,7 @@ public void TestCase128() } [Test] - public void TestCase129() + public void TestCase134() { TestCSSNode root_node = new TestCSSNode(); { @@ -5798,7 +5968,7 @@ public void TestCase129() } [Test] - public void TestCase130() + public void TestCase135() { TestCSSNode root_node = new TestCSSNode(); { @@ -5854,7 +6024,7 @@ public void TestCase130() } [Test] - public void TestCase131() + public void TestCase136() { TestCSSNode root_node = new TestCSSNode(); { @@ -5898,7 +6068,7 @@ public void TestCase131() } [Test] - public void TestCase132() + public void TestCase137() { TestCSSNode root_node = new TestCSSNode(); { @@ -5922,7 +6092,7 @@ public void TestCase132() } [Test] - public void TestCase133() + public void TestCase138() { TestCSSNode root_node = new TestCSSNode(); { @@ -5946,7 +6116,7 @@ public void TestCase133() } [Test] - public void TestCase134() + public void TestCase139() { TestCSSNode root_node = new TestCSSNode(); { @@ -5972,7 +6142,7 @@ public void TestCase134() } [Test] - public void TestCase135() + public void TestCase140() { TestCSSNode root_node = new TestCSSNode(); { @@ -5998,7 +6168,7 @@ public void TestCase135() } [Test] - public void TestCase136() + public void TestCase141() { TestCSSNode root_node = new TestCSSNode(); { @@ -6022,7 +6192,7 @@ public void TestCase136() } [Test] - public void TestCase137() + public void TestCase142() { TestCSSNode root_node = new TestCSSNode(); { @@ -6046,7 +6216,7 @@ public void TestCase137() } [Test] - public void TestCase138() + public void TestCase143() { TestCSSNode root_node = new TestCSSNode(); { @@ -6072,7 +6242,7 @@ public void TestCase138() } [Test] - public void TestCase139() + public void TestCase144() { TestCSSNode root_node = new TestCSSNode(); { @@ -6098,7 +6268,7 @@ public void TestCase139() } [Test] - public void TestCase140() + public void TestCase145() { TestCSSNode root_node = new TestCSSNode(); { @@ -6151,7 +6321,7 @@ public void TestCase140() } [Test] - public void TestCase141() + public void TestCase146() { TestCSSNode root_node = new TestCSSNode(); { @@ -6205,7 +6375,7 @@ public void TestCase141() } [Test] - public void TestCase142() + public void TestCase147() { TestCSSNode root_node = new TestCSSNode(); { @@ -6259,7 +6429,7 @@ public void TestCase142() } [Test] - public void TestCase143() + public void TestCase148() { TestCSSNode root_node = new TestCSSNode(); { @@ -6314,7 +6484,7 @@ public void TestCase143() } [Test] - public void TestCase144() + public void TestCase149() { TestCSSNode root_node = new TestCSSNode(); { @@ -6367,7 +6537,7 @@ public void TestCase144() } [Test] - public void TestCase145() + public void TestCase150() { TestCSSNode root_node = new TestCSSNode(); { @@ -6421,7 +6591,7 @@ public void TestCase145() } [Test] - public void TestCase146() + public void TestCase151() { TestCSSNode root_node = new TestCSSNode(); { @@ -6476,7 +6646,7 @@ public void TestCase146() } [Test] - public void TestCase147() + public void TestCase152() { TestCSSNode root_node = new TestCSSNode(); { @@ -6532,7 +6702,7 @@ public void TestCase147() } [Test] - public void TestCase148() + public void TestCase153() { TestCSSNode root_node = new TestCSSNode(); { @@ -6587,7 +6757,7 @@ public void TestCase148() } [Test] - public void TestCase149() + public void TestCase154() { TestCSSNode root_node = new TestCSSNode(); { @@ -6643,7 +6813,7 @@ public void TestCase149() } [Test] - public void TestCase150() + public void TestCase155() { TestCSSNode root_node = new TestCSSNode(); { @@ -6682,7 +6852,7 @@ public void TestCase150() } [Test] - public void TestCase151() + public void TestCase156() { TestCSSNode root_node = new TestCSSNode(); { @@ -6720,7 +6890,7 @@ public void TestCase151() } [Test] - public void TestCase152() + public void TestCase157() { TestCSSNode root_node = new TestCSSNode(); { @@ -6758,7 +6928,7 @@ public void TestCase152() } [Test] - public void TestCase153() + public void TestCase158() { TestCSSNode root_node = new TestCSSNode(); { @@ -6806,7 +6976,7 @@ public void TestCase153() } [Test] - public void TestCase154() + public void TestCase159() { TestCSSNode root_node = new TestCSSNode(); { @@ -6852,7 +7022,7 @@ public void TestCase154() } [Test] - public void TestCase155() + public void TestCase160() { TestCSSNode root_node = new TestCSSNode(); { @@ -6898,7 +7068,7 @@ public void TestCase155() } [Test] - public void TestCase156() + public void TestCase161() { TestCSSNode root_node = new TestCSSNode(); { @@ -6939,7 +7109,7 @@ public void TestCase156() } [Test] - public void TestCase157() + public void TestCase162() { TestCSSNode root_node = new TestCSSNode(); { @@ -6978,7 +7148,7 @@ public void TestCase157() } [Test] - public void TestCase158() + public void TestCase163() { TestCSSNode root_node = new TestCSSNode(); { @@ -7017,7 +7187,7 @@ public void TestCase158() } [Test] - public void TestCase159() + public void TestCase164() { TestCSSNode root_node = new TestCSSNode(); { @@ -7056,7 +7226,7 @@ public void TestCase159() } [Test] - public void TestCase160() + public void TestCase165() { TestCSSNode root_node = new TestCSSNode(); { @@ -7096,7 +7266,7 @@ public void TestCase160() } [Test] - public void TestCase161() + public void TestCase166() { TestCSSNode root_node = new TestCSSNode(); { @@ -7139,7 +7309,7 @@ public void TestCase161() } [Test] - public void TestCase162() + public void TestCase167() { TestCSSNode root_node = new TestCSSNode(); { @@ -7182,7 +7352,7 @@ public void TestCase162() } [Test] - public void TestCase163() + public void TestCase168() { TestCSSNode root_node = new TestCSSNode(); { @@ -7248,7 +7418,7 @@ public void TestCase163() } [Test] - public void TestCase164() + public void TestCase169() { TestCSSNode root_node = new TestCSSNode(); { @@ -7320,7 +7490,7 @@ public void TestCase164() } [Test] - public void TestCase165() + public void TestCase170() { TestCSSNode root_node = new TestCSSNode(); { @@ -7382,7 +7552,7 @@ public void TestCase165() } [Test] - public void TestCase166() + public void TestCase171() { TestCSSNode root_node = new TestCSSNode(); { @@ -7476,7 +7646,7 @@ public void TestCase166() } [Test] - public void TestCase167() + public void TestCase172() { TestCSSNode root_node = new TestCSSNode(); { @@ -7557,7 +7727,7 @@ public void TestCase167() } [Test] - public void TestCase168() + public void TestCase173() { TestCSSNode root_node = new TestCSSNode(); { @@ -7597,7 +7767,7 @@ public void TestCase168() } [Test] - public void TestCase169() + public void TestCase174() { TestCSSNode root_node = new TestCSSNode(); { @@ -7637,7 +7807,7 @@ public void TestCase169() } [Test] - public void TestCase170() + public void TestCase175() { TestCSSNode root_node = new TestCSSNode(); { @@ -7677,7 +7847,7 @@ public void TestCase170() } [Test] - public void TestCase171() + public void TestCase176() { TestCSSNode root_node = new TestCSSNode(); { @@ -7715,7 +7885,7 @@ public void TestCase171() } [Test] - public void TestCase172() + public void TestCase177() { TestCSSNode root_node = new TestCSSNode(); { @@ -7754,7 +7924,7 @@ public void TestCase172() } [Test] - public void TestCase173() + public void TestCase178() { TestCSSNode root_node = new TestCSSNode(); { @@ -7792,7 +7962,7 @@ public void TestCase173() } [Test] - public void TestCase174() + public void TestCase179() { TestCSSNode root_node = new TestCSSNode(); { @@ -7831,7 +8001,7 @@ public void TestCase174() } [Test] - public void TestCase175() + public void TestCase180() { TestCSSNode root_node = new TestCSSNode(); { @@ -7869,7 +8039,7 @@ public void TestCase175() } [Test] - public void TestCase176() + public void TestCase181() { TestCSSNode root_node = new TestCSSNode(); { @@ -7908,7 +8078,7 @@ public void TestCase176() } [Test] - public void TestCase177() + public void TestCase182() { TestCSSNode root_node = new TestCSSNode(); { @@ -7944,7 +8114,7 @@ public void TestCase177() } [Test] - public void TestCase178() + public void TestCase183() { TestCSSNode root_node = new TestCSSNode(); { @@ -8193,4 +8363,3 @@ public void TestCase178() } } - diff --git a/src/csharp/Facebook.CSSLayout.Tests/TestConstants.cs b/src/csharp/Facebook.CSSLayout.Tests/TestConstants.cs index eec927aaada..03c660b49c3 100644 --- a/src/csharp/Facebook.CSSLayout.Tests/TestConstants.cs +++ b/src/csharp/Facebook.CSSLayout.Tests/TestConstants.cs @@ -23,6 +23,7 @@ public class TestConstants public static readonly float BIG_MIN_WIDTH = 100f; public static readonly string SMALL_TEXT = "small"; public static readonly string LONG_TEXT = "loooooooooong with space"; + public static readonly string MEASURE_WITH_RATIO_2 = "measureWithRatio2"; /** END_GENERATED **/ } } diff --git a/src/csharp/Facebook.CSSLayout/CSSNode.cs b/src/csharp/Facebook.CSSLayout/CSSNode.cs index c6d50881196..4985e2a9aec 100644 --- a/src/csharp/Facebook.CSSLayout/CSSNode.cs +++ b/src/csharp/Facebook.CSSLayout/CSSNode.cs @@ -17,7 +17,7 @@ namespace Facebook.CSSLayout * Should measure the given node and put the result in the given MeasureOutput. */ - public delegate MeasureOutput MeasureFunction(CSSNode node, float width); + public delegate MeasureOutput MeasureFunction(CSSNode node, float width, float height); /** * A CSS Node. It has a style object you can manipulate at {@link #style}. After calling @@ -140,13 +140,13 @@ public bool IsMeasureDefined get { return mMeasureFunction != null; } } - internal MeasureOutput measure(MeasureOutput measureOutput, float width) + internal MeasureOutput measure(MeasureOutput measureOutput, float width, float height) { if (!IsMeasureDefined) { throw new Exception("Measure function isn't defined!"); } - return Assertions.assertNotNull(mMeasureFunction)(this, width); + return Assertions.assertNotNull(mMeasureFunction)(this, width, height); } /** @@ -156,7 +156,7 @@ internal MeasureOutput measure(MeasureOutput measureOutput, float width) public void CalculateLayout() { layout.resetResult(); - LayoutEngine.layoutNode(DummyLayoutContext, this, CSSConstants.Undefined, null); + LayoutEngine.layoutNode(DummyLayoutContext, this, CSSConstants.Undefined, CSSConstants.Undefined, null); } static readonly CSSLayoutContext DummyLayoutContext = new CSSLayoutContext(); @@ -469,10 +469,10 @@ public static class CSSNodeExtensions { /* Explicitly mark this node as dirty. - + Calling this function is required when the measure function points to the same instance, but changes its behavior. - + For all other property changes, the node is automatically marked dirty. */ diff --git a/src/csharp/Facebook.CSSLayout/CachedCSSLayout.cs b/src/csharp/Facebook.CSSLayout/CachedCSSLayout.cs index 4831c53ee1e..511d9af63cb 100644 --- a/src/csharp/Facebook.CSSLayout/CachedCSSLayout.cs +++ b/src/csharp/Facebook.CSSLayout/CachedCSSLayout.cs @@ -20,5 +20,6 @@ class CachedCSSLayout : CSSLayout public float requestedWidth = CSSConstants.Undefined; public float requestedHeight = CSSConstants.Undefined; public float parentMaxWidth = CSSConstants.Undefined; + public float parentMaxHeight = CSSConstants.Undefined; } } diff --git a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs index 47b7cb3d32c..87b682fcf0b 100644 --- a/src/csharp/Facebook.CSSLayout/LayoutEngine.cs +++ b/src/csharp/Facebook.CSSLayout/LayoutEngine.cs @@ -14,7 +14,7 @@ namespace Facebook.CSSLayout { /** - * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float)}. + * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float, float)}. */ static class LayoutEngine @@ -205,7 +205,7 @@ static boolean isMeasureDefined(CSSNode node) return node.IsMeasureDefined; } - static boolean needsRelayout(CSSNode node, float parentMaxWidth) + static boolean needsRelayout(CSSNode node, float parentMaxWidth, float parentMaxHeight) { return node.isDirty() || !FloatUtil.floatsEqual( @@ -214,18 +214,20 @@ static boolean needsRelayout(CSSNode node, float parentMaxWidth) !FloatUtil.floatsEqual( node.lastLayout.requestedWidth, node.layout.dimensions[DIMENSION_WIDTH]) || - !FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth); + !FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth) || + !FloatUtil.floatsEqual(node.lastLayout.parentMaxHeight, parentMaxHeight); } - internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, CSSDirection? parentDirection) + internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, float parentMaxHeight, CSSDirection? parentDirection) { - if (needsRelayout(node, parentMaxWidth)) + if (needsRelayout(node, parentMaxWidth, parentMaxHeight)) { node.lastLayout.requestedWidth = node.layout.dimensions[DIMENSION_WIDTH]; node.lastLayout.requestedHeight = node.layout.dimensions[DIMENSION_HEIGHT]; node.lastLayout.parentMaxWidth = parentMaxWidth; + node.lastLayout.parentMaxHeight = parentMaxHeight; - layoutNodeImpl(layoutContext, node, parentMaxWidth, parentDirection); + layoutNodeImpl(layoutContext, node, parentMaxWidth, parentMaxHeight, parentDirection); node.lastLayout.copy(node.layout); } else @@ -236,7 +238,7 @@ internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, fl node.markHasNewLayout(); } - static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, CSSDirection? parentDirection) + static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, float parentMaxHeight, CSSDirection? parentDirection) { var childCount_ = node.getChildCount(); for (int i_ = 0; i_ < childCount_; i_++) @@ -274,6 +276,7 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p // invocations during the layout calculation. int childCount = node.getChildCount(); float paddingAndBorderAxisResolvedRow = ((node.style.padding.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.border.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis])) + (node.style.padding.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]) + node.style.border.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]))); + float paddingAndBorderAxisColumn = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); if (isMeasureDefined(node)) { boolean isResolvedRowDimDefined = !float.IsNaN(node.layout.dimensions[dim[resolvedRowAxis]]); @@ -289,6 +292,17 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p } width -= paddingAndBorderAxisResolvedRow; + float height = CSSConstants.Undefined; + if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + height = node.style.dimensions[DIMENSION_HEIGHT]; + } else if (!float.IsNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]])) { + height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]; + } else { + height = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])); + } + height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); + // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. @@ -301,7 +315,8 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p MeasureOutput measureDim = node.measure( layoutContext.measureOutput, - width + width, + height ); if (isRowUndefined) { node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width + @@ -309,7 +324,7 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p } if (isColumnUndefined) { node.layout.dimensions[DIMENSION_HEIGHT] = measureDim.height + - ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); + paddingAndBorderAxisColumn; } } if (childCount == 0) { @@ -390,6 +405,7 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p float crossDim = 0; float maxWidth; + float maxHeight; for (i = startLine; i < childCount; ++i) { child = node.getChildAt(i); child.lineIndex = linesCount; @@ -470,6 +486,8 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p } else { maxWidth = CSSConstants.Undefined; + maxHeight = CSSConstants.Undefined; + if (!isMainRowDirection) { if ((!float.IsNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) { maxWidth = node.layout.dimensions[dim[resolvedRowAxis]] - @@ -479,11 +497,20 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) - paddingAndBorderAxisResolvedRow; } + } else { + if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(layoutContext, child, maxWidth, direction); + layoutNode(layoutContext, child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -613,9 +640,18 @@ static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float p (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSSConstants.Undefined; + if ((!float.IsNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(layoutContext, currentFlexChild, maxWidth, direction); + layoutNode(layoutContext, currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild.nextFlexChild; diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java index d6377205582..674e9469138 100644 --- a/src/java/src/com/facebook/csslayout/CSSNode.java +++ b/src/java/src/com/facebook/csslayout/CSSNode.java @@ -53,7 +53,7 @@ public static interface MeasureFunction { * * NB: measure is NOT guaranteed to be threadsafe/re-entrant safe! */ - public void measure(CSSNode node, float width, MeasureOutput measureOutput); + public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput); } // VisibleForTesting @@ -125,13 +125,13 @@ public boolean isMeasureDefined() { return mMeasureFunction != null; } - /*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width) { + /*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width, float height) { if (!isMeasureDefined()) { throw new RuntimeException("Measure function isn't defined!"); } measureOutput.height = CSSConstants.UNDEFINED; measureOutput.width = CSSConstants.UNDEFINED; - Assertions.assertNotNull(mMeasureFunction).measure(this, width, measureOutput); + Assertions.assertNotNull(mMeasureFunction).measure(this, width, height, measureOutput); return measureOutput; } @@ -140,7 +140,7 @@ public boolean isMeasureDefined() { */ public void calculateLayout(CSSLayoutContext layoutContext) { layout.resetResult(); - LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED, null); + LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, null); } /** diff --git a/src/java/src/com/facebook/csslayout/CachedCSSLayout.java b/src/java/src/com/facebook/csslayout/CachedCSSLayout.java index a2efa406bcf..e5393ef673a 100644 --- a/src/java/src/com/facebook/csslayout/CachedCSSLayout.java +++ b/src/java/src/com/facebook/csslayout/CachedCSSLayout.java @@ -18,4 +18,5 @@ public class CachedCSSLayout extends CSSLayout { public float requestedWidth = CSSConstants.UNDEFINED; public float requestedHeight = CSSConstants.UNDEFINED; public float parentMaxWidth = CSSConstants.UNDEFINED; + public float parentMaxHeight = CSSConstants.UNDEFINED; } diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 8d92129b97c..76e057ff228 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -16,7 +16,7 @@ import static com.facebook.csslayout.CSSLayout.POSITION_TOP; /** - * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float)}. + * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float, float)}. */ public class LayoutEngine { @@ -106,7 +106,7 @@ private static void setDimensionFromStyle(CSSNode node, int axis) { return; } // We only run if there's a width or height defined - if (Float.isNaN(node.style.dimensions[dim[axis]]) || + if (Float.isNaN(node.style.dimensions[dim[axis]]) || node.style.dimensions[dim[axis]] <= 0.0) { return; } @@ -180,7 +180,7 @@ private static boolean isMeasureDefined(CSSNode node) { return node.isMeasureDefined(); } - static boolean needsRelayout(CSSNode node, float parentMaxWidth) { + static boolean needsRelayout(CSSNode node, float parentMaxWidth, float parentMaxHeight) { return node.isDirty() || !FloatUtil.floatsEqual( node.lastLayout.requestedHeight, @@ -188,20 +188,23 @@ static boolean needsRelayout(CSSNode node, float parentMaxWidth) { !FloatUtil.floatsEqual( node.lastLayout.requestedWidth, node.layout.dimensions[DIMENSION_WIDTH]) || - !FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth); + !FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth) || + !FloatUtil.floatsEqual(node.lastLayout.parentMaxHeight, parentMaxHeight); } /*package*/ static void layoutNode( CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, + float parentMaxHeight, CSSDirection parentDirection) { - if (needsRelayout(node, parentMaxWidth)) { + if (needsRelayout(node, parentMaxWidth, parentMaxHeight)) { node.lastLayout.requestedWidth = node.layout.dimensions[DIMENSION_WIDTH]; node.lastLayout.requestedHeight = node.layout.dimensions[DIMENSION_HEIGHT]; node.lastLayout.parentMaxWidth = parentMaxWidth; + node.lastLayout.parentMaxHeight = parentMaxHeight; - layoutNodeImpl(layoutContext, node, parentMaxWidth, parentDirection); + layoutNodeImpl(layoutContext, node, parentMaxWidth, parentMaxHeight, parentDirection); node.lastLayout.copy(node.layout); } else { node.layout.copy(node.lastLayout); @@ -214,6 +217,7 @@ private static void layoutNodeImpl( CSSLayoutContext layoutContext, CSSNode node, float parentMaxWidth, + float parentMaxHeight, CSSDirection parentDirection) { for (int i = 0, childCount = node.getChildCount(); i < childCount; i++) { node.getChildAt(i).layout.resetResult(); @@ -248,6 +252,7 @@ private static void layoutNodeImpl( // invocations during the layout calculation. int childCount = node.getChildCount(); float paddingAndBorderAxisResolvedRow = ((node.style.padding.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.border.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis])) + (node.style.padding.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]) + node.style.border.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis]))); + float paddingAndBorderAxisColumn = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); if (isMeasureDefined(node)) { boolean isResolvedRowDimDefined = !Float.isNaN(node.layout.dimensions[dim[resolvedRowAxis]]); @@ -263,6 +268,17 @@ private static void layoutNodeImpl( } width -= paddingAndBorderAxisResolvedRow; + float height = CSSConstants.UNDEFINED; + if ((!Float.isNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + height = node.style.dimensions[DIMENSION_HEIGHT]; + } else if (!Float.isNaN(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]])) { + height = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]; + } else { + height = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])); + } + height -= ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); + // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. @@ -275,7 +291,8 @@ private static void layoutNodeImpl( MeasureOutput measureDim = node.measure( layoutContext.measureOutput, - width + width, + height ); if (isRowUndefined) { node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width + @@ -283,7 +300,7 @@ private static void layoutNodeImpl( } if (isColumnUndefined) { node.layout.dimensions[DIMENSION_HEIGHT] = measureDim.height + - ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); + paddingAndBorderAxisColumn; } } if (childCount == 0) { @@ -364,6 +381,7 @@ private static void layoutNodeImpl( float crossDim = 0; float maxWidth; + float maxHeight; for (i = startLine; i < childCount; ++i) { child = node.getChildAt(i); child.lineIndex = linesCount; @@ -444,6 +462,8 @@ private static void layoutNodeImpl( } else { maxWidth = CSSConstants.UNDEFINED; + maxHeight = CSSConstants.UNDEFINED; + if (!isMainRowDirection) { if ((!Float.isNaN(node.style.dimensions[dim[resolvedRowAxis]]) && node.style.dimensions[dim[resolvedRowAxis]] >= 0.0)) { maxWidth = node.layout.dimensions[dim[resolvedRowAxis]] - @@ -453,11 +473,20 @@ private static void layoutNodeImpl( (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) - paddingAndBorderAxisResolvedRow; } + } else { + if ((!Float.isNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else { + maxHeight = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) - + paddingAndBorderAxisColumn; + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(layoutContext, child, maxWidth, direction); + layoutNode(layoutContext, child, maxWidth, maxHeight, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -587,9 +616,18 @@ private static void layoutNodeImpl( (node.style.margin.getWithFallback(leadingSpacing[resolvedRowAxis], leading[resolvedRowAxis]) + node.style.margin.getWithFallback(trailingSpacing[resolvedRowAxis], trailing[resolvedRowAxis])) - paddingAndBorderAxisResolvedRow; } + maxHeight = CSSConstants.UNDEFINED; + if ((!Float.isNaN(node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]) && node.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { + maxHeight = node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - + paddingAndBorderAxisColumn; + } else if (isMainRowDirection) { + maxHeight = parentMaxHeight - + (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) - + paddingAndBorderAxisColumn; + } // And we recursively call the layout algorithm for this child - layoutNode(layoutContext, currentFlexChild, maxWidth, direction); + layoutNode(layoutContext, currentFlexChild, maxWidth, maxHeight, direction); child = currentFlexChild; currentFlexChild = currentFlexChild.nextFlexChild; diff --git a/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java index 965d70a6a2d..6e630fbb1a3 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java @@ -223,7 +223,7 @@ public void testInvalidatesOnNewMeasureFunction() { c1.setMeasureFunction(new CSSNode.MeasureFunction() { @Override - public void measure(CSSNode node, float width, MeasureOutput measureOutput) { + public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) { measureOutput.width = 100; measureOutput.height = 20; } diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index 971a9fe161d..3e1b35cddb3 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -27,20 +27,33 @@ public class LayoutEngineTest { new CSSNode.MeasureFunction() { @Override - public void measure(CSSNode node, float width, MeasureOutput measureOutput) { - if (CSSConstants.isUndefined(width)) { - width = 10000000; - } - + public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) { TestCSSNode testNode = (TestCSSNode) node; if (testNode.context.equals(TestConstants.SMALL_TEXT)) { + if (CSSConstants.isUndefined(width)) { + width = 10000000; + } measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH); measureOutput.height = TestConstants.SMALL_HEIGHT; } else if (testNode.context.equals(TestConstants.LONG_TEXT)) { + if (CSSConstants.isUndefined(width)) { + width = 10000000; + } 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 (width > 0) { + measureOutput.width = width; + measureOutput.height = width * 2; + } else if (height > 0) { + measureOutput.width = height * 2; + measureOutput.height = height; + } else { + measureOutput.width = 99999; + measureOutput.height = 99999; + } } else { throw new RuntimeException("Got unknown test: " + testNode.context); } @@ -4246,6 +4259,168 @@ public void testCase94() @Test public void testCase95() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_WIDTH] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 100; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; + } + + test("should layout node with fixed width and custom measure function", root_node, root_layout); + } + + @Test + public void testCase96() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_HEIGHT] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 200; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + + test("should layout node with fixed height and custom measure function", root_node, root_layout); + } + + @Test + public void testCase97() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.dimensions[DIMENSION_WIDTH] = 100; + node_0.style.dimensions[DIMENSION_HEIGHT] = 100; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 100; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + + test("should layout node with fixed height and fixed width, ignoring custom measure function", root_node, root_layout); + } + + @Test + public void testCase98() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.setMeasureFunction(sTestMeasureFunction); + node_0.context = "measureWithRatio2"; + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 99999; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 99999; + } + + test("should layout node with no fixed dimension and custom measure function", root_node, root_layout); + } + + @Test + public void testCase99() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN; + node_0.style.dimensions[DIMENSION_WIDTH] = 320; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.setMeasureFunction(sTestMeasureFunction); + node_1.context = "measureWithRatio2"; + node_1 = node_0.getChildAt(1); + node_1.style.flexDirection = CSSFlexDirection.ROW; + node_1.style.dimensions[DIMENSION_HEIGHT] = 100; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "measureWithRatio2"; + node_2 = node_1.getChildAt(1); + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "measureWithRatio2"; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.position[POSITION_TOP] = 0; + node_0.layout.position[POSITION_LEFT] = 0; + node_0.layout.dimensions[DIMENSION_WIDTH] = 320; + node_0.layout.dimensions[DIMENSION_HEIGHT] = 740; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.position[POSITION_TOP] = 0; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 320; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 640; + node_1 = node_0.getChildAt(1); + node_1.layout.position[POSITION_TOP] = 640; + node_1.layout.position[POSITION_LEFT] = 0; + node_1.layout.dimensions[DIMENSION_WIDTH] = 320; + node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; + addChildren(node_1, 2); + { + TestCSSNode node_2; + 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] = 200; + node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; + node_2 = node_1.getChildAt(1); + node_2.layout.position[POSITION_TOP] = 0; + node_2.layout.position[POSITION_LEFT] = 200; + node_2.layout.dimensions[DIMENSION_WIDTH] = 200; + node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; + } + } + } + + test("should layout node with nested stacks and custom measure function", root_node, root_layout); + } + + @Test + public void testCase100() { TestCSSNode root_node = new TestCSSNode(); { @@ -4268,7 +4443,7 @@ public void testCase95() } @Test - public void testCase96() + public void testCase101() { TestCSSNode root_node = new TestCSSNode(); { @@ -4290,7 +4465,7 @@ public void testCase96() } @Test - public void testCase97() + public void testCase102() { TestCSSNode root_node = new TestCSSNode(); { @@ -4341,7 +4516,7 @@ public void testCase97() } @Test - public void testCase98() + public void testCase103() { TestCSSNode root_node = new TestCSSNode(); { @@ -4394,7 +4569,7 @@ public void testCase98() } @Test - public void testCase99() + public void testCase104() { TestCSSNode root_node = new TestCSSNode(); { @@ -4448,7 +4623,7 @@ public void testCase99() } @Test - public void testCase100() + public void testCase105() { TestCSSNode root_node = new TestCSSNode(); { @@ -4501,7 +4676,7 @@ public void testCase100() } @Test - public void testCase101() + public void testCase106() { TestCSSNode root_node = new TestCSSNode(); { @@ -4555,7 +4730,7 @@ public void testCase101() } @Test - public void testCase102() + public void testCase107() { TestCSSNode root_node = new TestCSSNode(); { @@ -4594,7 +4769,7 @@ public void testCase102() } @Test - public void testCase103() + public void testCase108() { TestCSSNode root_node = new TestCSSNode(); { @@ -4659,7 +4834,7 @@ public void testCase103() } @Test - public void testCase104() + public void testCase109() { TestCSSNode root_node = new TestCSSNode(); { @@ -4702,7 +4877,7 @@ public void testCase104() } @Test - public void testCase105() + public void testCase110() { TestCSSNode root_node = new TestCSSNode(); { @@ -4746,7 +4921,7 @@ public void testCase105() } @Test - public void testCase106() + public void testCase111() { TestCSSNode root_node = new TestCSSNode(); { @@ -4784,7 +4959,7 @@ public void testCase106() } @Test - public void testCase107() + public void testCase112() { TestCSSNode root_node = new TestCSSNode(); { @@ -4823,7 +4998,7 @@ public void testCase107() } @Test - public void testCase108() + public void testCase113() { TestCSSNode root_node = new TestCSSNode(); { @@ -4881,7 +5056,7 @@ public void testCase108() } @Test - public void testCase109() + public void testCase114() { TestCSSNode root_node = new TestCSSNode(); { @@ -4940,7 +5115,7 @@ public void testCase109() } @Test - public void testCase110() + public void testCase115() { TestCSSNode root_node = new TestCSSNode(); { @@ -4997,7 +5172,7 @@ public void testCase110() } @Test - public void testCase111() + public void testCase116() { TestCSSNode root_node = new TestCSSNode(); { @@ -5038,7 +5213,7 @@ public void testCase111() } @Test - public void testCase112() + public void testCase117() { TestCSSNode root_node = new TestCSSNode(); { @@ -5085,7 +5260,7 @@ public void testCase112() } @Test - public void testCase113() + public void testCase118() { TestCSSNode root_node = new TestCSSNode(); { @@ -5133,7 +5308,7 @@ public void testCase113() } @Test - public void testCase114() + public void testCase119() { TestCSSNode root_node = new TestCSSNode(); { @@ -5181,7 +5356,7 @@ public void testCase114() } @Test - public void testCase115() + public void testCase120() { TestCSSNode root_node = new TestCSSNode(); { @@ -5226,7 +5401,7 @@ public void testCase115() } @Test - public void testCase116() + public void testCase121() { TestCSSNode root_node = new TestCSSNode(); { @@ -5264,7 +5439,7 @@ public void testCase116() } @Test - public void testCase117() + public void testCase122() { TestCSSNode root_node = new TestCSSNode(); { @@ -5322,7 +5497,7 @@ public void testCase117() } @Test - public void testCase118() + public void testCase123() { TestCSSNode root_node = new TestCSSNode(); { @@ -5359,7 +5534,7 @@ public void testCase118() } @Test - public void testCase119() + public void testCase124() { TestCSSNode root_node = new TestCSSNode(); { @@ -5396,7 +5571,7 @@ public void testCase119() } @Test - public void testCase120() + public void testCase125() { TestCSSNode root_node = new TestCSSNode(); { @@ -5434,7 +5609,7 @@ public void testCase120() } @Test - public void testCase121() + public void testCase126() { TestCSSNode root_node = new TestCSSNode(); { @@ -5472,7 +5647,7 @@ public void testCase121() } @Test - public void testCase122() + public void testCase127() { TestCSSNode root_node = new TestCSSNode(); { @@ -5509,7 +5684,7 @@ public void testCase122() } @Test - public void testCase123() + public void testCase128() { TestCSSNode root_node = new TestCSSNode(); { @@ -5546,7 +5721,7 @@ public void testCase123() } @Test - public void testCase124() + public void testCase129() { TestCSSNode root_node = new TestCSSNode(); { @@ -5582,7 +5757,7 @@ public void testCase124() } @Test - public void testCase125() + public void testCase130() { TestCSSNode root_node = new TestCSSNode(); { @@ -5618,7 +5793,7 @@ public void testCase125() } @Test - public void testCase126() + public void testCase131() { TestCSSNode root_node = new TestCSSNode(); { @@ -5654,7 +5829,7 @@ public void testCase126() } @Test - public void testCase127() + public void testCase132() { TestCSSNode root_node = new TestCSSNode(); { @@ -5690,7 +5865,7 @@ public void testCase127() } @Test - public void testCase128() + public void testCase133() { TestCSSNode root_node = new TestCSSNode(); { @@ -5740,7 +5915,7 @@ public void testCase128() } @Test - public void testCase129() + public void testCase134() { TestCSSNode root_node = new TestCSSNode(); { @@ -5795,7 +5970,7 @@ public void testCase129() } @Test - public void testCase130() + public void testCase135() { TestCSSNode root_node = new TestCSSNode(); { @@ -5851,7 +6026,7 @@ public void testCase130() } @Test - public void testCase131() + public void testCase136() { TestCSSNode root_node = new TestCSSNode(); { @@ -5895,7 +6070,7 @@ public void testCase131() } @Test - public void testCase132() + public void testCase137() { TestCSSNode root_node = new TestCSSNode(); { @@ -5919,7 +6094,7 @@ public void testCase132() } @Test - public void testCase133() + public void testCase138() { TestCSSNode root_node = new TestCSSNode(); { @@ -5943,7 +6118,7 @@ public void testCase133() } @Test - public void testCase134() + public void testCase139() { TestCSSNode root_node = new TestCSSNode(); { @@ -5969,7 +6144,7 @@ public void testCase134() } @Test - public void testCase135() + public void testCase140() { TestCSSNode root_node = new TestCSSNode(); { @@ -5995,7 +6170,7 @@ public void testCase135() } @Test - public void testCase136() + public void testCase141() { TestCSSNode root_node = new TestCSSNode(); { @@ -6019,7 +6194,7 @@ public void testCase136() } @Test - public void testCase137() + public void testCase142() { TestCSSNode root_node = new TestCSSNode(); { @@ -6043,7 +6218,7 @@ public void testCase137() } @Test - public void testCase138() + public void testCase143() { TestCSSNode root_node = new TestCSSNode(); { @@ -6069,7 +6244,7 @@ public void testCase138() } @Test - public void testCase139() + public void testCase144() { TestCSSNode root_node = new TestCSSNode(); { @@ -6095,7 +6270,7 @@ public void testCase139() } @Test - public void testCase140() + public void testCase145() { TestCSSNode root_node = new TestCSSNode(); { @@ -6148,7 +6323,7 @@ public void testCase140() } @Test - public void testCase141() + public void testCase146() { TestCSSNode root_node = new TestCSSNode(); { @@ -6202,7 +6377,7 @@ public void testCase141() } @Test - public void testCase142() + public void testCase147() { TestCSSNode root_node = new TestCSSNode(); { @@ -6256,7 +6431,7 @@ public void testCase142() } @Test - public void testCase143() + public void testCase148() { TestCSSNode root_node = new TestCSSNode(); { @@ -6311,7 +6486,7 @@ public void testCase143() } @Test - public void testCase144() + public void testCase149() { TestCSSNode root_node = new TestCSSNode(); { @@ -6364,7 +6539,7 @@ public void testCase144() } @Test - public void testCase145() + public void testCase150() { TestCSSNode root_node = new TestCSSNode(); { @@ -6418,7 +6593,7 @@ public void testCase145() } @Test - public void testCase146() + public void testCase151() { TestCSSNode root_node = new TestCSSNode(); { @@ -6473,7 +6648,7 @@ public void testCase146() } @Test - public void testCase147() + public void testCase152() { TestCSSNode root_node = new TestCSSNode(); { @@ -6529,7 +6704,7 @@ public void testCase147() } @Test - public void testCase148() + public void testCase153() { TestCSSNode root_node = new TestCSSNode(); { @@ -6584,7 +6759,7 @@ public void testCase148() } @Test - public void testCase149() + public void testCase154() { TestCSSNode root_node = new TestCSSNode(); { @@ -6640,7 +6815,7 @@ public void testCase149() } @Test - public void testCase150() + public void testCase155() { TestCSSNode root_node = new TestCSSNode(); { @@ -6679,7 +6854,7 @@ public void testCase150() } @Test - public void testCase151() + public void testCase156() { TestCSSNode root_node = new TestCSSNode(); { @@ -6717,7 +6892,7 @@ public void testCase151() } @Test - public void testCase152() + public void testCase157() { TestCSSNode root_node = new TestCSSNode(); { @@ -6755,7 +6930,7 @@ public void testCase152() } @Test - public void testCase153() + public void testCase158() { TestCSSNode root_node = new TestCSSNode(); { @@ -6803,7 +6978,7 @@ public void testCase153() } @Test - public void testCase154() + public void testCase159() { TestCSSNode root_node = new TestCSSNode(); { @@ -6849,7 +7024,7 @@ public void testCase154() } @Test - public void testCase155() + public void testCase160() { TestCSSNode root_node = new TestCSSNode(); { @@ -6895,7 +7070,7 @@ public void testCase155() } @Test - public void testCase156() + public void testCase161() { TestCSSNode root_node = new TestCSSNode(); { @@ -6936,7 +7111,7 @@ public void testCase156() } @Test - public void testCase157() + public void testCase162() { TestCSSNode root_node = new TestCSSNode(); { @@ -6975,7 +7150,7 @@ public void testCase157() } @Test - public void testCase158() + public void testCase163() { TestCSSNode root_node = new TestCSSNode(); { @@ -7014,7 +7189,7 @@ public void testCase158() } @Test - public void testCase159() + public void testCase164() { TestCSSNode root_node = new TestCSSNode(); { @@ -7053,7 +7228,7 @@ public void testCase159() } @Test - public void testCase160() + public void testCase165() { TestCSSNode root_node = new TestCSSNode(); { @@ -7093,7 +7268,7 @@ public void testCase160() } @Test - public void testCase161() + public void testCase166() { TestCSSNode root_node = new TestCSSNode(); { @@ -7136,7 +7311,7 @@ public void testCase161() } @Test - public void testCase162() + public void testCase167() { TestCSSNode root_node = new TestCSSNode(); { @@ -7179,7 +7354,7 @@ public void testCase162() } @Test - public void testCase163() + public void testCase168() { TestCSSNode root_node = new TestCSSNode(); { @@ -7245,7 +7420,7 @@ public void testCase163() } @Test - public void testCase164() + public void testCase169() { TestCSSNode root_node = new TestCSSNode(); { @@ -7317,7 +7492,7 @@ public void testCase164() } @Test - public void testCase165() + public void testCase170() { TestCSSNode root_node = new TestCSSNode(); { @@ -7379,7 +7554,7 @@ public void testCase165() } @Test - public void testCase166() + public void testCase171() { TestCSSNode root_node = new TestCSSNode(); { @@ -7473,7 +7648,7 @@ public void testCase166() } @Test - public void testCase167() + public void testCase172() { TestCSSNode root_node = new TestCSSNode(); { @@ -7554,7 +7729,7 @@ public void testCase167() } @Test - public void testCase168() + public void testCase173() { TestCSSNode root_node = new TestCSSNode(); { @@ -7594,7 +7769,7 @@ public void testCase168() } @Test - public void testCase169() + public void testCase174() { TestCSSNode root_node = new TestCSSNode(); { @@ -7634,7 +7809,7 @@ public void testCase169() } @Test - public void testCase170() + public void testCase175() { TestCSSNode root_node = new TestCSSNode(); { @@ -7674,7 +7849,7 @@ public void testCase170() } @Test - public void testCase171() + public void testCase176() { TestCSSNode root_node = new TestCSSNode(); { @@ -7712,7 +7887,7 @@ public void testCase171() } @Test - public void testCase172() + public void testCase177() { TestCSSNode root_node = new TestCSSNode(); { @@ -7751,7 +7926,7 @@ public void testCase172() } @Test - public void testCase173() + public void testCase178() { TestCSSNode root_node = new TestCSSNode(); { @@ -7789,7 +7964,7 @@ public void testCase173() } @Test - public void testCase174() + public void testCase179() { TestCSSNode root_node = new TestCSSNode(); { @@ -7828,7 +8003,7 @@ public void testCase174() } @Test - public void testCase175() + public void testCase180() { TestCSSNode root_node = new TestCSSNode(); { @@ -7866,7 +8041,7 @@ public void testCase175() } @Test - public void testCase176() + public void testCase181() { TestCSSNode root_node = new TestCSSNode(); { @@ -7905,7 +8080,7 @@ public void testCase176() } @Test - public void testCase177() + public void testCase182() { TestCSSNode root_node = new TestCSSNode(); { @@ -7941,7 +8116,7 @@ public void testCase177() } @Test - public void testCase178() + public void testCase183() { TestCSSNode root_node = new TestCSSNode(); { diff --git a/src/java/tests/com/facebook/csslayout/TestConstants.java b/src/java/tests/com/facebook/csslayout/TestConstants.java index 68e02a0f83f..e90493838c0 100644 --- a/src/java/tests/com/facebook/csslayout/TestConstants.java +++ b/src/java/tests/com/facebook/csslayout/TestConstants.java @@ -21,5 +21,6 @@ public class TestConstants { public static final float BIG_MIN_WIDTH = 100f; public static final String SMALL_TEXT = "small"; public static final String LONG_TEXT = "loooooooooong with space"; + public static final String MEASURE_WITH_RATIO_2 = "measureWithRatio2"; /** END_GENERATED **/ } diff --git a/src/transpile.js b/src/transpile.js index 1021df402e1..afe96af63dd 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -26,11 +26,15 @@ global.layoutTestUtils = { testRandomLayout: function(node, i) { allTests.push({name: 'Random #' + i, node: node, expectedLayout: computeDOMLayout(node)}); }, + testLayoutAgainstExpectedOnly: function(node, expectedLayout) { + allTests.push({name: currentTest, node: node, expectedLayout: expectedLayout}); + }, computeLayout: layoutTestUtils.computeLayout, reduceTest: reduceTest, text: layoutTestUtils.text, texts: layoutTestUtils.texts, - textSizes: layoutTestUtils.textSizes + textSizes: layoutTestUtils.textSizes, + measureWithRatio2: layoutTestUtils.measureWithRatio2 }; global.describe = function(name, cb) { @@ -114,6 +118,9 @@ function printLayout(test) { function addMeasure(node) { if ('measure' in node.style) { + if (node.children && node.children.length) { + throw new Error('Using custom measure function is supported only for leaf nodes.'); + } add('node_' + (level - 3) + '->measure = measure;'); add('node_' + (level - 3) + '->context = "' + node.style.measure.toString() + '";'); } @@ -289,7 +296,8 @@ function makeConstDefs() { '#define BIG_HEIGHT ' + layoutTestUtils.textSizes.bigHeight, '#define BIG_MIN_WIDTH ' + layoutTestUtils.textSizes.bigMinWidth, '#define SMALL_TEXT "' + layoutTestUtils.texts.small + '"', - '#define LONG_TEXT "' + layoutTestUtils.texts.big + '"' + '#define LONG_TEXT "' + layoutTestUtils.texts.big + '"', + '#define MEASURE_WITH_RATIO_2 "' + layoutTestUtils.measureWithRatio2() + '"' ]; return lines.join('\n'); }