diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index 1c888bc5..46b18d97 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -12,6 +12,7 @@ function __transpileToJavaCommon(code) { .replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED') .replace(/CSS_JUSTIFY_/g, 'CSSJustify.') .replace(/CSS_ALIGN_/g, 'CSSAlign.') + .replace(/CSS_POSITION_/g, 'CSSPositionType.') .replace(/css_flex_direction_t/g, 'CSSFlexDirection') .replace(/css_direction_t/g, 'CSSDirection') .replace(/css_align_t/g, 'CSSAlign') @@ -25,6 +26,9 @@ function __transpileToJavaCommon(code) { .replace(/layout\[pos/g, 'layout.position[pos') .replace(/layout\[leading/g, 'layout.position[leading') .replace(/layout\[trailing/g, 'layout.position[trailing') + .replace(/getPositionType\((.+?)\)/g, '$1.style.positionType') + .replace(/getJustifyContent\((.+?)\)/g, '$1.style.justifyContent') + .replace(/getAlignContent\((.+?)\)/g, '$1.style.alignContent') .replace(/\/\*\(c\)!([^*]+)\*\//g, '') .replace(/var\/\*\(java\)!([^*]+)\*\//g, '$1') .replace(/\/\*\(java\)!([^*]+)\*\//g, '$1') @@ -35,7 +39,6 @@ function __transpileSingleTestToJava(code) { .replace(/CSS_DIRECTION_/g, 'CSSDirection.') .replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.') .replace(/CSS_WRAP/g, 'CSSWrap.WRAP') - .replace(/CSS_POSITION_/g, 'CSSPositionType.') .replace(/new_test_css_node/g, 'new TestCSSNode') .replace( // style.position[CSS_TOP] => style.position[CSSLayout.POSITION_TOP] /(style|layout)\.position\[CSS_(LEFT|TOP|RIGHT|BOTTOM)\]/g, diff --git a/src/Layout.c b/src/Layout.c index c4da1d7e..4e8d9862 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -376,18 +376,6 @@ static float getPaddingAndBorderAxis(css_node_t *node, css_flex_direction_t axis return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); } -static css_position_type_t getPositionType(css_node_t *node) { - return node->style.position_type; -} - -static css_justify_t getJustifyContent(css_node_t *node) { - return node->style.justify_content; -} - -static css_align_t getAlignContent(css_node_t *node) { - return node->style.align_content; -} - static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { if (child->style.align_self != CSS_ALIGN_AUTO) { return child->style.align_self; @@ -435,7 +423,7 @@ static float getFlex(css_node_t *node) { static bool isFlex(css_node_t *node) { return ( - getPositionType(node) == CSS_POSITION_RELATIVE && + node->style.position_type == CSS_POSITION_RELATIVE && getFlex(node) > 0 ); } @@ -553,23 +541,29 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction node->layout.position[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); + // Inline immutable values from the target node to avoid excessive method + // invocations during the layout calculation. + int childCount = node->children_count; + float paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + if (isMeasureDefined(node)) { + bool isResolvedRowDimDefined = !isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); + float width = CSS_UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { width = node->style.dimensions[CSS_WIDTH]; - } else if (!isUndefined(node->layout.dimensions[dim[resolvedRowAxis]])) { + } else if (isResolvedRowDimDefined) { width = node->layout.dimensions[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, resolvedRowAxis); + width -= paddingAndBorderAxisResolvedRow; // 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. - bool isRowUndefined = !isDimDefined(node, resolvedRowAxis) && - isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); + bool isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined; bool isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]); @@ -582,40 +576,50 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction ); if (isRowUndefined) { node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } if (isColumnUndefined) { node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - if (node->children_count == 0) { + if (childCount == 0) { return; } } + bool isNodeFlexWrap = isFlexWrap(node); + + float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); + float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); + float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); + float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); + + bool isMainDimDefined = !isUndefined(node->layout.dimensions[dim[mainAxis]]); + bool isCrossDimDefined = !isUndefined(node->layout.dimensions[dim[crossAxis]]); + bool isMainRowDirection = isRowDirection(mainAxis); + int i; int ii; css_node_t* child; css_flex_direction_t axis; // Pre-fill some dimensions straight from the parent - for (i = 0; i < node->children_count; ++i) { + for (i = 0; i < childCount; ++i) { child = node->get_child(node->context, i); // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) == CSS_ALIGN_STRETCH && - getPositionType(child) == CSS_POSITION_RELATIVE && - !isUndefined(node->layout.dimensions[dim[crossAxis]]) && + child->style.position_type == CSS_POSITION_RELATIVE && + isCrossDimDefined && !isDimDefined(child, crossAxis)) { child->layout.dimensions[dim[crossAxis]] = fmaxf( boundAxis(child, crossAxis, node->layout.dimensions[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); - } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + } else if (child->style.position_type == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). for (ii = 0; ii < 2; ii++) { @@ -639,9 +643,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } float definedMainDim = CSS_UNDEFINED; - if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { - definedMainDim = node->layout.dimensions[dim[mainAxis]] - - getPaddingAndBorderAxis(node, mainAxis); + if (isMainDimDefined) { + definedMainDim = node->layout.dimensions[dim[mainAxis]] - paddingAndBorderAxisMain; } // We want to execute the next two loops one per line with flex-wrap @@ -653,7 +656,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction float linesCrossDim = 0; float linesMainDim = 0; int linesCount = 0; - while (endLine < node->children_count) { + while (endLine < childCount) { // Layout non flexible children and count children by type // mainContentDim is accumulation of the dimensions and margin of all the @@ -669,15 +672,15 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction int nonFlexibleChildrenCount = 0; float maxWidth; - for (i = startLine; i < node->children_count; ++i) { + for (i = startLine; i < childCount; ++i) { child = node->get_child(node->context, i); float nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed // dimension for the node-> - if (!isUndefined(node->layout.dimensions[dim[mainAxis]]) && isFlex(child)) { + if (isMainDimDefined && isFlex(child)) { flexibleChildrenCount++; - totalFlexible += getFlex(child); + totalFlexible += child->style.flex; // Even if we don't know its exact size yet, we already know the padding, // border and margin. We'll use this partial information, which represents @@ -688,14 +691,14 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } else { maxWidth = CSS_UNDEFINED; - if (!isRowDirection(mainAxis)) { - maxWidth = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); - + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; + } else { + maxWidth = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis) - + paddingAndBorderAxisResolvedRow; } } @@ -706,7 +709,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // Absolute positioned elements do not take part of the layout, so we // don't use them to compute mainContentDim - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child->style.position_type == CSS_POSITION_RELATIVE) { nonFlexibleChildrenCount++; // At this point we know the final size and margin of the element. nextContentDim = getDimWithMargin(child, mainAxis); @@ -714,8 +717,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } // The element we are about to add would make us go to the next line - if (isFlexWrap(node) && - !isUndefined(node->layout.dimensions[dim[mainAxis]]) && + if (isNodeFlexWrap && + isMainDimDefined && mainContentDim + nextContentDim > definedMainDim && // If there's only one element, then it's bigger than the content // and needs its own line @@ -739,7 +742,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // The remaining available space that needs to be allocated float remainingMainDim = 0; - if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { + if (isMainDimDefined) { remainingMainDim = definedMainDim - mainContentDim; } else { remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim; @@ -758,13 +761,13 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction for (i = startLine; i < endLine; ++i) { child = node->get_child(node->context, i); if (isFlex(child)) { - baseMainDim = flexibleMainDim * getFlex(child) + + baseMainDim = flexibleMainDim * child->style.flex + getPaddingAndBorderAxis(child, mainAxis); boundMainDim = boundAxis(child, mainAxis, baseMainDim); if (baseMainDim != boundMainDim) { remainingMainDim -= boundMainDim; - totalFlexible -= getFlex(child); + totalFlexible -= child->style.flex; } } } @@ -784,17 +787,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // At this point we know the final size of the element in the main // dimension child->layout.dimensions[dim[mainAxis]] = boundAxis(child, mainAxis, - flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis) + flexibleMainDim * child->style.flex + getPaddingAndBorderAxis(child, mainAxis) ); maxWidth = CSS_UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); - } else if (!isRowDirection(mainAxis)) { + paddingAndBorderAxisResolvedRow; + } else if (!isMainRowDirection) { maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } // And we recursively call the layout algorithm for this child @@ -805,7 +808,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // We use justifyContent to figure out how to allocate the remaining // space available } else { - css_justify_t justifyContent = getJustifyContent(node); + css_justify_t justifyContent = node->style.justify_content; if (justifyContent == CSS_JUSTIFY_CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { @@ -833,14 +836,13 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // variables that are also useful to compute the total dimensions of the // container! float crossDim = 0; - float mainDim = leadingMainDim + - getLeadingPaddingAndBorder(node, mainAxis); + float mainDim = leadingMainDim + leadingPaddingAndBorderMain; for (i = startLine; i < endLine; ++i) { child = node->get_child(node->context, i); child->line_index = linesCount; - if (getPositionType(child) == CSS_POSITION_ABSOLUTE && + if (child->style.position_type == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) { // In case the child is position absolute and has left/top being // defined, we override the position to whatever the user said @@ -854,7 +856,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction child->layout.position[pos[mainAxis]] += mainDim; // Define the trailing position accordingly. - if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { + if (isMainDimDefined) { setTrailingPosition(node, child, mainAxis); } } @@ -862,7 +864,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // Now that we placed the element, we need to update the variables // We only need to do that for relative elements. Absolute elements // do not take part in that phase. - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child->style.position_type == CSS_POSITION_RELATIVE) { // The main dimension is the sum of all the elements dimension plus // the spacing. mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); @@ -873,13 +875,13 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } float containerCrossAxis = node->layout.dimensions[dim[crossAxis]]; - if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { + if (!isCrossDimDefined) { containerCrossAxis = fmaxf( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, crossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); } @@ -887,7 +889,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction for (i = startLine; i < endLine; ++i) { child = node->get_child(node->context, i); - if (getPositionType(child) == CSS_POSITION_ABSOLUTE && + if (child->style.position_type == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) { // In case the child is absolutely positionned and has a // top/left/bottom/right being set, we override all the previously @@ -897,11 +899,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction getLeadingMargin(child, crossAxis); } else { - float leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); + float leadingCrossDim = leadingPaddingAndBorderCross; // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child->style.position_type == CSS_POSITION_RELATIVE) { css_align_t alignItem = getAlignItem(node, child); if (alignItem == CSS_ALIGN_STRETCH) { // You can only stretch if the dimension has not already been set @@ -909,8 +911,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction if (!isDimDefined(child, crossAxis)) { child->layout.dimensions[dim[crossAxis]] = fmaxf( boundAxis(child, crossAxis, containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); @@ -919,8 +920,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // The remaining space between the parent dimensions+padding and child // dimensions+margin. float remainingCrossDim = containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getDimWithMargin(child, crossAxis); + paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis); if (alignItem == CSS_ALIGN_CENTER) { leadingCrossDim += remainingCrossDim / 2; @@ -934,7 +934,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction child->layout.position[pos[crossAxis]] += linesCrossDim + leadingCrossDim; // Define the trailing position accordingly. - if (!isUndefined(node->layout.dimensions[dim[crossAxis]])) { + if (isCrossDimDefined) { setTrailingPosition(node, child, crossAxis); } } @@ -959,16 +959,15 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm // section 9.4 // - if (linesCount > 1 && - !isUndefined(node->layout.dimensions[dim[crossAxis]])) { + if (linesCount > 1 && isCrossDimDefined) { float nodeCrossAxisInnerSize = node->layout.dimensions[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis); + paddingAndBorderAxisCross; float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; float crossDimLead = 0; - float currentLead = getLeadingPaddingAndBorder(node, crossAxis); + float currentLead = leadingPaddingAndBorderCross; - css_align_t alignContent = getAlignContent(node); + css_align_t alignContent = node->style.align_content; if (alignContent == CSS_ALIGN_FLEX_END) { currentLead += remainingAlignContentDim; } else if (alignContent == CSS_ALIGN_CENTER) { @@ -985,9 +984,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // compute the line's height and find the endIndex float lineHeight = 0; - for (ii = startIndex; ii < node->children_count; ++ii) { + for (ii = startIndex; ii < childCount; ++ii) { child = node->get_child(node->context, ii); - if (getPositionType(child) != CSS_POSITION_RELATIVE) { + if (child->style.position_type != CSS_POSITION_RELATIVE) { continue; } if (child->line_index != i) { @@ -1005,7 +1004,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction for (ii = startIndex; ii < endIndex; ++ii) { child = node->get_child(node->context, ii); - if (getPositionType(child) != CSS_POSITION_RELATIVE) { + if (child->style.position_type != CSS_POSITION_RELATIVE) { continue; } @@ -1033,25 +1032,25 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. - if (isUndefined(node->layout.dimensions[dim[mainAxis]])) { + if (!isMainDimDefined) { node->layout.dimensions[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final // dimension boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders - getPaddingAndBorderAxis(node, mainAxis) + paddingAndBorderAxisMain ); needsMainTrailingPos = true; } - if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { + if (!isCrossDimDefined) { node->layout.dimensions[dim[crossAxis]] = fmaxf( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); needsCrossTrailingPos = true; @@ -1059,7 +1058,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // Set trailing position if necessary if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < node->children_count; ++i) { + for (i = 0; i < childCount; ++i) { child = node->get_child(node->context, i); if (needsMainTrailingPos) { @@ -1073,9 +1072,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction } // Calculate dimensions for absolutely positioned elements - for (i = 0; i < node->children_count; ++i) { + for (i = 0; i < childCount; ++i) { child = node->get_child(node->context, i); - if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + if (child->style.position_type == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). for (ii = 0; ii < 2; ii++) { diff --git a/src/Layout.js b/src/Layout.js index bb9eeb9b..9d8a4abc 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -287,14 +287,10 @@ var computeLayout = (function() { return 'relative'; } - function getFlex(node) { - return node.style.flex; - } - function isFlex(node) { return ( getPositionType(node) === CSS_POSITION_RELATIVE && - getFlex(node) > 0 + node.style.flex > 0 ); } @@ -413,23 +409,29 @@ var computeLayout = (function() { node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); + // Inline immutable values from the target node to avoid excessive method + // invocations during the layout calculation. + var/*int*/ childCount = node.children.length; + var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + if (isMeasureDefined(node)) { + var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]); + var/*float*/ width = CSS_UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { width = node.style.width; - } else if (!isUndefined(node.layout[dim[resolvedRowAxis]])) { + } else if (isResolvedRowDimDefined) { width = node.layout[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, resolvedRowAxis); + width -= paddingAndBorderAxisResolvedRow; // 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. - var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && - isUndefined(node.layout[dim[resolvedRowAxis]]); + var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined; var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]); @@ -442,36 +444,46 @@ var computeLayout = (function() { ); if (isRowUndefined) { node.layout.width = measureDim.width + - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } if (isColumnUndefined) { node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - if (node.children.length === 0) { + if (childCount === 0) { return; } } + var/*bool*/ isNodeFlexWrap = isFlexWrap(node); + + var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); + var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); + var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); + var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); + + var/*bool*/ isMainDimDefined = !isUndefined(node.layout[dim[mainAxis]]); + var/*bool*/ isCrossDimDefined = !isUndefined(node.layout[dim[crossAxis]]); + var/*bool*/ isMainRowDirection = isRowDirection(mainAxis); + var/*int*/ i; var/*int*/ ii; var/*css_node_t**/ child; var/*(c)!css_flex_direction_t*//*(java)!int*/ axis; // Pre-fill some dimensions straight from the parent - for (i = 0; i < node.children.length; ++i) { + for (i = 0; i < childCount; ++i) { child = node.children[i]; // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) === CSS_ALIGN_STRETCH && getPositionType(child) === CSS_POSITION_RELATIVE && - !isUndefined(node.layout[dim[crossAxis]]) && + isCrossDimDefined && !isDimDefined(child, crossAxis)) { child.layout[dim[crossAxis]] = fmaxf( boundAxis(child, crossAxis, node.layout[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); @@ -499,9 +511,8 @@ var computeLayout = (function() { } var/*float*/ definedMainDim = CSS_UNDEFINED; - if (!isUndefined(node.layout[dim[mainAxis]])) { - definedMainDim = node.layout[dim[mainAxis]] - - getPaddingAndBorderAxis(node, mainAxis); + if (isMainDimDefined) { + definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain; } // We want to execute the next two loops one per line with flex-wrap @@ -513,7 +524,7 @@ var computeLayout = (function() { var/*float*/ linesCrossDim = 0; var/*float*/ linesMainDim = 0; var/*int*/ linesCount = 0; - while (endLine < node.children.length) { + while (endLine < childCount) { // Layout non flexible children and count children by type // mainContentDim is accumulation of the dimensions and margin of all the @@ -529,15 +540,15 @@ var computeLayout = (function() { var/*int*/ nonFlexibleChildrenCount = 0; var/*float*/ maxWidth; - for (i = startLine; i < node.children.length; ++i) { + for (i = startLine; i < childCount; ++i) { child = node.children[i]; var/*float*/ nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed // dimension for the node. - if (!isUndefined(node.layout[dim[mainAxis]]) && isFlex(child)) { + if (isMainDimDefined && isFlex(child)) { flexibleChildrenCount++; - totalFlexible += getFlex(child); + totalFlexible += child.style.flex; // Even if we don't know its exact size yet, we already know the padding, // border and margin. We'll use this partial information, which represents @@ -548,14 +559,14 @@ var computeLayout = (function() { } else { maxWidth = CSS_UNDEFINED; - if (!isRowDirection(mainAxis)) { - maxWidth = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); - + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; + } else { + maxWidth = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis) - + paddingAndBorderAxisResolvedRow; } } @@ -574,8 +585,8 @@ var computeLayout = (function() { } // The element we are about to add would make us go to the next line - if (isFlexWrap(node) && - !isUndefined(node.layout[dim[mainAxis]]) && + if (isNodeFlexWrap && + isMainDimDefined && mainContentDim + nextContentDim > definedMainDim && // If there's only one element, then it's bigger than the content // and needs its own line @@ -599,7 +610,7 @@ var computeLayout = (function() { // The remaining available space that needs to be allocated var/*float*/ remainingMainDim = 0; - if (!isUndefined(node.layout[dim[mainAxis]])) { + if (isMainDimDefined) { remainingMainDim = definedMainDim - mainContentDim; } else { remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim; @@ -618,13 +629,13 @@ var computeLayout = (function() { for (i = startLine; i < endLine; ++i) { child = node.children[i]; if (isFlex(child)) { - baseMainDim = flexibleMainDim * getFlex(child) + + baseMainDim = flexibleMainDim * child.style.flex + getPaddingAndBorderAxis(child, mainAxis); boundMainDim = boundAxis(child, mainAxis, baseMainDim); if (baseMainDim !== boundMainDim) { remainingMainDim -= boundMainDim; - totalFlexible -= getFlex(child); + totalFlexible -= child.style.flex; } } } @@ -644,17 +655,17 @@ var computeLayout = (function() { // At this point we know the final size of the element in the main // dimension child.layout[dim[mainAxis]] = boundAxis(child, mainAxis, - flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis) + flexibleMainDim * child.style.flex + getPaddingAndBorderAxis(child, mainAxis) ); maxWidth = CSS_UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); - } else if (!isRowDirection(mainAxis)) { + paddingAndBorderAxisResolvedRow; + } else if (!isMainRowDirection) { maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } // And we recursively call the layout algorithm for this child @@ -693,8 +704,7 @@ var computeLayout = (function() { // variables that are also useful to compute the total dimensions of the // container! var/*float*/ crossDim = 0; - var/*float*/ mainDim = leadingMainDim + - getLeadingPaddingAndBorder(node, mainAxis); + var/*float*/ mainDim = leadingMainDim + leadingPaddingAndBorderMain; for (i = startLine; i < endLine; ++i) { child = node.children[i]; @@ -714,7 +724,7 @@ var computeLayout = (function() { child.layout[pos[mainAxis]] += mainDim; // Define the trailing position accordingly. - if (!isUndefined(node.layout[dim[mainAxis]])) { + if (isMainDimDefined) { setTrailingPosition(node, child, mainAxis); } } @@ -733,13 +743,13 @@ var computeLayout = (function() { } var/*float*/ containerCrossAxis = node.layout[dim[crossAxis]]; - if (isUndefined(node.layout[dim[crossAxis]])) { + if (!isCrossDimDefined) { containerCrossAxis = fmaxf( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, crossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); } @@ -757,7 +767,7 @@ var computeLayout = (function() { getLeadingMargin(child, crossAxis); } else { - var/*float*/ leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); + var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross; // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis @@ -769,8 +779,7 @@ var computeLayout = (function() { if (!isDimDefined(child, crossAxis)) { child.layout[dim[crossAxis]] = fmaxf( boundAxis(child, crossAxis, containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); @@ -779,8 +788,7 @@ var computeLayout = (function() { // The remaining space between the parent dimensions+padding and child // dimensions+margin. var/*float*/ remainingCrossDim = containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getDimWithMargin(child, crossAxis); + paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis); if (alignItem === CSS_ALIGN_CENTER) { leadingCrossDim += remainingCrossDim / 2; @@ -794,7 +802,7 @@ var computeLayout = (function() { child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim; // Define the trailing position accordingly. - if (!isUndefined(node.layout[dim[crossAxis]])) { + if (isCrossDimDefined) { setTrailingPosition(node, child, crossAxis); } } @@ -819,14 +827,13 @@ var computeLayout = (function() { // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm // section 9.4 // - if (linesCount > 1 && - !isUndefined(node.layout[dim[crossAxis]])) { + if (linesCount > 1 && isCrossDimDefined) { var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis); + paddingAndBorderAxisCross; var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; var/*float*/ crossDimLead = 0; - var/*float*/ currentLead = getLeadingPaddingAndBorder(node, crossAxis); + var/*float*/ currentLead = leadingPaddingAndBorderCross; var/*css_align_t*/ alignContent = getAlignContent(node); if (alignContent === CSS_ALIGN_FLEX_END) { @@ -845,7 +852,7 @@ var computeLayout = (function() { // compute the line's height and find the endIndex var/*float*/ lineHeight = 0; - for (ii = startIndex; ii < node.children.length; ++ii) { + for (ii = startIndex; ii < childCount; ++ii) { child = node.children[ii]; if (getPositionType(child) !== CSS_POSITION_RELATIVE) { continue; @@ -893,25 +900,25 @@ var computeLayout = (function() { // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. - if (isUndefined(node.layout[dim[mainAxis]])) { + if (!isMainDimDefined) { node.layout[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final // dimension boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders - getPaddingAndBorderAxis(node, mainAxis) + paddingAndBorderAxisMain ); needsMainTrailingPos = true; } - if (isUndefined(node.layout[dim[crossAxis]])) { + if (!isCrossDimDefined) { node.layout[dim[crossAxis]] = fmaxf( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); needsCrossTrailingPos = true; @@ -919,7 +926,7 @@ var computeLayout = (function() { // Set trailing position if necessary if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < node.children.length; ++i) { + for (i = 0; i < childCount; ++i) { child = node.children[i]; if (needsMainTrailingPos) { @@ -933,7 +940,7 @@ var computeLayout = (function() { } // Calculate dimensions for absolutely positioned elements - for (i = 0; i < node.children.length; ++i) { + for (i = 0; i < childCount; ++i) { child = node.children[i]; if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both @@ -981,4 +988,4 @@ var computeLayout = (function() { // the public API. if (typeof exports === 'object') { module.exports = computeLayout; -} \ No newline at end of file +} diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 2b8a5ed8..a4b7baea 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -269,10 +269,6 @@ public class LayoutEngine { } } - private static int getPositionType(CSSNode node) { - return node.style.positionType.ordinal(); - } - private static CSSAlign getAlignItem(CSSNode node, CSSNode child) { if (child.style.alignSelf != CSSAlign.AUTO) { return child.style.alignSelf; @@ -280,20 +276,12 @@ public class LayoutEngine { return node.style.alignItems; } - private static CSSAlign getAlignContent(CSSNode node) { - return node.style.alignContent; - } - - private static CSSJustify getJustifyContent(CSSNode node) { - return node.style.justifyContent; - } - private static boolean isFlexWrap(CSSNode node) { return node.style.flexWrap == CSSWrap.WRAP; } private static boolean isFlex(CSSNode node) { - return getPositionType(node) == CSS_POSITION_RELATIVE && node.style.flex > 0; + return node.style.positionType == CSSPositionType.RELATIVE && node.style.flex > 0; } private static boolean isMeasureDefined(CSSNode node) { @@ -370,23 +358,29 @@ public class LayoutEngine { node.layout.position[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); + // Inline immutable values from the target node to avoid excessive method + // invocations during the layout calculation. + int childCount = node.getChildCount(); + float paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis); + if (isMeasureDefined(node)) { + boolean isResolvedRowDimDefined = !isUndefined(node.layout.dimensions[dim[resolvedRowAxis]]); + float width = CSSConstants.UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { width = node.style.dimensions[DIMENSION_WIDTH]; - } else if (!isUndefined(node.layout.dimensions[dim[resolvedRowAxis]])) { + } else if (isResolvedRowDimDefined) { width = node.layout.dimensions[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, resolvedRowAxis); + width -= paddingAndBorderAxisResolvedRow; // 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. - boolean isRowUndefined = !isDimDefined(node, resolvedRowAxis) && - isUndefined(node.layout.dimensions[dim[resolvedRowAxis]]); + boolean isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined; boolean isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node.layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]); @@ -399,40 +393,50 @@ public class LayoutEngine { ); if (isRowUndefined) { node.layout.dimensions[DIMENSION_WIDTH] = measureDim.width + - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } if (isColumnUndefined) { node.layout.dimensions[DIMENSION_HEIGHT] = measureDim.height + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - if (node.getChildCount() == 0) { + if (childCount == 0) { return; } } + boolean isNodeFlexWrap = isFlexWrap(node); + + float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); + float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); + float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); + float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); + + boolean isMainDimDefined = !isUndefined(node.layout.dimensions[dim[mainAxis]]); + boolean isCrossDimDefined = !isUndefined(node.layout.dimensions[dim[crossAxis]]); + boolean isMainRowDirection = isRowDirection(mainAxis); + int i; int ii; CSSNode child; int axis; // Pre-fill some dimensions straight from the parent - for (i = 0; i < node.getChildCount(); ++i) { + for (i = 0; i < childCount; ++i) { child = node.getChildAt(i); // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) == CSSAlign.STRETCH && - getPositionType(child) == CSS_POSITION_RELATIVE && - !isUndefined(node.layout.dimensions[dim[crossAxis]]) && + child.style.positionType == CSSPositionType.RELATIVE && + isCrossDimDefined && !isDimDefined(child, crossAxis)) { child.layout.dimensions[dim[crossAxis]] = Math.max( boundAxis(child, crossAxis, node.layout.dimensions[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); - } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + } else if (child.style.positionType == CSSPositionType.ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). for (ii = 0; ii < 2; ii++) { @@ -456,9 +460,8 @@ public class LayoutEngine { } float definedMainDim = CSSConstants.UNDEFINED; - if (!isUndefined(node.layout.dimensions[dim[mainAxis]])) { - definedMainDim = node.layout.dimensions[dim[mainAxis]] - - getPaddingAndBorderAxis(node, mainAxis); + if (isMainDimDefined) { + definedMainDim = node.layout.dimensions[dim[mainAxis]] - paddingAndBorderAxisMain; } // We want to execute the next two loops one per line with flex-wrap @@ -470,7 +473,7 @@ public class LayoutEngine { float linesCrossDim = 0; float linesMainDim = 0; int linesCount = 0; - while (endLine < node.getChildCount()) { + while (endLine < childCount) { // Layout non flexible children and count children by type // mainContentDim is accumulation of the dimensions and margin of all the @@ -486,15 +489,15 @@ public class LayoutEngine { int nonFlexibleChildrenCount = 0; float maxWidth; - for (i = startLine; i < node.getChildCount(); ++i) { + for (i = startLine; i < childCount; ++i) { child = node.getChildAt(i); float nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed // dimension for the node. - if (!isUndefined(node.layout.dimensions[dim[mainAxis]]) && isFlex(child)) { + if (isMainDimDefined && isFlex(child)) { flexibleChildrenCount++; - totalFlexible += getFlex(child); + totalFlexible += child.style.flex; // Even if we don't know its exact size yet, we already know the padding, // border and margin. We'll use this partial information, which represents @@ -505,14 +508,14 @@ public class LayoutEngine { } else { maxWidth = CSSConstants.UNDEFINED; - if (!isRowDirection(mainAxis)) { - maxWidth = parentMaxWidth - - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); - + if (!isMainRowDirection) { if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout.dimensions[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; + } else { + maxWidth = parentMaxWidth - + getMarginAxis(node, resolvedRowAxis) - + paddingAndBorderAxisResolvedRow; } } @@ -523,7 +526,7 @@ public class LayoutEngine { // Absolute positioned elements do not take part of the layout, so we // don't use them to compute mainContentDim - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child.style.positionType == CSSPositionType.RELATIVE) { nonFlexibleChildrenCount++; // At this point we know the final size and margin of the element. nextContentDim = getDimWithMargin(child, mainAxis); @@ -531,8 +534,8 @@ public class LayoutEngine { } // The element we are about to add would make us go to the next line - if (isFlexWrap(node) && - !isUndefined(node.layout.dimensions[dim[mainAxis]]) && + if (isNodeFlexWrap && + isMainDimDefined && mainContentDim + nextContentDim > definedMainDim && // If there's only one element, then it's bigger than the content // and needs its own line @@ -556,7 +559,7 @@ public class LayoutEngine { // The remaining available space that needs to be allocated float remainingMainDim = 0; - if (!isUndefined(node.layout.dimensions[dim[mainAxis]])) { + if (isMainDimDefined) { remainingMainDim = definedMainDim - mainContentDim; } else { remainingMainDim = Math.max(mainContentDim, 0) - mainContentDim; @@ -575,13 +578,13 @@ public class LayoutEngine { for (i = startLine; i < endLine; ++i) { child = node.getChildAt(i); if (isFlex(child)) { - baseMainDim = flexibleMainDim * getFlex(child) + + baseMainDim = flexibleMainDim * child.style.flex + getPaddingAndBorderAxis(child, mainAxis); boundMainDim = boundAxis(child, mainAxis, baseMainDim); if (baseMainDim != boundMainDim) { remainingMainDim -= boundMainDim; - totalFlexible -= getFlex(child); + totalFlexible -= child.style.flex; } } } @@ -601,17 +604,17 @@ public class LayoutEngine { // At this point we know the final size of the element in the main // dimension child.layout.dimensions[dim[mainAxis]] = boundAxis(child, mainAxis, - flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis) + flexibleMainDim * child.style.flex + getPaddingAndBorderAxis(child, mainAxis) ); maxWidth = CSSConstants.UNDEFINED; if (isDimDefined(node, resolvedRowAxis)) { maxWidth = node.layout.dimensions[dim[resolvedRowAxis]] - - getPaddingAndBorderAxis(node, resolvedRowAxis); - } else if (!isRowDirection(mainAxis)) { + paddingAndBorderAxisResolvedRow; + } else if (!isMainRowDirection) { maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - - getPaddingAndBorderAxis(node, resolvedRowAxis); + paddingAndBorderAxisResolvedRow; } // And we recursively call the layout algorithm for this child @@ -622,7 +625,7 @@ public class LayoutEngine { // We use justifyContent to figure out how to allocate the remaining // space available } else { - CSSJustify justifyContent = getJustifyContent(node); + CSSJustify justifyContent = node.style.justifyContent; if (justifyContent == CSSJustify.CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent == CSSJustify.FLEX_END) { @@ -650,14 +653,13 @@ public class LayoutEngine { // variables that are also useful to compute the total dimensions of the // container! float crossDim = 0; - float mainDim = leadingMainDim + - getLeadingPaddingAndBorder(node, mainAxis); + float mainDim = leadingMainDim + leadingPaddingAndBorderMain; for (i = startLine; i < endLine; ++i) { child = node.getChildAt(i); child.lineIndex = linesCount; - if (getPositionType(child) == CSS_POSITION_ABSOLUTE && + if (child.style.positionType == CSSPositionType.ABSOLUTE && isPosDefined(child, leading[mainAxis])) { // In case the child is position absolute and has left/top being // defined, we override the position to whatever the user said @@ -671,7 +673,7 @@ public class LayoutEngine { child.layout.position[pos[mainAxis]] += mainDim; // Define the trailing position accordingly. - if (!isUndefined(node.layout.dimensions[dim[mainAxis]])) { + if (isMainDimDefined) { setTrailingPosition(node, child, mainAxis); } } @@ -679,7 +681,7 @@ public class LayoutEngine { // Now that we placed the element, we need to update the variables // We only need to do that for relative elements. Absolute elements // do not take part in that phase. - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child.style.positionType == CSSPositionType.RELATIVE) { // The main dimension is the sum of all the elements dimension plus // the spacing. mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); @@ -690,13 +692,13 @@ public class LayoutEngine { } float containerCrossAxis = node.layout.dimensions[dim[crossAxis]]; - if (isUndefined(node.layout.dimensions[dim[crossAxis]])) { + if (!isCrossDimDefined) { containerCrossAxis = Math.max( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, crossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); } @@ -704,7 +706,7 @@ public class LayoutEngine { for (i = startLine; i < endLine; ++i) { child = node.getChildAt(i); - if (getPositionType(child) == CSS_POSITION_ABSOLUTE && + if (child.style.positionType == CSSPositionType.ABSOLUTE && isPosDefined(child, leading[crossAxis])) { // In case the child is absolutely positionned and has a // top/left/bottom/right being set, we override all the previously @@ -714,11 +716,11 @@ public class LayoutEngine { getLeadingMargin(child, crossAxis); } else { - float leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); + float leadingCrossDim = leadingPaddingAndBorderCross; // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis - if (getPositionType(child) == CSS_POSITION_RELATIVE) { + if (child.style.positionType == CSSPositionType.RELATIVE) { CSSAlign alignItem = getAlignItem(node, child); if (alignItem == CSSAlign.STRETCH) { // You can only stretch if the dimension has not already been set @@ -726,8 +728,7 @@ public class LayoutEngine { if (!isDimDefined(child, crossAxis)) { child.layout.dimensions[dim[crossAxis]] = Math.max( boundAxis(child, crossAxis, containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis)), + paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); @@ -736,8 +737,7 @@ public class LayoutEngine { // The remaining space between the parent dimensions+padding and child // dimensions+margin. float remainingCrossDim = containerCrossAxis - - getPaddingAndBorderAxis(node, crossAxis) - - getDimWithMargin(child, crossAxis); + paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis); if (alignItem == CSSAlign.CENTER) { leadingCrossDim += remainingCrossDim / 2; @@ -751,7 +751,7 @@ public class LayoutEngine { child.layout.position[pos[crossAxis]] += linesCrossDim + leadingCrossDim; // Define the trailing position accordingly. - if (!isUndefined(node.layout.dimensions[dim[crossAxis]])) { + if (isCrossDimDefined) { setTrailingPosition(node, child, crossAxis); } } @@ -776,16 +776,15 @@ public class LayoutEngine { // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm // section 9.4 // - if (linesCount > 1 && - !isUndefined(node.layout.dimensions[dim[crossAxis]])) { + if (linesCount > 1 && isCrossDimDefined) { float nodeCrossAxisInnerSize = node.layout.dimensions[dim[crossAxis]] - - getPaddingAndBorderAxis(node, crossAxis); + paddingAndBorderAxisCross; float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; float crossDimLead = 0; - float currentLead = getLeadingPaddingAndBorder(node, crossAxis); + float currentLead = leadingPaddingAndBorderCross; - CSSAlign alignContent = getAlignContent(node); + CSSAlign alignContent = node.style.alignContent; if (alignContent == CSSAlign.FLEX_END) { currentLead += remainingAlignContentDim; } else if (alignContent == CSSAlign.CENTER) { @@ -802,9 +801,9 @@ public class LayoutEngine { // compute the line's height and find the endIndex float lineHeight = 0; - for (ii = startIndex; ii < node.getChildCount(); ++ii) { + for (ii = startIndex; ii < childCount; ++ii) { child = node.getChildAt(ii); - if (getPositionType(child) != CSS_POSITION_RELATIVE) { + if (child.style.positionType != CSSPositionType.RELATIVE) { continue; } if (child.lineIndex != i) { @@ -822,7 +821,7 @@ public class LayoutEngine { for (ii = startIndex; ii < endIndex; ++ii) { child = node.getChildAt(ii); - if (getPositionType(child) != CSS_POSITION_RELATIVE) { + if (child.style.positionType != CSSPositionType.RELATIVE) { continue; } @@ -850,25 +849,25 @@ public class LayoutEngine { // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. - if (isUndefined(node.layout.dimensions[dim[mainAxis]])) { + if (!isMainDimDefined) { node.layout.dimensions[dim[mainAxis]] = Math.max( // We're missing the last padding at this point to get the final // dimension boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders - getPaddingAndBorderAxis(node, mainAxis) + paddingAndBorderAxisMain ); needsMainTrailingPos = true; } - if (isUndefined(node.layout.dimensions[dim[crossAxis]])) { + if (!isCrossDimDefined) { node.layout.dimensions[dim[crossAxis]] = Math.max( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), - getPaddingAndBorderAxis(node, crossAxis) + boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), + paddingAndBorderAxisCross ); needsCrossTrailingPos = true; @@ -876,7 +875,7 @@ public class LayoutEngine { // Set trailing position if necessary if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < node.getChildCount(); ++i) { + for (i = 0; i < childCount; ++i) { child = node.getChildAt(i); if (needsMainTrailingPos) { @@ -890,9 +889,9 @@ public class LayoutEngine { } // Calculate dimensions for absolutely positioned elements - for (i = 0; i < node.getChildCount(); ++i) { + for (i = 0; i < childCount; ++i) { child = node.getChildAt(i); - if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + if (child.style.positionType == CSSPositionType.ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). for (ii = 0; ii < 2; ii++) { diff --git a/src/transpile.js b/src/transpile.js index e343ac51..2f93d154 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -261,6 +261,9 @@ function transpileAnnotatedJStoC(jsCode) { .replace(/node\./g, 'node->') .replace(/child\./g, 'child->') .replace(/parent\./g, 'parent->') + .replace(/getPositionType\((.+?)\)/g, '$1->style.position_type') + .replace(/getJustifyContent\((.+?)\)/g, '$1->style.justify_content') + .replace(/getAlignContent\((.+?)\)/g, '$1->style.align_content') .replace(/var\/\*\(c\)!([^*]+)\*\//g, '$1') .replace(/var\/\*([^\/]+)\*\//g, '$1') .replace(/ === /g, ' == ')