From fca176109d84a7b583bc091f91109d8c359ac1fc Mon Sep 17 00:00:00 2001 From: Lukas Reichart Date: Sun, 10 May 2015 17:46:48 +0200 Subject: [PATCH 1/8] If the measure function is defined: only return from execution of layoutNode, when the node has no children. --- src/Layout.c | 4 +++- src/Layout.js | 4 +++- src/java/src/com/facebook/csslayout/LayoutEngine.java | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Layout.c b/src/Layout.c index cbbb4c32..51888b9f 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -431,7 +431,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - return; + if (node->children_count == 0) { + return; + } } int i; diff --git a/src/Layout.js b/src/Layout.js index fd39b4fb..315f9bca 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -315,7 +315,9 @@ var computeLayout = (function() { getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - return; + if (node.children.length === 0) { + return; + } } var/*int*/ i; diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 01ee44d0..7fe74cc5 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -369,7 +369,9 @@ public class LayoutEngine { getPaddingAndBorderAxis(node, CSSFlexDirection.COLUMN); } } - return; + if (node.getChildCount() == 0) { + return; + } } int i; From 36a46673f9479f94f83277464c5c43766989c417 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 6 May 2015 21:22:44 +0100 Subject: [PATCH 2/8] Support ROW_REVERSE, COLUMN_REVERSE and RTL direction --- src/JavaTranspiler.js | 8 +- src/Layout-test-utils.c | 2 +- src/Layout-test-utils.js | 1 + src/Layout.c | 163 +- src/Layout.h | 16 +- src/Layout.js | 172 +- src/__tests__/Layout-test.c | 2118 +++++++++- src/__tests__/Layout-test.js | 616 ++- .../com/facebook/csslayout/CSSDirection.java | 15 + .../facebook/csslayout/CSSFlexDirection.java | 2 + .../src/com/facebook/csslayout/CSSLayout.java | 22 +- .../src/com/facebook/csslayout/CSSNode.java | 6 +- .../src/com/facebook/csslayout/CSSStyle.java | 1 + .../com/facebook/csslayout/LayoutEngine.java | 207 +- .../facebook/csslayout/LayoutEngineTest.java | 3618 +++++++++++++---- src/transpile.js | 9 +- 16 files changed, 6112 insertions(+), 864 deletions(-) create mode 100644 src/java/src/com/facebook/csslayout/CSSDirection.java diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index 56ce90fd..d3b1304e 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -11,6 +11,8 @@ function __transpileToJavaCommon(code) { return code .replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED') .replace(/css_flex_direction_t/g, 'CSSFlexDirection') + .replace(/css_direction_t/g, 'CSSDirection') + .replace(/CSS_DIRECTION_/g, 'CSSDirection.') .replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.') .replace(/css_align_t/g, 'CSSAlign') .replace(/CSS_ALIGN_/g, 'CSSAlign.') @@ -33,7 +35,11 @@ function __transpileToJavaCommon(code) { .replace( /(\w+)\.layout\[((?:getLeading|getPos)\([^\)]+\))\]\s+=\s+([^;]+);/gm, 'setLayoutPosition($1, $2, $3);') + .replace( + /(\w+)\.layout\[((?:getTrailing|getPos)\([^\)]+\))\]\s+=\s+([^;]+);/gm, + 'setLayoutPosition($1, $2, $3);') .replace(/(\w+)\.layout\[((?:getLeading|getPos)\([^\]]+\))\]/g, 'getLayoutPosition($1, $2)') + .replace(/(\w+)\.layout\[((?:getTrailing|getPos)\([^\]]+\))\]/g, 'getLayoutPosition($1, $2)') .replace( /(\w+)\.layout\[(getDim\([^\)]+\))\]\s+=\s+([^;]+);/gm, 'setLayoutDimension($1, $2, $3);') @@ -63,7 +69,7 @@ function __transpileSingleTestToJava(code) { .replace( // layout.position[CSS_TOP] => layout.y /layout\.position\[CSS_(TOP|LEFT)\]/g, function (str, match1) { - return 'layout.' + (match1 === 'TOP' ? 'y' : 'x'); + return 'layout.' + (match1 === 'TOP' ? 'top' : 'left'); }) .replace( // style.position[CSS_TOP] => style.positionTop /style\.(position)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, diff --git a/src/Layout-test-utils.c b/src/Layout-test-utils.c index de88514a..095f7f17 100644 --- a/src/Layout-test-utils.c +++ b/src/Layout-test-utils.c @@ -88,7 +88,7 @@ css_dim_t measure(void *context, float width) { } void test(const char *name, css_node_t *style, css_node_t *expected_layout) { - layoutNode(style, CSS_UNDEFINED); + layoutNode(style, CSS_UNDEFINED, -1); if (!are_layout_equal(style, expected_layout)) { printf("%sF%s", "\x1B[31m", "\x1B[0m"); diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index 3e1efaaa..f2b15959 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -184,6 +184,7 @@ var layoutTestUtils = (function() { transferSpacing(div, node, 'padding', ''); transferSpacing(div, node, 'border', 'Width'); transfer(div, node, 'flexDirection'); + transfer(div, node, 'direction'); transfer(div, node, 'flex'); transfer(div, node, 'flexWrap'); transfer(div, node, 'justifyContent'); diff --git a/src/Layout.c b/src/Layout.c index cbbb4c32..023db820 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -36,6 +36,9 @@ static bool eq(float a, float b) { void init_css_node(css_node_t *node) { node->style.align_items = CSS_ALIGN_STRETCH; + node->style.direction = CSS_DIRECTION_INHERIT; + node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; + // Some of the fields default to undefined and not 0 node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED; node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; @@ -58,6 +61,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_direction = -1; node->layout.should_update = true; } @@ -119,8 +123,14 @@ static void print_css_node_rec( } if (options & CSS_PRINT_STYLE) { - if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { + if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) { + printf("flexDirection: 'column', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + printf("flexDirection: 'columnReverse', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { printf("flexDirection: 'row', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { + printf("flexDirection: 'rowReverse', "); } if (node->style.justify_content == CSS_JUSTIFY_CENTER) { @@ -210,25 +220,32 @@ void print_css_node(css_node_t *node, css_print_options_t options) { } -static css_position_t leading[2] = { +static css_position_t leading[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT }; -static css_position_t trailing[2] = { +static css_position_t trailing[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT }; -static css_position_t pos[2] = { +static css_position_t pos[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT }; -static css_dimension_t dim[2] = { +static css_dimension_t dim[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH }; - static float getMargin(css_node_t *node, int location) { return node->style.margin[location]; } @@ -278,10 +295,50 @@ static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { return node->style.align_items; } +static bool isRowDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_ROW || + flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; +} + +static bool isColumnDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_COLUMN || + flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; +} + +static css_direction_t resolveDirection(css_node_t *node, css_direction_t parentDirection) { + css_direction_t direction = node->style.direction; + + if (direction == CSS_DIRECTION_INHERIT) { + direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR; + } + + return direction; +} + static css_flex_direction_t getFlexDirection(css_node_t *node) { return node->style.flex_direction; } +static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) { + if (direction == CSS_DIRECTION_RTL) { + if (flex_direction == CSS_FLEX_DIRECTION_ROW) { + return CSS_FLEX_DIRECTION_ROW_REVERSE; + } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { + return CSS_FLEX_DIRECTION_ROW; + } + } + + return flex_direction; +} + +static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) { + if (isColumnDirection(flex_direction)) { + return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); + } else { + return CSS_FLEX_DIRECTION_COLUMN; + } +} + static float getFlex(css_node_t *node) { return node->style.flex; } @@ -328,10 +385,10 @@ static float boundAxis(css_node_t *node, css_flex_direction_t axis, float value) float min = CSS_UNDEFINED; float max = CSS_UNDEFINED; - if (axis == CSS_FLEX_DIRECTION_COLUMN) { + if (isColumnDirection(axis)) { min = node->style.minDimensions[CSS_HEIGHT]; max = node->style.maxDimensions[CSS_HEIGHT]; - } else if (axis == CSS_FLEX_DIRECTION_ROW) { + } else if (isRowDirection(axis)) { min = node->style.minDimensions[CSS_WIDTH]; max = node->style.maxDimensions[CSS_WIDTH]; } @@ -366,6 +423,11 @@ static void setDimensionFromStyle(css_node_t *node, css_flex_direction_t axis) { ); } +static void setTrailingPosition(css_node_t *node, css_node_t *child, css_flex_direction_t axis) { + child->layout.position[trailing[axis]] = node->layout.dimensions[dim[axis]] - + child->layout.dimensions[dim[axis]] - child->layout.position[pos[axis]]; + } + // If both left and right are defined, then use left. Otherwise return // +left or -right depending on which is defined. static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { @@ -376,13 +438,12 @@ 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) { +static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { /** START_GENERATED **/ - - css_flex_direction_t mainAxis = getFlexDirection(node); - css_flex_direction_t crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ? - CSS_FLEX_DIRECTION_COLUMN : - CSS_FLEX_DIRECTION_ROW; + css_direction_t direction = resolveDirection(node, parentDirection); + css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); + css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); + css_flex_direction_t resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); // Handle width and height style attributes setDimensionFromStyle(node, mainAxis); @@ -392,26 +453,30 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // delta composed of the margin and left/top/right/bottom node->layout.position[leading[mainAxis]] += getMargin(node, leading[mainAxis]) + getRelativePosition(node, mainAxis); + node->layout.position[trailing[mainAxis]] += getMargin(node, trailing[mainAxis]) + + getRelativePosition(node, mainAxis); node->layout.position[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + getRelativePosition(node, crossAxis); + node->layout.position[trailing[crossAxis]] += getMargin(node, trailing[crossAxis]) + + getRelativePosition(node, crossAxis); if (isMeasureDefined(node)) { float width = CSS_UNDEFINED; - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + if (isDimDefined(node, resolvedRowAxis)) { width = node->style.dimensions[CSS_WIDTH]; - } else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]])) { - width = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]]; + } else if (!isUndefined(node->layout.dimensions[dim[resolvedRowAxis]])) { + width = node->layout.dimensions[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + width -= getPaddingAndBorderAxis(node, resolvedRowAxis); // 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, CSS_FLEX_DIRECTION_ROW) && - isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]]); + bool isRowUndefined = !isDimDefined(node, resolvedRowAxis) && + isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); bool isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]); @@ -424,7 +489,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { ); if (isRowUndefined) { node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getPaddingAndBorderAxis(node, resolvedRowAxis); } if (isColumnUndefined) { node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + @@ -527,20 +592,20 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { } else { maxWidth = CSS_UNDEFINED; - if (mainAxis != CSS_FLEX_DIRECTION_ROW) { + if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(child, maxWidth); + layoutNode(child, maxWidth, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -626,17 +691,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { ); maxWidth = CSS_UNDEFINED; - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - } else if (mainAxis != CSS_FLEX_DIRECTION_ROW) { + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); + } else if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); } // And we recursively call the layout algorithm for this child - layoutNode(child, maxWidth); + layoutNode(child, maxWidth, direction); } } @@ -689,6 +754,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. child->layout.position[pos[mainAxis]] += mainDim; + + // Define the trailing position accordingly. + if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { + setTrailingPosition(node, child, mainAxis); + } } // Now that we placed the element, we need to update the variables @@ -783,6 +853,12 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) ); + + // Now that the width is defined, we should update the trailing + // positions for the children. + for (i = 0; i < node->children_count; ++i) { + setTrailingPosition(node, node->get_child(node->context, i), mainAxis); + } } if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { @@ -835,8 +911,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { /** END_GENERATED **/ } -void layoutNode(css_node_t *node, float parentMaxWidth) { +void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { css_layout_t *layout = &node->layout; + css_direction_t direction = node->style.direction; layout->should_update = true; bool skipLayout = @@ -844,6 +921,7 @@ void layoutNode(css_node_t *node, float parentMaxWidth) { 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_direction, direction); if (skipLayout) { layout->dimensions[CSS_WIDTH] = layout->last_dimensions[CSS_WIDTH]; @@ -854,8 +932,9 @@ void layoutNode(css_node_t *node, float parentMaxWidth) { 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_direction = direction; - layoutNodeImpl(node, parentMaxWidth); + layoutNodeImpl(node, parentMaxWidth, 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 a75232d6..c07dde72 100644 --- a/src/Layout.h +++ b/src/Layout.h @@ -23,9 +23,17 @@ static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define CSS_UNDEFINED NAN +typedef enum { + CSS_DIRECTION_INHERIT = 0, + CSS_DIRECTION_LTR, + CSS_DIRECTION_RTL +} css_direction_t; + typedef enum { CSS_FLEX_DIRECTION_COLUMN = 0, - CSS_FLEX_DIRECTION_ROW + CSS_FLEX_DIRECTION_COLUMN_REVERSE, + CSS_FLEX_DIRECTION_ROW, + CSS_FLEX_DIRECTION_ROW_REVERSE } css_flex_direction_t; typedef enum { @@ -72,7 +80,7 @@ typedef enum { } css_dimension_t; typedef struct { - float position[2]; + float position[4]; float dimensions[2]; // Instead of recomputing the entire layout every single time, we @@ -82,6 +90,7 @@ typedef struct { float last_parent_max_width; float last_dimensions[2]; float last_position[2]; + css_direction_t last_direction; } css_layout_t; typedef struct { @@ -89,6 +98,7 @@ typedef struct { } css_dim_t; typedef struct { + css_direction_t direction; css_flex_direction_t flex_direction; css_justify_t justify_content; css_align_t align_items; @@ -142,7 +152,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); +void layoutNode(css_node_t *node, float maxWidth, css_direction_t parentDirection); bool isUndefined(float value); #endif diff --git a/src/Layout.js b/src/Layout.js index fd39b4fb..0880c7be 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -11,8 +11,14 @@ var computeLayout = (function() { var CSS_UNDEFINED; + var CSS_DIRECTION_INHERIT = 'inherit'; + var CSS_DIRECTION_LTR = 'ltr'; + var CSS_DIRECTION_RTL = 'rtl'; + var CSS_FLEX_DIRECTION_ROW = 'row'; + var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse'; var CSS_FLEX_DIRECTION_COLUMN = 'column'; + var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse'; // var CSS_JUSTIFY_FLEX_START = 'flex-start'; var CSS_JUSTIFY_CENTER = 'center'; @@ -29,20 +35,28 @@ var computeLayout = (function() { var CSS_POSITION_ABSOLUTE = 'absolute'; var leading = { - row: 'left', - column: 'top' + 'row': 'left', + 'row-reverse': 'right', + 'column': 'top', + 'column-reverse': 'bottom' }; var trailing = { - row: 'right', - column: 'bottom' + 'row': 'right', + 'row-reverse': 'left', + 'column': 'bottom', + 'column-reverse': 'top' }; var pos = { - row: 'left', - column: 'top' + 'row': 'left', + 'row-reverse': 'right', + 'column': 'top', + 'column-reverse': 'bottom' }; var dim = { - row: 'width', - column: 'height' + 'row': 'width', + 'row-reverse': 'width', + 'column': 'height', + 'column-reverse': 'height' }; function capitalizeFirst(str) { @@ -67,7 +81,9 @@ var computeLayout = (function() { width: undefined, height: undefined, top: 0, - left: 0 + left: 0, + right: 0, + bottom: 0 }; if (!node.style) { node.style = {}; @@ -88,6 +104,10 @@ var computeLayout = (function() { } else { delete node.children; } + + delete layout.right; + delete layout.bottom; + return layout; } @@ -154,11 +174,56 @@ var computeLayout = (function() { return 'stretch'; } + function isRowDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_ROW || + flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; + } + + function isColumnDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_COLUMN || + flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; + } + + function resolveAxis(axis, direction) { + if (direction === CSS_DIRECTION_RTL) { + if (axis === CSS_FLEX_DIRECTION_ROW) { + return CSS_FLEX_DIRECTION_ROW_REVERSE; + } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) { + return CSS_FLEX_DIRECTION_ROW; + } + } + + return axis; + } + + function resolveDirection(node, parentDirection) { + var direction; + if ('direction' in node.style) { + direction = node.style.direction; + } else { + direction = CSS_DIRECTION_INHERIT; + } + + if (direction === CSS_DIRECTION_INHERIT) { + direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection); + } + + return direction; + } + function getFlexDirection(node) { if ('flexDirection' in node.style) { return node.style.flexDirection; } - return 'column'; + return CSS_FLEX_DIRECTION_COLUMN; + } + + function getCrossFlexDirection(flexDirection, direction) { + if (isColumnDirection(flexDirection)) { + return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); + } else { + return CSS_FLEX_DIRECTION_COLUMN; + } } function getPositionType(node) { @@ -208,13 +273,17 @@ var computeLayout = (function() { function boundAxis(node, axis, value) { var min = { - row: node.style.minWidth, - column: node.style.minHeight + 'row': node.style.minWidth, + 'row-reverse': node.style.minWidth, + 'column': node.style.minHeight, + 'column-reverse': node.style.minHeight }[axis]; var max = { - row: node.style.maxWidth, - column: node.style.maxHeight + 'row': node.style.maxWidth, + 'row-reverse': node.style.maxWidth, + 'column': node.style.maxHeight, + 'column-reverse': node.style.maxHeight }[axis]; var boundValue = value; @@ -252,6 +321,11 @@ var computeLayout = (function() { ); } + function setTrailingPosition(node, child, axis) { + child.layout[trailing[axis]] = node.layout[dim[axis]] - + child.layout[dim[axis]] - child.layout[pos[axis]]; + } + // If both left and right are defined, then use left. Otherwise return // +left or -right depending on which is defined. function getRelativePosition(node, axis) { @@ -261,12 +335,11 @@ var computeLayout = (function() { return -getPosition(node, trailing[axis]); } - function layoutNode(node, parentMaxWidth) { - - var/*css_flex_direction_t*/ mainAxis = getFlexDirection(node); - var/*css_flex_direction_t*/ crossAxis = mainAxis === CSS_FLEX_DIRECTION_ROW ? - CSS_FLEX_DIRECTION_COLUMN : - CSS_FLEX_DIRECTION_ROW; + function layoutNode(node, parentMaxWidth, /*css_direction_t*/parentDirection) { + var/*css_direction_t*/ direction = resolveDirection(node, parentDirection); + var/*css_flex_direction_t*/ mainAxis = resolveAxis(getFlexDirection(node), direction); + var/*css_flex_direction_t*/ crossAxis = getCrossFlexDirection(mainAxis, direction); + var/*css_flex_direction_t*/ resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); // Handle width and height style attributes setDimensionFromStyle(node, mainAxis); @@ -276,26 +349,30 @@ var computeLayout = (function() { // delta composed of the margin and left/top/right/bottom node.layout[leading[mainAxis]] += getMargin(node, leading[mainAxis]) + getRelativePosition(node, mainAxis); + node.layout[trailing[mainAxis]] += getMargin(node, trailing[mainAxis]) + + getRelativePosition(node, mainAxis); node.layout[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + getRelativePosition(node, crossAxis); + node.layout[trailing[crossAxis]] += getMargin(node, trailing[crossAxis]) + + getRelativePosition(node, crossAxis); if (isMeasureDefined(node)) { var/*float*/ width = CSS_UNDEFINED; - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + if (isDimDefined(node, resolvedRowAxis)) { width = node.style.width; - } else if (!isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_ROW]])) { - width = node.layout[dim[CSS_FLEX_DIRECTION_ROW]]; + } else if (!isUndefined(node.layout[dim[resolvedRowAxis]])) { + width = node.layout[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + width -= getPaddingAndBorderAxis(node, resolvedRowAxis); // 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, CSS_FLEX_DIRECTION_ROW) && - isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_ROW]]); + var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && + isUndefined(node.layout[dim[resolvedRowAxis]]); var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]); @@ -308,7 +385,7 @@ var computeLayout = (function() { ); if (isRowUndefined) { node.layout.width = measureDim.width + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getPaddingAndBorderAxis(node, resolvedRowAxis); } if (isColumnUndefined) { node.layout.height = measureDim.height + @@ -411,20 +488,20 @@ var computeLayout = (function() { } else { maxWidth = CSS_UNDEFINED; - if (mainAxis !== CSS_FLEX_DIRECTION_ROW) { + if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node.layout[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout === 0) { - layoutNode(/*(java)!layoutContext, */child, maxWidth); + layoutNode(/*(java)!layoutContext, */child, maxWidth, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -510,17 +587,17 @@ var computeLayout = (function() { ); maxWidth = CSS_UNDEFINED; - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - } else if (mainAxis !== CSS_FLEX_DIRECTION_ROW) { + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node.layout[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); + } else if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); } // And we recursively call the layout algorithm for this child - layoutNode(/*(java)!layoutContext, */child, maxWidth); + layoutNode(/*(java)!layoutContext, */child, maxWidth, direction); } } @@ -573,6 +650,11 @@ var computeLayout = (function() { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. child.layout[pos[mainAxis]] += mainDim; + + // Define the trailing position accordingly. + if (!isUndefined(node.layout[dim[mainAxis]])) { + setTrailingPosition(node, child, mainAxis); + } } // Now that we placed the element, we need to update the variables @@ -667,6 +749,12 @@ var computeLayout = (function() { // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) ); + + // Now that the width is defined, we should update the trailing + // positions for the children. + for (i = 0; i < node.children.length; ++i) { + setTrailingPosition(node, node.children[i], mainAxis); + } } if (isUndefined(node.layout[dim[crossAxis]])) { diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index c1bb8ff5..6560e7d5 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -86,6 +86,59 @@ int main() test("should layout node with children", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 500; + node_1->style.dimensions[CSS_HEIGHT] = 500; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 250; + node_1->style.dimensions[CSS_HEIGHT] = 250; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.dimensions[CSS_WIDTH] = 125; + node_1->style.dimensions[CSS_HEIGHT] = 125; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 500; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 500; + node_1->layout.dimensions[CSS_HEIGHT] = 500; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 250; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 250; + node_1->layout.dimensions[CSS_HEIGHT] = 250; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 125; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 125; + node_1->layout.dimensions[CSS_HEIGHT] = 125; + } + } + + test("should layout node with children in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -154,6 +207,76 @@ int main() test("should layout node with nested children", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 500; + node_1->style.dimensions[CSS_HEIGHT] = 500; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; + node_1->style.dimensions[CSS_WIDTH] = 500; + node_1->style.dimensions[CSS_HEIGHT] = 500; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.dimensions[CSS_WIDTH] = 250; + node_2->style.dimensions[CSS_HEIGHT] = 250; + node_2 = node_1->get_child(node_1->context, 1); + node_2->style.dimensions[CSS_WIDTH] = 250; + node_2->style.dimensions[CSS_HEIGHT] = 250; + } + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 500; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 500; + node_1->layout.dimensions[CSS_HEIGHT] = 500; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 500; + node_1->layout.dimensions[CSS_HEIGHT] = 500; + 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] = 250; + node_2->layout.position[CSS_LEFT] = 0; + node_2->layout.dimensions[CSS_WIDTH] = 250; + node_2->layout.dimensions[CSS_HEIGHT] = 250; + node_2 = node_1->get_child(node_1->context, 1); + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 0; + node_2->layout.dimensions[CSS_WIDTH] = 250; + node_2->layout.dimensions[CSS_HEIGHT] = 250; + } + } + } + + test("should layout node with nested children in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -246,6 +369,121 @@ int main() test("should layout node with several children", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + node_0->style.margin[CSS_LEFT] = 10; + node_0->style.margin[CSS_TOP] = 10; + node_0->style.margin[CSS_RIGHT] = 10; + node_0->style.margin[CSS_BOTTOM] = 10; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.margin[CSS_LEFT] = 50; + node_1->style.margin[CSS_TOP] = 50; + node_1->style.margin[CSS_RIGHT] = 50; + node_1->style.margin[CSS_BOTTOM] = 50; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.margin[CSS_LEFT] = 25; + node_1->style.margin[CSS_TOP] = 25; + node_1->style.margin[CSS_RIGHT] = 25; + node_1->style.margin[CSS_BOTTOM] = 25; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.margin[CSS_LEFT] = 10; + node_1->style.margin[CSS_TOP] = 10; + node_1->style.margin[CSS_RIGHT] = 10; + node_1->style.margin[CSS_BOTTOM] = 10; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 10; + node_0->layout.position[CSS_LEFT] = 10; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 850; + node_1->layout.position[CSS_LEFT] = 50; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 675; + node_1->layout.position[CSS_LEFT] = 25; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 540; + node_1->layout.position[CSS_LEFT] = 10; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with several children in reverse", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 300; + node_1->style.dimensions[CSS_HEIGHT] = 150; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 100; + node_1->layout.dimensions[CSS_WIDTH] = 300; + node_1->layout.dimensions[CSS_HEIGHT] = 150; + } + } + + test("should layout rtl with reverse correctly", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -291,6 +529,52 @@ int main() test("should layout node with row flex direction", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 300; + node_1->style.dimensions[CSS_HEIGHT] = 150; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 900; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 600; + node_1->layout.dimensions[CSS_WIDTH] = 300; + node_1->layout.dimensions[CSS_HEIGHT] = 150; + } + } + + test("should layout node with row flex direction in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -334,6 +618,50 @@ int main() test("should layout node based on children main dimensions", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 300; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 300; + node_1->style.dimensions[CSS_HEIGHT] = 150; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 350; + 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] = 150; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 300; + node_1->layout.dimensions[CSS_HEIGHT] = 150; + } + } + + test("should layout node based on children main dimensions in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -378,6 +706,51 @@ int main() test("should layout node with just flex", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.dimensions[CSS_WIDTH] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 800; + } + } + + test("should layout node with just flex in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -446,6 +819,78 @@ int main() test("should layout node with flex recursively", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; + node_1->style.flex = 1; + node_1->style.dimensions[CSS_WIDTH] = 1000; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; + node_2->style.flex = 1; + node_2->style.dimensions[CSS_WIDTH] = 1000; + init_css_node_children(node_2, 1); + { + css_node_t *node_3; + node_3 = node_2->get_child(node_2->context, 0); + node_3->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; + node_3->style.flex = 1; + node_3->style.dimensions[CSS_WIDTH] = 1000; + } + } + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 1000; + node_1->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_1, 1); + { + 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] = 1000; + node_2->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_2, 1); + { + css_node_t *node_3; + node_3 = node_2->get_child(node_2->context, 0); + node_3->layout.position[CSS_TOP] = 0; + node_3->layout.position[CSS_LEFT] = 0; + node_3->layout.dimensions[CSS_WIDTH] = 1000; + node_3->layout.dimensions[CSS_HEIGHT] = 1000; + } + } + } + } + + test("should layout node with flex recursively in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -496,6 +941,57 @@ int main() test("should layout node with targeted margin", 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_REVERSE; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + node_0->style.margin[CSS_LEFT] = 5; + node_0->style.margin[CSS_TOP] = 10; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.margin[CSS_LEFT] = 15; + node_1->style.margin[CSS_TOP] = 50; + node_1->style.margin[CSS_BOTTOM] = 20; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.margin[CSS_LEFT] = 30; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 10; + node_0->layout.position[CSS_LEFT] = 5; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 880; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 730; + node_1->layout.position[CSS_LEFT] = 30; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with targeted margin in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -541,6 +1037,52 @@ int main() test("should layout node with justifyContent: flex-start", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_FLEX_START; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with justifyContent: flex-start in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -586,6 +1128,52 @@ int main() test("should layout node with justifyContent: flex-end", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with justifyContent: flex-end in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -631,6 +1219,52 @@ int main() test("should layout node with justifyContent: space-between", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with justifyContent: space-between in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -676,6 +1310,52 @@ int main() test("should layout node with justifyContent: space-around", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 700; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 200; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with justifyContent: space-around in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -721,6 +1401,52 @@ int main() test("should layout node with justifyContent: center", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_CENTER; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 500; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 400; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with justifyContent: center in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -803,6 +1529,52 @@ int main() test("should layout node with alignItems: flex-start", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_FLEX_START; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 200; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with alignItems: flex-start in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -848,6 +1620,52 @@ int main() test("should layout node with alignItems: center", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_CENTER; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 200; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 400; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 450; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with alignItems: center in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -893,6 +1711,52 @@ int main() test("should layout node with alignItems: flex-end", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_FLEX_END; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 200; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 800; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 900; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with alignItems: flex-end in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -939,6 +1803,53 @@ int main() test("should layout node with alignSelf overrides alignItems", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_FLEX_END; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 200; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.align_self = CSS_ALIGN_CENTER; + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 800; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 800; + node_1->layout.position[CSS_LEFT] = 450; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with alignSelf overrides alignItems in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -975,6 +1886,43 @@ int main() test("should layout node with alignItem: stretch", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_STRETCH; + node_0->style.dimensions[CSS_WIDTH] = 1000; + node_0->style.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 1000; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 900; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 1000; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should layout node with alignItem: stretch in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1007,6 +1955,39 @@ int main() test("should layout empty node", 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_REVERSE; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + } + } + + 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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout empty node in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1043,6 +2024,43 @@ int main() test("should layout child with margin", 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_REVERSE; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.margin[CSS_LEFT] = 5; + node_1->style.margin[CSS_TOP] = 5; + node_1->style.margin[CSS_RIGHT] = 5; + node_1->style.margin[CSS_BOTTOM] = 5; + } + } + + 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] = 10; + node_0->layout.dimensions[CSS_HEIGHT] = 10; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 5; + node_1->layout.position[CSS_LEFT] = 5; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout child with margin in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1084,6 +2102,48 @@ int main() test("should not shrink children if not enough space", 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_REVERSE; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_HEIGHT] = 200; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + 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] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = -200; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should not shrink children if not enough space in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1138,6 +2198,42 @@ int main() test("should layout flex-end taking into account margin", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.margin[CSS_TOP] = 10; + } + } + + 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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 10; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout flex-end taking into account margin in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1196,6 +2292,65 @@ int main() test("should layout alignItems with margin", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; + node_1->style.align_items = CSS_ALIGN_FLEX_END; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.margin[CSS_LEFT] = 10; + node_2->style.margin[CSS_TOP] = 10; + node_2->style.margin[CSS_RIGHT] = 10; + node_2->style.margin[CSS_BOTTOM] = 10; + node_2 = node_1->get_child(node_1->context, 1); + node_2->style.dimensions[CSS_HEIGHT] = 100; + } + } + } + + 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] = 20; + node_0->layout.dimensions[CSS_HEIGHT] = 120; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 20; + node_1->layout.dimensions[CSS_HEIGHT] = 120; + 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] = 110; + node_2->layout.position[CSS_LEFT] = 10; + node_2->layout.dimensions[CSS_WIDTH] = 0; + node_2->layout.dimensions[CSS_HEIGHT] = 0; + node_2 = node_1->get_child(node_1->context, 1); + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 20; + node_2->layout.dimensions[CSS_WIDTH] = 0; + node_2->layout.dimensions[CSS_HEIGHT] = 100; + } + } + } + + test("should layout alignItems with margin in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -1263,6 +2418,41 @@ int main() test("should layout alignItems stretch and margin", 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_REVERSE; + node_0->style.align_items = CSS_ALIGN_STRETCH; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.margin[CSS_LEFT] = 10; + } + } + + 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] = 10; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 10; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout alignItems stretch and margin in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2026,6 +3216,48 @@ int main() test("should layout node with space-around and child position absolute", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1 = node_0->get_child(node_0->context, 1); + } + } + + 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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + 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] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout node with space-around and child position absolute in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2062,6 +3294,43 @@ int main() test("should layout node with flex and main margin", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 700; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1->style.margin[CSS_RIGHT] = 5; + } + } + + 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] = 700; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 695; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout node with flex and main margin in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2105,6 +3374,50 @@ int main() test("should layout node with multiple flex and padding", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 700; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.padding[CSS_LEFT] = 5; + } + } + + 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] = 700; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + 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] = 352.5; + node_1->layout.dimensions[CSS_WIDTH] = 347.5; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 352.5; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout node with multiple flex and padding in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2148,6 +3461,50 @@ int main() test("should layout node with multiple flex and margin", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 700; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.margin[CSS_RIGHT] = 5; + } + } + + 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] = 700; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + 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] = 352.5; + node_1->layout.dimensions[CSS_WIDTH] = 347.5; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 347.5; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout node with multiple flex and margin in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2225,6 +3582,43 @@ int main() test("should layout node with flex and position absolute", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 600; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.flex = 1; + } + } + + 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] = 600; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 600; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout node with flex and position absolute in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2470,6 +3864,42 @@ int main() test("should handle negative margin and min padding correctly", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.border[CSS_LEFT] = 1; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.margin[CSS_LEFT] = -8; + } + } + + 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] = 1; + node_0->layout.dimensions[CSS_HEIGHT] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 1; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should handle negative margin and min padding correctly in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2631,6 +4061,58 @@ int main() test("should layout node with text and flex", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.direction = CSS_DIRECTION_RTL; + node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_1->style.dimensions[CSS_WIDTH] = 500; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.flex = 1; + node_2->measure = measure; + node_2->context = "loooooooooong with space"; + } + } + } + + 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] = 500; + node_0->layout.dimensions[CSS_HEIGHT] = 18; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 500; + node_1->layout.dimensions[CSS_HEIGHT] = 18; + init_css_node_children(node_1, 1); + { + 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] = 500; + node_2->layout.dimensions[CSS_HEIGHT] = 18; + } + } + } + + test("should layout node with text and flex in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2871,6 +4353,48 @@ int main() test("should layout space-between when remaining space is negative", 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_REVERSE; + node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 900; + node_1 = node_0->get_child(node_0->context, 1); + } + } + + 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] = 0; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + 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] = -800; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 900; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = -800; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout space-between when remaining space is negative in reverse", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2907,6 +4431,43 @@ int main() test("should layout flex-end when remaining space is negative", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; + node_0->style.dimensions[CSS_WIDTH] = 200; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 900; + } + } + + 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] = 0; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 900; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout flex-end when remaining space is negative in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -2961,6 +4522,61 @@ int main() test("should layout text with flexDirection row", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_1->style.dimensions[CSS_WIDTH] = 200; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.margin[CSS_LEFT] = 20; + node_2->style.margin[CSS_TOP] = 20; + node_2->style.margin[CSS_RIGHT] = 20; + node_2->style.margin[CSS_BOTTOM] = 20; + node_2->measure = measure; + node_2->context = "loooooooooong with space"; + } + } + } + + 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] = 58; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 58; + init_css_node_children(node_1, 1); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->layout.position[CSS_TOP] = 20; + node_2->layout.position[CSS_LEFT] = 7.578125; + node_2->layout.dimensions[CSS_WIDTH] = 172.421875; + node_2->layout.dimensions[CSS_HEIGHT] = 18; + } + } + } + + test("should layout text with flexDirection row in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -3102,6 +4718,53 @@ int main() 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_REVERSE; + node_0->style.align_self = CSS_ALIGN_FLEX_START; + node_0->style.dimensions[CSS_WIDTH] = 100; + node_0->style.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.align_self = CSS_ALIGN_FLEX_START; + node_1->style.flex = 2.5; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.align_self = CSS_ALIGN_FLEX_START; + node_1->style.flex = 7.5; + } + } + + 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; + 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] = 75; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 25; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 75; + } + } + + test("should layout with arbitrary flex in reverse", 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_REVERSE; node_0->style.align_self = CSS_ALIGN_FLEX_START; node_0->style.dimensions[CSS_WIDTH] = 100; node_0->style.dimensions[CSS_HEIGHT] = 100; @@ -3128,19 +4791,19 @@ int main() { 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_TOP] = 100; node_1->layout.position[CSS_LEFT] = 0; node_1->layout.dimensions[CSS_WIDTH] = 0; node_1->layout.dimensions[CSS_HEIGHT] = 0; node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_TOP] = 100; node_1->layout.position[CSS_LEFT] = 0; node_1->layout.dimensions[CSS_WIDTH] = 0; node_1->layout.dimensions[CSS_HEIGHT] = 0; } } - test("should layout with negative flex", root_node, root_layout); + test("should layout with negative flex in reverse", root_node, root_layout); } { @@ -3727,6 +5390,60 @@ int main() test("should layout flex-wrap", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.flex_wrap = CSS_WRAP; + node_0->style.dimensions[CSS_WIDTH] = 100; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 40; + node_1->style.dimensions[CSS_HEIGHT] = 10; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 40; + node_1->style.dimensions[CSS_HEIGHT] = 10; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.dimensions[CSS_WIDTH] = 40; + node_1->style.dimensions[CSS_HEIGHT] = 10; + } + } + + 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] = 20; + init_css_node_children(node_0, 3); + { + 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] = 60; + node_1->layout.dimensions[CSS_WIDTH] = 40; + node_1->layout.dimensions[CSS_HEIGHT] = 10; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 20; + node_1->layout.dimensions[CSS_WIDTH] = 40; + node_1->layout.dimensions[CSS_HEIGHT] = 10; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 10; + node_1->layout.position[CSS_LEFT] = 60; + node_1->layout.dimensions[CSS_WIDTH] = 40; + node_1->layout.dimensions[CSS_HEIGHT] = 10; + } + } + + test("should layout flex-wrap in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4004,6 +5721,58 @@ int main() test("should override flex direction size with min bounds", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 300; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSS_WIDTH] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.flex = 1; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + 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] = 250; + node_1->layout.dimensions[CSS_WIDTH] = 50; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 50; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 50; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should override flex direction size with min bounds in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4056,6 +5825,59 @@ int main() test("should not override flex direction size within bounds", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 300; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSS_WIDTH] = 110; + node_1->style.minDimensions[CSS_WIDTH] = 90; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.flex = 1; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 200; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 100; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should not override flex direction size within bounds in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4107,6 +5929,58 @@ int main() test("should override flex direction size with max bounds", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 300; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSS_WIDTH] = 60; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.flex = 1; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + 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] = 180; + node_1->layout.dimensions[CSS_WIDTH] = 120; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 120; + node_1->layout.dimensions[CSS_WIDTH] = 60; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 120; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should override flex direction size with max bounds in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4160,6 +6034,60 @@ int main() test("should ignore flex size if fully max bound", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 300; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSS_WIDTH] = 60; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSS_WIDTH] = 60; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSS_WIDTH] = 60; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + 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] = 240; + node_1->layout.dimensions[CSS_WIDTH] = 60; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 180; + node_1->layout.dimensions[CSS_WIDTH] = 60; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 120; + node_1->layout.dimensions[CSS_WIDTH] = 60; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should ignore flex size if fully max bound in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4213,6 +6141,60 @@ int main() test("should ignore flex size if fully min bound", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 300; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex = 1; + node_1->style.minDimensions[CSS_WIDTH] = 120; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSS_WIDTH] = 120; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.flex = 1; + node_1->style.minDimensions[CSS_WIDTH] = 120; + } + } + + 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] = 300; + node_0->layout.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 3); + { + 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] = 180; + node_1->layout.dimensions[CSS_WIDTH] = 120; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 60; + node_1->layout.dimensions[CSS_WIDTH] = 120; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = -60; + node_1->layout.dimensions[CSS_WIDTH] = 120; + node_1->layout.dimensions[CSS_HEIGHT] = 200; + } + } + + test("should ignore flex size if fully min bound in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4606,6 +6588,44 @@ int main() test("should keep cross axis size within min bounds", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.dimensions[CSS_WIDTH] = 1000; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1->style.minDimensions[CSS_WIDTH] = 100; + node_1->style.minDimensions[CSS_HEIGHT] = 110; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 110; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 900; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 110; + } + } + + test("should keep cross axis size within min bounds in rtl", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4873,6 +6893,98 @@ int main() test("should layout absolutely positioned node with padded flex 1 parent", root_node, root_layout); } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.dimensions[CSS_WIDTH] = 200; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.dimensions[CSS_WIDTH] = 50; + node_2->style.dimensions[CSS_HEIGHT] = 50; + node_2 = node_1->get_child(node_1->context, 1); + node_2->style.dimensions[CSS_WIDTH] = 50; + node_2->style.dimensions[CSS_HEIGHT] = 50; + } + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.direction = CSS_DIRECTION_LTR; + node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + init_css_node_children(node_1, 2); + { + css_node_t *node_2; + node_2 = node_1->get_child(node_1->context, 0); + node_2->style.dimensions[CSS_WIDTH] = 50; + node_2->style.dimensions[CSS_HEIGHT] = 50; + node_2 = node_1->get_child(node_1->context, 1); + node_2->style.dimensions[CSS_WIDTH] = 50; + node_2->style.dimensions[CSS_HEIGHT] = 50; + } + } + } + + 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] = 200; + 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] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + 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] = 150; + node_2->layout.dimensions[CSS_WIDTH] = 50; + node_2->layout.dimensions[CSS_HEIGHT] = 50; + node_2 = node_1->get_child(node_1->context, 1); + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 100; + node_2->layout.dimensions[CSS_WIDTH] = 50; + node_2->layout.dimensions[CSS_HEIGHT] = 50; + } + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 50; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 200; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + 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] = 50; + node_2->layout.dimensions[CSS_HEIGHT] = 50; + node_2 = node_1->get_child(node_1->context, 1); + node_2->layout.position[CSS_TOP] = 0; + node_2->layout.position[CSS_LEFT] = 50; + node_2->layout.dimensions[CSS_WIDTH] = 50; + node_2->layout.dimensions[CSS_HEIGHT] = 50; + } + } + } + + test("should layout nested nodes with mixed directions", root_node, root_layout); + } /** END_GENERATED **/ return tests_finished(); } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index f0bb41e4..b23f52fb 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -19,14 +19,14 @@ describe('Javascript Only', function() { it('should fill root node with layout, style, and children', function() { testFillNodes( {}, - {layout: {width: undefined, height: undefined, top: 0, left: 0}, style: {}, children: []} + {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: []} ); }); it('should fill root and child node with layout, style, and children', function() { testFillNodes( {children: [{}]}, - {layout: {width: undefined, height: undefined, top: 0, left: 0}, style: {}, children: [ - {layout: {width: undefined, height: undefined, top: 0, left: 0}, style: {}, children: []} + {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: [ + {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: []} ]} ); }); @@ -46,9 +46,9 @@ describe('Javascript Only', function() { ]} ); }); - }); + describe('Layout', function() { it('should layout a single node with width and height', function() { testLayout({ @@ -73,6 +73,21 @@ describe('Layout', function() { ); }); + it('should layout node with children in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ + {style: {width: 500, height: 500}}, + {style: {width: 250, height: 250}}, + {style: {width: 125, height: 125}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 500, height: 500, top: 500, left: 0}, + {width: 250, height: 250, top: 250, left: 0}, + {width: 125, height: 125, top: 125, left: 0} + ]} + ); + }); + it('should layout node with nested children', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ @@ -92,6 +107,25 @@ describe('Layout', function() { ); }); + it('should layout node with nested children in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ + {style: {width: 500, height: 500}}, + {style: {width: 500, height: 500, flexDirection: 'column-reverse'}, children: [ + {style: {width: 250, height: 250}}, + {style: {width: 250, height: 250}} + ]} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 500, height: 500, top: 500, left: 0}, + {width: 500, height: 500, top: 0, left: 0, children: [ + {width: 250, height: 250, top: 250, left: 0}, + {width: 250, height: 250, top: 0, left: 0} + ]} + ]} + ); + }); + it('should layout node with margin', function() { testLayout( {style: {width: 100, height: 200, margin: 10}}, @@ -114,6 +148,34 @@ describe('Layout', function() { ); }); + it('should layout node with several children in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', margin: 10}, children: [ + {style: {width: 100, height: 100, margin: 50}}, + {style: {width: 100, height: 100, margin: 25}}, + {style: {width: 100, height: 100, margin: 10}} + ]}, + {width: 1000, height: 1000, top: 10, left: 10, children: [ + {width: 100, height: 100, top: 850, left: 50}, + {width: 100, height: 100, top: 675, left: 25}, + {width: 100, height: 100, top: 540, left: 10} + ]} + ); + }); + + it('should layout rtl with reverse correctly', function() { + testLayout( + {style: {width: 1000, height: 1000, direction: 'rtl', flexDirection: 'row-reverse'}, children: [ + {style: {width: 100, height: 200}}, + {style: {width: 300, height: 150}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 200, top: 0, left: 0}, + {width: 300, height: 150, top: 0, left: 100} + ]} + ); + }); + it('should layout node with row flex direction', function() { testLayout( {style: {width: 1000, height: 1000, flexDirection: 'row'}, children: [ @@ -127,6 +189,19 @@ describe('Layout', function() { ); }); + it('should layout node with row flex direction in rtl', function() { + testLayout( + {style: {width: 1000, height: 1000, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {width: 100, height: 200}}, + {style: {width: 300, height: 150}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 200, top: 0, left: 900}, + {width: 300, height: 150, top: 0, left: 600} + ]} + ); + }); + it('should layout node based on children main dimensions', function() { testLayout( {style: {width: 300}, children: [ @@ -140,6 +215,19 @@ describe('Layout', function() { ); }); + it('should layout node based on children main dimensions in reverse', function() { + testLayout( + {style: {width: 300, flexDirection: 'column-reverse'}, children: [ + {style: {width: 100, height: 200}}, + {style: {width: 300, height: 150}} + ]}, + {width: 300, height: 350, top: 0, left: 0, children: [ + {width: 100, height: 200, top: 150, left: 0}, + {width: 300, height: 150, top: 0, left: 0} + ]} + ); + }); + it('should layout node with just flex', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ @@ -153,6 +241,19 @@ describe('Layout', function() { ); }); + it('should layout node with just flex in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ + {style: {width: 100, height: 200}}, + {style: {width: 100, flex: 1}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 200, top: 800, left: 0}, + {width: 100, height: 800, top: 0, left: 0} + ]} + ); + }); + it('should layout node with flex recursively', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ @@ -172,6 +273,25 @@ describe('Layout', function() { ); }); + it('should layout node with flex recursively in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ + {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}, children: [ + {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}, children: [ + {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}} + ]} + ]} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 1000, height: 1000, top: 0, left: 0} + ]} + ]} + ]} + ); + }); + it('should layout node with targeted margin', function() { testLayout( {style: {width: 1000, height: 1000, marginTop: 10, marginLeft: 5}, children: [ @@ -185,6 +305,19 @@ describe('Layout', function() { ); }); + it('should layout node with targeted margin in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', marginTop: 10, marginLeft: 5}, children: [ + {style: {width: 100, height: 100, marginTop: 50, marginLeft: 15, marginBottom: 20}}, + {style: {width: 100, height: 100, marginLeft: 30}} + ]}, + {width: 1000, height: 1000, top: 10, left: 5, children: [ + {width: 100, height: 100, top: 880, left: 15}, + {width: 100, height: 100, top: 730, left: 30} + ]} + ); + }); + it('should layout node with justifyContent: flex-start', function() { testLayout( {style: {width: 1000, height: 1000, justifyContent: 'flex-start'}, children: [ @@ -198,6 +331,19 @@ describe('Layout', function() { ); }); + it('should layout node with justifyContent: flex-start in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'flex-start'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 900, left: 0}, + {width: 100, height: 100, top: 800, left: 0} + ]} + ); + }); + it('should layout node with justifyContent: flex-end', function() { testLayout( {style: {width: 1000, height: 1000, justifyContent: 'flex-end'}, children: [ @@ -211,6 +357,19 @@ describe('Layout', function() { ); }); + it('should layout node with justifyContent: flex-end in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'flex-end'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 100, left: 0}, + {width: 100, height: 100, top: 0, left: 0} + ]} + ); + }); + it('should layout node with justifyContent: space-between', function() { testLayout( {style: {width: 1000, height: 1000, justifyContent: 'space-between'}, children: [ @@ -224,6 +383,19 @@ describe('Layout', function() { ); }); + it('should layout node with justifyContent: space-between in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'space-between'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 900, left: 0}, + {width: 100, height: 100, top: 0, left: 0} + ]} + ); + }); + it('should layout node with justifyContent: space-around', function() { testLayout( {style: {width: 1000, height: 1000, justifyContent: 'space-around'}, children: [ @@ -237,6 +409,19 @@ describe('Layout', function() { ); }); + it('should layout node with justifyContent: space-around in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'space-around'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 700, left: 0}, + {width: 100, height: 100, top: 200, left: 0} + ]} + ); + }); + it('should layout node with justifyContent: center', function() { testLayout( {style: {width: 1000, height: 1000, justifyContent: 'center'}, children: [ @@ -250,6 +435,19 @@ describe('Layout', function() { ); }); + it('should layout node with justifyContent: center in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'center'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 500, left: 0}, + {width: 100, height: 100, top: 400, left: 0} + ]} + ); + }); + it('should layout node with flex override height', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ @@ -274,6 +472,19 @@ describe('Layout', function() { ); }); + it('should layout node with alignItems: flex-start in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-start'}, children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 200, height: 100, top: 900, left: 0}, + {width: 100, height: 100, top: 800, left: 0} + ]} + ); + }); + it('should layout node with alignItems: center', function() { testLayout( {style: {width: 1000, height: 1000, alignItems: 'center'}, children: [ @@ -287,6 +498,19 @@ describe('Layout', function() { ); }); + it('should layout node with alignItems: center in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'center'}, children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 200, height: 100, top: 900, left: 400}, + {width: 100, height: 100, top: 800, left: 450} + ]} + ); + }); + it('should layout node with alignItems: flex-end', function() { testLayout( {style: {width: 1000, height: 1000, alignItems: 'flex-end'}, children: [ @@ -300,6 +524,19 @@ describe('Layout', function() { ); }); + it('should layout node with alignItems: flex-end in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 200, height: 100, top: 900, left: 800}, + {width: 100, height: 100, top: 800, left: 900} + ]} + ); + }); + it('should layout node with alignSelf overrides alignItems', function() { testLayout( {style: {width: 1000, height: 1000, alignItems: 'flex-end'}, children: [ @@ -313,6 +550,19 @@ describe('Layout', function() { ); }); + it('should layout node with alignSelf overrides alignItems in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ + {style: {width: 200, height: 100}}, + {style: {width: 100, height: 100, alignSelf: 'center'}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 200, height: 100, top: 900, left: 800}, + {width: 100, height: 100, top: 800, left: 450} + ]} + ); + }); + it('should layout node with alignItem: stretch', function() { testLayout( {style: {width: 1000, height: 1000, alignItems: 'stretch'}, children: [ @@ -324,6 +574,17 @@ describe('Layout', function() { ); }); + it('should layout node with alignItem: stretch in reverse', function() { + testLayout( + {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'stretch'}, children: [ + {style: {height: 100}} + ]}, + {width: 1000, height: 1000, top: 0, left: 0, children: [ + {width: 1000, height: 100, top: 900, left: 0} + ]} + ); + }); + it('should layout empty node', function() { testLayout( {style: {}, children: [ @@ -335,6 +596,17 @@ describe('Layout', function() { ); }); + it('should layout empty node in reverse', function() { + testLayout( + {style: {flexDirection: 'column-reverse'}, children: [ + {style: {}} + ]}, + {width: 0, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 0, left: 0} + ]} + ); + }); + it('should layout child with margin', function() { testLayout( {style: {}, children: [ @@ -346,6 +618,17 @@ describe('Layout', function() { ); }); + it('should layout child with margin in reverse', function() { + testLayout( + {style: {flexDirection: 'column-reverse'}, children: [ + {style: {margin: 5}} + ]}, + {width: 10, height: 10, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 5, left: 5} + ]} + ); + }); + it('should not shrink children if not enough space', function() { testLayout( {style: {height: 100}, children: [ @@ -359,6 +642,19 @@ describe('Layout', function() { ); }); + it('should not shrink children if not enough space in reverse', function() { + testLayout( + {style: {height: 100, flexDirection: 'column-reverse'}, children: [ + {style: {height: 100}}, + {style: {height: 200}} + ]}, + {width: 0, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 100, top: 0, left: 0}, + {width: 0, height: 200, top: -200, left: 0} + ]} + ); + }); + it('should layout for center', function() { testLayout( {style: {justifyContent: 'center'}}, @@ -377,6 +673,17 @@ describe('Layout', function() { ); }); + it('should layout flex-end taking into account margin in reverse', function() { + testLayout( + {style: {height: 100, flexDirection: 'column-reverse', justifyContent: 'flex-end'}, children: [ + {style: {marginTop: 10}} + ]}, + {width: 0, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 10, left: 0} + ]} + ); + }); + it('should layout alignItems with margin', function() { testLayout( {style: {}, children: [ @@ -394,6 +701,23 @@ describe('Layout', function() { ); }); + it('should layout alignItems with margin in reverse', function() { + testLayout( + {style: {}, children: [ + {style: {flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ + {style: {margin: 10}}, + {style: {height: 100}} + ]} + ]}, + {width: 20, height: 120, top: 0, left: 0, children: [ + {width: 20, height: 120, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 110, left: 10}, + {width: 0, height: 100, top: 0, left: 20} + ]} + ]} + ); + }); + it('should layout flex inside of an empty element', function() { testLayout( {style: {}, children: [ @@ -416,6 +740,17 @@ describe('Layout', function() { ); }); + it('should layout alignItems stretch and margin in reverse', function() { + testLayout( + {style: {flexDirection: 'column-reverse', alignItems: 'stretch'}, children: [ + {style: {marginLeft: 10}} + ]}, + {width: 10, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 0, left: 10} + ]} + ); + }); + it('should layout node with padding', function() { testLayout( {style: {padding: 5}}, @@ -652,6 +987,19 @@ describe('Layout', function() { ); }); + it('should layout node with space-around and child position absolute in reverse', function() { + testLayout( + {style: {height: 200, flexDirection: 'column-reverse', justifyContent: 'space-around'}, children: [ + {style: {position: 'absolute'}}, + {style: {}} + ]}, + {width: 0, height: 200, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 100, left: 0}, + {width: 0, height: 0, top: 100, left: 0} + ]} + ); + }); + it('should layout node with flex and main margin', function() { testLayout( {style: {width: 700, flexDirection: 'row'}, children: [ @@ -663,6 +1011,17 @@ describe('Layout', function() { ); }); + it('should layout node with flex and main margin in rtl', function() { + testLayout( + {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {marginRight: 5, flex: 1}} + ]}, + {width: 700, height: 0, top: 0, left: 0, children: [ + {width: 695, height: 0, top: 0, left: 0} + ]} + ); + }); + it('should layout node with multiple flex and padding', function() { testLayout( {style: {width: 700, flexDirection: 'row'}, children: [ @@ -676,6 +1035,19 @@ describe('Layout', function() { ); }); + it('should layout node with multiple flex and padding in rtl', function() { + testLayout( + {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1}}, + {style: {paddingLeft: 5, flex: 1}} + ]}, + {width: 700, height: 0, top: 0, left: 0, children: [ + {width: 347.5, height: 0, top: 0, left: 352.5}, + {width: 352.5, height: 0, top: 0, left: 0} + ]} + ); + }); + it('should layout node with multiple flex and margin', function() { testLayout( {style: {width: 700, flexDirection: 'row'}, children: [ @@ -689,6 +1061,19 @@ describe('Layout', function() { ); }); + it('should layout node with multiple flex and margin in rtl', function() { + testLayout( + {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1}}, + {style: {marginRight: 5, flex: 1}} + ]}, + {width: 700, height: 0, top: 0, left: 0, children: [ + {width: 347.5, height: 0, top: 0, left: 352.5}, + {width: 347.5, height: 0, top: 0, left: 0} + ]} + ); + }); + it('should layout node with flex and overflow', function() { testLayout( {style: {height: 300}, children: [ @@ -713,6 +1098,17 @@ describe('Layout', function() { ); }); + it('should layout node with flex and position absolute in rtl', function() { + testLayout( + {style: {width: 600, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1, position: 'absolute'}} + ]}, + {width: 600, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 0, left: 600} + ]} + ); + }); + it('should layout node with double flex and position absolute', function() { testLayout( {style: {height: 500}, children: [ @@ -788,6 +1184,17 @@ describe('Layout', function() { ); }); + it('should handle negative margin and min padding correctly in rtl', function() { + testLayout( + {style: {borderLeftWidth: 1, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {marginLeft: -8}} + ]}, + {width: 1, height: 0, top: 0, left: 0, children: [ + {width: 0, height: 0, top: 0, left: 1} + ]} + ); + }); + it('should layout node with just text', function() { testLayout( {style: {measure: text(texts.small)}}, @@ -839,6 +1246,21 @@ describe('Layout', function() { ); }); + it('should layout node with text and flex in rtl', function() { + testLayout( + {style: {}, children: [ + {style: {width: 500, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1, measure: text(texts.big)}} + ]} + ]}, + {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ + {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ + {width: 500, height: textSizes.smallHeight, top: 0, left: 0} + ]} + ]} + ); + }); + it('should layout node with text and stretch', function() { testLayout( {style: {width: 130}, children: [ @@ -908,6 +1330,19 @@ describe('Layout', function() { ); }); + it('should layout space-between when remaining space is negative in reverse', function() { + testLayout( + {style: {height: 100, flexDirection: 'column-reverse', justifyContent: 'space-between'}, children: [ + {style: {height: 900}}, + {style: {}} + ]}, + {width: 0, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 900, top: -800, left: 0}, + {width: 0, height: 0, top: -800, left: 0} + ]} + ); + }); + it('should layout flex-end when remaining space is negative', function() { testLayout( {style: {width: 200, flexDirection: 'row', justifyContent: 'flex-end'}, children: [ @@ -919,6 +1354,17 @@ describe('Layout', function() { ); }); + it('should layout flex-end when remaining space is negative in rtl', function() { + testLayout( + {style: {width: 200, direction: 'rtl', flexDirection: 'row', justifyContent: 'flex-end'}, children: [ + {style: {width: 900}} + ]}, + {width: 200, height: 0, top: 0, left: 0, children: [ + {width: 900, height: 0, top: 0, left: 0} + ]} + ); + }); + it('should layout text with flexDirection row', function() { testLayout( {style: {}, children: [ @@ -934,6 +1380,21 @@ describe('Layout', function() { ); }); + it('should layout text with flexDirection row in rtl', function() { + testLayout( + {style: { direction: 'rtl' }, children: [ + {style: {width: 200, flexDirection: 'row'}, children: [ + {style: {margin: 20, measure: text(texts.big)}} + ]} + ]}, + {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ + {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ + {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 7.578125} + ]} + ]} + ); + }); + it('should layout with text and margin', function() { testLayout( {style: {}, children: [ @@ -973,15 +1434,28 @@ describe('Layout', function() { ); }); - it('should layout with negative flex', function() { + it('should layout with arbitrary flex in reverse', function() { testLayout( - {style: {width: 100, height: 100, alignSelf: 'flex-start'}, children: [ + {style: {width: 100, height: 100, flexDirection: 'column-reverse', alignSelf: 'flex-start'}, children: [ + {style: {flex: 2.5, alignSelf: 'flex-start'}}, + {style: {flex: 7.5, alignSelf: 'flex-start'}} + ]}, + {width: 100, height: 100, top: 0, left: 0, children: [ + {width: 0, height: 25, top: 75, left: 0}, + {width: 0, height: 75, top: 0, left: 0} + ]} + ); + }); + + it('should layout with negative flex in reverse', function() { + testLayout( + {style: {width: 100, height: 100, flexDirection: 'column-reverse', alignSelf: 'flex-start'}, children: [ {style: {flex: -2.5, alignSelf: 'flex-start'}}, {style: {flex: 0, alignSelf: 'flex-start'}} ]}, {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0}, - {width: 0, height: 0, top: 0, left: 0} + {width: 0, height: 0, top: 100, left: 0}, + {width: 0, height: 0, top: 100, left: 0} ]} ); }); @@ -1196,6 +1670,21 @@ describe('Layout', function() { ); }); + it('should layout flex-wrap in rtl', function() { + testLayout( + {style: {flexWrap: 'wrap', direction: 'rtl', flexDirection: 'row', width: 100}, children: [ + {style: {width: 40, height: 10}}, + {style: {width: 40, height: 10}}, + {style: {width: 40, height: 10}} + ]}, + {width: 100, height: 20, top: 0, left: 0, children: [ + {width: 40, height: 10, top: 0, left: 60}, + {width: 40, height: 10, top: 0, left: 20}, + {width: 40, height: 10, top: 10, left: 60} + ]} + ); + }); + it('should layout flex wrap with a line bigger than container', function() { testLayout( {style: {height: 100, flexWrap: 'wrap'}, children: [ @@ -1315,6 +1804,21 @@ describe('Layout', function() { ); }); + it('should override flex direction size with min bounds in rtl', function() { + testLayout( + {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1}}, + {style: {flex: 1, minWidth: 200}}, + {style: {flex: 1}} + ]}, + {width: 300, height: 200, top: 0, left: 0, children: [ + {width: 50, height: 200, top: 0, left: 250}, + {width: 200, height: 200, top: 0, left: 50}, + {width: 50, height: 200, top: 0, left: 0} + ]} + ); + }); + it('should not override flex direction size within bounds', function() { testLayout( {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ @@ -1330,6 +1834,21 @@ describe('Layout', function() { ); }); + it('should not override flex direction size within bounds in rtl', function() { + testLayout( + {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1}}, + {style: {flex: 1, minWidth: 90, maxWidth: 110}}, + {style: {flex: 1}} + ]}, + {width: 300, height: 200, top: 0, left: 0, children: [ + {width: 100, height: 200, top: 0, left: 200}, + {width: 100, height: 200, top: 0, left: 100}, + {width: 100, height: 200, top: 0, left: 0} + ]} + ); + }); + it('should override flex direction size with max bounds', function() { testLayout( {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ @@ -1345,6 +1864,21 @@ describe('Layout', function() { ); }); + it('should override flex direction size with max bounds in rtl', function() { + testLayout( + {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1}}, + {style: {flex: 1, maxWidth: 60}}, + {style: {flex: 1}} + ]}, + {width: 300, height: 200, top: 0, left: 0, children: [ + {width: 120, height: 200, top: 0, left: 180}, + {width: 60, height: 200, top: 0, left: 120}, + {width: 120, height: 200, top: 0, left: 0} + ]} + ); + }); + it('should ignore flex size if fully max bound', function() { testLayout( {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ @@ -1360,6 +1894,21 @@ describe('Layout', function() { ); }); + it('should ignore flex size if fully max bound in rtl', function() { + testLayout( + {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1, maxWidth: 60}}, + {style: {flex: 1, maxWidth: 60}}, + {style: {flex: 1, maxWidth: 60}} + ]}, + {width: 300, height: 200, top: 0, left: 0, children: [ + {width: 60, height: 200, top: 0, left: 240}, + {width: 60, height: 200, top: 0, left: 180}, + {width: 60, height: 200, top: 0, left: 120} + ]} + ); + }); + it('should ignore flex size if fully min bound', function() { testLayout( {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ @@ -1375,6 +1924,21 @@ describe('Layout', function() { ); }); + it('should ignore flex size if fully min bound in rtl', function() { + testLayout( + {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {flex: 1, minWidth: 120}}, + {style: {flex: 1, minWidth: 120}}, + {style: {flex: 1, minWidth: 120}} + ]}, + {width: 300, height: 200, top: 0, left: 0, children: [ + {width: 120, height: 200, top: 0, left: 180}, + {width: 120, height: 200, top: 0, left: 60}, + {width: 120, height: 200, top: 0, left: -60} + ]} + ); + }); + it('should pre-fill child size within bounds', function() { testLayout( {style: {width: 300, height: 200}, children: [ @@ -1491,6 +2055,17 @@ describe('Layout', function() { ); }); + it('should keep cross axis size within min bounds in rtl', function() { + testLayout( + {style: {width: 1000, direction: 'rtl', flexDirection: 'row'}, children: [ + {style: {height: 100, minHeight: 110, minWidth: 100}} + ]}, + {width: 1000, height: 110, top: 0, left: 0, children: [ + {width: 100, height: 110, top: 0, left: 900} + ]} + ); + }); + it('should layout node with position absolute, top and left and max bounds', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ @@ -1586,5 +2161,28 @@ describe('Layout', function() { ); }); - + it('should layout nested nodes with mixed directions', function() { + testLayout( + {style: {width: 200, height: 200, direction: 'rtl'}, children: [ + {style: {flexDirection: 'row'}, children: [ + {style: {width: 50, height: 50}}, + {style: {width: 50, height: 50}} + ]}, + {style: {direction: 'ltr', flexDirection: 'row'}, children: [ + {style: {width: 50, height: 50}}, + {style: {width: 50, height: 50}} + ]} + ]}, + {width: 200, height: 200, top: 0, left: 0, children: [ + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 50, height: 50, top: 0, left: 150}, + {width: 50, height: 50, top: 0, left: 100} + ]}, + {width: 200, height: 50, top: 50, left: 0, children: [ + {width: 50, height: 50, top: 0, left: 0}, + {width: 50, height: 50, top: 0, left: 50} + ]} + ]} + ); + }); }); diff --git a/src/java/src/com/facebook/csslayout/CSSDirection.java b/src/java/src/com/facebook/csslayout/CSSDirection.java new file mode 100644 index 00000000..26e93bd6 --- /dev/null +++ b/src/java/src/com/facebook/csslayout/CSSDirection.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +package com.facebook.csslayout; + +public enum CSSDirection { + INHERIT, + LTR, + RTL, +} diff --git a/src/java/src/com/facebook/csslayout/CSSFlexDirection.java b/src/java/src/com/facebook/csslayout/CSSFlexDirection.java index 52991781..b5040e25 100644 --- a/src/java/src/com/facebook/csslayout/CSSFlexDirection.java +++ b/src/java/src/com/facebook/csslayout/CSSFlexDirection.java @@ -10,5 +10,7 @@ package com.facebook.csslayout; public enum CSSFlexDirection { COLUMN, + COLUMN_REVERSE, ROW, + ROW_REVERSE } diff --git a/src/java/src/com/facebook/csslayout/CSSLayout.java b/src/java/src/com/facebook/csslayout/CSSLayout.java index eb2f084b..87faefc5 100644 --- a/src/java/src/com/facebook/csslayout/CSSLayout.java +++ b/src/java/src/com/facebook/csslayout/CSSLayout.java @@ -13,8 +13,10 @@ package com.facebook.csslayout; */ public class CSSLayout { - public float x; - public float y; + public float top; + public float left; + public float right; + public float bottom; public float width = CSSConstants.UNDEFINED; public float height = CSSConstants.UNDEFINED; @@ -22,15 +24,19 @@ public class CSSLayout { * This should always get called before calling {@link LayoutEngine#layoutNode(CSSNode, float)} */ public void resetResult() { - x = 0; - y = 0; + left = 0; + top = 0; + right = 0; + bottom = 0; width = CSSConstants.UNDEFINED; height = CSSConstants.UNDEFINED; } public void copy(CSSLayout layout) { - x = layout.x; - y = layout.y; + left = layout.left; + top = layout.top; + right = layout.right; + bottom = layout.bottom; width = layout.width; height = layout.height; } @@ -38,8 +44,8 @@ public class CSSLayout { @Override public String toString() { return "layout: {" + - "x: " + x + ", " + - "y: " + y + ", " + + "left: " + left + ", " + + "top: " + top + ", " + "width: " + width + ", " + "height: " + height + "}"; diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java index df8c3c63..f3f97983 100644 --- a/src/java/src/com/facebook/csslayout/CSSNode.java +++ b/src/java/src/com/facebook/csslayout/CSSNode.java @@ -125,7 +125,7 @@ public class CSSNode { */ public void calculateLayout(CSSLayoutContext layoutContext) { layout.resetResult(); - LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED); + LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED, null); } /** @@ -328,11 +328,11 @@ public class CSSNode { } public float getLayoutX() { - return layout.x; + return layout.left; } public float getLayoutY() { - return layout.y; + return layout.top; } public float getLayoutWidth() { diff --git a/src/java/src/com/facebook/csslayout/CSSStyle.java b/src/java/src/com/facebook/csslayout/CSSStyle.java index 602de3ed..9bf46eb1 100644 --- a/src/java/src/com/facebook/csslayout/CSSStyle.java +++ b/src/java/src/com/facebook/csslayout/CSSStyle.java @@ -13,6 +13,7 @@ package com.facebook.csslayout; */ public class CSSStyle { + public CSSDirection direction = CSSDirection.INHERIT; public CSSFlexDirection flexDirection = CSSFlexDirection.COLUMN; public CSSJustify justifyContent = CSSJustify.FLEX_START; public CSSAlign alignItems = CSSAlign.STRETCH; diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 01ee44d0..de8f15cc 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -28,24 +28,34 @@ public class LayoutEngine { private static void setLayoutPosition(CSSNode node, PositionIndex position, float value) { switch (position) { case TOP: - node.layout.y = value; + node.layout.top = value; break; case LEFT: - node.layout.x = value; + node.layout.left = value; + break; + case RIGHT: + node.layout.right = value; + break; + case BOTTOM: + node.layout.bottom = value; break; default: - throw new RuntimeException("Didn't get TOP or LEFT!"); + throw new RuntimeException("Didn't get TOP, LEFT, RIGHT, or BOTTOM!"); } } private static float getLayoutPosition(CSSNode node, PositionIndex position) { switch (position) { case TOP: - return node.layout.y; + return node.layout.top; case LEFT: - return node.layout.x; + return node.layout.left; + case RIGHT: + return node.layout.right; + case BOTTOM: + return node.layout.bottom; default: - throw new RuntimeException("Didn't get TOP or LEFT!"); + throw new RuntimeException("Didn't get TOP, LEFT, RIGHT, or BOTTOM!"); } } @@ -100,19 +110,61 @@ public class LayoutEngine { } private static PositionIndex getLeading(CSSFlexDirection axis) { - return axis == CSSFlexDirection.COLUMN ? PositionIndex.TOP : PositionIndex.LEFT; + switch (axis) { + case COLUMN: + return PositionIndex.TOP; + case COLUMN_REVERSE: + return PositionIndex.BOTTOM; + case ROW: + return PositionIndex.LEFT; + case ROW_REVERSE: + return PositionIndex.RIGHT; + default: + throw new RuntimeException("Didn't get TOP, LEFT, RIGHT, or BOTTOM!"); + } } private static PositionIndex getTrailing(CSSFlexDirection axis) { - return axis == CSSFlexDirection.COLUMN ? PositionIndex.BOTTOM : PositionIndex.RIGHT; + switch (axis) { + case COLUMN: + return PositionIndex.BOTTOM; + case COLUMN_REVERSE: + return PositionIndex.TOP; + case ROW: + return PositionIndex.RIGHT; + case ROW_REVERSE: + return PositionIndex.LEFT; + default: + throw new RuntimeException("Didn't get COLUMN, COLUMN_REVERSE, ROW, or ROW_REVERSE!"); + } } private static PositionIndex getPos(CSSFlexDirection axis) { - return axis == CSSFlexDirection.COLUMN ? PositionIndex.TOP : PositionIndex.LEFT; + switch (axis) { + case COLUMN: + return PositionIndex.TOP; + case COLUMN_REVERSE: + return PositionIndex.BOTTOM; + case ROW: + return PositionIndex.LEFT; + case ROW_REVERSE: + return PositionIndex.RIGHT; + default: + throw new RuntimeException("Didn't get COLUMN, COLUMN_REVERSE, ROW, or ROW_REVERSE!"); + } } private static DimensionIndex getDim(CSSFlexDirection axis) { - return axis == CSSFlexDirection.COLUMN ? DimensionIndex.HEIGHT : DimensionIndex.WIDTH; + switch (axis) { + case COLUMN: + case COLUMN_REVERSE: + return DimensionIndex.HEIGHT; + case ROW: + case ROW_REVERSE: + return DimensionIndex.WIDTH; + default: + throw new RuntimeException("Didn't get COLUMN, COLUMN_REVERSE, ROW, or ROW_REVERSE!"); + } } private static boolean isDimDefined(CSSNode node, CSSFlexDirection axis) { @@ -196,10 +248,10 @@ public class LayoutEngine { float min = CSSConstants.UNDEFINED; float max = CSSConstants.UNDEFINED; - if (axis == CSSFlexDirection.COLUMN) { + if (isColumnDirection(axis)) { min = node.style.minHeight; max = node.style.maxHeight; - } else if (axis == CSSFlexDirection.ROW) { + } else if (isRowDirection(axis)) { min = node.style.minWidth; max = node.style.maxWidth; } @@ -233,6 +285,18 @@ public class LayoutEngine { setLayoutDimension(node, getDim(axis), maxLayoutDimension); } + private static void setTrailingPosition( + CSSNode node, + CSSNode child, + CSSFlexDirection axis) { + setLayoutPosition( + child, + getTrailing(axis), + getLayoutDimension(node, getDim(axis)) - + getLayoutDimension(child, getDim(axis)) - + getLayoutPosition(child, getPos(axis))); + } + private static float getRelativePosition(CSSNode node, CSSFlexDirection axis) { float lead = getStylePosition(node, getLeading(axis)); if (!CSSConstants.isUndefined(lead)) { @@ -245,10 +309,53 @@ public class LayoutEngine { return node.style.flex; } + private static boolean isRowDirection(CSSFlexDirection flexDirection) { + return flexDirection == CSSFlexDirection.ROW || + flexDirection == CSSFlexDirection.ROW_REVERSE; + } + + private static boolean isColumnDirection(CSSFlexDirection flexDirection) { + return flexDirection == CSSFlexDirection.COLUMN || + flexDirection == CSSFlexDirection.COLUMN_REVERSE; + } + + private static CSSFlexDirection resolveAxis( + CSSFlexDirection axis, + CSSDirection direction) { + if (direction == CSSDirection.RTL) { + if (axis == CSSFlexDirection.ROW) { + return CSSFlexDirection.ROW_REVERSE; + } else if (axis == CSSFlexDirection.ROW_REVERSE) { + return CSSFlexDirection.ROW; + } + } + + return axis; + } + + private static CSSDirection resolveDirection(CSSNode node, CSSDirection parentDirection) { + CSSDirection direction = node.style.direction; + if (direction == CSSDirection.INHERIT) { + direction = (parentDirection == null ? CSSDirection.LTR : parentDirection); + } + + return direction; + } + private static CSSFlexDirection getFlexDirection(CSSNode node) { return node.style.flexDirection; } + private static CSSFlexDirection getCrossFlexDirection( + CSSFlexDirection flexDirection, + CSSDirection direction) { + if (isColumnDirection(flexDirection)) { + return resolveAxis(CSSFlexDirection.ROW, direction); + } else { + return CSSFlexDirection.COLUMN; + } + } + private static CSSPositionType getPositionType(CSSNode node) { return node.style.positionType; } @@ -292,13 +399,14 @@ public class LayoutEngine { /*package*/ static void layoutNode( CSSLayoutContext layoutContext, CSSNode node, - float parentMaxWidth) { + float parentMaxWidth, + CSSDirection parentDirection) { if (needsRelayout(node, parentMaxWidth)) { node.lastLayout.requestedWidth = node.layout.width; node.lastLayout.requestedHeight = node.layout.height; node.lastLayout.parentMaxWidth = parentMaxWidth; - layoutNodeImpl(layoutContext, node, parentMaxWidth); + layoutNodeImpl(layoutContext, node, parentMaxWidth, parentDirection); node.lastLayout.copy(node.layout); } else { node.layout.copy(node.lastLayout); @@ -310,18 +418,18 @@ public class LayoutEngine { private static void layoutNodeImpl( CSSLayoutContext layoutContext, CSSNode node, - float parentMaxWidth) { + float parentMaxWidth, + CSSDirection parentDirection) { for (int i = 0; i < node.getChildCount(); i++) { node.getChildAt(i).layout.resetResult(); } /** START_GENERATED **/ - - CSSFlexDirection mainAxis = getFlexDirection(node); - CSSFlexDirection crossAxis = mainAxis == CSSFlexDirection.ROW ? - CSSFlexDirection.COLUMN : - CSSFlexDirection.ROW; + CSSDirection direction = resolveDirection(node, parentDirection); + CSSFlexDirection mainAxis = resolveAxis(getFlexDirection(node), direction); + CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); + CSSFlexDirection resolvedRowAxis = resolveAxis(CSSFlexDirection.ROW, direction); // Handle width and height style attributes setDimensionFromStyle(node, mainAxis); @@ -331,26 +439,30 @@ public class LayoutEngine { // delta composed of the margin and left/top/right/bottom setLayoutPosition(node, getLeading(mainAxis), getLayoutPosition(node, getLeading(mainAxis)) + getMargin(node, getLeading(mainAxis)) + getRelativePosition(node, mainAxis)); + setLayoutPosition(node, getTrailing(mainAxis), getLayoutPosition(node, getTrailing(mainAxis)) + getMargin(node, getTrailing(mainAxis)) + + getRelativePosition(node, mainAxis)); setLayoutPosition(node, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getMargin(node, getLeading(crossAxis)) + getRelativePosition(node, crossAxis)); + setLayoutPosition(node, getTrailing(crossAxis), getLayoutPosition(node, getTrailing(crossAxis)) + getMargin(node, getTrailing(crossAxis)) + + getRelativePosition(node, crossAxis)); if (isMeasureDefined(node)) { float width = CSSConstants.UNDEFINED; - if (isDimDefined(node, CSSFlexDirection.ROW)) { + if (isDimDefined(node, resolvedRowAxis)) { width = node.style.width; - } else if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.ROW)))) { - width = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)); + } else if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(resolvedRowAxis)))) { + width = getLayoutDimension(node, getDim(resolvedRowAxis)); } else { width = parentMaxWidth - - getMarginAxis(node, CSSFlexDirection.ROW); + getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + width -= getPaddingAndBorderAxis(node, resolvedRowAxis); // 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, CSSFlexDirection.ROW) && - CSSConstants.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.ROW))); + boolean isRowUndefined = !isDimDefined(node, resolvedRowAxis) && + CSSConstants.isUndefined(getLayoutDimension(node, getDim(resolvedRowAxis))); boolean isColumnUndefined = !isDimDefined(node, CSSFlexDirection.COLUMN) && CSSConstants.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.COLUMN))); @@ -362,7 +474,7 @@ public class LayoutEngine { ); if (isRowUndefined) { node.layout.width = measureDim.width + - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + getPaddingAndBorderAxis(node, resolvedRowAxis); } if (isColumnUndefined) { node.layout.height = measureDim.height + @@ -465,20 +577,20 @@ public class LayoutEngine { } else { maxWidth = CSSConstants.UNDEFINED; - if (mainAxis != CSSFlexDirection.ROW) { + if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSSFlexDirection.ROW) - - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); - if (isDimDefined(node, CSSFlexDirection.ROW)) { - maxWidth = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) - - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = getLayoutDimension(node, getDim(resolvedRowAxis)) - + getPaddingAndBorderAxis(node, resolvedRowAxis); } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(layoutContext, child, maxWidth); + layoutNode(layoutContext, child, maxWidth, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -564,17 +676,17 @@ public class LayoutEngine { )); maxWidth = CSSConstants.UNDEFINED; - if (isDimDefined(node, CSSFlexDirection.ROW)) { - maxWidth = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) - - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); - } else if (mainAxis != CSSFlexDirection.ROW) { + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = getLayoutDimension(node, getDim(resolvedRowAxis)) - + getPaddingAndBorderAxis(node, resolvedRowAxis); + } else if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSSFlexDirection.ROW) - - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); } // And we recursively call the layout algorithm for this child - layoutNode(layoutContext, child, maxWidth); + layoutNode(layoutContext, child, maxWidth, direction); } } @@ -627,6 +739,11 @@ public class LayoutEngine { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. setLayoutPosition(child, getPos(mainAxis), getLayoutPosition(child, getPos(mainAxis)) + mainDim); + + // Define the trailing position accordingly. + if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) { + setTrailingPosition(node, child, mainAxis); + } } // Now that we placed the element, we need to update the variables @@ -721,6 +838,12 @@ public class LayoutEngine { // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) )); + + // Now that the width is defined, we should update the trailing + // positions for the children. + for (i = 0; i < node.getChildCount(); ++i) { + setTrailingPosition(node, node.getChildAt(i), mainAxis); + } } if (CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) { diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index ce0e890c..6efbef3a 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -69,8 +69,8 @@ public class LayoutEngineTest { private static boolean areLayoutsEqual(CSSNode a, CSSNode b) { boolean doNodesHaveSameLayout = - areFloatsEqual(a.layout.x, b.layout.x) && - areFloatsEqual(a.layout.y, b.layout.y) && + areFloatsEqual(a.layout.left, b.layout.left) && + areFloatsEqual(a.layout.top, b.layout.top) && areFloatsEqual(a.layout.width, b.layout.width) && areFloatsEqual(a.layout.height, b.layout.height); if (!doNodesHaveSameLayout) { @@ -102,8 +102,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 200; } @@ -137,26 +137,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 500; node_1.layout.height = 500; node_1 = node_0.getChildAt(1); - node_1.layout.y = 500; - node_1.layout.x = 0; + node_1.layout.top = 500; + node_1.layout.left = 0; node_1.layout.width = 250; node_1.layout.height = 250; node_1 = node_0.getChildAt(2); - node_1.layout.y = 750; - node_1.layout.x = 0; + node_1.layout.top = 750; + node_1.layout.left = 0; node_1.layout.width = 125; node_1.layout.height = 125; } @@ -167,6 +167,61 @@ public class LayoutEngineTest { @Test public void testCase2() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 500; + node_1.style.height = 500; + node_1 = node_0.getChildAt(1); + node_1.style.width = 250; + node_1.style.height = 250; + node_1 = node_0.getChildAt(2); + node_1.style.width = 125; + node_1.style.height = 125; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 500; + node_1.layout.left = 0; + node_1.layout.width = 500; + node_1.layout.height = 500; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 250; + node_1.layout.left = 0; + node_1.layout.width = 250; + node_1.layout.height = 250; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 125; + node_1.layout.left = 0; + node_1.layout.width = 125; + node_1.layout.height = 125; + } + } + + test("should layout node with children in reverse", root_node, root_layout); + } + + @Test + public void testCase3() { TestCSSNode root_node = new TestCSSNode(); { @@ -198,34 +253,34 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 500; node_1.layout.height = 500; node_1 = node_0.getChildAt(1); - node_1.layout.y = 500; - node_1.layout.x = 0; + node_1.layout.top = 500; + node_1.layout.left = 0; node_1.layout.width = 500; node_1.layout.height = 500; addChildren(node_1, 2); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 250; node_2.layout.height = 250; node_2 = node_1.getChildAt(1); - node_2.layout.y = 250; - node_2.layout.x = 0; + node_2.layout.top = 250; + node_2.layout.left = 0; node_2.layout.width = 250; node_2.layout.height = 250; } @@ -236,7 +291,79 @@ public class LayoutEngineTest { } @Test - public void testCase3() + public void testCase4() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 500; + node_1.style.height = 500; + node_1 = node_0.getChildAt(1); + node_1.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_1.style.width = 500; + node_1.style.height = 500; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.width = 250; + node_2.style.height = 250; + node_2 = node_1.getChildAt(1); + node_2.style.width = 250; + node_2.style.height = 250; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 500; + node_1.layout.left = 0; + node_1.layout.width = 500; + node_1.layout.height = 500; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 500; + node_1.layout.height = 500; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 250; + node_2.layout.left = 0; + node_2.layout.width = 250; + node_2.layout.height = 250; + node_2 = node_1.getChildAt(1); + node_2.layout.top = 0; + node_2.layout.left = 0; + node_2.layout.width = 250; + node_2.layout.height = 250; + } + } + } + + test("should layout node with nested children in reverse", root_node, root_layout); + } + + @Test + public void testCase5() { TestCSSNode root_node = new TestCSSNode(); { @@ -252,8 +379,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 10; - node_0.layout.x = 10; + node_0.layout.top = 10; + node_0.layout.left = 10; node_0.layout.width = 100; node_0.layout.height = 200; } @@ -262,7 +389,7 @@ public class LayoutEngineTest { } @Test - public void testCase4() + public void testCase6() { TestCSSNode root_node = new TestCSSNode(); { @@ -303,26 +430,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 10; - node_0.layout.x = 10; + node_0.layout.top = 10; + node_0.layout.left = 10; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 50; - node_1.layout.x = 50; + node_1.layout.top = 50; + node_1.layout.left = 50; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 225; - node_1.layout.x = 25; + node_1.layout.top = 225; + node_1.layout.left = 25; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(2); - node_1.layout.y = 360; - node_1.layout.x = 10; + node_1.layout.top = 360; + node_1.layout.left = 10; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -332,7 +459,126 @@ public class LayoutEngineTest { } @Test - public void testCase5() + public void testCase7() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + node_0.style.margin[Spacing.LEFT] = 10; + node_0.style.margin[Spacing.TOP] = 10; + node_0.style.margin[Spacing.RIGHT] = 10; + node_0.style.margin[Spacing.BOTTOM] = 10; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1.style.margin[Spacing.LEFT] = 50; + node_1.style.margin[Spacing.TOP] = 50; + node_1.style.margin[Spacing.RIGHT] = 50; + node_1.style.margin[Spacing.BOTTOM] = 50; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + node_1.style.margin[Spacing.LEFT] = 25; + node_1.style.margin[Spacing.TOP] = 25; + node_1.style.margin[Spacing.RIGHT] = 25; + node_1.style.margin[Spacing.BOTTOM] = 25; + node_1 = node_0.getChildAt(2); + node_1.style.width = 100; + node_1.style.height = 100; + node_1.style.margin[Spacing.LEFT] = 10; + node_1.style.margin[Spacing.TOP] = 10; + node_1.style.margin[Spacing.RIGHT] = 10; + node_1.style.margin[Spacing.BOTTOM] = 10; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 10; + node_0.layout.left = 10; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 850; + node_1.layout.left = 50; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 675; + node_1.layout.left = 25; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 540; + node_1.layout.left = 10; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with several children in reverse", root_node, root_layout); + } + + @Test + public void testCase8() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 200; + node_1 = node_0.getChildAt(1); + node_1.style.width = 300; + node_1.style.height = 150; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 100; + node_1.layout.width = 300; + node_1.layout.height = 150; + } + } + + test("should layout rtl with reverse correctly", root_node, root_layout); + } + + @Test + public void testCase9() { TestCSSNode root_node = new TestCSSNode(); { @@ -355,21 +601,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 100; + node_1.layout.top = 0; + node_1.layout.left = 100; node_1.layout.width = 300; node_1.layout.height = 150; } @@ -379,7 +625,55 @@ public class LayoutEngineTest { } @Test - public void testCase6() + public void testCase10() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 200; + node_1 = node_0.getChildAt(1); + node_1.style.width = 300; + node_1.style.height = 150; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 900; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 600; + node_1.layout.width = 300; + node_1.layout.height = 150; + } + } + + test("should layout node with row flex direction in rtl", root_node, root_layout); + } + + @Test + public void testCase11() { TestCSSNode root_node = new TestCSSNode(); { @@ -400,21 +694,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 350; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 200; - node_1.layout.x = 0; + node_1.layout.top = 200; + node_1.layout.left = 0; node_1.layout.width = 300; node_1.layout.height = 150; } @@ -424,7 +718,53 @@ public class LayoutEngineTest { } @Test - public void testCase7() + public void testCase12() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 300; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 200; + node_1 = node_0.getChildAt(1); + node_1.style.width = 300; + node_1.style.height = 150; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 350; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 150; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 300; + node_1.layout.height = 150; + } + } + + test("should layout node based on children main dimensions in reverse", root_node, root_layout); + } + + @Test + public void testCase13() { TestCSSNode root_node = new TestCSSNode(); { @@ -446,21 +786,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 200; - node_1.layout.x = 0; + node_1.layout.top = 200; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 800; } @@ -470,7 +810,54 @@ public class LayoutEngineTest { } @Test - public void testCase8() + public void testCase14() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 200; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.width = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 800; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 800; + } + } + + test("should layout node with just flex in reverse", root_node, root_layout); + } + + @Test + public void testCase15() { TestCSSNode root_node = new TestCSSNode(); { @@ -503,32 +890,32 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 1000; node_1.layout.height = 1000; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 1000; node_2.layout.height = 1000; addChildren(node_2, 1); { TestCSSNode node_3; node_3 = node_2.getChildAt(0); - node_3.layout.y = 0; - node_3.layout.x = 0; + node_3.layout.top = 0; + node_3.layout.left = 0; node_3.layout.width = 1000; node_3.layout.height = 1000; } @@ -540,7 +927,81 @@ public class LayoutEngineTest { } @Test - public void testCase9() + public void testCase16() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_1.style.flex = 1; + node_1.style.width = 1000; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_2.style.flex = 1; + node_2.style.width = 1000; + addChildren(node_2, 1); + { + TestCSSNode node_3; + node_3 = node_2.getChildAt(0); + node_3.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_3.style.flex = 1; + node_3.style.width = 1000; + } + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 1000; + node_1.layout.height = 1000; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 0; + node_2.layout.left = 0; + node_2.layout.width = 1000; + node_2.layout.height = 1000; + addChildren(node_2, 1); + { + TestCSSNode node_3; + node_3 = node_2.getChildAt(0); + node_3.layout.top = 0; + node_3.layout.left = 0; + node_3.layout.width = 1000; + node_3.layout.height = 1000; + } + } + } + } + + test("should layout node with flex recursively in reverse", root_node, root_layout); + } + + @Test + public void testCase17() { TestCSSNode root_node = new TestCSSNode(); { @@ -568,21 +1029,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 10; - node_0.layout.x = 5; + node_0.layout.top = 10; + node_0.layout.left = 5; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 50; - node_1.layout.x = 15; + node_1.layout.top = 50; + node_1.layout.left = 15; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 170; - node_1.layout.x = 30; + node_1.layout.top = 170; + node_1.layout.left = 30; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -592,7 +1053,60 @@ public class LayoutEngineTest { } @Test - public void testCase10() + public void testCase18() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.width = 1000; + node_0.style.height = 1000; + node_0.style.margin[Spacing.LEFT] = 5; + node_0.style.margin[Spacing.TOP] = 10; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1.style.margin[Spacing.LEFT] = 15; + node_1.style.margin[Spacing.TOP] = 50; + node_1.style.margin[Spacing.BOTTOM] = 20; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + node_1.style.margin[Spacing.LEFT] = 30; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 10; + node_0.layout.left = 5; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 880; + node_1.layout.left = 15; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 730; + node_1.layout.left = 30; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with targeted margin in reverse", root_node, root_layout); + } + + @Test + public void testCase19() { TestCSSNode root_node = new TestCSSNode(); { @@ -615,21 +1129,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -639,7 +1153,55 @@ public class LayoutEngineTest { } @Test - public void testCase11() + public void testCase20() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.FLEX_START; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 800; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with justifyContent: flex-start in reverse", root_node, root_layout); + } + + @Test + public void testCase21() { TestCSSNode root_node = new TestCSSNode(); { @@ -662,21 +1224,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 800; - node_1.layout.x = 0; + node_1.layout.top = 800; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 900; - node_1.layout.x = 0; + node_1.layout.top = 900; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -686,7 +1248,55 @@ public class LayoutEngineTest { } @Test - public void testCase12() + public void testCase22() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.FLEX_END; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 100; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with justifyContent: flex-end in reverse", root_node, root_layout); + } + + @Test + public void testCase23() { TestCSSNode root_node = new TestCSSNode(); { @@ -709,21 +1319,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 900; - node_1.layout.x = 0; + node_1.layout.top = 900; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -733,7 +1343,55 @@ public class LayoutEngineTest { } @Test - public void testCase13() + public void testCase24() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.SPACE_BETWEEN; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with justifyContent: space-between in reverse", root_node, root_layout); + } + + @Test + public void testCase25() { TestCSSNode root_node = new TestCSSNode(); { @@ -756,21 +1414,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 200; - node_1.layout.x = 0; + node_1.layout.top = 200; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 700; - node_1.layout.x = 0; + node_1.layout.top = 700; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -780,7 +1438,55 @@ public class LayoutEngineTest { } @Test - public void testCase14() + public void testCase26() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.SPACE_AROUND; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 700; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 200; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with justifyContent: space-around in reverse", root_node, root_layout); + } + + @Test + public void testCase27() { TestCSSNode root_node = new TestCSSNode(); { @@ -803,21 +1509,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 400; - node_1.layout.x = 0; + node_1.layout.top = 400; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 500; - node_1.layout.x = 0; + node_1.layout.top = 500; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -827,7 +1533,55 @@ public class LayoutEngineTest { } @Test - public void testCase15() + public void testCase28() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.CENTER; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 500; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 400; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with justifyContent: center in reverse", root_node, root_layout); + } + + @Test + public void testCase29() { TestCSSNode root_node = new TestCSSNode(); { @@ -847,16 +1601,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 1000; } @@ -866,7 +1620,7 @@ public class LayoutEngineTest { } @Test - public void testCase16() + public void testCase30() { TestCSSNode root_node = new TestCSSNode(); { @@ -889,21 +1643,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -913,7 +1667,55 @@ public class LayoutEngineTest { } @Test - public void testCase17() + public void testCase31() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.FLEX_START; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 200; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 0; + node_1.layout.width = 200; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 800; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with alignItems: flex-start in reverse", root_node, root_layout); + } + + @Test + public void testCase32() { TestCSSNode root_node = new TestCSSNode(); { @@ -936,21 +1738,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 400; + node_1.layout.top = 0; + node_1.layout.left = 400; node_1.layout.width = 200; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 450; + node_1.layout.top = 100; + node_1.layout.left = 450; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -960,7 +1762,55 @@ public class LayoutEngineTest { } @Test - public void testCase18() + public void testCase33() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.CENTER; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 200; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 400; + node_1.layout.width = 200; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 800; + node_1.layout.left = 450; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with alignItems: center in reverse", root_node, root_layout); + } + + @Test + public void testCase34() { TestCSSNode root_node = new TestCSSNode(); { @@ -983,21 +1833,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 800; + node_1.layout.top = 0; + node_1.layout.left = 800; node_1.layout.width = 200; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 900; + node_1.layout.top = 100; + node_1.layout.left = 900; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -1007,7 +1857,55 @@ public class LayoutEngineTest { } @Test - public void testCase19() + public void testCase35() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.FLEX_END; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 200; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 800; + node_1.layout.width = 200; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 800; + node_1.layout.left = 900; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with alignItems: flex-end in reverse", root_node, root_layout); + } + + @Test + public void testCase36() { TestCSSNode root_node = new TestCSSNode(); { @@ -1031,21 +1929,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 800; + node_1.layout.top = 0; + node_1.layout.left = 800; node_1.layout.width = 200; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 450; + node_1.layout.top = 100; + node_1.layout.left = 450; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -1055,7 +1953,56 @@ public class LayoutEngineTest { } @Test - public void testCase20() + public void testCase37() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.FLEX_END; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 200; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.alignSelf = CSSAlign.CENTER; + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 800; + node_1.layout.width = 200; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 800; + node_1.layout.left = 450; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should layout node with alignSelf overrides alignItems in reverse", root_node, root_layout); + } + + @Test + public void testCase38() { TestCSSNode root_node = new TestCSSNode(); { @@ -1074,16 +2021,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 1000; node_1.layout.height = 100; } @@ -1093,7 +2040,46 @@ public class LayoutEngineTest { } @Test - public void testCase21() + public void testCase39() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.STRETCH; + node_0.style.width = 1000; + node_0.style.height = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 900; + node_1.layout.left = 0; + node_1.layout.width = 1000; + node_1.layout.height = 100; + } + } + + test("should layout node with alignItem: stretch in reverse", root_node, root_layout); + } + + @Test + public void testCase40() { TestCSSNode root_node = new TestCSSNode(); { @@ -1108,16 +2094,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1127,7 +2113,42 @@ public class LayoutEngineTest { } @Test - public void testCase22() + public void testCase41() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 0; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout empty node in reverse", root_node, root_layout); + } + + @Test + public void testCase42() { TestCSSNode root_node = new TestCSSNode(); { @@ -1146,16 +2167,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 10; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 5; - node_1.layout.x = 5; + node_1.layout.top = 5; + node_1.layout.left = 5; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1165,7 +2186,46 @@ public class LayoutEngineTest { } @Test - public void testCase23() + public void testCase43() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.margin[Spacing.LEFT] = 5; + node_1.style.margin[Spacing.TOP] = 5; + node_1.style.margin[Spacing.RIGHT] = 5; + node_1.style.margin[Spacing.BOTTOM] = 5; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 10; + node_0.layout.height = 10; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 5; + node_1.layout.left = 5; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout child with margin in reverse", root_node, root_layout); + } + + @Test + public void testCase44() { TestCSSNode root_node = new TestCSSNode(); { @@ -1184,21 +2244,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 200; } @@ -1208,7 +2268,51 @@ public class LayoutEngineTest { } @Test - public void testCase24() + public void testCase45() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.height = 200; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 0; + node_0.layout.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = -200; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 200; + } + } + + test("should not shrink children if not enough space in reverse", root_node, root_layout); + } + + @Test + public void testCase46() { TestCSSNode root_node = new TestCSSNode(); { @@ -1219,8 +2323,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; } @@ -1229,7 +2333,7 @@ public class LayoutEngineTest { } @Test - public void testCase25() + public void testCase47() { TestCSSNode root_node = new TestCSSNode(); { @@ -1247,16 +2351,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1266,7 +2370,45 @@ public class LayoutEngineTest { } @Test - public void testCase26() + public void testCase48() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.FLEX_END; + node_0.style.height = 100; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.margin[Spacing.TOP] = 10; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 0; + node_0.layout.height = 100; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 10; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout flex-end taking into account margin in reverse", root_node, root_layout); + } + + @Test + public void testCase49() { TestCSSNode root_node = new TestCSSNode(); { @@ -1293,29 +2435,29 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 20; node_0.layout.height = 120; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 20; node_1.layout.height = 120; addChildren(node_1, 2); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 10; - node_2.layout.x = 10; + node_2.layout.top = 10; + node_2.layout.left = 10; node_2.layout.width = 0; node_2.layout.height = 0; node_2 = node_1.getChildAt(1); - node_2.layout.y = 20; - node_2.layout.x = 20; + node_2.layout.top = 20; + node_2.layout.left = 20; node_2.layout.width = 0; node_2.layout.height = 100; } @@ -1326,7 +2468,68 @@ public class LayoutEngineTest { } @Test - public void testCase27() + public void testCase50() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_1.style.alignItems = CSSAlign.FLEX_END; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.margin[Spacing.LEFT] = 10; + node_2.style.margin[Spacing.TOP] = 10; + node_2.style.margin[Spacing.RIGHT] = 10; + node_2.style.margin[Spacing.BOTTOM] = 10; + node_2 = node_1.getChildAt(1); + node_2.style.height = 100; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 20; + node_0.layout.height = 120; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 20; + node_1.layout.height = 120; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 110; + node_2.layout.left = 10; + node_2.layout.width = 0; + node_2.layout.height = 0; + node_2 = node_1.getChildAt(1); + node_2.layout.top = 0; + node_2.layout.left = 20; + node_2.layout.width = 0; + node_2.layout.height = 100; + } + } + } + + test("should layout alignItems with margin in reverse", root_node, root_layout); + } + + @Test + public void testCase51() { TestCSSNode root_node = new TestCSSNode(); { @@ -1342,16 +2545,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1361,7 +2564,7 @@ public class LayoutEngineTest { } @Test - public void testCase28() + public void testCase52() { TestCSSNode root_node = new TestCSSNode(); { @@ -1378,16 +2581,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 10; + node_1.layout.top = 0; + node_1.layout.left = 10; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1397,7 +2600,44 @@ public class LayoutEngineTest { } @Test - public void testCase29() + public void testCase53() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignItems = CSSAlign.STRETCH; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.margin[Spacing.LEFT] = 10; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 10; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 10; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout alignItems stretch and margin in reverse", root_node, root_layout); + } + + @Test + public void testCase54() { TestCSSNode root_node = new TestCSSNode(); { @@ -1411,8 +2651,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 10; } @@ -1421,7 +2661,7 @@ public class LayoutEngineTest { } @Test - public void testCase30() + public void testCase55() { TestCSSNode root_node = new TestCSSNode(); { @@ -1440,16 +2680,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 10; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 5; - node_1.layout.x = 5; + node_1.layout.top = 5; + node_1.layout.left = 5; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1459,7 +2699,7 @@ public class LayoutEngineTest { } @Test - public void testCase31() + public void testCase56() { TestCSSNode root_node = new TestCSSNode(); { @@ -1482,16 +2722,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 20; node_0.layout.height = 20; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 10; - node_1.layout.x = 10; + node_1.layout.top = 10; + node_1.layout.left = 10; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1501,7 +2741,7 @@ public class LayoutEngineTest { } @Test - public void testCase32() + public void testCase57() { TestCSSNode root_node = new TestCSSNode(); { @@ -1521,16 +2761,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 20; node_0.layout.height = 20; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 20; node_1.layout.height = 20; } @@ -1540,7 +2780,7 @@ public class LayoutEngineTest { } @Test - public void testCase33() + public void testCase58() { TestCSSNode root_node = new TestCSSNode(); { @@ -1564,16 +2804,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 120; node_0.layout.height = 120; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 50; - node_1.layout.x = 50; + node_1.layout.top = 50; + node_1.layout.left = 50; node_1.layout.width = 20; node_1.layout.height = 20; } @@ -1583,7 +2823,7 @@ public class LayoutEngineTest { } @Test - public void testCase34() + public void testCase59() { TestCSSNode root_node = new TestCSSNode(); { @@ -1608,24 +2848,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 32; node_0.layout.height = 32; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 32; node_1.layout.height = 32; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 16; - node_2.layout.x = 16; + node_2.layout.top = 16; + node_2.layout.left = 16; node_2.layout.width = 0; node_2.layout.height = 0; } @@ -1636,7 +2876,7 @@ public class LayoutEngineTest { } @Test - public void testCase35() + public void testCase60() { TestCSSNode root_node = new TestCSSNode(); { @@ -1648,8 +2888,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 5; - node_0.layout.x = 5; + node_0.layout.top = 5; + node_0.layout.left = 5; node_0.layout.width = 0; node_0.layout.height = 0; } @@ -1658,7 +2898,7 @@ public class LayoutEngineTest { } @Test - public void testCase36() + public void testCase61() { TestCSSNode root_node = new TestCSSNode(); { @@ -1676,16 +2916,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 10; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 7.5f; - node_1.layout.x = 0; + node_1.layout.top = 7.5f; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1695,7 +2935,7 @@ public class LayoutEngineTest { } @Test - public void testCase37() + public void testCase62() { TestCSSNode root_node = new TestCSSNode(); { @@ -1706,8 +2946,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = -5; - node_0.layout.x = 0; + node_0.layout.top = -5; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; } @@ -1716,7 +2956,7 @@ public class LayoutEngineTest { } @Test - public void testCase38() + public void testCase63() { TestCSSNode root_node = new TestCSSNode(); { @@ -1728,8 +2968,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 10; - node_0.layout.x = 0; + node_0.layout.top = 10; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; } @@ -1738,7 +2978,7 @@ public class LayoutEngineTest { } @Test - public void testCase39() + public void testCase64() { TestCSSNode root_node = new TestCSSNode(); { @@ -1761,26 +3001,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 500; node_0.layout.height = 0; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 250; node_1.layout.height = 0; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 250; + node_1.layout.top = 0; + node_1.layout.left = 250; node_1.layout.width = 50; node_1.layout.height = 0; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 250; + node_1.layout.top = 0; + node_1.layout.left = 250; node_1.layout.width = 250; node_1.layout.height = 0; } @@ -1790,7 +3030,7 @@ public class LayoutEngineTest { } @Test - public void testCase40() + public void testCase65() { TestCSSNode root_node = new TestCSSNode(); { @@ -1807,16 +3047,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -1826,7 +3066,7 @@ public class LayoutEngineTest { } @Test - public void testCase41() + public void testCase66() { TestCSSNode root_node = new TestCSSNode(); { @@ -1844,16 +3084,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 12; node_1.layout.height = 0; } @@ -1863,7 +3103,7 @@ public class LayoutEngineTest { } @Test - public void testCase42() + public void testCase67() { TestCSSNode root_node = new TestCSSNode(); { @@ -1875,8 +3115,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 20; } @@ -1885,7 +3125,7 @@ public class LayoutEngineTest { } @Test - public void testCase43() + public void testCase68() { TestCSSNode root_node = new TestCSSNode(); { @@ -1897,8 +3137,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 20; node_0.layout.height = 0; } @@ -1907,7 +3147,7 @@ public class LayoutEngineTest { } @Test - public void testCase44() + public void testCase69() { TestCSSNode root_node = new TestCSSNode(); { @@ -1931,30 +3171,30 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 400; node_0.layout.height = 0; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 400; node_1.layout.height = 0; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 400; node_2.layout.height = 0; } node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 0; } @@ -1964,7 +3204,7 @@ public class LayoutEngineTest { } @Test - public void testCase45() + public void testCase70() { TestCSSNode root_node = new TestCSSNode(); { @@ -1984,16 +3224,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 10; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 5; - node_1.layout.x = 5; + node_1.layout.top = 5; + node_1.layout.left = 5; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2003,7 +3243,7 @@ public class LayoutEngineTest { } @Test - public void testCase46() + public void testCase71() { TestCSSNode root_node = new TestCSSNode(); { @@ -2023,21 +3263,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 10; - node_1.layout.x = 10; + node_1.layout.top = 10; + node_1.layout.left = 10; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2047,7 +3287,7 @@ public class LayoutEngineTest { } @Test - public void testCase47() + public void testCase72() { TestCSSNode root_node = new TestCSSNode(); { @@ -2068,16 +3308,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 40; node_0.layout.height = 40; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 20; - node_1.layout.x = 5; + node_1.layout.top = 20; + node_1.layout.left = 5; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2087,7 +3327,7 @@ public class LayoutEngineTest { } @Test - public void testCase48() + public void testCase73() { TestCSSNode root_node = new TestCSSNode(); { @@ -2105,16 +3345,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 10; - node_1.layout.x = 0; + node_1.layout.top = 10; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2124,7 +3364,7 @@ public class LayoutEngineTest { } @Test - public void testCase49() + public void testCase74() { TestCSSNode root_node = new TestCSSNode(); { @@ -2142,16 +3382,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 10; + node_1.layout.top = 0; + node_1.layout.left = 10; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2161,7 +3401,7 @@ public class LayoutEngineTest { } @Test - public void testCase50() + public void testCase75() { TestCSSNode root_node = new TestCSSNode(); { @@ -2180,21 +3420,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 200; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2204,7 +3444,51 @@ public class LayoutEngineTest { } @Test - public void testCase51() + public void testCase76() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.SPACE_AROUND; + node_0.style.height = 200; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.positionType = CSSPositionType.ABSOLUTE; + node_1 = node_0.getChildAt(1); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 0; + node_0.layout.height = 200; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 100; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 0; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 100; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout node with space-around and child position absolute in reverse", root_node, root_layout); + } + + @Test + public void testCase77() { TestCSSNode root_node = new TestCSSNode(); { @@ -2223,16 +3507,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 700; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 5; + node_1.layout.top = 0; + node_1.layout.left = 5; node_1.layout.width = 695; node_1.layout.height = 0; } @@ -2242,7 +3526,46 @@ public class LayoutEngineTest { } @Test - public void testCase52() + public void testCase78() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 700; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.margin[Spacing.RIGHT] = 5; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 700; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 695; + node_1.layout.height = 0; + } + } + + test("should layout node with flex and main margin in rtl", root_node, root_layout); + } + + @Test + public void testCase79() { TestCSSNode root_node = new TestCSSNode(); { @@ -2263,21 +3586,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 700; node_0.layout.height = 0; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 347.5f; node_1.layout.height = 0; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 347.5f; + node_1.layout.top = 0; + node_1.layout.left = 347.5f; node_1.layout.width = 352.5f; node_1.layout.height = 0; } @@ -2287,7 +3610,53 @@ public class LayoutEngineTest { } @Test - public void testCase53() + public void testCase80() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 700; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.padding[Spacing.LEFT] = 5; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 700; + node_0.layout.height = 0; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 352.5f; + node_1.layout.width = 347.5f; + node_1.layout.height = 0; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 352.5f; + node_1.layout.height = 0; + } + } + + test("should layout node with multiple flex and padding in rtl", root_node, root_layout); + } + + @Test + public void testCase81() { TestCSSNode root_node = new TestCSSNode(); { @@ -2308,21 +3677,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 700; node_0.layout.height = 0; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 347.5f; node_1.layout.height = 0; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 352.5f; + node_1.layout.top = 0; + node_1.layout.left = 352.5f; node_1.layout.width = 347.5f; node_1.layout.height = 0; } @@ -2332,7 +3701,53 @@ public class LayoutEngineTest { } @Test - public void testCase54() + public void testCase82() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 700; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.margin[Spacing.RIGHT] = 5; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 700; + node_0.layout.height = 0; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 352.5f; + node_1.layout.width = 347.5f; + node_1.layout.height = 0; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 347.5f; + node_1.layout.height = 0; + } + } + + test("should layout node with multiple flex and margin in rtl", root_node, root_layout); + } + + @Test + public void testCase83() { TestCSSNode root_node = new TestCSSNode(); { @@ -2351,21 +3766,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 300; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 600; node_1 = node_0.getChildAt(1); - node_1.layout.y = 600; - node_1.layout.x = 0; + node_1.layout.top = 600; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2375,7 +3790,7 @@ public class LayoutEngineTest { } @Test - public void testCase55() + public void testCase84() { TestCSSNode root_node = new TestCSSNode(); { @@ -2394,16 +3809,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 600; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2413,7 +3828,46 @@ public class LayoutEngineTest { } @Test - public void testCase56() + public void testCase85() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 600; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.positionType = CSSPositionType.ABSOLUTE; + node_1.style.flex = 1; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 600; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 600; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout node with flex and position absolute in rtl", root_node, root_layout); + } + + @Test + public void testCase86() { TestCSSNode root_node = new TestCSSNode(); { @@ -2433,21 +3887,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 500; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 500; node_1 = node_0.getChildAt(1); - node_1.layout.y = 500; - node_1.layout.x = 0; + node_1.layout.top = 500; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2457,7 +3911,7 @@ public class LayoutEngineTest { } @Test - public void testCase57() + public void testCase87() { TestCSSNode root_node = new TestCSSNode(); { @@ -2471,8 +3925,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 10; } @@ -2481,7 +3935,7 @@ public class LayoutEngineTest { } @Test - public void testCase58() + public void testCase88() { TestCSSNode root_node = new TestCSSNode(); { @@ -2499,16 +3953,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 1; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2518,7 +3972,7 @@ public class LayoutEngineTest { } @Test - public void testCase59() + public void testCase89() { TestCSSNode root_node = new TestCSSNode(); { @@ -2539,16 +3993,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 2; node_0.layout.height = 2; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 1; - node_1.layout.x = 6; + node_1.layout.top = 1; + node_1.layout.left = 6; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2558,7 +4012,7 @@ public class LayoutEngineTest { } @Test - public void testCase60() + public void testCase90() { TestCSSNode root_node = new TestCSSNode(); { @@ -2580,16 +4034,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 50; node_0.layout.height = 40; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 20; + node_1.layout.top = 0; + node_1.layout.left = 20; node_1.layout.width = 40; node_1.layout.height = 40; } @@ -2599,7 +4053,7 @@ public class LayoutEngineTest { } @Test - public void testCase61() + public void testCase91() { TestCSSNode root_node = new TestCSSNode(); { @@ -2616,16 +4070,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 5; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 5; node_1.layout.height = 0; } @@ -2635,7 +4089,7 @@ public class LayoutEngineTest { } @Test - public void testCase62() + public void testCase92() { TestCSSNode root_node = new TestCSSNode(); { @@ -2653,16 +4107,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -2672,7 +4126,45 @@ public class LayoutEngineTest { } @Test - public void testCase63() + public void testCase93() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.border[Spacing.LEFT] = 1; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.margin[Spacing.LEFT] = -8; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 1; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should handle negative margin and min padding correctly in rtl", root_node, root_layout); + } + + @Test + public void testCase94() { TestCSSNode root_node = new TestCSSNode(); { @@ -2684,8 +4176,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 34.671875f; node_0.layout.height = 18; } @@ -2694,7 +4186,7 @@ public class LayoutEngineTest { } @Test - public void testCase64() + public void testCase95() { TestCSSNode root_node = new TestCSSNode(); { @@ -2707,8 +4199,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 10; node_0.layout.height = 18; } @@ -2717,7 +4209,7 @@ public class LayoutEngineTest { } @Test - public void testCase65() + public void testCase96() { TestCSSNode root_node = new TestCSSNode(); { @@ -2729,8 +4221,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 172.421875f; node_0.layout.height = 18; } @@ -2739,7 +4231,7 @@ public class LayoutEngineTest { } @Test - public void testCase66() + public void testCase97() { TestCSSNode root_node = new TestCSSNode(); { @@ -2762,24 +4254,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 300; node_1.layout.height = 0; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 300; node_2.layout.height = 0; } @@ -2790,7 +4282,7 @@ public class LayoutEngineTest { } @Test - public void testCase67() + public void testCase98() { TestCSSNode root_node = new TestCSSNode(); { @@ -2815,24 +4307,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 500; node_0.layout.height = 18; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 500; node_1.layout.height = 18; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 500; node_2.layout.height = 18; } @@ -2843,7 +4335,61 @@ public class LayoutEngineTest { } @Test - public void testCase68() + public void testCase99() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.direction = CSSDirection.RTL; + node_1.style.flexDirection = CSSFlexDirection.ROW; + node_1.style.width = 500; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.flex = 1; + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "loooooooooong with space"; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 500; + node_0.layout.height = 18; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 500; + node_1.layout.height = 18; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 0; + node_2.layout.left = 0; + node_2.layout.width = 500; + node_2.layout.height = 18; + } + } + } + + test("should layout node with text and flex in rtl", root_node, root_layout); + } + + @Test + public void testCase100() { TestCSSNode root_node = new TestCSSNode(); { @@ -2868,24 +4414,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 130; node_0.layout.height = 36; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 130; node_1.layout.height = 36; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 130; node_2.layout.height = 36; } @@ -2896,7 +4442,7 @@ public class LayoutEngineTest { } @Test - public void testCase69() + public void testCase101() { TestCSSNode root_node = new TestCSSNode(); { @@ -2922,24 +4468,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 36; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 36; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 130; node_2.layout.height = 36; } @@ -2950,7 +4496,7 @@ public class LayoutEngineTest { } @Test - public void testCase70() + public void testCase102() { TestCSSNode root_node = new TestCSSNode(); { @@ -2970,16 +4516,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 36; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100.4375f; node_1.layout.height = 36; } @@ -2989,7 +4535,7 @@ public class LayoutEngineTest { } @Test - public void testCase71() + public void testCase103() { TestCSSNode root_node = new TestCSSNode(); { @@ -3022,24 +4568,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 76; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 20; - node_1.layout.x = 20; + node_1.layout.top = 20; + node_1.layout.left = 20; node_1.layout.width = 100.4375f; node_1.layout.height = 36; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 100.4375f; node_2.layout.height = 36; } @@ -3050,7 +4596,7 @@ public class LayoutEngineTest { } @Test - public void testCase72() + public void testCase104() { TestCSSNode root_node = new TestCSSNode(); { @@ -3069,21 +4615,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 900; node_1 = node_0.getChildAt(1); - node_1.layout.y = 900; - node_1.layout.x = 0; + node_1.layout.top = 900; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3093,7 +4639,51 @@ public class LayoutEngineTest { } @Test - public void testCase73() + public void testCase105() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.justifyContent = CSSJustify.SPACE_BETWEEN; + node_0.style.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 900; + node_1 = node_0.getChildAt(1); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 0; + node_0.layout.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = -800; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 900; + node_1 = node_0.getChildAt(1); + node_1.layout.top = -800; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 0; + } + } + + test("should layout space-between when remaining space is negative in reverse", root_node, root_layout); + } + + @Test + public void testCase106() { TestCSSNode root_node = new TestCSSNode(); { @@ -3112,16 +4702,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = -700; + node_1.layout.top = 0; + node_1.layout.left = -700; node_1.layout.width = 900; node_1.layout.height = 0; } @@ -3131,7 +4721,46 @@ public class LayoutEngineTest { } @Test - public void testCase74() + public void testCase107() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.justifyContent = CSSJustify.FLEX_END; + node_0.style.width = 200; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 900; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 0; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 900; + node_1.layout.height = 0; + } + } + + test("should layout flex-end when remaining space is negative in rtl", root_node, root_layout); + } + + @Test + public void testCase108() { TestCSSNode root_node = new TestCSSNode(); { @@ -3159,24 +4788,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 58; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 58; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 20; - node_2.layout.x = 20; + node_2.layout.top = 20; + node_2.layout.left = 20; node_2.layout.width = 172.421875f; node_2.layout.height = 18; } @@ -3187,7 +4816,64 @@ public class LayoutEngineTest { } @Test - public void testCase75() + public void testCase109() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flexDirection = CSSFlexDirection.ROW; + node_1.style.width = 200; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.margin[Spacing.LEFT] = 20; + node_2.style.margin[Spacing.TOP] = 20; + node_2.style.margin[Spacing.RIGHT] = 20; + node_2.style.margin[Spacing.BOTTOM] = 20; + node_2.setMeasureFunction(sTestMeasureFunction); + node_2.context = "loooooooooong with space"; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 58; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 200; + node_1.layout.height = 58; + addChildren(node_1, 1); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 20; + node_2.layout.left = 7.578125f; + node_2.layout.width = 172.421875f; + node_2.layout.height = 18; + } + } + } + + test("should layout text with flexDirection row in rtl", root_node, root_layout); + } + + @Test + public void testCase110() { TestCSSNode root_node = new TestCSSNode(); { @@ -3214,24 +4900,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 76; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 76; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 20; - node_2.layout.x = 20; + node_2.layout.top = 20; + node_2.layout.left = 20; node_2.layout.width = 160; node_2.layout.height = 36; } @@ -3242,7 +4928,7 @@ public class LayoutEngineTest { } @Test - public void testCase76() + public void testCase111() { TestCSSNode root_node = new TestCSSNode(); { @@ -3264,16 +4950,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 100; } @@ -3283,7 +4969,7 @@ public class LayoutEngineTest { } @Test - public void testCase77() + public void testCase112() { TestCSSNode root_node = new TestCSSNode(); { @@ -3306,21 +4992,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 25; node_1 = node_0.getChildAt(1); - node_1.layout.y = 25; - node_1.layout.x = 0; + node_1.layout.top = 25; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 75; } @@ -3330,11 +5016,60 @@ public class LayoutEngineTest { } @Test - public void testCase78() + public void testCase113() { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; + node_0.style.alignSelf = CSSAlign.FLEX_START; + node_0.style.width = 100; + node_0.style.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.alignSelf = CSSAlign.FLEX_START; + node_1.style.flex = 2.5f; + node_1 = node_0.getChildAt(1); + node_1.style.alignSelf = CSSAlign.FLEX_START; + node_1.style.flex = 7.5f; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 100; + node_0.layout.height = 100; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 75; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 25; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 0; + node_1.layout.height = 75; + } + } + + test("should layout with arbitrary flex in reverse", root_node, root_layout); + } + + @Test + public void testCase114() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; node_0.style.alignSelf = CSSAlign.FLEX_START; node_0.style.width = 100; node_0.style.height = 100; @@ -3353,31 +5088,31 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } } - test("should layout with negative flex", root_node, root_layout); + test("should layout with negative flex in reverse", root_node, root_layout); } @Test - public void testCase79() + public void testCase115() { TestCSSNode root_node = new TestCSSNode(); { @@ -3398,21 +5133,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 50; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 50; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 50; node_1.layout.height = 0; } @@ -3422,7 +5157,7 @@ public class LayoutEngineTest { } @Test - public void testCase80() + public void testCase116() { TestCSSNode root_node = new TestCSSNode(); { @@ -3441,16 +5176,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 80; } @@ -3460,7 +5195,7 @@ public class LayoutEngineTest { } @Test - public void testCase81() + public void testCase117() { TestCSSNode root_node = new TestCSSNode(); { @@ -3490,24 +5225,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 200; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 200; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 50; - node_2.layout.x = 0; + node_2.layout.top = 50; + node_2.layout.left = 0; node_2.layout.width = 100; node_2.layout.height = 100; } @@ -3518,7 +5253,7 @@ public class LayoutEngineTest { } @Test - public void testCase82() + public void testCase118() { TestCSSNode root_node = new TestCSSNode(); { @@ -3536,16 +5271,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 0; + node_1.layout.top = 100; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3555,7 +5290,7 @@ public class LayoutEngineTest { } @Test - public void testCase83() + public void testCase119() { TestCSSNode root_node = new TestCSSNode(); { @@ -3573,16 +5308,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 100; + node_1.layout.top = 0; + node_1.layout.left = 100; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3592,7 +5327,7 @@ public class LayoutEngineTest { } @Test - public void testCase84() + public void testCase120() { TestCSSNode root_node = new TestCSSNode(); { @@ -3611,16 +5346,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 90; - node_1.layout.x = 0; + node_1.layout.top = 90; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 10; } @@ -3630,7 +5365,7 @@ public class LayoutEngineTest { } @Test - public void testCase85() + public void testCase121() { TestCSSNode root_node = new TestCSSNode(); { @@ -3649,16 +5384,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 90; + node_1.layout.top = 0; + node_1.layout.left = 90; node_1.layout.width = 10; node_1.layout.height = 0; } @@ -3668,7 +5403,7 @@ public class LayoutEngineTest { } @Test - public void testCase86() + public void testCase122() { TestCSSNode root_node = new TestCSSNode(); { @@ -3686,16 +5421,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = -10; - node_1.layout.x = 0; + node_1.layout.top = -10; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 10; } @@ -3705,7 +5440,7 @@ public class LayoutEngineTest { } @Test - public void testCase87() + public void testCase123() { TestCSSNode root_node = new TestCSSNode(); { @@ -3723,16 +5458,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = -10; + node_1.layout.top = 0; + node_1.layout.left = -10; node_1.layout.width = 10; node_1.layout.height = 0; } @@ -3742,7 +5477,7 @@ public class LayoutEngineTest { } @Test - public void testCase88() + public void testCase124() { TestCSSNode root_node = new TestCSSNode(); { @@ -3759,16 +5494,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 1; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 1; } @@ -3778,7 +5513,7 @@ public class LayoutEngineTest { } @Test - public void testCase89() + public void testCase125() { TestCSSNode root_node = new TestCSSNode(); { @@ -3795,16 +5530,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = -3; - node_1.layout.x = 0; + node_1.layout.top = -3; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3814,7 +5549,7 @@ public class LayoutEngineTest { } @Test - public void testCase90() + public void testCase126() { TestCSSNode root_node = new TestCSSNode(); { @@ -3831,16 +5566,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 20; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 20; - node_1.layout.x = 0; + node_1.layout.top = 20; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3850,7 +5585,7 @@ public class LayoutEngineTest { } @Test - public void testCase91() + public void testCase127() { TestCSSNode root_node = new TestCSSNode(); { @@ -3867,16 +5602,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 5; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 0; } @@ -3886,7 +5621,7 @@ public class LayoutEngineTest { } @Test - public void testCase92() + public void testCase128() { TestCSSNode root_node = new TestCSSNode(); { @@ -3908,24 +5643,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 800; node_0.layout.height = 0; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 5; + node_1.layout.top = 0; + node_1.layout.left = 5; node_1.layout.width = 800; node_1.layout.height = 0; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 0; - node_2.layout.x = 0; + node_2.layout.top = 0; + node_2.layout.left = 0; node_2.layout.width = 800; node_2.layout.height = 0; } @@ -3936,7 +5671,7 @@ public class LayoutEngineTest { } @Test - public void testCase93() + public void testCase129() { TestCSSNode root_node = new TestCSSNode(); { @@ -3962,26 +5697,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 20; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 40; node_1.layout.height = 10; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 40; + node_1.layout.top = 0; + node_1.layout.left = 40; node_1.layout.width = 40; node_1.layout.height = 10; node_1 = node_0.getChildAt(2); - node_1.layout.y = 10; - node_1.layout.x = 0; + node_1.layout.top = 10; + node_1.layout.left = 0; node_1.layout.width = 40; node_1.layout.height = 10; } @@ -3991,7 +5726,63 @@ public class LayoutEngineTest { } @Test - public void testCase94() + public void testCase130() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.flexWrap = CSSWrap.WRAP; + node_0.style.width = 100; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 40; + node_1.style.height = 10; + node_1 = node_0.getChildAt(1); + node_1.style.width = 40; + node_1.style.height = 10; + node_1 = node_0.getChildAt(2); + node_1.style.width = 40; + node_1.style.height = 10; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 100; + node_0.layout.height = 20; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 60; + node_1.layout.width = 40; + node_1.layout.height = 10; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 20; + node_1.layout.width = 40; + node_1.layout.height = 10; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 10; + node_1.layout.left = 60; + node_1.layout.width = 40; + node_1.layout.height = 10; + } + } + + test("should layout flex-wrap in rtl", root_node, root_layout); + } + + @Test + public void testCase131() { TestCSSNode root_node = new TestCSSNode(); { @@ -4011,21 +5802,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 0; node_0.layout.height = 100; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 100; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 0; node_1.layout.height = 200; } @@ -4035,7 +5826,7 @@ public class LayoutEngineTest { } @Test - public void testCase95() + public void testCase132() { TestCSSNode root_node = new TestCSSNode(); { @@ -4049,8 +5840,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 90; node_0.layout.height = 190; } @@ -4059,7 +5850,7 @@ public class LayoutEngineTest { } @Test - public void testCase96() + public void testCase133() { TestCSSNode root_node = new TestCSSNode(); { @@ -4073,8 +5864,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 110; node_0.layout.height = 210; } @@ -4083,7 +5874,7 @@ public class LayoutEngineTest { } @Test - public void testCase97() + public void testCase134() { TestCSSNode root_node = new TestCSSNode(); { @@ -4099,8 +5890,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 110; node_0.layout.height = 210; } @@ -4109,7 +5900,7 @@ public class LayoutEngineTest { } @Test - public void testCase98() + public void testCase135() { TestCSSNode root_node = new TestCSSNode(); { @@ -4125,8 +5916,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 90; node_0.layout.height = 190; } @@ -4135,7 +5926,7 @@ public class LayoutEngineTest { } @Test - public void testCase99() + public void testCase136() { TestCSSNode root_node = new TestCSSNode(); { @@ -4149,8 +5940,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 200; } @@ -4159,7 +5950,7 @@ public class LayoutEngineTest { } @Test - public void testCase100() + public void testCase137() { TestCSSNode root_node = new TestCSSNode(); { @@ -4173,8 +5964,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 200; } @@ -4183,7 +5974,7 @@ public class LayoutEngineTest { } @Test - public void testCase101() + public void testCase138() { TestCSSNode root_node = new TestCSSNode(); { @@ -4199,8 +5990,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 40; node_0.layout.height = 30; } @@ -4209,7 +6000,7 @@ public class LayoutEngineTest { } @Test - public void testCase102() + public void testCase139() { TestCSSNode root_node = new TestCSSNode(); { @@ -4225,8 +6016,8 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 50; node_0.layout.height = 40; } @@ -4235,7 +6026,7 @@ public class LayoutEngineTest { } @Test - public void testCase103() + public void testCase140() { TestCSSNode root_node = new TestCSSNode(); { @@ -4259,26 +6050,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 50; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 50; + node_1.layout.top = 0; + node_1.layout.left = 50; node_1.layout.width = 200; node_1.layout.height = 200; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 250; + node_1.layout.top = 0; + node_1.layout.left = 250; node_1.layout.width = 50; node_1.layout.height = 200; } @@ -4288,7 +6079,61 @@ public class LayoutEngineTest { } @Test - public void testCase104() + public void testCase141() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 300; + node_0.style.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.minWidth = 200; + node_1 = node_0.getChildAt(2); + node_1.style.flex = 1; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 250; + node_1.layout.width = 50; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 50; + node_1.layout.width = 200; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 50; + node_1.layout.height = 200; + } + } + + test("should override flex direction size with min bounds in rtl", root_node, root_layout); + } + + @Test + public void testCase142() { TestCSSNode root_node = new TestCSSNode(); { @@ -4313,26 +6158,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 100; + node_1.layout.top = 0; + node_1.layout.left = 100; node_1.layout.width = 100; node_1.layout.height = 200; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 200; + node_1.layout.top = 0; + node_1.layout.left = 200; node_1.layout.width = 100; node_1.layout.height = 200; } @@ -4342,7 +6187,62 @@ public class LayoutEngineTest { } @Test - public void testCase105() + public void testCase143() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 300; + node_0.style.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.maxWidth = 110; + node_1.style.minWidth = 90; + node_1 = node_0.getChildAt(2); + node_1.style.flex = 1; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 200; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 100; + node_1.layout.width = 100; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 200; + } + } + + test("should not override flex direction size within bounds in rtl", root_node, root_layout); + } + + @Test + public void testCase144() { TestCSSNode root_node = new TestCSSNode(); { @@ -4366,26 +6266,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 120; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 120; + node_1.layout.top = 0; + node_1.layout.left = 120; node_1.layout.width = 60; node_1.layout.height = 200; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 180; + node_1.layout.top = 0; + node_1.layout.left = 180; node_1.layout.width = 120; node_1.layout.height = 200; } @@ -4395,7 +6295,61 @@ public class LayoutEngineTest { } @Test - public void testCase106() + public void testCase145() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 300; + node_0.style.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.maxWidth = 60; + node_1 = node_0.getChildAt(2); + node_1.style.flex = 1; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 180; + node_1.layout.width = 120; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 120; + node_1.layout.width = 60; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 120; + node_1.layout.height = 200; + } + } + + test("should override flex direction size with max bounds in rtl", root_node, root_layout); + } + + @Test + public void testCase146() { TestCSSNode root_node = new TestCSSNode(); { @@ -4421,26 +6375,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 60; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 60; + node_1.layout.top = 0; + node_1.layout.left = 60; node_1.layout.width = 60; node_1.layout.height = 200; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 120; + node_1.layout.top = 0; + node_1.layout.left = 120; node_1.layout.width = 60; node_1.layout.height = 200; } @@ -4450,7 +6404,63 @@ public class LayoutEngineTest { } @Test - public void testCase107() + public void testCase147() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 300; + node_0.style.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.maxWidth = 60; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.maxWidth = 60; + node_1 = node_0.getChildAt(2); + node_1.style.flex = 1; + node_1.style.maxWidth = 60; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 240; + node_1.layout.width = 60; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 180; + node_1.layout.width = 60; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = 120; + node_1.layout.width = 60; + node_1.layout.height = 200; + } + } + + test("should ignore flex size if fully max bound in rtl", root_node, root_layout); + } + + @Test + public void testCase148() { TestCSSNode root_node = new TestCSSNode(); { @@ -4476,26 +6486,26 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 120; node_1.layout.height = 200; node_1 = node_0.getChildAt(1); - node_1.layout.y = 0; - node_1.layout.x = 120; + node_1.layout.top = 0; + node_1.layout.left = 120; node_1.layout.width = 120; node_1.layout.height = 200; node_1 = node_0.getChildAt(2); - node_1.layout.y = 0; - node_1.layout.x = 240; + node_1.layout.top = 0; + node_1.layout.left = 240; node_1.layout.width = 120; node_1.layout.height = 200; } @@ -4505,7 +6515,63 @@ public class LayoutEngineTest { } @Test - public void testCase108() + public void testCase149() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 300; + node_0.style.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flex = 1; + node_1.style.minWidth = 120; + node_1 = node_0.getChildAt(1); + node_1.style.flex = 1; + node_1.style.minWidth = 120; + node_1 = node_0.getChildAt(2); + node_1.style.flex = 1; + node_1.style.minWidth = 120; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 300; + node_0.layout.height = 200; + addChildren(node_0, 3); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 180; + node_1.layout.width = 120; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 60; + node_1.layout.width = 120; + node_1.layout.height = 200; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = -60; + node_1.layout.width = 120; + node_1.layout.height = 200; + } + } + + test("should ignore flex size if fully min bound in rtl", root_node, root_layout); + } + + @Test + public void testCase150() { TestCSSNode root_node = new TestCSSNode(); { @@ -4525,16 +6591,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 300; node_1.layout.height = 200; } @@ -4544,7 +6610,7 @@ public class LayoutEngineTest { } @Test - public void testCase109() + public void testCase151() { TestCSSNode root_node = new TestCSSNode(); { @@ -4563,16 +6629,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 290; node_1.layout.height = 200; } @@ -4582,7 +6648,7 @@ public class LayoutEngineTest { } @Test - public void testCase110() + public void testCase152() { TestCSSNode root_node = new TestCSSNode(); { @@ -4601,16 +6667,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 200; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 310; node_1.layout.height = 200; } @@ -4620,7 +6686,7 @@ public class LayoutEngineTest { } @Test - public void testCase111() + public void testCase153() { TestCSSNode root_node = new TestCSSNode(); { @@ -4644,21 +6710,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 200; node_0.layout.height = 600; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; node_1 = node_0.getChildAt(1); - node_1.layout.y = 300; - node_1.layout.x = 0; + node_1.layout.top = 300; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; } @@ -4668,7 +6734,7 @@ public class LayoutEngineTest { } @Test - public void testCase112() + public void testCase154() { TestCSSNode root_node = new TestCSSNode(); { @@ -4690,21 +6756,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 100; node_0.layout.height = 500; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; node_1 = node_0.getChildAt(1); - node_1.layout.y = 300; - node_1.layout.x = 0; + node_1.layout.top = 300; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; } @@ -4714,7 +6780,7 @@ public class LayoutEngineTest { } @Test - public void testCase113() + public void testCase155() { TestCSSNode root_node = new TestCSSNode(); { @@ -4736,21 +6802,21 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 300; node_0.layout.height = 700; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; node_1 = node_0.getChildAt(1); - node_1.layout.y = 300; - node_1.layout.x = 0; + node_1.layout.top = 300; + node_1.layout.left = 0; node_1.layout.width = 200; node_1.layout.height = 300; } @@ -4760,7 +6826,7 @@ public class LayoutEngineTest { } @Test - public void testCase114() + public void testCase156() { TestCSSNode root_node = new TestCSSNode(); { @@ -4782,16 +6848,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 100; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 1000; node_1.layout.height = 100; } @@ -4801,7 +6867,7 @@ public class LayoutEngineTest { } @Test - public void testCase115() + public void testCase157() { TestCSSNode root_node = new TestCSSNode(); { @@ -4821,16 +6887,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 90; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 900; node_1.layout.height = 90; } @@ -4840,7 +6906,7 @@ public class LayoutEngineTest { } @Test - public void testCase116() + public void testCase158() { TestCSSNode root_node = new TestCSSNode(); { @@ -4860,16 +6926,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 110; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 1100; node_1.layout.height = 110; } @@ -4879,7 +6945,7 @@ public class LayoutEngineTest { } @Test - public void testCase117() + public void testCase159() { TestCSSNode root_node = new TestCSSNode(); { @@ -4899,16 +6965,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 110; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 100; node_1.layout.height = 110; } @@ -4918,7 +6984,47 @@ public class LayoutEngineTest { } @Test - public void testCase118() + public void testCase160() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.width = 1000; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 100; + node_1.style.minWidth = 100; + node_1.style.minHeight = 110; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 1000; + node_0.layout.height = 110; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 900; + node_1.layout.width = 100; + node_1.layout.height = 110; + } + } + + test("should keep cross axis size within min bounds in rtl", root_node, root_layout); + } + + @Test + public void testCase161() { TestCSSNode root_node = new TestCSSNode(); { @@ -4942,16 +7048,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 100; + node_1.layout.top = 100; + node_1.layout.left = 100; node_1.layout.width = 500; node_1.layout.height = 600; } @@ -4961,7 +7067,7 @@ public class LayoutEngineTest { } @Test - public void testCase119() + public void testCase162() { TestCSSNode root_node = new TestCSSNode(); { @@ -4985,16 +7091,16 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 1000; node_0.layout.height = 1000; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 100; + node_1.layout.top = 100; + node_1.layout.left = 100; node_1.layout.width = 900; node_1.layout.height = 1000; } @@ -5004,7 +7110,7 @@ public class LayoutEngineTest { } @Test - public void testCase120() + public void testCase163() { TestCSSNode root_node = new TestCSSNode(); { @@ -5040,24 +7146,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 400; node_0.layout.height = 400; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 100; + node_1.layout.top = 100; + node_1.layout.left = 100; node_1.layout.width = 200; node_1.layout.height = 200; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 10; - node_2.layout.x = 10; + node_2.layout.top = 10; + node_2.layout.left = 10; node_2.layout.width = 180; node_2.layout.height = 180; } @@ -5068,7 +7174,7 @@ public class LayoutEngineTest { } @Test - public void testCase121() + public void testCase164() { TestCSSNode root_node = new TestCSSNode(); { @@ -5108,24 +7214,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 400; node_0.layout.height = 400; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 100; - node_1.layout.x = 100; + node_1.layout.top = 100; + node_1.layout.left = 100; node_1.layout.width = 200; node_1.layout.height = 200; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 11; - node_2.layout.x = 11; + node_2.layout.top = 11; + node_2.layout.left = 11; node_2.layout.width = 178; node_2.layout.height = 178; } @@ -5136,7 +7242,7 @@ public class LayoutEngineTest { } @Test - public void testCase122() + public void testCase165() { TestCSSNode root_node = new TestCSSNode(); { @@ -5168,24 +7274,24 @@ public class LayoutEngineTest { TestCSSNode root_layout = new TestCSSNode(); { TestCSSNode node_0 = root_layout; - node_0.layout.y = 0; - node_0.layout.x = 0; + node_0.layout.top = 0; + node_0.layout.left = 0; node_0.layout.width = 400; node_0.layout.height = 400; addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.layout.y = 0; - node_1.layout.x = 0; + node_1.layout.top = 0; + node_1.layout.left = 0; node_1.layout.width = 400; node_1.layout.height = 400; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.layout.y = 10; - node_2.layout.x = 10; + node_2.layout.top = 10; + node_2.layout.left = 10; node_2.layout.width = 380; node_2.layout.height = 380; } @@ -5194,5 +7300,99 @@ public class LayoutEngineTest { test("should layout absolutely positioned node with padded flex 1 parent", root_node, root_layout); } + + @Test + public void testCase166() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.width = 200; + node_0.style.height = 200; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.flexDirection = CSSFlexDirection.ROW; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.width = 50; + node_2.style.height = 50; + node_2 = node_1.getChildAt(1); + node_2.style.width = 50; + node_2.style.height = 50; + } + node_1 = node_0.getChildAt(1); + node_1.style.direction = CSSDirection.LTR; + node_1.style.flexDirection = CSSFlexDirection.ROW; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.style.width = 50; + node_2.style.height = 50; + node_2 = node_1.getChildAt(1); + node_2.style.width = 50; + node_2.style.height = 50; + } + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 200; + addChildren(node_0, 2); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 200; + node_1.layout.height = 50; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 0; + node_2.layout.left = 150; + node_2.layout.width = 50; + node_2.layout.height = 50; + node_2 = node_1.getChildAt(1); + node_2.layout.top = 0; + node_2.layout.left = 100; + node_2.layout.width = 50; + node_2.layout.height = 50; + } + node_1 = node_0.getChildAt(1); + node_1.layout.top = 50; + node_1.layout.left = 0; + node_1.layout.width = 200; + node_1.layout.height = 50; + addChildren(node_1, 2); + { + TestCSSNode node_2; + node_2 = node_1.getChildAt(0); + node_2.layout.top = 0; + node_2.layout.left = 0; + node_2.layout.width = 50; + node_2.layout.height = 50; + node_2 = node_1.getChildAt(1); + node_2.layout.top = 0; + node_2.layout.left = 50; + node_2.layout.width = 50; + node_2.layout.height = 50; + } + } + } + + test("should layout nested nodes with mixed directions", root_node, root_layout); + } /** END_GENERATED **/ } diff --git a/src/transpile.js b/src/transpile.js index 193631dc..cc39b2f1 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -111,9 +111,15 @@ function printLayout(test) { } } + addEnum(node, 'direction', 'direction', { + 'ltr': 'CSS_DIRECTION_LTR', + 'rtl': 'CSS_DIRECTION_RTL' + }); addEnum(node, 'flexDirection', 'flex_direction', { 'row': 'CSS_FLEX_DIRECTION_ROW', - 'column': 'CSS_FLEX_DIRECTION_COLUMN' + 'row-reverse': 'CSS_FLEX_DIRECTION_ROW_REVERSE', + 'column': 'CSS_FLEX_DIRECTION_COLUMN', + 'column-reverse': 'CSS_FLEX_DIRECTION_COLUMN_REVERSE' }); addEnum(node, 'justifyContent', 'justify_content', { 'flex-start': 'CSS_JUSTIFY_FLEX_START', @@ -234,6 +240,7 @@ function transpileAnnotatedJStoC(jsCode) { .replace(/layout\[dim/g, 'layout.dimensions[dim') .replace(/layout\[pos/g, 'layout.position[pos') .replace(/layout\[leading/g, 'layout.position[leading') + .replace(/layout\[trailing/g, 'layout.position[trailing') .replace(/style\[dim/g, 'style.dimensions[dim') .replace(/node.children\[i\]/g, 'node->get_child(node->context, i)') .replace(/node\./g, 'node->') From bf1d7eacfdac78dad65e77d985b49f1232590383 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Tue, 12 May 2015 09:54:02 +0100 Subject: [PATCH 3/8] Fixed spacing for wrapped elements --- src/Layout.c | 1 + src/Layout.js | 1 + src/__tests__/Layout-test.c | 79 ++++++++++++++++++ src/__tests__/Layout-test.js | 21 +++++ .../com/facebook/csslayout/LayoutEngine.java | 1 + .../facebook/csslayout/LayoutEngineTest.java | 81 +++++++++++++++++++ 6 files changed, 184 insertions(+) diff --git a/src/Layout.c b/src/Layout.c index 023db820..116e4ae3 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -624,6 +624,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { + nonFlexibleChildrenCount --; alreadyComputedNextLayout = 1; break; } diff --git a/src/Layout.js b/src/Layout.js index 0880c7be..b263f66b 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -520,6 +520,7 @@ var computeLayout = (function() { // If there's only one element, then it's bigger than the content // and needs its own line i !== startLine) { + nonFlexibleChildrenCount --; alreadyComputedNextLayout = 1; break; } diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 6560e7d5..6a67bb4c 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -6985,6 +6985,85 @@ int main() test("should layout nested nodes with mixed directions", root_node, root_layout); } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; + node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; + node_0->style.flex_wrap = CSS_WRAP; + node_0->style.dimensions[CSS_WIDTH] = 320; + node_0->style.dimensions[CSS_HEIGHT] = 200; + init_css_node_children(node_0, 6); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 2); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 3); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 4); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 5); + node_1->style.dimensions[CSS_WIDTH] = 100; + node_1->style.dimensions[CSS_HEIGHT] = 100; + } + } + + 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] = 200; + init_css_node_children(node_0, 6); + { + 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] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 110; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 2); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 220; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 3); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 4); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 110; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 5); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 220; + node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + } + } + + test("should correctly space wrapped nodes", root_node, root_layout); + } /** END_GENERATED **/ return tests_finished(); } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index b23f52fb..399e6a6c 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -2185,4 +2185,25 @@ describe('Layout', function() { ]} ); }); + + it('should correctly space wrapped nodes', function() { + testLayout( + {style: {width: 320, height: 200, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, children: [ + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}}, + {style: {width: 100, height: 100}}, + ]}, + {width: 320, height: 200, top: 0, left: 0, children: [ + {width: 100, height: 100, top: 0, left: 0}, + {width: 100, height: 100, top: 0, left: 110}, + {width: 100, height: 100, top: 0, left: 220}, + {width: 100, height: 100, top: 100, left: 0}, + {width: 100, height: 100, top: 100, left: 110}, + {width: 100, height: 100, top: 100, left: 220}, + ]} + ); + }); }); diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index de8f15cc..39d9b8be 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -609,6 +609,7 @@ public class LayoutEngine { // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { + nonFlexibleChildrenCount --; alreadyComputedNextLayout = 1; break; } diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index 6efbef3a..e47c7989 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -7394,5 +7394,86 @@ public class LayoutEngineTest { test("should layout nested nodes with mixed directions", root_node, root_layout); } + + @Test + public void testCase167() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.flexDirection = CSSFlexDirection.ROW; + node_0.style.justifyContent = CSSJustify.SPACE_BETWEEN; + node_0.style.flexWrap = CSSWrap.WRAP; + node_0.style.width = 320; + node_0.style.height = 200; + addChildren(node_0, 6); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(1); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(2); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(3); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(4); + node_1.style.width = 100; + node_1.style.height = 100; + node_1 = node_0.getChildAt(5); + node_1.style.width = 100; + node_1.style.height = 100; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 320; + node_0.layout.height = 200; + addChildren(node_0, 6); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(1); + node_1.layout.top = 0; + node_1.layout.left = 110; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(2); + node_1.layout.top = 0; + node_1.layout.left = 220; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(3); + node_1.layout.top = 100; + node_1.layout.left = 0; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(4); + node_1.layout.top = 100; + node_1.layout.left = 110; + node_1.layout.width = 100; + node_1.layout.height = 100; + node_1 = node_0.getChildAt(5); + node_1.layout.top = 100; + node_1.layout.left = 220; + node_1.layout.width = 100; + node_1.layout.height = 100; + } + } + + test("should correctly space wrapped nodes", root_node, root_layout); + } /** END_GENERATED **/ } From 9175721f07d3b7a8a1091f969fbd0b3ff8a10278 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Tue, 12 May 2015 10:10:39 +0100 Subject: [PATCH 4/8] Removed space before -- for consistency with code style. --- src/Layout.c | 2 +- src/Layout.js | 2 +- src/java/src/com/facebook/csslayout/LayoutEngine.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Layout.c b/src/Layout.c index 116e4ae3..8c7fa5ec 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -624,7 +624,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { - nonFlexibleChildrenCount --; + nonFlexibleChildrenCount--; alreadyComputedNextLayout = 1; break; } diff --git a/src/Layout.js b/src/Layout.js index b263f66b..1653d705 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -520,7 +520,7 @@ var computeLayout = (function() { // If there's only one element, then it's bigger than the content // and needs its own line i !== startLine) { - nonFlexibleChildrenCount --; + nonFlexibleChildrenCount--; alreadyComputedNextLayout = 1; break; } diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 39d9b8be..25a0e233 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -609,7 +609,7 @@ public class LayoutEngine { // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { - nonFlexibleChildrenCount --; + nonFlexibleChildrenCount--; alreadyComputedNextLayout = 1; break; } From bb8fdf57ebfdd0897774e1b3cf4928c869b62b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Oghin=C4=83?= Date: Thu, 14 May 2015 13:59:13 +0100 Subject: [PATCH 5/8] [java] implement proper spacing objects, with support for default spacing --- src/JavaTranspiler.js | 10 +- .../src/com/facebook/csslayout/CSSNode.java | 39 +- .../src/com/facebook/csslayout/CSSStyle.java | 6 +- .../com/facebook/csslayout/LayoutEngine.java | 24 +- .../src/com/facebook/csslayout/Spacing.java | 177 ++++++--- .../facebook/csslayout/LayoutEngineTest.java | 376 +++++++++--------- 6 files changed, 359 insertions(+), 273 deletions(-) diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index d3b1304e..7d2c9148 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -76,10 +76,16 @@ function __transpileSingleTestToJava(code) { function (str, match1, match2) { return 'style.' + match1 + match2[0] + match2.substring(1).toLowerCase(); }) - .replace( // style.margin[CSS_TOP] => style.margin[Spacing.TOP] + .replace( // style.margin[CSS_TOP] = 12.3 => style.margin[Spacing.TOP].set(12.3) + /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]\s+=\s+(-?[\.\d]+)/g, + function (str, match1, match2, match3) { + var propertyCap = match1.charAt(0).toUpperCase() + match1.slice(1); + return 'set' + propertyCap + '(Spacing.' + match2 + ', ' + match3 + ')'; + }) + .replace( // style.margin[CSS_TOP] => style.margin.get(Spacing.TOP) /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, function (str, match1, match2) { - return 'style.' + match1 + '[Spacing.' + match2 + ']'; + return 'style.' + match1 + '.get(Spacing.' + match2 + ')'; }) .replace(/get_child\(.*context\,\s([^\)]+)\)/g, 'getChildAt($1)') .replace(/init_css_node_children/g, 'addChildren') diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java index f3f97983..9d62c7fa 100644 --- a/src/java/src/com/facebook/csslayout/CSSNode.java +++ b/src/java/src/com/facebook/csslayout/CSSNode.java @@ -49,10 +49,6 @@ public class CSSNode { public void measure(CSSNode node, float width, MeasureOutput measureOutput); } - private final float[] mMargin = Spacing.newFullSpacingArray(); - private final float[] mPadding = Spacing.newFullSpacingArray(); - private final float[] mBorder = Spacing.newFullSpacingArray(); - // VisibleForTesting /*package*/ final CSSStyle style = new CSSStyle(); /*package*/ final CSSLayout layout = new CSSLayout(); @@ -263,24 +259,19 @@ public class CSSNode { } public void setMargin(int spacingType, float margin) { - setSpacing(mMargin, style.margin, spacingType, margin); + if (style.margin.set(spacingType, margin)) { + dirty(); + } } public void setPadding(int spacingType, float padding) { - setSpacing(mPadding, style.padding, spacingType, padding); + if (style.padding.set(spacingType, padding)) { + dirty(); + } } public void setBorder(int spacingType, float border) { - setSpacing(mBorder, style.border, spacingType, border); - } - - protected void setSpacing( - float[] spacingDef, - float[] cssStyle, - int spacingType, - float spacing) { - if (!valuesEqual(spacingDef[spacingType], spacing)) { - Spacing.updateSpacing(spacingDef, cssStyle, spacingType, spacing, 0); + if (style.border.set(spacingType, border)) { dirty(); } } @@ -342,4 +333,20 @@ public class CSSNode { public float getLayoutHeight() { return layout.height; } + + /** + * Get this node's padding, as defined by style + default padding. + */ + public Spacing getStylePadding() { + return style.padding; + } + + /** + * Set a default padding (left/top/right/bottom) for this node. + */ + public void setDefaultPadding(int spacingType, float padding) { + if (style.padding.setDefault(spacingType, padding)) { + dirty(); + } + } } diff --git a/src/java/src/com/facebook/csslayout/CSSStyle.java b/src/java/src/com/facebook/csslayout/CSSStyle.java index 9bf46eb1..6d01db3d 100644 --- a/src/java/src/com/facebook/csslayout/CSSStyle.java +++ b/src/java/src/com/facebook/csslayout/CSSStyle.java @@ -22,9 +22,9 @@ public class CSSStyle { public CSSWrap flexWrap = CSSWrap.NOWRAP; public float flex; - public float[] margin = Spacing.newSpacingResultArray(); - public float[] padding = Spacing.newSpacingResultArray(); - public float[] border = Spacing.newSpacingResultArray(); + public Spacing margin = new Spacing(); + public Spacing padding = new Spacing(); + public Spacing border = new Spacing(); public float positionTop = CSSConstants.UNDEFINED; public float positionBottom = CSSConstants.UNDEFINED; diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 25a0e233..5458f92b 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -184,13 +184,13 @@ public class LayoutEngine { private static float getMargin(CSSNode node, PositionIndex position) { switch (position) { case TOP: - return node.style.margin[Spacing.TOP]; + return node.style.margin.get(Spacing.TOP); case BOTTOM: - return node.style.margin[Spacing.BOTTOM]; + return node.style.margin.get(Spacing.BOTTOM); case LEFT: - return node.style.margin[Spacing.LEFT]; + return node.style.margin.get(Spacing.LEFT); case RIGHT: - return node.style.margin[Spacing.RIGHT]; + return node.style.margin.get(Spacing.RIGHT); default: throw new RuntimeException("Someone added a new cardinal direction..."); } @@ -199,13 +199,13 @@ public class LayoutEngine { private static float getPadding(CSSNode node, PositionIndex position) { switch (position) { case TOP: - return node.style.padding[Spacing.TOP]; + return node.style.padding.get(Spacing.TOP); case BOTTOM: - return node.style.padding[Spacing.BOTTOM]; + return node.style.padding.get(Spacing.BOTTOM); case LEFT: - return node.style.padding[Spacing.LEFT]; + return node.style.padding.get(Spacing.LEFT); case RIGHT: - return node.style.padding[Spacing.RIGHT]; + return node.style.padding.get(Spacing.RIGHT); default: throw new RuntimeException("Someone added a new cardinal direction..."); } @@ -214,13 +214,13 @@ public class LayoutEngine { private static float getBorder(CSSNode node, PositionIndex position) { switch (position) { case TOP: - return node.style.border[Spacing.TOP]; + return node.style.border.get(Spacing.TOP); case BOTTOM: - return node.style.border[Spacing.BOTTOM]; + return node.style.border.get(Spacing.BOTTOM); case LEFT: - return node.style.border[Spacing.LEFT]; + return node.style.border.get(Spacing.LEFT); case RIGHT: - return node.style.border[Spacing.RIGHT]; + return node.style.border.get(Spacing.RIGHT); default: throw new RuntimeException("Someone added a new cardinal direction..."); } diff --git a/src/java/src/com/facebook/csslayout/Spacing.java b/src/java/src/com/facebook/csslayout/Spacing.java index 32ab3a97..24b25590 100644 --- a/src/java/src/com/facebook/csslayout/Spacing.java +++ b/src/java/src/com/facebook/csslayout/Spacing.java @@ -9,27 +9,102 @@ package com.facebook.csslayout; /** - * Utility class for handling CSS spacing (padding, margin, and borders). This is mostly necessary - * to properly implement interactions and updates for properties like margin, marginLeft, and - * marginHorizontal. This is not a great API and should probably be updated to use actual objects - * for type safety, defaults safety, and simplicity. + * Class representing CSS spacing (padding, margin, and borders). This is mostly necessary to + * properly implement interactions and updates for properties like margin, marginLeft, and + * marginHorizontal. */ public class Spacing { - // Indices into FullSpacingArray and SpacingResultArray + /** + * Spacing type that represents the left direction. E.g. {@code marginLeft}. + */ public static final int LEFT = 0; + /** + * Spacing type that represents the top direction. E.g. {@code marginTop}. + */ public static final int TOP = 1; + /** + * Spacing type that represents the right direction. E.g. {@code marginRight}. + */ public static final int RIGHT = 2; + /** + * Spacing type that represents the bottom direction. E.g. {@code marginBottom}. + */ public static final int BOTTOM = 3; + /** + * Spacing type that represents vertical direction (top and bottom). E.g. {@code marginVertical}. + */ public static final int VERTICAL = 4; + /** + * Spacing type that represents horizontal direction (left and right). E.g. + * {@code marginHorizontal}. + */ public static final int HORIZONTAL = 5; + /** + * Spacing type that represents all directions (left, top, right, bottom). E.g. {@code margin}. + */ public static final int ALL = 6; + private final float[] mSpacing = newFullSpacingArray(); + private final float[] mDefaultSpacing = newSpacingResultArray(); + private final float[] mSpacingResult = newSpacingResultArray(); + private boolean mDirty; + /** - * @return an instance of an array that can be used with {@link #updateSpacing}. Stores - * the value for each spacing type or NaN if it hasn't been explicitly set. + * Set a spacing value. + * + * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM}, + * {@link #VERTICAL}, {@link #HORIZONTAL}, {@link #ALL} + * @param value the value for this direction + * @return {@code true} if the spacing has changed, or {@code false} if the same value was already + * set */ - public static float[] newFullSpacingArray() { + public boolean set(int spacingType, float value) { + if (!FloatUtil.floatsEqual(mSpacing[spacingType], value)) { + mSpacing[spacingType] = value; + mDirty = true; + } + return mDirty; + } + + /** + * Set a default spacing value. This is used as a fallback when no spacing has been set for a + * particular direction. + * + * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} + * @param value the default value for this direction + * @return + */ + public boolean setDefault(int spacingType, float value) { + if (!FloatUtil.floatsEqual(mDefaultSpacing[spacingType], value)) { + mDefaultSpacing[spacingType] = value; + mDirty = true; + } + return mDirty; + } + + /** + * Get the spacing for a direction. This takes into account any default values that have been set. + * + * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} + */ + public float get(int spacingType) { + ensureResult(); + return mSpacingResult[spacingType]; + } + + /** + * Get the raw value (that was set using {@link #set(int, float)}), without taking into account + * any default values. + * + * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM}, + * {@link #VERTICAL}, {@link #HORIZONTAL}, {@link #ALL} + */ + public float getRaw(int spacingType) { + return mSpacing[spacingType]; + } + + private static float[] newFullSpacingArray() { return new float[] { CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, @@ -42,18 +117,11 @@ public class Spacing { }; } - /** - * @return {@link #newSpacingResultArray} filled with zero. - */ - public static float[] newSpacingResultArray() { + private static float[] newSpacingResultArray() { return newSpacingResultArray(0); } - /** - * @return an instance of an array used to store the end result of the interactions between the - * values in a full spacing array. Use {@link #TOP}, etc to access result values. - */ - public static float[] newSpacingResultArray(float defaultValue) { + private static float[] newSpacingResultArray(float defaultValue) { return new float[] { defaultValue, defaultValue, @@ -63,41 +131,46 @@ public class Spacing { } /** - * Given the fullSpacing from {@link #newFullSpacingArray()} and the spacingResult from - * {@link #newSpacingResultArray()} from a View, update them both to reflect a new value for the - * given spacingType (e.g. {@link #TOP}). defaultValue specifies the result value that should be - * used whenever a spacing property hasn't been set. + * Given the {@param fullSpacing} and the spacingResult from {@link #newSpacingResultArray()} from + * a View, update the result array to reflect values that have been set in {@param fullSpacing} + * array. {@param defaultValues} specifies the result values that should be used whenever a + * spacing property hasn't been set. */ - public static void updateSpacing( - float[] fullSpacing, - float[] spacingResult, - int spacingType, - float value, - float defaultValue) { - fullSpacing[spacingType] = value; - spacingResult[Spacing.TOP] = - !CSSConstants.isUndefined(fullSpacing[Spacing.TOP]) ? fullSpacing[Spacing.TOP] - : !CSSConstants.isUndefined(fullSpacing[Spacing.VERTICAL]) ? - fullSpacing[Spacing.VERTICAL] - : !CSSConstants.isUndefined(fullSpacing[Spacing.ALL]) ? fullSpacing[Spacing.ALL] - : defaultValue; - spacingResult[Spacing.BOTTOM] = - !CSSConstants.isUndefined(fullSpacing[Spacing.BOTTOM]) ? fullSpacing[Spacing.BOTTOM] - : !CSSConstants.isUndefined(fullSpacing[Spacing.VERTICAL]) ? - fullSpacing[Spacing.VERTICAL] - : !CSSConstants.isUndefined(fullSpacing[Spacing.ALL]) ? fullSpacing[Spacing.ALL] - : defaultValue; - spacingResult[Spacing.LEFT] = - !CSSConstants.isUndefined(fullSpacing[Spacing.LEFT]) ? fullSpacing[Spacing.LEFT] - : !CSSConstants.isUndefined(fullSpacing[Spacing.HORIZONTAL]) ? - fullSpacing[Spacing.HORIZONTAL] - : !CSSConstants.isUndefined(fullSpacing[Spacing.ALL]) ? fullSpacing[Spacing.ALL] - : defaultValue; - spacingResult[Spacing.RIGHT] = - !CSSConstants.isUndefined(fullSpacing[Spacing.RIGHT]) ? fullSpacing[Spacing.RIGHT] - : !CSSConstants.isUndefined(fullSpacing[Spacing.HORIZONTAL]) ? - fullSpacing[Spacing.HORIZONTAL] - : !CSSConstants.isUndefined(fullSpacing[Spacing.ALL]) ? fullSpacing[Spacing.ALL] - : defaultValue; + private void ensureResult() { + if (mDirty) { + mSpacingResult[TOP] = + !CSSConstants.isUndefined(mSpacing[TOP]) + ? mSpacing[TOP] + : !CSSConstants.isUndefined(mSpacing[VERTICAL]) + ? mSpacing[VERTICAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[TOP]; + mSpacingResult[BOTTOM] = + !CSSConstants.isUndefined(mSpacing[BOTTOM]) + ? mSpacing[BOTTOM] + : !CSSConstants.isUndefined(mSpacing[VERTICAL]) + ? mSpacing[VERTICAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[BOTTOM]; + mSpacingResult[LEFT] = + !CSSConstants.isUndefined(mSpacing[LEFT]) + ? mSpacing[LEFT] + : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) + ? mSpacing[HORIZONTAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[LEFT]; + mSpacingResult[RIGHT] = + !CSSConstants.isUndefined(mSpacing[RIGHT]) + ? mSpacing[RIGHT] + : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) + ? mSpacing[HORIZONTAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[RIGHT]; + mDirty = false; + } } } diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index e47c7989..a0c01885 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -370,10 +370,10 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 100; node_0.style.height = 200; - node_0.style.margin[Spacing.LEFT] = 10; - node_0.style.margin[Spacing.TOP] = 10; - node_0.style.margin[Spacing.RIGHT] = 10; - node_0.style.margin[Spacing.BOTTOM] = 10; + node_0.setMargin(Spacing.LEFT, 10); + node_0.setMargin(Spacing.TOP, 10); + node_0.setMargin(Spacing.RIGHT, 10); + node_0.setMargin(Spacing.BOTTOM, 10); } TestCSSNode root_layout = new TestCSSNode(); @@ -396,34 +396,34 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.margin[Spacing.LEFT] = 10; - node_0.style.margin[Spacing.TOP] = 10; - node_0.style.margin[Spacing.RIGHT] = 10; - node_0.style.margin[Spacing.BOTTOM] = 10; + node_0.setMargin(Spacing.LEFT, 10); + node_0.setMargin(Spacing.TOP, 10); + node_0.setMargin(Spacing.RIGHT, 10); + node_0.setMargin(Spacing.BOTTOM, 10); addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 50; - node_1.style.margin[Spacing.TOP] = 50; - node_1.style.margin[Spacing.RIGHT] = 50; - node_1.style.margin[Spacing.BOTTOM] = 50; + node_1.setMargin(Spacing.LEFT, 50); + node_1.setMargin(Spacing.TOP, 50); + node_1.setMargin(Spacing.RIGHT, 50); + node_1.setMargin(Spacing.BOTTOM, 50); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 25; - node_1.style.margin[Spacing.TOP] = 25; - node_1.style.margin[Spacing.RIGHT] = 25; - node_1.style.margin[Spacing.BOTTOM] = 25; + node_1.setMargin(Spacing.LEFT, 25); + node_1.setMargin(Spacing.TOP, 25); + node_1.setMargin(Spacing.RIGHT, 25); + node_1.setMargin(Spacing.BOTTOM, 25); node_1 = node_0.getChildAt(2); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 10; - node_1.style.margin[Spacing.TOP] = 10; - node_1.style.margin[Spacing.RIGHT] = 10; - node_1.style.margin[Spacing.BOTTOM] = 10; + node_1.setMargin(Spacing.LEFT, 10); + node_1.setMargin(Spacing.TOP, 10); + node_1.setMargin(Spacing.RIGHT, 10); + node_1.setMargin(Spacing.BOTTOM, 10); } } @@ -467,34 +467,34 @@ public class LayoutEngineTest { node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.margin[Spacing.LEFT] = 10; - node_0.style.margin[Spacing.TOP] = 10; - node_0.style.margin[Spacing.RIGHT] = 10; - node_0.style.margin[Spacing.BOTTOM] = 10; + node_0.setMargin(Spacing.LEFT, 10); + node_0.setMargin(Spacing.TOP, 10); + node_0.setMargin(Spacing.RIGHT, 10); + node_0.setMargin(Spacing.BOTTOM, 10); addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 50; - node_1.style.margin[Spacing.TOP] = 50; - node_1.style.margin[Spacing.RIGHT] = 50; - node_1.style.margin[Spacing.BOTTOM] = 50; + node_1.setMargin(Spacing.LEFT, 50); + node_1.setMargin(Spacing.TOP, 50); + node_1.setMargin(Spacing.RIGHT, 50); + node_1.setMargin(Spacing.BOTTOM, 50); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 25; - node_1.style.margin[Spacing.TOP] = 25; - node_1.style.margin[Spacing.RIGHT] = 25; - node_1.style.margin[Spacing.BOTTOM] = 25; + node_1.setMargin(Spacing.LEFT, 25); + node_1.setMargin(Spacing.TOP, 25); + node_1.setMargin(Spacing.RIGHT, 25); + node_1.setMargin(Spacing.BOTTOM, 25); node_1 = node_0.getChildAt(2); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 10; - node_1.style.margin[Spacing.TOP] = 10; - node_1.style.margin[Spacing.RIGHT] = 10; - node_1.style.margin[Spacing.BOTTOM] = 10; + node_1.setMargin(Spacing.LEFT, 10); + node_1.setMargin(Spacing.TOP, 10); + node_1.setMargin(Spacing.RIGHT, 10); + node_1.setMargin(Spacing.BOTTOM, 10); } } @@ -1008,21 +1008,21 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.margin[Spacing.LEFT] = 5; - node_0.style.margin[Spacing.TOP] = 10; + node_0.setMargin(Spacing.LEFT, 5); + node_0.setMargin(Spacing.TOP, 10); addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 15; - node_1.style.margin[Spacing.TOP] = 50; - node_1.style.margin[Spacing.BOTTOM] = 20; + node_1.setMargin(Spacing.LEFT, 15); + node_1.setMargin(Spacing.TOP, 50); + node_1.setMargin(Spacing.BOTTOM, 20); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 30; + node_1.setMargin(Spacing.LEFT, 30); } } @@ -1061,21 +1061,21 @@ public class LayoutEngineTest { node_0.style.flexDirection = CSSFlexDirection.COLUMN_REVERSE; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.margin[Spacing.LEFT] = 5; - node_0.style.margin[Spacing.TOP] = 10; + node_0.setMargin(Spacing.LEFT, 5); + node_0.setMargin(Spacing.TOP, 10); addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 15; - node_1.style.margin[Spacing.TOP] = 50; - node_1.style.margin[Spacing.BOTTOM] = 20; + node_1.setMargin(Spacing.LEFT, 15); + node_1.setMargin(Spacing.TOP, 50); + node_1.setMargin(Spacing.BOTTOM, 20); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.margin[Spacing.LEFT] = 30; + node_1.setMargin(Spacing.LEFT, 30); } } @@ -2157,10 +2157,10 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = 5; - node_1.style.margin[Spacing.TOP] = 5; - node_1.style.margin[Spacing.RIGHT] = 5; - node_1.style.margin[Spacing.BOTTOM] = 5; + node_1.setMargin(Spacing.LEFT, 5); + node_1.setMargin(Spacing.TOP, 5); + node_1.setMargin(Spacing.RIGHT, 5); + node_1.setMargin(Spacing.BOTTOM, 5); } } @@ -2196,10 +2196,10 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = 5; - node_1.style.margin[Spacing.TOP] = 5; - node_1.style.margin[Spacing.RIGHT] = 5; - node_1.style.margin[Spacing.BOTTOM] = 5; + node_1.setMargin(Spacing.LEFT, 5); + node_1.setMargin(Spacing.TOP, 5); + node_1.setMargin(Spacing.RIGHT, 5); + node_1.setMargin(Spacing.BOTTOM, 5); } } @@ -2344,7 +2344,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.TOP] = 10; + node_1.setMargin(Spacing.TOP, 10); } } @@ -2382,7 +2382,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.TOP] = 10; + node_1.setMargin(Spacing.TOP, 10); } } @@ -2422,10 +2422,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 10; - node_2.style.margin[Spacing.TOP] = 10; - node_2.style.margin[Spacing.RIGHT] = 10; - node_2.style.margin[Spacing.BOTTOM] = 10; + node_2.setMargin(Spacing.LEFT, 10); + node_2.setMargin(Spacing.TOP, 10); + node_2.setMargin(Spacing.RIGHT, 10); + node_2.setMargin(Spacing.BOTTOM, 10); node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -2483,10 +2483,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 10; - node_2.style.margin[Spacing.TOP] = 10; - node_2.style.margin[Spacing.RIGHT] = 10; - node_2.style.margin[Spacing.BOTTOM] = 10; + node_2.setMargin(Spacing.LEFT, 10); + node_2.setMargin(Spacing.TOP, 10); + node_2.setMargin(Spacing.RIGHT, 10); + node_2.setMargin(Spacing.BOTTOM, 10); node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -2574,7 +2574,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = 10; + node_1.setMargin(Spacing.LEFT, 10); } } @@ -2611,7 +2611,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = 10; + node_1.setMargin(Spacing.LEFT, 10); } } @@ -2642,10 +2642,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 5; - node_0.style.padding[Spacing.TOP] = 5; - node_0.style.padding[Spacing.RIGHT] = 5; - node_0.style.padding[Spacing.BOTTOM] = 5; + node_0.setPadding(Spacing.LEFT, 5); + node_0.setPadding(Spacing.TOP, 5); + node_0.setPadding(Spacing.RIGHT, 5); + node_0.setPadding(Spacing.BOTTOM, 5); } TestCSSNode root_layout = new TestCSSNode(); @@ -2666,10 +2666,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 5; - node_0.style.padding[Spacing.TOP] = 5; - node_0.style.padding[Spacing.RIGHT] = 5; - node_0.style.padding[Spacing.BOTTOM] = 5; + node_0.setPadding(Spacing.LEFT, 5); + node_0.setPadding(Spacing.TOP, 5); + node_0.setPadding(Spacing.RIGHT, 5); + node_0.setPadding(Spacing.BOTTOM, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2704,18 +2704,18 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 5; - node_0.style.padding[Spacing.TOP] = 5; - node_0.style.padding[Spacing.RIGHT] = 5; - node_0.style.padding[Spacing.BOTTOM] = 5; + node_0.setPadding(Spacing.LEFT, 5); + node_0.setPadding(Spacing.TOP, 5); + node_0.setPadding(Spacing.RIGHT, 5); + node_0.setPadding(Spacing.BOTTOM, 5); addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = 5; - node_1.style.margin[Spacing.TOP] = 5; - node_1.style.margin[Spacing.RIGHT] = 5; - node_1.style.margin[Spacing.BOTTOM] = 5; + node_1.setMargin(Spacing.LEFT, 5); + node_1.setMargin(Spacing.TOP, 5); + node_1.setMargin(Spacing.RIGHT, 5); + node_1.setMargin(Spacing.BOTTOM, 5); } } @@ -2751,10 +2751,10 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.STRETCH; - node_1.style.padding[Spacing.LEFT] = 10; - node_1.style.padding[Spacing.TOP] = 10; - node_1.style.padding[Spacing.RIGHT] = 10; - node_1.style.padding[Spacing.BOTTOM] = 10; + node_1.setPadding(Spacing.LEFT, 10); + node_1.setPadding(Spacing.TOP, 10); + node_1.setPadding(Spacing.RIGHT, 10); + node_1.setPadding(Spacing.BOTTOM, 10); } } @@ -2785,19 +2785,19 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 50; - node_0.style.padding[Spacing.TOP] = 50; - node_0.style.padding[Spacing.RIGHT] = 50; - node_0.style.padding[Spacing.BOTTOM] = 50; + node_0.setPadding(Spacing.LEFT, 50); + node_0.setPadding(Spacing.TOP, 50); + node_0.setPadding(Spacing.RIGHT, 50); + node_0.setPadding(Spacing.BOTTOM, 50); addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.STRETCH; - node_1.style.padding[Spacing.LEFT] = 10; - node_1.style.padding[Spacing.TOP] = 10; - node_1.style.padding[Spacing.RIGHT] = 10; - node_1.style.padding[Spacing.BOTTOM] = 10; + node_1.setPadding(Spacing.LEFT, 10); + node_1.setPadding(Spacing.TOP, 10); + node_1.setPadding(Spacing.RIGHT, 10); + node_1.setPadding(Spacing.BOTTOM, 10); } } @@ -2837,10 +2837,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 16; - node_2.style.margin[Spacing.TOP] = 16; - node_2.style.margin[Spacing.RIGHT] = 16; - node_2.style.margin[Spacing.BOTTOM] = 16; + node_2.setMargin(Spacing.LEFT, 16); + node_2.setMargin(Spacing.TOP, 16); + node_2.setMargin(Spacing.RIGHT, 16); + node_2.setMargin(Spacing.BOTTOM, 16); } } } @@ -2905,7 +2905,7 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.justifyContent = CSSJustify.SPACE_AROUND; node_0.style.height = 10; - node_0.style.padding[Spacing.TOP] = 5; + node_0.setPadding(Spacing.TOP, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3040,7 +3040,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.margin[Spacing.RIGHT] = 15; + node_1.setMargin(Spacing.RIGHT, 15); } } @@ -3077,7 +3077,7 @@ public class LayoutEngineTest { node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.CENTER; node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.padding[Spacing.RIGHT] = 12; + node_1.setPadding(Spacing.RIGHT, 12); } } @@ -3109,7 +3109,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.style.height = 5; - node_0.style.padding[Spacing.BOTTOM] = 20; + node_0.setPadding(Spacing.BOTTOM, 20); } TestCSSNode root_layout = new TestCSSNode(); @@ -3131,7 +3131,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.style.width = 5; - node_0.style.padding[Spacing.LEFT] = 20; + node_0.setPadding(Spacing.LEFT, 20); } TestCSSNode root_layout = new TestCSSNode(); @@ -3209,10 +3209,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 5; - node_0.style.padding[Spacing.TOP] = 5; - node_0.style.padding[Spacing.RIGHT] = 5; - node_0.style.padding[Spacing.BOTTOM] = 5; + node_0.setPadding(Spacing.LEFT, 5); + node_0.setPadding(Spacing.TOP, 5); + node_0.setPadding(Spacing.RIGHT, 5); + node_0.setPadding(Spacing.BOTTOM, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3292,10 +3292,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.padding[Spacing.LEFT] = 20; - node_0.style.padding[Spacing.TOP] = 20; - node_0.style.padding[Spacing.RIGHT] = 20; - node_0.style.padding[Spacing.BOTTOM] = 20; + node_0.setPadding(Spacing.LEFT, 20); + node_0.setPadding(Spacing.TOP, 20); + node_0.setPadding(Spacing.RIGHT, 20); + node_0.setPadding(Spacing.BOTTOM, 20); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3337,7 +3337,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.margin[Spacing.TOP] = 5; + node_1.setMargin(Spacing.TOP, 5); node_1.style.positionTop = 5; } } @@ -3374,7 +3374,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.margin[Spacing.LEFT] = 5; + node_1.setMargin(Spacing.LEFT, 5); node_1.style.positionLeft = 5; } } @@ -3500,7 +3500,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.flex = 1; - node_1.style.margin[Spacing.LEFT] = 5; + node_1.setMargin(Spacing.LEFT, 5); } } @@ -3539,7 +3539,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.flex = 1; - node_1.style.margin[Spacing.RIGHT] = 5; + node_1.setMargin(Spacing.RIGHT, 5); } } @@ -3579,7 +3579,7 @@ public class LayoutEngineTest { node_1.style.flex = 1; node_1 = node_0.getChildAt(1); node_1.style.flex = 1; - node_1.style.padding[Spacing.RIGHT] = 5; + node_1.setPadding(Spacing.RIGHT, 5); } } @@ -3625,7 +3625,7 @@ public class LayoutEngineTest { node_1.style.flex = 1; node_1 = node_0.getChildAt(1); node_1.style.flex = 1; - node_1.style.padding[Spacing.LEFT] = 5; + node_1.setPadding(Spacing.LEFT, 5); } } @@ -3670,7 +3670,7 @@ public class LayoutEngineTest { node_1.style.flex = 1; node_1 = node_0.getChildAt(1); node_1.style.flex = 1; - node_1.style.margin[Spacing.LEFT] = 5; + node_1.setMargin(Spacing.LEFT, 5); } } @@ -3716,7 +3716,7 @@ public class LayoutEngineTest { node_1.style.flex = 1; node_1 = node_0.getChildAt(1); node_1.style.flex = 1; - node_1.style.margin[Spacing.RIGHT] = 5; + node_1.setMargin(Spacing.RIGHT, 5); } } @@ -3916,10 +3916,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.border[Spacing.LEFT] = 5; - node_0.style.border[Spacing.TOP] = 5; - node_0.style.border[Spacing.RIGHT] = 5; - node_0.style.border[Spacing.BOTTOM] = 5; + node_0.setBorder(Spacing.LEFT, 5); + node_0.setBorder(Spacing.TOP, 5); + node_0.setBorder(Spacing.RIGHT, 5); + node_0.setBorder(Spacing.BOTTOM, 5); } TestCSSNode root_layout = new TestCSSNode(); @@ -3940,7 +3940,7 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.border[Spacing.TOP] = 1; + node_0.setBorder(Spacing.TOP, 1); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3977,10 +3977,10 @@ public class LayoutEngineTest { TestCSSNode root_node = new TestCSSNode(); { TestCSSNode node_0 = root_node; - node_0.style.border[Spacing.LEFT] = 1; - node_0.style.border[Spacing.TOP] = 1; - node_0.style.border[Spacing.RIGHT] = 1; - node_0.style.border[Spacing.BOTTOM] = 1; + node_0.setBorder(Spacing.LEFT, 1); + node_0.setBorder(Spacing.TOP, 1); + node_0.setBorder(Spacing.RIGHT, 1); + node_0.setBorder(Spacing.BOTTOM, 1); addChildren(node_0, 1); { TestCSSNode node_1; @@ -4023,11 +4023,11 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.STRETCH; - node_1.style.margin[Spacing.LEFT] = 20; - node_1.style.padding[Spacing.LEFT] = 20; - node_1.style.padding[Spacing.TOP] = 20; - node_1.style.padding[Spacing.RIGHT] = 20; - node_1.style.padding[Spacing.BOTTOM] = 20; + node_1.setMargin(Spacing.LEFT, 20); + node_1.setPadding(Spacing.LEFT, 20); + node_1.setPadding(Spacing.TOP, 20); + node_1.setPadding(Spacing.RIGHT, 20); + node_1.setPadding(Spacing.BOTTOM, 20); } } @@ -4063,7 +4063,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.border[Spacing.RIGHT] = 5; + node_1.setBorder(Spacing.RIGHT, 5); } } @@ -4095,12 +4095,12 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.style.flexDirection = CSSFlexDirection.ROW; - node_0.style.border[Spacing.RIGHT] = 1; + node_0.setBorder(Spacing.RIGHT, 1); addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.RIGHT] = -8; + node_1.setMargin(Spacing.RIGHT, -8); } } @@ -4133,12 +4133,12 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.direction = CSSDirection.RTL; node_0.style.flexDirection = CSSFlexDirection.ROW; - node_0.style.border[Spacing.LEFT] = 1; + node_0.setBorder(Spacing.LEFT, 1); addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.LEFT] = -8; + node_1.setMargin(Spacing.LEFT, -8); } } @@ -4542,19 +4542,19 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.alignSelf = CSSAlign.FLEX_START; node_0.style.width = 100; - node_0.style.padding[Spacing.LEFT] = 10; - node_0.style.padding[Spacing.TOP] = 10; - node_0.style.padding[Spacing.RIGHT] = 10; - node_0.style.padding[Spacing.BOTTOM] = 10; + node_0.setPadding(Spacing.LEFT, 10); + node_0.setPadding(Spacing.TOP, 10); + node_0.setPadding(Spacing.RIGHT, 10); + node_0.setPadding(Spacing.BOTTOM, 10); addChildren(node_0, 1); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.FLEX_START; - node_1.style.margin[Spacing.LEFT] = 10; - node_1.style.margin[Spacing.TOP] = 10; - node_1.style.margin[Spacing.RIGHT] = 10; - node_1.style.margin[Spacing.BOTTOM] = 10; + node_1.setMargin(Spacing.LEFT, 10); + node_1.setMargin(Spacing.TOP, 10); + node_1.setMargin(Spacing.RIGHT, 10); + node_1.setMargin(Spacing.BOTTOM, 10); addChildren(node_1, 1); { TestCSSNode node_2; @@ -4775,10 +4775,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 20; - node_2.style.margin[Spacing.TOP] = 20; - node_2.style.margin[Spacing.RIGHT] = 20; - node_2.style.margin[Spacing.BOTTOM] = 20; + node_2.setMargin(Spacing.LEFT, 20); + node_2.setMargin(Spacing.TOP, 20); + node_2.setMargin(Spacing.RIGHT, 20); + node_2.setMargin(Spacing.BOTTOM, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -4832,10 +4832,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 20; - node_2.style.margin[Spacing.TOP] = 20; - node_2.style.margin[Spacing.RIGHT] = 20; - node_2.style.margin[Spacing.BOTTOM] = 20; + node_2.setMargin(Spacing.LEFT, 20); + node_2.setMargin(Spacing.TOP, 20); + node_2.setMargin(Spacing.RIGHT, 20); + node_2.setMargin(Spacing.BOTTOM, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -4887,10 +4887,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.margin[Spacing.LEFT] = 20; - node_2.style.margin[Spacing.TOP] = 20; - node_2.style.margin[Spacing.RIGHT] = 20; - node_2.style.margin[Spacing.BOTTOM] = 20; + node_2.setMargin(Spacing.LEFT, 20); + node_2.setMargin(Spacing.TOP, 20); + node_2.setMargin(Spacing.RIGHT, 20); + node_2.setMargin(Spacing.BOTTOM, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -5487,7 +5487,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.border[Spacing.BOTTOM] = 1; + node_1.setBorder(Spacing.BOTTOM, 1); } } @@ -5523,7 +5523,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.TOP] = -6; + node_1.setMargin(Spacing.TOP, -6); } } @@ -5559,7 +5559,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.margin[Spacing.TOP] = 20; + node_1.setMargin(Spacing.TOP, 20); } } @@ -5591,7 +5591,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.style.justifyContent = CSSJustify.FLEX_END; - node_0.style.border[Spacing.BOTTOM] = 5; + node_0.setBorder(Spacing.BOTTOM, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -5981,10 +5981,10 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.maxWidth = 30; node_0.style.maxHeight = 10; - node_0.style.padding[Spacing.LEFT] = 20; - node_0.style.padding[Spacing.TOP] = 15; - node_0.style.padding[Spacing.RIGHT] = 20; - node_0.style.padding[Spacing.BOTTOM] = 15; + node_0.setPadding(Spacing.LEFT, 20); + node_0.setPadding(Spacing.TOP, 15); + node_0.setPadding(Spacing.RIGHT, 20); + node_0.setPadding(Spacing.BOTTOM, 15); } TestCSSNode root_layout = new TestCSSNode(); @@ -6007,10 +6007,10 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.minWidth = 50; node_0.style.minHeight = 40; - node_0.style.padding[Spacing.LEFT] = 20; - node_0.style.padding[Spacing.TOP] = 15; - node_0.style.padding[Spacing.RIGHT] = 20; - node_0.style.padding[Spacing.BOTTOM] = 15; + node_0.setPadding(Spacing.LEFT, 20); + node_0.setPadding(Spacing.TOP, 15); + node_0.setPadding(Spacing.RIGHT, 20); + node_0.setPadding(Spacing.BOTTOM, 15); } TestCSSNode root_layout = new TestCSSNode(); @@ -7122,10 +7122,10 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.padding[Spacing.LEFT] = 10; - node_1.style.padding[Spacing.TOP] = 10; - node_1.style.padding[Spacing.RIGHT] = 10; - node_1.style.padding[Spacing.BOTTOM] = 10; + node_1.setPadding(Spacing.LEFT, 10); + node_1.setPadding(Spacing.TOP, 10); + node_1.setPadding(Spacing.RIGHT, 10); + node_1.setPadding(Spacing.BOTTOM, 10); node_1.style.positionLeft = 100; node_1.style.positionTop = 100; node_1.style.positionRight = 100; @@ -7186,14 +7186,14 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.padding[Spacing.LEFT] = 10; - node_1.style.padding[Spacing.TOP] = 10; - node_1.style.padding[Spacing.RIGHT] = 10; - node_1.style.padding[Spacing.BOTTOM] = 10; - node_1.style.border[Spacing.LEFT] = 1; - node_1.style.border[Spacing.TOP] = 1; - node_1.style.border[Spacing.RIGHT] = 1; - node_1.style.border[Spacing.BOTTOM] = 1; + node_1.setPadding(Spacing.LEFT, 10); + node_1.setPadding(Spacing.TOP, 10); + node_1.setPadding(Spacing.RIGHT, 10); + node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setBorder(Spacing.LEFT, 1); + node_1.setBorder(Spacing.TOP, 1); + node_1.setBorder(Spacing.RIGHT, 1); + node_1.setBorder(Spacing.BOTTOM, 1); node_1.style.positionLeft = 100; node_1.style.positionTop = 100; node_1.style.positionRight = 100; @@ -7254,10 +7254,10 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.flex = 1; - node_1.style.padding[Spacing.LEFT] = 10; - node_1.style.padding[Spacing.TOP] = 10; - node_1.style.padding[Spacing.RIGHT] = 10; - node_1.style.padding[Spacing.BOTTOM] = 10; + node_1.setPadding(Spacing.LEFT, 10); + node_1.setPadding(Spacing.TOP, 10); + node_1.setPadding(Spacing.RIGHT, 10); + node_1.setPadding(Spacing.BOTTOM, 10); addChildren(node_1, 1); { TestCSSNode node_2; From 03dfe7bb17a516c8838b780557f46e888ab31411 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Mon, 11 May 2015 15:39:02 +0100 Subject: [PATCH 6/8] Implement (padding|border|margin)-(start|end) support --- src/JavaTranspiler.js | 6 +- src/Layout-test-utils.js | 12 +- src/Layout.c | 178 ++++++-- src/Layout.h | 8 +- src/Layout.js | 185 +++++--- src/__tests__/Layout-test.c | 403 +++++++++++++++++ src/__tests__/Layout-test.js | 101 ++++- .../com/facebook/csslayout/LayoutEngine.java | 156 +++++-- .../src/com/facebook/csslayout/Spacing.java | 32 +- .../facebook/csslayout/LayoutEngineTest.java | 421 ++++++++++++++++++ src/transpile.js | 4 + 11 files changed, 1373 insertions(+), 133 deletions(-) diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index 7d2c9148..53ccc85d 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -77,13 +77,13 @@ function __transpileSingleTestToJava(code) { return 'style.' + match1 + match2[0] + match2.substring(1).toLowerCase(); }) .replace( // style.margin[CSS_TOP] = 12.3 => style.margin[Spacing.TOP].set(12.3) - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]\s+=\s+(-?[\.\d]+)/g, + /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]\s+=\s+(-?[\.\d]+)/g, function (str, match1, match2, match3) { var propertyCap = match1.charAt(0).toUpperCase() + match1.slice(1); return 'set' + propertyCap + '(Spacing.' + match2 + ', ' + match3 + ')'; }) - .replace( // style.margin[CSS_TOP] => style.margin.get(Spacing.TOP) - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, + .replace( // style.margin[CSS_TOP] => style.margin[Spacing.TOP] + /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]/g, function (str, match1, match2) { return 'style.' + match1 + '.get(Spacing.' + match2 + ')'; }) diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index f2b15959..69a57668 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -144,6 +144,10 @@ var layoutTestUtils = (function() { return layout; } + function capitalizeFirst(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } + function computeCSSLayout(rootNode) { fillNodes(rootNode); realComputeLayout(rootNode); @@ -155,8 +159,10 @@ var layoutTestUtils = (function() { function transfer(div, node, name, ext) { if (name in node.style) { - div.style['-webkit-' + name] = node.style[name] + (ext || ''); - div.style[name] = node.style[name] + (ext || ''); + var value = node.style[name] + (ext || ''); + div.style['-webkit-' + name] = value; + div.style['webkit' + capitalizeFirst(name)] = value; + div.style[name] = value; } } @@ -166,6 +172,8 @@ var layoutTestUtils = (function() { transfer(div, node, type + 'Top' + suffix, 'px'); transfer(div, node, type + 'Bottom' + suffix, 'px'); transfer(div, node, type + 'Right' + suffix, 'px'); + transfer(div, node, type + 'Start' + suffix, 'px'); + transfer(div, node, type + 'End' + suffix, 'px'); } function renderNode(parent, node) { diff --git a/src/Layout.c b/src/Layout.c index baa2d2cc..4b697d2e 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -54,6 +54,13 @@ void init_css_node(css_node_t *node) { node->style.position[CSS_RIGHT] = CSS_UNDEFINED; node->style.position[CSS_BOTTOM] = CSS_UNDEFINED; + node->style.margin[CSS_START] = CSS_UNDEFINED; + node->style.margin[CSS_END] = CSS_UNDEFINED; + node->style.padding[CSS_START] = CSS_UNDEFINED; + node->style.padding[CSS_END] = CSS_UNDEFINED; + node->style.border[CSS_START] = CSS_UNDEFINED; + node->style.border[CSS_END] = CSS_UNDEFINED; + node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; @@ -170,6 +177,8 @@ static void print_css_node_rec( print_number_0("marginRight", node->style.margin[CSS_RIGHT]); print_number_0("marginTop", node->style.margin[CSS_TOP]); print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]); + print_number_0("marginStart", node->style.margin[CSS_START]); + print_number_0("marginEnd", node->style.margin[CSS_END]); } if (four_equal(node->style.padding)) { @@ -179,6 +188,8 @@ static void print_css_node_rec( print_number_0("paddingRight", node->style.padding[CSS_RIGHT]); print_number_0("paddingTop", node->style.padding[CSS_TOP]); print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]); + print_number_0("paddingStart", node->style.padding[CSS_START]); + print_number_0("paddingEnd", node->style.padding[CSS_END]); } if (four_equal(node->style.border)) { @@ -188,6 +199,8 @@ static void print_css_node_rec( print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]); print_number_0("borderTopWidth", node->style.border[CSS_TOP]); print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]); + print_number_0("borderStartWidth", node->style.border[CSS_START]); + print_number_0("borderEndWidth", node->style.border[CSS_END]); } print_number_nan("width", node->style.dimensions[CSS_WIDTH]); @@ -245,39 +258,106 @@ static css_dimension_t dim[4] = { /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH }; - -static float getMargin(css_node_t *node, int location) { - return node->style.margin[location]; +static bool isRowDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_ROW || + flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; } -static float getPadding(css_node_t *node, int location) { - if (node->style.padding[location] >= 0) { - return node->style.padding[location]; +static bool isColumnDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_COLUMN || + flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; +} + +static float getLeadingMargin(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) { + return node->style.margin[CSS_START]; } + + return node->style.margin[leading[axis]]; +} + +static float getTrailingMargin(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) { + return node->style.margin[CSS_END]; + } + + return node->style.margin[trailing[axis]]; +} + +static float getLeadingPadding(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.padding[CSS_START]) && + node->style.padding[CSS_START] >= 0) { + return node->style.padding[CSS_START]; + } + + if (node->style.padding[leading[axis]] >= 0) { + return node->style.padding[leading[axis]]; + } + return 0; } -static float getBorder(css_node_t *node, int location) { - if (node->style.border[location] >= 0) { - return node->style.border[location]; +static float getTrailingPadding(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.padding[CSS_END]) && + node->style.padding[CSS_END] >= 0) { + return node->style.padding[CSS_END]; } + + if (node->style.padding[trailing[axis]] >= 0) { + return node->style.padding[trailing[axis]]; + } + return 0; } -static float getPaddingAndBorder(css_node_t *node, int location) { - return getPadding(node, location) + getBorder(node, location); +static float getLeadingBorder(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.border[CSS_START]) && + node->style.border[CSS_START] >= 0) { + return node->style.border[CSS_START]; + } + + if (node->style.border[leading[axis]] >= 0) { + return node->style.border[leading[axis]]; + } + + return 0; +} + +static float getTrailingBorder(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.border[CSS_END]) && + node->style.border[CSS_END] >= 0) { + return node->style.border[CSS_END]; + } + + if (node->style.border[trailing[axis]] >= 0) { + return node->style.border[trailing[axis]]; + } + + return 0; +} + +static float getLeadingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { + return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); +} + +static float getTrailingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { + return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); } static float getBorderAxis(css_node_t *node, css_flex_direction_t axis) { - return getBorder(node, leading[axis]) + getBorder(node, trailing[axis]); + return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); } static float getMarginAxis(css_node_t *node, css_flex_direction_t axis) { - return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]); + return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } static float getPaddingAndBorderAxis(css_node_t *node, css_flex_direction_t axis) { - return getPaddingAndBorder(node, leading[axis]) + getPaddingAndBorder(node, trailing[axis]); + return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); } static css_position_type_t getPositionType(css_node_t *node) { @@ -295,16 +375,6 @@ static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { return node->style.align_items; } -static bool isRowDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_ROW || - flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; -} - -static bool isColumnDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_COLUMN || - flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; -} - static css_direction_t resolveDirection(css_node_t *node, css_direction_t parentDirection) { css_direction_t direction = node->style.direction; @@ -356,8 +426,8 @@ static bool isFlexWrap(css_node_t *node) { static float getDimWithMargin(css_node_t *node, css_flex_direction_t axis) { return node->layout.dimensions[dim[axis]] + - getMargin(node, leading[axis]) + - getMargin(node, trailing[axis]); + getLeadingMargin(node, axis) + + getTrailingMargin(node, axis); } static bool isDimDefined(css_node_t *node, css_flex_direction_t axis) { @@ -451,13 +521,13 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // The position is set by the parent, but we need to complete it with a // delta composed of the margin and left/top/right/bottom - node->layout.position[leading[mainAxis]] += getMargin(node, leading[mainAxis]) + + node->layout.position[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); - node->layout.position[trailing[mainAxis]] += getMargin(node, trailing[mainAxis]) + + node->layout.position[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); - node->layout.position[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + + node->layout.position[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); - node->layout.position[trailing[crossAxis]] += getMargin(node, trailing[crossAxis]) + + node->layout.position[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); if (isMeasureDefined(node)) { @@ -740,7 +810,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // container! float crossDim = 0; float mainDim = leadingMainDim + - getPaddingAndBorder(node, leading[mainAxis]); + getLeadingPaddingAndBorder(node, mainAxis); for (i = startLine; i < endLine; ++i) { child = node->get_child(node->context, i); @@ -751,8 +821,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // defined, we override the position to whatever the user said // (and margin/border). child->layout.position[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getBorder(node, leading[mainAxis]) + - getMargin(child, leading[mainAxis]); + getLeadingBorder(node, mainAxis) + + getLeadingMargin(child, mainAxis); } else { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. @@ -799,11 +869,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // top/left/bottom/right being set, we override all the previously // computed positions to set it correctly. child->layout.position[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getBorder(node, leading[crossAxis]) + - getMargin(child, leading[crossAxis]); + getLeadingBorder(node, crossAxis) + + getLeadingMargin(child, crossAxis); } else { - float leadingCrossDim = getPaddingAndBorder(node, leading[crossAxis]); + float leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis @@ -838,6 +908,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction // And we apply the position child->layout.position[pos[crossAxis]] += linesCrossDim + leadingCrossDim; + + // Define the trailing position accordingly. + if (!isUndefined(node->layout.dimensions[dim[crossAxis]])) { + setTrailingPosition(node, child, crossAxis); + } } } @@ -846,22 +921,21 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction startLine = endLine; } + bool needsMainTrailingPos = false; + bool needsCrossTrailingPos = false; + // 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]])) { node->layout.dimensions[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final // dimension - boundAxis(node, mainAxis, linesMainDim + getPaddingAndBorder(node, trailing[mainAxis])), + boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) ); - // Now that the width is defined, we should update the trailing - // positions for the children. - for (i = 0; i < node->children_count; ++i) { - setTrailingPosition(node, node->get_child(node->context, i), mainAxis); - } + needsMainTrailingPos = true; } if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { @@ -872,9 +946,27 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), getPaddingAndBorderAxis(node, crossAxis) ); + + needsCrossTrailingPos = true; } - // Calculate dimensions for absolutely positioned elements + // Set trailing position if necessary + + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); + + if (needsMainTrailingPos) { + setTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + // Calculate dimensions for absolutely positioned elements for (i = 0; i < node->children_count; ++i) { child = node->get_child(node->context, i); diff --git a/src/Layout.h b/src/Layout.h index c07dde72..2e737e57 100644 --- a/src/Layout.h +++ b/src/Layout.h @@ -71,6 +71,8 @@ typedef enum { CSS_TOP, CSS_RIGHT, CSS_BOTTOM, + CSS_START, + CSS_END, CSS_POSITION_COUNT } css_position_t; @@ -106,7 +108,7 @@ typedef struct { css_position_type_t position_type; css_wrap_type_t flex_wrap; float flex; - float margin[4]; + float margin[6]; float position[4]; /** * You should skip all the rules that contain negative values for the @@ -118,8 +120,8 @@ typedef struct { * {left: -5 ...} * {left: 0 ...} */ - float padding[4]; - float border[4]; + float padding[6]; + float border[6]; float dimensions[2]; float minDimensions[2]; float maxDimensions[2]; diff --git a/src/Layout.js b/src/Layout.js index 6d09517a..300bf2bd 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -63,15 +63,19 @@ var computeLayout = (function() { return str.charAt(0).toUpperCase() + str.slice(1); } - function getSpacing(node, type, suffix, location) { - var key = type + capitalizeFirst(location) + suffix; - if (key in node.style) { - return node.style[key]; - } + function getSpacing(node, type, suffix, locations) { + for (var i = 0; i < locations.length; ++i) { + var location = locations[i]; - key = type + suffix; - if (key in node.style) { - return node.style[key]; + var key = type + capitalizeFirst(location) + suffix; + if (key in node.style) { + return node.style[key]; + } + + key = type + suffix; + if (key in node.style) { + return node.style[key]; + } } return 0; @@ -111,15 +115,19 @@ var computeLayout = (function() { return layout; } - function getPositiveSpacing(node, type, suffix, location) { - var key = type + capitalizeFirst(location) + suffix; - if (key in node.style && node.style[key] >= 0) { - return node.style[key]; - } + function getPositiveSpacing(node, type, suffix, locations) { + for (var i = 0; i < locations.length; ++i) { + var location = locations[i]; - key = type + suffix; - if (key in node.style && node.style[key] >= 0) { - return node.style[key]; + var key = type + capitalizeFirst(location) + suffix; + if (key in node.style && node.style[key] >= 0) { + return node.style[key]; + } + + key = type + suffix; + if (key in node.style && node.style[key] >= 0) { + return node.style[key]; + } } return 0; @@ -129,32 +137,89 @@ var computeLayout = (function() { return value === undefined; } - function getMargin(node, location) { - return getSpacing(node, 'margin', '', location); + function isRowDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_ROW || + flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; } - function getPadding(node, location) { - return getPositiveSpacing(node, 'padding', '', location); + function isColumnDirection(flexDirection) { + return flexDirection === CSS_FLEX_DIRECTION_COLUMN || + flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; } - function getBorder(node, location) { - return getPositiveSpacing(node, 'border', 'Width', location); + function getLeadingLocations(axis) { + var locations = [leading[axis]]; + if (isRowDirection(axis)) { + locations.unshift('start'); + } + + return locations; } - function getPaddingAndBorder(node, location) { - return getPadding(node, location) + getBorder(node, location); + function getTrailingLocations(axis) { + var locations = [trailing[axis]]; + if (isRowDirection(axis)) { + locations.unshift('end'); + } + + return locations; + } + + function getMargin(node, locations) { + return getSpacing(node, 'margin', '', locations); + } + + function getLeadingMargin(node, axis) { + return getMargin(node, getLeadingLocations(axis)); + } + + function getTrailingMargin(node, axis) { + return getMargin(node, getTrailingLocations(axis)); + } + + function getPadding(node, locations) { + return getPositiveSpacing(node, 'padding', '', locations); + } + + function getLeadingPadding(node, axis) { + return getPadding(node, getLeadingLocations(axis)); + } + + function getTrailingPadding(node, axis) { + return getPadding(node, getTrailingLocations(axis)); + } + + function getBorder(node, locations) { + return getPositiveSpacing(node, 'border', 'Width', locations); + } + + function getLeadingBorder(node, axis) { + return getBorder(node, getLeadingLocations(axis)); + } + + function getTrailingBorder(node, axis) { + return getBorder(node, getTrailingLocations(axis)); + } + + function getLeadingPaddingAndBorder(node, axis) { + return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); + } + + function getTrailingPaddingAndBorder(node, axis) { + return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); } function getBorderAxis(node, axis) { - return getBorder(node, leading[axis]) + getBorder(node, trailing[axis]); + return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); } function getMarginAxis(node, axis) { - return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]); + return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } function getPaddingAndBorderAxis(node, axis) { - return getPaddingAndBorder(node, leading[axis]) + getPaddingAndBorder(node, trailing[axis]); + return getLeadingPaddingAndBorder(node, axis) + + getTrailingPaddingAndBorder(node, axis); } function getJustifyContent(node) { @@ -174,16 +239,6 @@ var computeLayout = (function() { return 'stretch'; } - function isRowDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_ROW || - flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; - } - - function isColumnDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_COLUMN || - flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; - } - function resolveAxis(axis, direction) { if (direction === CSS_DIRECTION_RTL) { if (axis === CSS_FLEX_DIRECTION_ROW) { @@ -347,13 +402,13 @@ var computeLayout = (function() { // The position is set by the parent, but we need to complete it with a // delta composed of the margin and left/top/right/bottom - node.layout[leading[mainAxis]] += getMargin(node, leading[mainAxis]) + + node.layout[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); - node.layout[trailing[mainAxis]] += getMargin(node, trailing[mainAxis]) + + node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); - node.layout[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + + node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); - node.layout[trailing[crossAxis]] += getMargin(node, trailing[crossAxis]) + + node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); if (isMeasureDefined(node)) { @@ -636,7 +691,7 @@ var computeLayout = (function() { // container! var/*float*/ crossDim = 0; var/*float*/ mainDim = leadingMainDim + - getPaddingAndBorder(node, leading[mainAxis]); + getLeadingPaddingAndBorder(node, mainAxis); for (i = startLine; i < endLine; ++i) { child = node.children[i]; @@ -647,8 +702,8 @@ var computeLayout = (function() { // defined, we override the position to whatever the user said // (and margin/border). child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getBorder(node, leading[mainAxis]) + - getMargin(child, leading[mainAxis]); + getLeadingBorder(node, mainAxis) + + getLeadingMargin(child, mainAxis); } else { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. @@ -695,11 +750,11 @@ var computeLayout = (function() { // top/left/bottom/right being set, we override all the previously // computed positions to set it correctly. child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getBorder(node, leading[crossAxis]) + - getMargin(child, leading[crossAxis]); + getLeadingBorder(node, crossAxis) + + getLeadingMargin(child, crossAxis); } else { - var/*float*/ leadingCrossDim = getPaddingAndBorder(node, leading[crossAxis]); + var/*float*/ leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis @@ -734,6 +789,11 @@ var computeLayout = (function() { // And we apply the position child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim; + + // Define the trailing position accordingly. + if (!isUndefined(node.layout[dim[crossAxis]])) { + setTrailingPosition(node, child, crossAxis); + } } } @@ -742,22 +802,21 @@ var computeLayout = (function() { startLine = endLine; } + var/*bool*/ needsMainTrailingPos = false; + var/*bool*/ needsCrossTrailingPos = false; + // 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]])) { node.layout[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final // dimension - boundAxis(node, mainAxis, linesMainDim + getPaddingAndBorder(node, trailing[mainAxis])), + boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) ); - // Now that the width is defined, we should update the trailing - // positions for the children. - for (i = 0; i < node.children.length; ++i) { - setTrailingPosition(node, node.children[i], mainAxis); - } + needsMainTrailingPos = true; } if (isUndefined(node.layout[dim[crossAxis]])) { @@ -768,9 +827,27 @@ var computeLayout = (function() { boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), getPaddingAndBorderAxis(node, crossAxis) ); + + needsCrossTrailingPos = true; } - // Calculate dimensions for absolutely positioned elements + // Set trailing position if necessary + + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (i = 0; i < node.children.length; ++i) { + child = node.children[i]; + + if (needsMainTrailingPos) { + setTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + // Calculate dimensions for absolutely positioned elements for (i = 0; i < node.children.length; ++i) { child = node.children[i]; diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 6a67bb4c..917ed223 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -287,6 +287,8 @@ int main() node_0->style.margin[CSS_TOP] = 10; node_0->style.margin[CSS_RIGHT] = 10; node_0->style.margin[CSS_BOTTOM] = 10; + node_0->style.margin[CSS_START] = 10; + node_0->style.margin[CSS_END] = 10; } css_node_t *root_layout = new_test_css_node(); @@ -311,6 +313,8 @@ int main() node_0->style.margin[CSS_TOP] = 10; node_0->style.margin[CSS_RIGHT] = 10; node_0->style.margin[CSS_BOTTOM] = 10; + node_0->style.margin[CSS_START] = 10; + node_0->style.margin[CSS_END] = 10; init_css_node_children(node_0, 3); { css_node_t *node_1; @@ -321,6 +325,8 @@ int main() node_1->style.margin[CSS_TOP] = 50; node_1->style.margin[CSS_RIGHT] = 50; node_1->style.margin[CSS_BOTTOM] = 50; + node_1->style.margin[CSS_START] = 50; + node_1->style.margin[CSS_END] = 50; node_1 = node_0->get_child(node_0->context, 1); node_1->style.dimensions[CSS_WIDTH] = 100; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -328,6 +334,8 @@ int main() node_1->style.margin[CSS_TOP] = 25; node_1->style.margin[CSS_RIGHT] = 25; node_1->style.margin[CSS_BOTTOM] = 25; + node_1->style.margin[CSS_START] = 25; + node_1->style.margin[CSS_END] = 25; node_1 = node_0->get_child(node_0->context, 2); node_1->style.dimensions[CSS_WIDTH] = 100; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -335,6 +343,8 @@ int main() node_1->style.margin[CSS_TOP] = 10; node_1->style.margin[CSS_RIGHT] = 10; node_1->style.margin[CSS_BOTTOM] = 10; + node_1->style.margin[CSS_START] = 10; + node_1->style.margin[CSS_END] = 10; } } @@ -380,6 +390,8 @@ int main() node_0->style.margin[CSS_TOP] = 10; node_0->style.margin[CSS_RIGHT] = 10; node_0->style.margin[CSS_BOTTOM] = 10; + node_0->style.margin[CSS_START] = 10; + node_0->style.margin[CSS_END] = 10; init_css_node_children(node_0, 3); { css_node_t *node_1; @@ -390,6 +402,8 @@ int main() node_1->style.margin[CSS_TOP] = 50; node_1->style.margin[CSS_RIGHT] = 50; node_1->style.margin[CSS_BOTTOM] = 50; + node_1->style.margin[CSS_START] = 50; + node_1->style.margin[CSS_END] = 50; node_1 = node_0->get_child(node_0->context, 1); node_1->style.dimensions[CSS_WIDTH] = 100; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -397,6 +411,8 @@ int main() node_1->style.margin[CSS_TOP] = 25; node_1->style.margin[CSS_RIGHT] = 25; node_1->style.margin[CSS_BOTTOM] = 25; + node_1->style.margin[CSS_START] = 25; + node_1->style.margin[CSS_END] = 25; node_1 = node_0->get_child(node_0->context, 2); node_1->style.dimensions[CSS_WIDTH] = 100; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -404,6 +420,8 @@ int main() node_1->style.margin[CSS_TOP] = 10; node_1->style.margin[CSS_RIGHT] = 10; node_1->style.margin[CSS_BOTTOM] = 10; + node_1->style.margin[CSS_START] = 10; + node_1->style.margin[CSS_END] = 10; } } @@ -2000,6 +2018,8 @@ int main() node_1->style.margin[CSS_TOP] = 5; node_1->style.margin[CSS_RIGHT] = 5; node_1->style.margin[CSS_BOTTOM] = 5; + node_1->style.margin[CSS_START] = 5; + node_1->style.margin[CSS_END] = 5; } } @@ -2037,6 +2057,8 @@ int main() node_1->style.margin[CSS_TOP] = 5; node_1->style.margin[CSS_RIGHT] = 5; node_1->style.margin[CSS_BOTTOM] = 5; + node_1->style.margin[CSS_START] = 5; + node_1->style.margin[CSS_END] = 5; } } @@ -2251,6 +2273,8 @@ int main() node_2->style.margin[CSS_TOP] = 10; node_2->style.margin[CSS_RIGHT] = 10; node_2->style.margin[CSS_BOTTOM] = 10; + node_2->style.margin[CSS_START] = 10; + node_2->style.margin[CSS_END] = 10; node_2 = node_1->get_child(node_1->context, 1); node_2->style.dimensions[CSS_HEIGHT] = 100; } @@ -2310,6 +2334,8 @@ int main() node_2->style.margin[CSS_TOP] = 10; node_2->style.margin[CSS_RIGHT] = 10; node_2->style.margin[CSS_BOTTOM] = 10; + node_2->style.margin[CSS_START] = 10; + node_2->style.margin[CSS_END] = 10; node_2 = node_1->get_child(node_1->context, 1); node_2->style.dimensions[CSS_HEIGHT] = 100; } @@ -2461,6 +2487,8 @@ int main() node_0->style.padding[CSS_TOP] = 5; node_0->style.padding[CSS_RIGHT] = 5; node_0->style.padding[CSS_BOTTOM] = 5; + node_0->style.padding[CSS_START] = 5; + node_0->style.padding[CSS_END] = 5; } css_node_t *root_layout = new_test_css_node(); @@ -2483,6 +2511,8 @@ int main() node_0->style.padding[CSS_TOP] = 5; node_0->style.padding[CSS_RIGHT] = 5; node_0->style.padding[CSS_BOTTOM] = 5; + node_0->style.padding[CSS_START] = 5; + node_0->style.padding[CSS_END] = 5; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -2519,6 +2549,8 @@ int main() node_0->style.padding[CSS_TOP] = 5; node_0->style.padding[CSS_RIGHT] = 5; node_0->style.padding[CSS_BOTTOM] = 5; + node_0->style.padding[CSS_START] = 5; + node_0->style.padding[CSS_END] = 5; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -2527,6 +2559,8 @@ int main() node_1->style.margin[CSS_TOP] = 5; node_1->style.margin[CSS_RIGHT] = 5; node_1->style.margin[CSS_BOTTOM] = 5; + node_1->style.margin[CSS_START] = 5; + node_1->style.margin[CSS_END] = 5; } } @@ -2564,6 +2598,8 @@ int main() node_1->style.padding[CSS_TOP] = 10; node_1->style.padding[CSS_RIGHT] = 10; node_1->style.padding[CSS_BOTTOM] = 10; + node_1->style.padding[CSS_START] = 10; + node_1->style.padding[CSS_END] = 10; } } @@ -2596,6 +2632,8 @@ int main() node_0->style.padding[CSS_TOP] = 50; node_0->style.padding[CSS_RIGHT] = 50; node_0->style.padding[CSS_BOTTOM] = 50; + node_0->style.padding[CSS_START] = 50; + node_0->style.padding[CSS_END] = 50; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -2605,6 +2643,8 @@ int main() node_1->style.padding[CSS_TOP] = 10; node_1->style.padding[CSS_RIGHT] = 10; node_1->style.padding[CSS_BOTTOM] = 10; + node_1->style.padding[CSS_START] = 10; + node_1->style.padding[CSS_END] = 10; } } @@ -2646,6 +2686,8 @@ int main() node_2->style.margin[CSS_TOP] = 16; node_2->style.margin[CSS_RIGHT] = 16; node_2->style.margin[CSS_BOTTOM] = 16; + node_2->style.margin[CSS_START] = 16; + node_2->style.margin[CSS_END] = 16; } } } @@ -2996,6 +3038,8 @@ int main() node_0->style.padding[CSS_TOP] = 5; node_0->style.padding[CSS_RIGHT] = 5; node_0->style.padding[CSS_BOTTOM] = 5; + node_0->style.padding[CSS_START] = 5; + node_0->style.padding[CSS_END] = 5; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -3075,6 +3119,8 @@ int main() node_0->style.padding[CSS_TOP] = 20; node_0->style.padding[CSS_RIGHT] = 20; node_0->style.padding[CSS_BOTTOM] = 20; + node_0->style.padding[CSS_START] = 20; + node_0->style.padding[CSS_END] = 20; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -3669,6 +3715,8 @@ int main() node_0->style.border[CSS_TOP] = 5; node_0->style.border[CSS_RIGHT] = 5; node_0->style.border[CSS_BOTTOM] = 5; + node_0->style.border[CSS_START] = 5; + node_0->style.border[CSS_END] = 5; } css_node_t *root_layout = new_test_css_node(); @@ -3726,6 +3774,8 @@ int main() node_0->style.border[CSS_TOP] = 1; node_0->style.border[CSS_RIGHT] = 1; node_0->style.border[CSS_BOTTOM] = 1; + node_0->style.border[CSS_START] = 1; + node_0->style.border[CSS_END] = 1; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -3771,6 +3821,8 @@ int main() node_1->style.padding[CSS_TOP] = 20; node_1->style.padding[CSS_RIGHT] = 20; node_1->style.padding[CSS_BOTTOM] = 20; + node_1->style.padding[CSS_START] = 20; + node_1->style.padding[CSS_END] = 20; } } @@ -4263,6 +4315,8 @@ int main() node_0->style.padding[CSS_TOP] = 10; node_0->style.padding[CSS_RIGHT] = 10; node_0->style.padding[CSS_BOTTOM] = 10; + node_0->style.padding[CSS_START] = 10; + node_0->style.padding[CSS_END] = 10; init_css_node_children(node_0, 1); { css_node_t *node_1; @@ -4272,6 +4326,8 @@ int main() node_1->style.margin[CSS_TOP] = 10; node_1->style.margin[CSS_RIGHT] = 10; node_1->style.margin[CSS_BOTTOM] = 10; + node_1->style.margin[CSS_START] = 10; + node_1->style.margin[CSS_END] = 10; init_css_node_children(node_1, 1); { css_node_t *node_2; @@ -4486,6 +4542,8 @@ int main() node_2->style.margin[CSS_TOP] = 20; node_2->style.margin[CSS_RIGHT] = 20; node_2->style.margin[CSS_BOTTOM] = 20; + node_2->style.margin[CSS_START] = 20; + node_2->style.margin[CSS_END] = 20; node_2->measure = measure; node_2->context = "loooooooooong with space"; } @@ -4541,6 +4599,8 @@ int main() node_2->style.margin[CSS_TOP] = 20; node_2->style.margin[CSS_RIGHT] = 20; node_2->style.margin[CSS_BOTTOM] = 20; + node_2->style.margin[CSS_START] = 20; + node_2->style.margin[CSS_END] = 20; node_2->measure = measure; node_2->context = "loooooooooong with space"; } @@ -4594,6 +4654,8 @@ int main() node_2->style.margin[CSS_TOP] = 20; node_2->style.margin[CSS_RIGHT] = 20; node_2->style.margin[CSS_BOTTOM] = 20; + node_2->style.margin[CSS_START] = 20; + node_2->style.margin[CSS_END] = 20; node_2->measure = measure; node_2->context = "loooooooooong with space"; } @@ -6723,6 +6785,8 @@ int main() node_1->style.padding[CSS_TOP] = 10; node_1->style.padding[CSS_RIGHT] = 10; node_1->style.padding[CSS_BOTTOM] = 10; + node_1->style.padding[CSS_START] = 10; + node_1->style.padding[CSS_END] = 10; node_1->style.position[CSS_LEFT] = 100; node_1->style.position[CSS_TOP] = 100; node_1->style.position[CSS_RIGHT] = 100; @@ -6785,10 +6849,14 @@ int main() node_1->style.padding[CSS_TOP] = 10; node_1->style.padding[CSS_RIGHT] = 10; node_1->style.padding[CSS_BOTTOM] = 10; + node_1->style.padding[CSS_START] = 10; + node_1->style.padding[CSS_END] = 10; node_1->style.border[CSS_LEFT] = 1; node_1->style.border[CSS_TOP] = 1; node_1->style.border[CSS_RIGHT] = 1; node_1->style.border[CSS_BOTTOM] = 1; + node_1->style.border[CSS_START] = 1; + node_1->style.border[CSS_END] = 1; node_1->style.position[CSS_LEFT] = 100; node_1->style.position[CSS_TOP] = 100; node_1->style.position[CSS_RIGHT] = 100; @@ -6851,6 +6919,8 @@ int main() node_1->style.padding[CSS_TOP] = 10; node_1->style.padding[CSS_RIGHT] = 10; node_1->style.padding[CSS_BOTTOM] = 10; + node_1->style.padding[CSS_START] = 10; + node_1->style.padding[CSS_END] = 10; init_css_node_children(node_1, 1); { css_node_t *node_2; @@ -7064,6 +7134,339 @@ int main() test("should correctly space wrapped nodes", 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] = 200; + node_0->style.padding[CSS_LEFT] = 5; + node_0->style.padding[CSS_RIGHT] = 5; + node_0->style.padding[CSS_START] = 15; + node_0->style.padding[CSS_END] = 15; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 170; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should give start/end padding precedence over left/right padding", 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] = 200; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + node_1->style.margin[CSS_LEFT] = 5; + node_1->style.margin[CSS_RIGHT] = 5; + node_1->style.margin[CSS_START] = 15; + node_1->style.margin[CSS_END] = 15; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 170; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should give start/end margin precedence over left/right margin", 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] = 200; + node_0->style.border[CSS_LEFT] = 5; + node_0->style.border[CSS_RIGHT] = 5; + node_0->style.border[CSS_START] = 15; + node_0->style.border[CSS_END] = 15; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 170; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should give start/end border precedence over left/right border", 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] = 200; + node_0->style.padding[CSS_START] = 15; + node_0->style.padding[CSS_END] = 5; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end padding", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.dimensions[CSS_WIDTH] = 200; + node_0->style.padding[CSS_START] = 15; + node_0->style.padding[CSS_END] = 5; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 5; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end padding in rtl", 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] = 200; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + node_1->style.margin[CSS_START] = 15; + node_1->style.margin[CSS_END] = 5; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end margin", 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] = 200; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.direction = CSS_DIRECTION_RTL; + node_1->style.dimensions[CSS_HEIGHT] = 50; + node_1->style.margin[CSS_START] = 15; + node_1->style.margin[CSS_END] = 5; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 5; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end margin in rtl", 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] = 200; + node_0->style.border[CSS_START] = 15; + node_0->style.border[CSS_END] = 5; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 15; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end border", root_node, root_layout); + } + + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + node_0->style.direction = CSS_DIRECTION_RTL; + node_0->style.dimensions[CSS_WIDTH] = 200; + node_0->style.border[CSS_START] = 15; + node_0->style.border[CSS_END] = 5; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_HEIGHT] = 50; + } + } + + 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] = 50; + init_css_node_children(node_0, 1); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 5; + node_1->layout.dimensions[CSS_WIDTH] = 180; + node_1->layout.dimensions[CSS_HEIGHT] = 50; + } + } + + test("should layout node with correct start/end border in rtl", root_node, root_layout); + } /** END_GENERATED **/ return tests_finished(); } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 399e6a6c..d219acf3 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -2185,7 +2185,7 @@ describe('Layout', function() { ]} ); }); - + it('should correctly space wrapped nodes', function() { testLayout( {style: {width: 320, height: 200, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, children: [ @@ -2206,4 +2206,103 @@ describe('Layout', function() { ]} ); }); + + it('should give start/end padding precedence over left/right padding', function() { + testLayout( + {style: {width: 200, paddingLeft: 5, paddingStart: 15, paddingRight: 5, paddingEnd: 15}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 170, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should give start/end margin precedence over left/right margin', function() { + testLayout( + {style: {width: 200}, children: [ + {style: {height: 50, marginLeft: 5, marginStart: 15, marginRight: 5, marginEnd: 15}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 170, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should give start/end border precedence over left/right border', function() { + testLayout( + {style: {width: 200, borderLeftWidth: 5, borderStartWidth: 15, borderRightWidth: 5, borderEndWidth: 15}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 170, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should layout node with correct start/end padding', function() { + testLayout( + {style: {width: 200, paddingStart: 15, paddingEnd: 5}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should layout node with correct start/end padding in rtl', function() { + testLayout( + {style: {width: 200, direction: 'rtl', paddingStart: 15, paddingEnd: 5}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 5} + ]} + ); + }); + + it('should layout node with correct start/end margin', function() { + testLayout( + {style: {width: 200}, children: [ + {style: {height: 50, marginStart: 15, marginEnd: 5}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should layout node with correct start/end margin in rtl', function() { + testLayout( + {style: {width: 200}, children: [ + {style: {height: 50, direction: 'rtl', marginStart: 15, marginEnd: 5}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 5} + ]} + ); + }); + + it('should layout node with correct start/end border', function() { + testLayout( + {style: {width: 200, borderStartWidth: 15, borderEndWidth: 5}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 15} + ]} + ); + }); + + it('should layout node with correct start/end border in rtl', function() { + testLayout( + {style: {width: 200, direction: 'rtl', borderStartWidth: 15, borderEndWidth: 5}, children: [ + {style: {height: 50}} + ]}, + {width: 200, height: 50, top: 0, left: 0, children: [ + {width: 180, height: 50, top: 0, left: 5} + ]} + ); + }); }); diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index c96dd17c..41e895a2 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -18,6 +18,8 @@ public class LayoutEngine { LEFT, BOTTOM, RIGHT, + START, + END, } private static enum DimensionIndex { @@ -191,11 +193,37 @@ public class LayoutEngine { return node.style.margin.get(Spacing.LEFT); case RIGHT: return node.style.margin.get(Spacing.RIGHT); + case START: + return node.style.margin.get(Spacing.START); + case END: + return node.style.margin.get(Spacing.END); default: throw new RuntimeException("Someone added a new cardinal direction..."); } } + private static float getLeadingMargin(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float leadingMargin = getMargin(node, PositionIndex.START); + if (!CSSConstants.isUndefined(leadingMargin)) { + return leadingMargin; + } + } + + return getMargin(node, getLeading(axis)); + } + + private static float getTrailingMargin(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float trailingMargin = getMargin(node, PositionIndex.END); + if (!CSSConstants.isUndefined(trailingMargin)) { + return trailingMargin; + } + } + + return getMargin(node, getTrailing(axis)); + } + private static float getPadding(CSSNode node, PositionIndex position) { switch (position) { case TOP: @@ -206,11 +234,37 @@ public class LayoutEngine { return node.style.padding.get(Spacing.LEFT); case RIGHT: return node.style.padding.get(Spacing.RIGHT); + case START: + return node.style.padding.get(Spacing.START); + case END: + return node.style.padding.get(Spacing.END); default: throw new RuntimeException("Someone added a new cardinal direction..."); } } + private static float getLeadingPadding(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float leadingPadding = getPadding(node, PositionIndex.START); + if (!CSSConstants.isUndefined(leadingPadding)) { + return leadingPadding; + } + } + + return getPadding(node, getLeading(axis)); + } + + private static float getTrailingPadding(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float trailingPadding = getPadding(node, PositionIndex.END); + if (!CSSConstants.isUndefined(trailingPadding)) { + return trailingPadding; + } + } + + return getPadding(node, getTrailing(axis)); + } + private static float getBorder(CSSNode node, PositionIndex position) { switch (position) { case TOP: @@ -221,27 +275,55 @@ public class LayoutEngine { return node.style.border.get(Spacing.LEFT); case RIGHT: return node.style.border.get(Spacing.RIGHT); + case START: + return node.style.border.get(Spacing.START); + case END: + return node.style.border.get(Spacing.END); default: throw new RuntimeException("Someone added a new cardinal direction..."); } } - private static float getPaddingAndBorder(CSSNode node, PositionIndex position) { - return getPadding(node, position) + getBorder(node, position); + private static float getLeadingBorder(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float leadingBorder = getBorder(node, PositionIndex.START); + if (!CSSConstants.isUndefined(leadingBorder)) { + return leadingBorder; + } + } + + return getBorder(node, getLeading(axis)); + } + + private static float getTrailingBorder(CSSNode node, CSSFlexDirection axis) { + if (isRowDirection(axis)) { + float trailingBorder = getBorder(node, PositionIndex.END); + if (!CSSConstants.isUndefined(trailingBorder)) { + return trailingBorder; + } + } + + return getBorder(node, getTrailing(axis)); + } + + private static float getLeadingPaddingAndBorder(CSSNode node, CSSFlexDirection axis) { + return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); + } + + private static float getTrailingPaddingAndBorder(CSSNode node, CSSFlexDirection axis) { + return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); } private static float getBorderAxis(CSSNode node, CSSFlexDirection axis) { - return getBorder(node, getLeading(axis)) + getBorder(node, getTrailing(axis)); + return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); } private static float getMarginAxis(CSSNode node, CSSFlexDirection axis) { - return getMargin(node, getLeading(axis)) + getMargin(node, getTrailing(axis)); + return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } private static float getPaddingAndBorderAxis(CSSNode node, CSSFlexDirection axis) { - return getPaddingAndBorder( - node, - getLeading(axis)) + getPaddingAndBorder(node, getTrailing(axis)); + return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); } private static float boundAxis(CSSNode node, CSSFlexDirection axis, float value) { @@ -385,8 +467,8 @@ public class LayoutEngine { private static float getDimWithMargin(CSSNode node, CSSFlexDirection axis) { return getLayoutDimension(node, getDim(axis)) + - getMargin(node, getLeading(axis)) + - getMargin(node, getTrailing(axis)); + getLeadingMargin(node, axis) + + getTrailingMargin(node, axis); } private static boolean needsRelayout(CSSNode node, float parentMaxWidth) { @@ -437,13 +519,13 @@ public class LayoutEngine { // The position is set by the parent, but we need to complete it with a // delta composed of the margin and left/top/right/bottom - setLayoutPosition(node, getLeading(mainAxis), getLayoutPosition(node, getLeading(mainAxis)) + getMargin(node, getLeading(mainAxis)) + + setLayoutPosition(node, getLeading(mainAxis), getLayoutPosition(node, getLeading(mainAxis)) + getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis)); - setLayoutPosition(node, getTrailing(mainAxis), getLayoutPosition(node, getTrailing(mainAxis)) + getMargin(node, getTrailing(mainAxis)) + + setLayoutPosition(node, getTrailing(mainAxis), getLayoutPosition(node, getTrailing(mainAxis)) + getTrailingMargin(node, mainAxis) + getRelativePosition(node, mainAxis)); - setLayoutPosition(node, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getMargin(node, getLeading(crossAxis)) + + setLayoutPosition(node, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getLeadingMargin(node, crossAxis) + getRelativePosition(node, crossAxis)); - setLayoutPosition(node, getTrailing(crossAxis), getLayoutPosition(node, getTrailing(crossAxis)) + getMargin(node, getTrailing(crossAxis)) + + setLayoutPosition(node, getTrailing(crossAxis), getLayoutPosition(node, getTrailing(crossAxis)) + getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis)); if (isMeasureDefined(node)) { @@ -725,7 +807,7 @@ public class LayoutEngine { // container! float crossDim = 0; float mainDim = leadingMainDim + - getPaddingAndBorder(node, getLeading(mainAxis)); + getLeadingPaddingAndBorder(node, mainAxis); for (i = startLine; i < endLine; ++i) { child = node.getChildAt(i); @@ -736,8 +818,8 @@ public class LayoutEngine { // defined, we override the position to whatever the user said // (and margin/border). setLayoutPosition(child, getPos(mainAxis), getPosition(child, getLeading(mainAxis)) + - getBorder(node, getLeading(mainAxis)) + - getMargin(child, getLeading(mainAxis))); + getLeadingBorder(node, mainAxis) + + getLeadingMargin(child, mainAxis)); } else { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. @@ -784,11 +866,11 @@ public class LayoutEngine { // top/left/bottom/right being set, we override all the previously // computed positions to set it correctly. setLayoutPosition(child, getPos(crossAxis), getPosition(child, getLeading(crossAxis)) + - getBorder(node, getLeading(crossAxis)) + - getMargin(child, getLeading(crossAxis))); + getLeadingBorder(node, crossAxis) + + getLeadingMargin(child, crossAxis)); } else { - float leadingCrossDim = getPaddingAndBorder(node, getLeading(crossAxis)); + float leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis @@ -823,6 +905,11 @@ public class LayoutEngine { // And we apply the position setLayoutPosition(child, getPos(crossAxis), getLayoutPosition(child, getPos(crossAxis)) + linesCrossDim + leadingCrossDim); + + // Define the trailing position accordingly. + if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) { + setTrailingPosition(node, child, crossAxis); + } } } @@ -831,22 +918,21 @@ public class LayoutEngine { startLine = endLine; } + boolean needsMainTrailingPos = false; + boolean needsCrossTrailingPos = false; + // 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 (CSSConstants.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) { setLayoutDimension(node, getDim(mainAxis), Math.max( // We're missing the last padding at this point to get the final // dimension - boundAxis(node, mainAxis, linesMainDim + getPaddingAndBorder(node, getTrailing(mainAxis))), + boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) )); - // Now that the width is defined, we should update the trailing - // positions for the children. - for (i = 0; i < node.getChildCount(); ++i) { - setTrailingPosition(node, node.getChildAt(i), mainAxis); - } + needsMainTrailingPos = true; } if (CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) { @@ -857,9 +943,27 @@ public class LayoutEngine { boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), getPaddingAndBorderAxis(node, crossAxis) )); + + needsCrossTrailingPos = true; } - // Calculate dimensions for absolutely positioned elements + // Set trailing position if necessary + + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (i = 0; i < node.getChildCount(); ++i) { + child = node.getChildAt(i); + + if (needsMainTrailingPos) { + setTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + // Calculate dimensions for absolutely positioned elements for (i = 0; i < node.getChildCount(); ++i) { child = node.getChildAt(i); diff --git a/src/java/src/com/facebook/csslayout/Spacing.java b/src/java/src/com/facebook/csslayout/Spacing.java index 24b25590..cbdbce2c 100644 --- a/src/java/src/com/facebook/csslayout/Spacing.java +++ b/src/java/src/com/facebook/csslayout/Spacing.java @@ -40,10 +40,18 @@ public class Spacing { * {@code marginHorizontal}. */ public static final int HORIZONTAL = 5; + /** + * Spacing type that represents start direction e.g. left in left-to-right, right in right-to-left. + */ + public static final int START = 6; + /** + * Spacing type that represents end direction e.g. right in left-to-right, left in right-to-left. + */ + public static final int END = 7; /** * Spacing type that represents all directions (left, top, right, bottom). E.g. {@code margin}. */ - public static final int ALL = 6; + public static final int ALL = 8; private final float[] mSpacing = newFullSpacingArray(); private final float[] mDefaultSpacing = newSpacingResultArray(); @@ -114,6 +122,7 @@ public class Spacing { CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, + CSSConstants.UNDEFINED, }; } @@ -127,6 +136,11 @@ public class Spacing { defaultValue, defaultValue, defaultValue, + defaultValue, + defaultValue, + CSSConstants.UNDEFINED, + CSSConstants.UNDEFINED, + defaultValue, }; } @@ -170,6 +184,22 @@ public class Spacing { : !CSSConstants.isUndefined(mSpacing[ALL]) ? mSpacing[ALL] : mDefaultSpacing[RIGHT]; + mSpacingResult[START] = + !CSSConstants.isUndefined(mSpacing[START]) + ? mSpacing[START] + : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) + ? mSpacing[HORIZONTAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[START]; + mSpacingResult[END] = + !CSSConstants.isUndefined(mSpacing[END]) + ? mSpacing[END] + : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) + ? mSpacing[HORIZONTAL] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing[END]; mDirty = false; } } diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index a0c01885..9104b514 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -374,6 +374,8 @@ public class LayoutEngineTest { node_0.setMargin(Spacing.TOP, 10); node_0.setMargin(Spacing.RIGHT, 10); node_0.setMargin(Spacing.BOTTOM, 10); + node_0.setMargin(Spacing.START, 10); + node_0.setMargin(Spacing.END, 10); } TestCSSNode root_layout = new TestCSSNode(); @@ -400,6 +402,8 @@ public class LayoutEngineTest { node_0.setMargin(Spacing.TOP, 10); node_0.setMargin(Spacing.RIGHT, 10); node_0.setMargin(Spacing.BOTTOM, 10); + node_0.setMargin(Spacing.START, 10); + node_0.setMargin(Spacing.END, 10); addChildren(node_0, 3); { TestCSSNode node_1; @@ -410,6 +414,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 50); node_1.setMargin(Spacing.RIGHT, 50); node_1.setMargin(Spacing.BOTTOM, 50); + node_1.setMargin(Spacing.START, 50); + node_1.setMargin(Spacing.END, 50); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; @@ -417,6 +423,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 25); node_1.setMargin(Spacing.RIGHT, 25); node_1.setMargin(Spacing.BOTTOM, 25); + node_1.setMargin(Spacing.START, 25); + node_1.setMargin(Spacing.END, 25); node_1 = node_0.getChildAt(2); node_1.style.width = 100; node_1.style.height = 100; @@ -424,6 +432,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 10); node_1.setMargin(Spacing.RIGHT, 10); node_1.setMargin(Spacing.BOTTOM, 10); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); } } @@ -471,6 +481,8 @@ public class LayoutEngineTest { node_0.setMargin(Spacing.TOP, 10); node_0.setMargin(Spacing.RIGHT, 10); node_0.setMargin(Spacing.BOTTOM, 10); + node_0.setMargin(Spacing.START, 10); + node_0.setMargin(Spacing.END, 10); addChildren(node_0, 3); { TestCSSNode node_1; @@ -481,6 +493,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 50); node_1.setMargin(Spacing.RIGHT, 50); node_1.setMargin(Spacing.BOTTOM, 50); + node_1.setMargin(Spacing.START, 50); + node_1.setMargin(Spacing.END, 50); node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; @@ -488,6 +502,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 25); node_1.setMargin(Spacing.RIGHT, 25); node_1.setMargin(Spacing.BOTTOM, 25); + node_1.setMargin(Spacing.START, 25); + node_1.setMargin(Spacing.END, 25); node_1 = node_0.getChildAt(2); node_1.style.width = 100; node_1.style.height = 100; @@ -495,6 +511,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 10); node_1.setMargin(Spacing.RIGHT, 10); node_1.setMargin(Spacing.BOTTOM, 10); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); } } @@ -2161,6 +2179,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 5); node_1.setMargin(Spacing.RIGHT, 5); node_1.setMargin(Spacing.BOTTOM, 5); + node_1.setMargin(Spacing.START, 5); + node_1.setMargin(Spacing.END, 5); } } @@ -2200,6 +2220,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 5); node_1.setMargin(Spacing.RIGHT, 5); node_1.setMargin(Spacing.BOTTOM, 5); + node_1.setMargin(Spacing.START, 5); + node_1.setMargin(Spacing.END, 5); } } @@ -2426,6 +2448,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 10); node_2.setMargin(Spacing.RIGHT, 10); node_2.setMargin(Spacing.BOTTOM, 10); + node_2.setMargin(Spacing.START, 10); + node_2.setMargin(Spacing.END, 10); node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -2487,6 +2511,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 10); node_2.setMargin(Spacing.RIGHT, 10); node_2.setMargin(Spacing.BOTTOM, 10); + node_2.setMargin(Spacing.START, 10); + node_2.setMargin(Spacing.END, 10); node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -2646,6 +2672,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 5); node_0.setPadding(Spacing.RIGHT, 5); node_0.setPadding(Spacing.BOTTOM, 5); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); } TestCSSNode root_layout = new TestCSSNode(); @@ -2670,6 +2698,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 5); node_0.setPadding(Spacing.RIGHT, 5); node_0.setPadding(Spacing.BOTTOM, 5); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2708,6 +2738,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 5); node_0.setPadding(Spacing.RIGHT, 5); node_0.setPadding(Spacing.BOTTOM, 5); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2716,6 +2748,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 5); node_1.setMargin(Spacing.RIGHT, 5); node_1.setMargin(Spacing.BOTTOM, 5); + node_1.setMargin(Spacing.START, 5); + node_1.setMargin(Spacing.END, 5); } } @@ -2755,6 +2789,8 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 10); node_1.setPadding(Spacing.RIGHT, 10); node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); } } @@ -2789,6 +2825,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 50); node_0.setPadding(Spacing.RIGHT, 50); node_0.setPadding(Spacing.BOTTOM, 50); + node_0.setPadding(Spacing.START, 50); + node_0.setPadding(Spacing.END, 50); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2798,6 +2836,8 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 10); node_1.setPadding(Spacing.RIGHT, 10); node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); } } @@ -2841,6 +2881,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 16); node_2.setMargin(Spacing.RIGHT, 16); node_2.setMargin(Spacing.BOTTOM, 16); + node_2.setMargin(Spacing.START, 16); + node_2.setMargin(Spacing.END, 16); } } } @@ -3213,6 +3255,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 5); node_0.setPadding(Spacing.RIGHT, 5); node_0.setPadding(Spacing.BOTTOM, 5); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3296,6 +3340,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 20); node_0.setPadding(Spacing.RIGHT, 20); node_0.setPadding(Spacing.BOTTOM, 20); + node_0.setPadding(Spacing.START, 20); + node_0.setPadding(Spacing.END, 20); addChildren(node_0, 1); { TestCSSNode node_1; @@ -3920,6 +3966,8 @@ public class LayoutEngineTest { node_0.setBorder(Spacing.TOP, 5); node_0.setBorder(Spacing.RIGHT, 5); node_0.setBorder(Spacing.BOTTOM, 5); + node_0.setBorder(Spacing.START, 5); + node_0.setBorder(Spacing.END, 5); } TestCSSNode root_layout = new TestCSSNode(); @@ -3981,6 +4029,8 @@ public class LayoutEngineTest { node_0.setBorder(Spacing.TOP, 1); node_0.setBorder(Spacing.RIGHT, 1); node_0.setBorder(Spacing.BOTTOM, 1); + node_0.setBorder(Spacing.START, 1); + node_0.setBorder(Spacing.END, 1); addChildren(node_0, 1); { TestCSSNode node_1; @@ -4028,6 +4078,8 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 20); node_1.setPadding(Spacing.RIGHT, 20); node_1.setPadding(Spacing.BOTTOM, 20); + node_1.setPadding(Spacing.START, 20); + node_1.setPadding(Spacing.END, 20); } } @@ -4546,6 +4598,8 @@ public class LayoutEngineTest { node_0.setPadding(Spacing.TOP, 10); node_0.setPadding(Spacing.RIGHT, 10); node_0.setPadding(Spacing.BOTTOM, 10); + node_0.setPadding(Spacing.START, 10); + node_0.setPadding(Spacing.END, 10); addChildren(node_0, 1); { TestCSSNode node_1; @@ -4555,6 +4609,8 @@ public class LayoutEngineTest { node_1.setMargin(Spacing.TOP, 10); node_1.setMargin(Spacing.RIGHT, 10); node_1.setMargin(Spacing.BOTTOM, 10); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); addChildren(node_1, 1); { TestCSSNode node_2; @@ -4779,6 +4835,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 20); node_2.setMargin(Spacing.RIGHT, 20); node_2.setMargin(Spacing.BOTTOM, 20); + node_2.setMargin(Spacing.START, 20); + node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -4836,6 +4894,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 20); node_2.setMargin(Spacing.RIGHT, 20); node_2.setMargin(Spacing.BOTTOM, 20); + node_2.setMargin(Spacing.START, 20); + node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -4891,6 +4951,8 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.TOP, 20); node_2.setMargin(Spacing.RIGHT, 20); node_2.setMargin(Spacing.BOTTOM, 20); + node_2.setMargin(Spacing.START, 20); + node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -7126,6 +7188,8 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 10); node_1.setPadding(Spacing.RIGHT, 10); node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); node_1.style.positionLeft = 100; node_1.style.positionTop = 100; node_1.style.positionRight = 100; @@ -7190,10 +7254,14 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 10); node_1.setPadding(Spacing.RIGHT, 10); node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); node_1.setBorder(Spacing.LEFT, 1); node_1.setBorder(Spacing.TOP, 1); node_1.setBorder(Spacing.RIGHT, 1); node_1.setBorder(Spacing.BOTTOM, 1); + node_1.setBorder(Spacing.START, 1); + node_1.setBorder(Spacing.END, 1); node_1.style.positionLeft = 100; node_1.style.positionTop = 100; node_1.style.positionRight = 100; @@ -7258,6 +7326,8 @@ public class LayoutEngineTest { node_1.setPadding(Spacing.TOP, 10); node_1.setPadding(Spacing.RIGHT, 10); node_1.setPadding(Spacing.BOTTOM, 10); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); addChildren(node_1, 1); { TestCSSNode node_2; @@ -7475,5 +7545,356 @@ public class LayoutEngineTest { test("should correctly space wrapped nodes", root_node, root_layout); } + + @Test + public void testCase168() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + node_0.setPadding(Spacing.LEFT, 5); + node_0.setPadding(Spacing.RIGHT, 5); + node_0.setPadding(Spacing.START, 15); + node_0.setPadding(Spacing.END, 15); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 170; + node_1.layout.height = 50; + } + } + + test("should give start/end padding precedence over left/right padding", root_node, root_layout); + } + + @Test + public void testCase169() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + node_1.setMargin(Spacing.LEFT, 5); + node_1.setMargin(Spacing.RIGHT, 5); + node_1.setMargin(Spacing.START, 15); + node_1.setMargin(Spacing.END, 15); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 170; + node_1.layout.height = 50; + } + } + + test("should give start/end margin precedence over left/right margin", root_node, root_layout); + } + + @Test + public void testCase170() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + node_0.setBorder(Spacing.LEFT, 5); + node_0.setBorder(Spacing.RIGHT, 5); + node_0.setBorder(Spacing.START, 15); + node_0.setBorder(Spacing.END, 15); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 170; + node_1.layout.height = 50; + } + } + + test("should give start/end border precedence over left/right border", root_node, root_layout); + } + + @Test + public void testCase171() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + node_0.setPadding(Spacing.START, 15); + node_0.setPadding(Spacing.END, 5); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end padding", root_node, root_layout); + } + + @Test + public void testCase172() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.width = 200; + node_0.setPadding(Spacing.START, 15); + node_0.setPadding(Spacing.END, 5); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 5; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end padding in rtl", root_node, root_layout); + } + + @Test + public void testCase173() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + node_1.setMargin(Spacing.START, 15); + node_1.setMargin(Spacing.END, 5); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end margin", root_node, root_layout); + } + + @Test + public void testCase174() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.direction = CSSDirection.RTL; + node_1.style.height = 50; + node_1.setMargin(Spacing.START, 15); + node_1.setMargin(Spacing.END, 5); + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 5; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end margin in rtl", root_node, root_layout); + } + + @Test + public void testCase175() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 200; + node_0.setBorder(Spacing.START, 15); + node_0.setBorder(Spacing.END, 5); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 15; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end border", root_node, root_layout); + } + + @Test + public void testCase176() + { + TestCSSNode root_node = new TestCSSNode(); + { + TestCSSNode node_0 = root_node; + node_0.style.direction = CSSDirection.RTL; + node_0.style.width = 200; + node_0.setBorder(Spacing.START, 15); + node_0.setBorder(Spacing.END, 5); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.style.height = 50; + } + } + + TestCSSNode root_layout = new TestCSSNode(); + { + TestCSSNode node_0 = root_layout; + node_0.layout.top = 0; + node_0.layout.left = 0; + node_0.layout.width = 200; + node_0.layout.height = 50; + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.layout.top = 0; + node_1.layout.left = 5; + node_1.layout.width = 180; + node_1.layout.height = 50; + } + } + + test("should layout node with correct start/end border in rtl", root_node, root_layout); + } /** END_GENERATED **/ } diff --git a/src/transpile.js b/src/transpile.js index cc39b2f1..e2f7b268 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -97,11 +97,15 @@ function printLayout(test) { addFloat(node, spacing + suffix, spacing + '[CSS_TOP]'); addFloat(node, spacing + suffix, spacing + '[CSS_RIGHT]'); addFloat(node, spacing + suffix, spacing + '[CSS_BOTTOM]'); + addFloat(node, spacing + suffix, spacing + '[CSS_START]'); + addFloat(node, spacing + suffix, spacing + '[CSS_END]'); addFloat(node, spacing + 'Left' + suffix, spacing + '[CSS_LEFT]'); addFloat(node, spacing + 'Top' + suffix, spacing + '[CSS_TOP]'); addFloat(node, spacing + 'Right' + suffix, spacing + '[CSS_RIGHT]'); addFloat(node, spacing + 'Bottom' + suffix, spacing + '[CSS_BOTTOM]'); + addFloat(node, spacing + 'Start' + suffix, spacing + '[CSS_START]'); + addFloat(node, spacing + 'End' + suffix, spacing + '[CSS_END]'); } function addMeasure(node) { From 6d72f472f5464a0833d6e7b991389711e71ed8f8 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Thu, 14 May 2015 20:59:14 +0100 Subject: [PATCH 7/8] Add getters for CSSNode's style width and height --- src/java/src/com/facebook/csslayout/CSSNode.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java index 9d62c7fa..4135d734 100644 --- a/src/java/src/com/facebook/csslayout/CSSNode.java +++ b/src/java/src/com/facebook/csslayout/CSSNode.java @@ -341,6 +341,20 @@ public class CSSNode { return style.padding; } + /** + * Get this node's width, as defined in the style. + */ + public float getStyleWidth() { + return style.width; + } + + /** + * Get this node's height, as defined in the style. + */ + public float getStyleHeight() { + return style.height; + } + /** * Set a default padding (left/top/right/bottom) for this node. */ From 11f09d1a650f3ba169c42251cddef7fdd0987905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Oghin=C4=83?= Date: Fri, 15 May 2015 14:13:25 +0100 Subject: [PATCH 8/8] [java] simplify Spacing, reduce allocations --- .../src/com/facebook/csslayout/Spacing.java | 91 +++++-------------- 1 file changed, 22 insertions(+), 69 deletions(-) diff --git a/src/java/src/com/facebook/csslayout/Spacing.java b/src/java/src/com/facebook/csslayout/Spacing.java index cbdbce2c..9fa61890 100644 --- a/src/java/src/com/facebook/csslayout/Spacing.java +++ b/src/java/src/com/facebook/csslayout/Spacing.java @@ -8,6 +8,8 @@ */ package com.facebook.csslayout; +import javax.annotation.Nullable; + /** * Class representing CSS spacing (padding, margin, and borders). This is mostly necessary to * properly implement interactions and updates for properties like margin, marginLeft, and @@ -54,9 +56,7 @@ public class Spacing { public static final int ALL = 8; private final float[] mSpacing = newFullSpacingArray(); - private final float[] mDefaultSpacing = newSpacingResultArray(); - private final float[] mSpacingResult = newSpacingResultArray(); - private boolean mDirty; + @Nullable private float[] mDefaultSpacing = null; /** * Set a spacing value. @@ -70,9 +70,9 @@ public class Spacing { public boolean set(int spacingType, float value) { if (!FloatUtil.floatsEqual(mSpacing[spacingType], value)) { mSpacing[spacingType] = value; - mDirty = true; + return true; } - return mDirty; + return false; } /** @@ -84,11 +84,14 @@ public class Spacing { * @return */ public boolean setDefault(int spacingType, float value) { + if (mDefaultSpacing == null) { + mDefaultSpacing = newSpacingResultArray(); + } if (!FloatUtil.floatsEqual(mDefaultSpacing[spacingType], value)) { mDefaultSpacing[spacingType] = value; - mDirty = true; + return true; } - return mDirty; + return false; } /** @@ -97,8 +100,18 @@ public class Spacing { * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} */ public float get(int spacingType) { - ensureResult(); - return mSpacingResult[spacingType]; + int secondType = spacingType == TOP || spacingType == BOTTOM ? VERTICAL : HORIZONTAL; + float defaultValue = spacingType == START || spacingType == END ? CSSConstants.UNDEFINED : 0; + return + !CSSConstants.isUndefined(mSpacing[spacingType]) + ? mSpacing[spacingType] + : !CSSConstants.isUndefined(mSpacing[secondType]) + ? mSpacing[secondType] + : !CSSConstants.isUndefined(mSpacing[ALL]) + ? mSpacing[ALL] + : mDefaultSpacing != null + ? mDefaultSpacing[spacingType] + : defaultValue; } /** @@ -143,64 +156,4 @@ public class Spacing { defaultValue, }; } - - /** - * Given the {@param fullSpacing} and the spacingResult from {@link #newSpacingResultArray()} from - * a View, update the result array to reflect values that have been set in {@param fullSpacing} - * array. {@param defaultValues} specifies the result values that should be used whenever a - * spacing property hasn't been set. - */ - private void ensureResult() { - if (mDirty) { - mSpacingResult[TOP] = - !CSSConstants.isUndefined(mSpacing[TOP]) - ? mSpacing[TOP] - : !CSSConstants.isUndefined(mSpacing[VERTICAL]) - ? mSpacing[VERTICAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[TOP]; - mSpacingResult[BOTTOM] = - !CSSConstants.isUndefined(mSpacing[BOTTOM]) - ? mSpacing[BOTTOM] - : !CSSConstants.isUndefined(mSpacing[VERTICAL]) - ? mSpacing[VERTICAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[BOTTOM]; - mSpacingResult[LEFT] = - !CSSConstants.isUndefined(mSpacing[LEFT]) - ? mSpacing[LEFT] - : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) - ? mSpacing[HORIZONTAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[LEFT]; - mSpacingResult[RIGHT] = - !CSSConstants.isUndefined(mSpacing[RIGHT]) - ? mSpacing[RIGHT] - : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) - ? mSpacing[HORIZONTAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[RIGHT]; - mSpacingResult[START] = - !CSSConstants.isUndefined(mSpacing[START]) - ? mSpacing[START] - : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) - ? mSpacing[HORIZONTAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[START]; - mSpacingResult[END] = - !CSSConstants.isUndefined(mSpacing[END]) - ? mSpacing[END] - : !CSSConstants.isUndefined(mSpacing[HORIZONTAL]) - ? mSpacing[HORIZONTAL] - : !CSSConstants.isUndefined(mSpacing[ALL]) - ? mSpacing[ALL] - : mDefaultSpacing[END]; - mDirty = false; - } - } }