diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index a1bef154..96a8c763 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,17 +69,23 @@ 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, function (str, match1, match2) { 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|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[Spacing.TOP] - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, + /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]/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/Layout-test-utils.c b/src/Layout-test-utils.c index 30ea312b..9c25acb1 100644 --- a/src/Layout-test-utils.c +++ b/src/Layout-test-utils.c @@ -106,8 +106,7 @@ css_dim_t measure(void *context, float width) { static int test_ran_count = 0; void test(const char *name, css_node_t *style, css_node_t *expected_layout) { ++test_ran_count; - - layoutNode(style, CSS_UNDEFINED); + layoutNode(style, CSS_UNDEFINED, (css_direction_t)-1); if (!are_layout_equal(style, expected_layout)) { printf("%sF%s", "\x1B[31m", "\x1B[0m"); diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index d0e66b34..abaa6e17 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -156,6 +156,10 @@ var layoutTestUtils = (function() { return layout; } + function capitalizeFirst(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } + function computeCSSLayout(rootNode) { fillNodes(rootNode); realComputeLayout(rootNode); @@ -167,8 +171,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; } } @@ -178,6 +184,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) { @@ -196,6 +204,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 8f0c14a1..9fa6a29b 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -41,6 +41,9 @@ void init_css_node(css_node_t *node) { node->style.align_items = CSS_ALIGN_STRETCH; node->style.align_content = CSS_ALIGN_FLEX_START; + 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; @@ -56,6 +59,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; @@ -63,6 +73,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 = (css_direction_t)-1; node->layout.should_update = true; } @@ -124,8 +135,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) { @@ -173,6 +190,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)) { @@ -182,6 +201,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)) { @@ -191,6 +212,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]); @@ -223,57 +246,131 @@ 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]; +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,10 +392,40 @@ static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { return node->style.align_items; } +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; } @@ -316,8 +443,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) { @@ -345,10 +472,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]; } @@ -383,6 +510,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) { @@ -393,13 +525,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); @@ -407,28 +538,32 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // 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[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + + node->layout.position[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis); + node->layout.position[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis); + node->layout.position[trailing[crossAxis]] += getTrailingMargin(node, 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]]); @@ -441,14 +576,16 @@ 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] + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - return; + if (node->children_count == 0) { + return; + } } int i; @@ -545,20 +682,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 @@ -577,6 +714,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { + nonFlexibleChildrenCount--; alreadyComputedNextLayout = 1; break; } @@ -644,17 +782,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); } } @@ -690,7 +828,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // 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); @@ -702,12 +840,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // 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. 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 @@ -735,7 +878,6 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { } // Position elements in the cross axis - for (i = startLine; i < endLine; ++i) { child = node->get_child(node->context, i); @@ -745,11 +887,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // 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 @@ -784,6 +926,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // 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); + } } } @@ -810,19 +957,19 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { !isUndefined(node->layout.dimensions[dim[crossAxis]])) { float nodeCrossAxisInnerSize = node->layout.dimensions[dim[crossAxis]] - getPaddingAndBorderAxis(node, crossAxis); - float remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim; + float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; float crossDimLead = 0; - float currentLead = getPaddingAndBorder(node, leading[crossAxis]); + float currentLead = getLeadingPaddingAndBorder(node, crossAxis); css_align_t alignContent = getAlignContent(node); if (alignContent == CSS_ALIGN_FLEX_END) { - currentLead += remainingCrossDim; + currentLead += remainingAlignContentDim; } else if (alignContent == CSS_ALIGN_CENTER) { - currentLead += remainingCrossDim / 2; + currentLead += remainingAlignContentDim / 2; } else if (alignContent == CSS_ALIGN_STRETCH) { if (nodeCrossAxisInnerSize > linesCrossDim) { - crossDimLead = (remainingCrossDim / linesCount); + crossDimLead = (remainingAlignContentDim / linesCount); } } @@ -856,16 +1003,16 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { continue; } - css_align_t alignItem = getAlignItem(node, child); - if (alignItem == CSS_ALIGN_FLEX_START) { - child->layout.position[pos[crossAxis]] = currentLead + getMargin(child, leading[crossAxis]); - } else if (alignItem == CSS_ALIGN_FLEX_END) { - child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getMargin(child,trailing[crossAxis]) - child->layout.dimensions[dim[crossAxis]]; - } else if (alignItem == CSS_ALIGN_CENTER) { + css_align_t alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem == CSS_ALIGN_FLEX_START) { + child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) { + child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.dimensions[dim[crossAxis]]; + } else if (alignContentAlignItem == CSS_ALIGN_CENTER) { float childHeight = child->layout.dimensions[dim[crossAxis]]; child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignItem == CSS_ALIGN_STRETCH) { - child->layout.position[pos[crossAxis]] = currentLead + getMargin(child, leading[crossAxis]); + } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) { + child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); // TODO(prenaux): Correctly set the height of items with undefined // (auto) crossAxis dimension. } @@ -875,16 +1022,21 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { } } + 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) ); + + needsMainTrailingPos = true; } if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { @@ -895,9 +1047,26 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { 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); if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { @@ -936,8 +1105,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 = @@ -945,6 +1115,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]; @@ -955,8 +1126,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 7ad7d4c0..d30d8e79 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 { @@ -63,6 +71,8 @@ typedef enum { CSS_TOP, CSS_RIGHT, CSS_BOTTOM, + CSS_START, + CSS_END, CSS_POSITION_COUNT } css_position_t; @@ -72,7 +82,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,7 +92,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 { @@ -90,6 +100,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_content; @@ -98,7 +109,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 @@ -110,8 +121,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]; @@ -145,7 +156,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 d49c674e..7a367981 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,35 +35,47 @@ 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) { 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; @@ -67,7 +85,9 @@ var computeLayout = (function() { width: undefined, height: undefined, top: 0, - left: 0 + left: 0, + right: 0, + bottom: 0 }; if (!node.style) { node.style = {}; @@ -88,18 +108,26 @@ var computeLayout = (function() { } else { delete node.children; } + + delete layout.right; + delete layout.bottom; + 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; @@ -109,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) { @@ -161,11 +246,46 @@ var computeLayout = (function() { return 'stretch'; } + 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) { @@ -215,13 +335,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; @@ -259,6 +383,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) { @@ -268,12 +397,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); @@ -281,28 +409,32 @@ 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[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + + node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis); + node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis); + node.layout[trailing[crossAxis]] += getTrailingMargin(node, 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]]); @@ -315,14 +447,16 @@ 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 + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - return; + if (node.children.length === 0) { + return; + } } var/*int*/ i; @@ -419,20 +553,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 @@ -451,6 +585,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; } @@ -518,17 +653,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); } } @@ -564,7 +699,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]; @@ -576,12 +711,17 @@ 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. 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 @@ -609,7 +749,6 @@ var computeLayout = (function() { } // Position elements in the cross axis - for (i = startLine; i < endLine; ++i) { child = node.children[i]; @@ -619,11 +758,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 @@ -658,6 +797,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); + } } } @@ -684,19 +828,19 @@ var computeLayout = (function() { !isUndefined(node.layout[dim[crossAxis]])) { var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] - getPaddingAndBorderAxis(node, crossAxis); - var/*float*/ remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim; + var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; var/*float*/ crossDimLead = 0; - var/*float*/ currentLead = getPaddingAndBorder(node, leading[crossAxis]); + var/*float*/ currentLead = getLeadingPaddingAndBorder(node, crossAxis); var/*css_align_t*/ alignContent = getAlignContent(node); if (alignContent === CSS_ALIGN_FLEX_END) { - currentLead += remainingCrossDim; + currentLead += remainingAlignContentDim; } else if (alignContent === CSS_ALIGN_CENTER) { - currentLead += remainingCrossDim / 2; + currentLead += remainingAlignContentDim / 2; } else if (alignContent === CSS_ALIGN_STRETCH) { if (nodeCrossAxisInnerSize > linesCrossDim) { - crossDimLead = (remainingCrossDim / linesCount); + crossDimLead = (remainingAlignContentDim / linesCount); } } @@ -730,16 +874,16 @@ var computeLayout = (function() { continue; } - var/*css_align_t*/ alignItem = getAlignItem(node, child); - if (alignItem === CSS_ALIGN_FLEX_START) { - child.layout[pos[crossAxis]] = currentLead + getMargin(child, leading[crossAxis]); - } else if (alignItem === CSS_ALIGN_FLEX_END) { - child.layout[pos[crossAxis]] = currentLead + lineHeight - getMargin(child,trailing[crossAxis]) - child.layout[dim[crossAxis]]; - } else if (alignItem === CSS_ALIGN_CENTER) { + var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem === CSS_ALIGN_FLEX_START) { + child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) { + child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[dim[crossAxis]]; + } else if (alignContentAlignItem === CSS_ALIGN_CENTER) { var/*float*/ childHeight = child.layout[dim[crossAxis]]; child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignItem === CSS_ALIGN_STRETCH) { - child.layout[pos[crossAxis]] = currentLead + getMargin(child, leading[crossAxis]); + } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) { + child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); // TODO(prenaux): Correctly set the height of items with undefined // (auto) crossAxis dimension. } @@ -749,16 +893,21 @@ var computeLayout = (function() { } } + 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) ); + + needsMainTrailingPos = true; } if (isUndefined(node.layout[dim[crossAxis]])) { @@ -769,9 +918,26 @@ 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]; if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 269ce927..02ed06e9 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(); { @@ -164,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(); @@ -188,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; @@ -198,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; @@ -205,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; @@ -212,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; } } @@ -246,6 +379,129 @@ 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; + 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; + 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->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; + 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->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; + 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; + node_1->style.margin[CSS_START] = 10; + node_1->style.margin[CSS_END] = 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 +547,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 +636,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 +724,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 +837,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 +959,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 +1055,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 +1146,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 +1237,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 +1328,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 +1419,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 +1547,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 +1638,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 +1729,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 +1821,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 +1904,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 +1973,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(); { @@ -1019,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; } } @@ -1043,6 +2044,45 @@ 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; + node_1->style.margin[CSS_START] = 5; + 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] = 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 +2124,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 +2220,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(); { @@ -1155,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; } @@ -1196,6 +2316,67 @@ 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->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; + } + } + } + + 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 +2444,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(); { @@ -1271,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(); @@ -1293,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; @@ -1329,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; @@ -1337,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; } } @@ -1374,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; } } @@ -1406,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; @@ -1415,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; } } @@ -1456,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; } } } @@ -1806,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; @@ -1885,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; @@ -2026,6 +3262,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 +3340,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 +3420,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 +3507,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 +3628,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(); { @@ -2275,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(); @@ -2332,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; @@ -2377,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; } } @@ -2470,6 +3916,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 +4113,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(); { @@ -2781,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; @@ -2790,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; @@ -2871,6 +4409,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 +4487,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(); { @@ -2925,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"; } @@ -2961,6 +4580,63 @@ 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->style.margin[CSS_START] = 20; + node_2->style.margin[CSS_END] = 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] = 8; + node_2->layout.dimensions[CSS_WIDTH] = 172; + 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(); { @@ -2978,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"; } @@ -3102,6 +4780,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 +4853,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 +5452,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 +5783,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 +5887,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 +5991,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 +6096,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 +6203,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 +6650,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(); { @@ -4703,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; @@ -4765,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; @@ -4831,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; @@ -4874,6 +6964,510 @@ 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); + } + + { + 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); + } + + { + 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); + } + { css_node_t *root_node = new_test_css_node(); { @@ -4894,6 +7488,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; node_1 = node_0->get_child(node_0->context, 1); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4901,6 +7497,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; node_1 = node_0->get_child(node_0->context, 2); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4908,6 +7506,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; node_1 = node_0->get_child(node_0->context, 3); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4915,6 +7515,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; node_1 = node_0->get_child(node_0->context, 4); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -4922,6 +7524,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; node_1 = node_0->get_child(node_0->context, 5); node_1->style.align_self = CSS_ALIGN_FLEX_START; node_1->style.dimensions[CSS_WIDTH] = 50; @@ -4930,6 +7534,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; node_1 = node_0->get_child(node_0->context, 6); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4937,6 +7543,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; node_1 = node_0->get_child(node_0->context, 7); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 100; @@ -4944,6 +7552,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; node_1 = node_0->get_child(node_0->context, 8); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4951,6 +7561,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; node_1 = node_0->get_child(node_0->context, 9); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4958,6 +7570,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; node_1 = node_0->get_child(node_0->context, 10); node_1->style.align_self = CSS_ALIGN_FLEX_START; node_1->style.dimensions[CSS_WIDTH] = 50; @@ -4966,6 +7580,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; node_1 = node_0->get_child(node_0->context, 11); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4973,6 +7589,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; node_1 = node_0->get_child(node_0->context, 12); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4980,6 +7598,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; node_1 = node_0->get_child(node_0->context, 13); node_1->style.align_self = CSS_ALIGN_FLEX_START; node_1->style.dimensions[CSS_WIDTH] = 50; @@ -4988,6 +7608,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; node_1 = node_0->get_child(node_0->context, 14); node_1->style.dimensions[CSS_WIDTH] = 50; node_1->style.dimensions[CSS_HEIGHT] = 50; @@ -4995,6 +7617,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; } } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 6ff28331..3eddd369 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -20,14 +20,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: []} ]} ); }); @@ -47,9 +47,9 @@ describe('Javascript Only', function() { ]} ); }); - }); + describe('Layout', function() { it('should layout a single node with width and height', function() { testLayout({ @@ -74,6 +74,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: [ @@ -93,6 +108,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}}, @@ -115,6 +149,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: [ @@ -128,6 +190,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: [ @@ -141,6 +216,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: [ @@ -154,6 +242,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: [ @@ -173,6 +274,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: [ @@ -186,6 +306,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: [ @@ -199,6 +332,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: [ @@ -212,6 +358,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: [ @@ -225,6 +384,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: [ @@ -238,6 +410,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: [ @@ -251,6 +436,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: [ @@ -275,6 +473,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: [ @@ -288,6 +499,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: [ @@ -301,6 +525,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: [ @@ -314,6 +551,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: [ @@ -325,6 +575,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: [ @@ -336,6 +597,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: [ @@ -347,6 +619,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: [ @@ -360,6 +643,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'}}, @@ -378,6 +674,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: [ @@ -395,6 +702,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: [ @@ -417,6 +741,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}}, @@ -653,6 +988,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: [ @@ -664,6 +1012,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: [ @@ -677,6 +1036,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: [ @@ -690,6 +1062,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: [ @@ -714,6 +1099,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: [ @@ -789,6 +1185,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)}}, @@ -840,6 +1247,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: [ @@ -909,6 +1331,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: [ @@ -920,6 +1355,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: [ @@ -935,6 +1381,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: 8} + ]} + ]} + ); + }); + it('should layout with text and margin', function() { testLayout( {style: {}, children: [ @@ -974,15 +1435,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} ]} ); }); @@ -1197,6 +1671,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: [ @@ -1316,6 +1805,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: [ @@ -1331,6 +1835,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: [ @@ -1346,6 +1865,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: [ @@ -1361,6 +1895,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: [ @@ -1376,6 +1925,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: [ @@ -1492,6 +2056,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: [ @@ -1587,6 +2162,151 @@ 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} + ]} + ]} + ); + }); + + 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}, + ]} + ); + }); + + + 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} + ]} + ); + }); }); describe('Layout alignContent', function() { @@ -1676,5 +2396,4 @@ describe('Layout alignContent', function() { testAlignContent('flex-end', 'center'); testAlignContent('flex-end', 'flex-end'); testAlignContent('flex-end', 'stretch'); - }); 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 0dfa6b54..36461152 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(); @@ -127,7 +123,7 @@ public class CSSNode { */ public void calculateLayout(CSSLayoutContext layoutContext) { layout.resetResult(); - LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED); + LayoutEngine.layoutNode(layoutContext, this, CSSConstants.UNDEFINED, null); } /** @@ -265,24 +261,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(); } } @@ -330,11 +321,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() { @@ -344,4 +335,34 @@ 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; + } + + /** + * 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. + */ + 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 72e807bc..15b10a5b 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 alignContent = CSSAlign.FLEX_START; @@ -22,9 +23,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 9a692f20..56da96a6 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 { @@ -28,24 +30,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 +112,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) { @@ -132,74 +186,154 @@ 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); + 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: - 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); + 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: - 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); + 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) { 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 +367,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 +391,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; } @@ -282,8 +471,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) { @@ -296,13 +485,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); @@ -314,18 +504,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); @@ -333,28 +523,32 @@ 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, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getMargin(node, getLeading(crossAxis)) + + setLayoutPosition(node, getTrailing(mainAxis), getLayoutPosition(node, getTrailing(mainAxis)) + getTrailingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis)); + setLayoutPosition(node, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getLeadingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis)); + setLayoutPosition(node, getTrailing(crossAxis), getLayoutPosition(node, getTrailing(crossAxis)) + getTrailingMargin(node, 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))); @@ -366,14 +560,16 @@ public class LayoutEngine { ); if (isRowUndefined) { node.layout.width = measureDim.width + - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + getPaddingAndBorderAxis(node, resolvedRowAxis); } if (isColumnUndefined) { node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSSFlexDirection.COLUMN); } } - return; + if (node.getChildCount() == 0) { + return; + } } int i; @@ -470,20 +666,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 @@ -502,6 +698,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; } @@ -569,17 +766,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); } } @@ -615,7 +812,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); @@ -627,12 +824,17 @@ 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. 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 @@ -660,7 +862,6 @@ public class LayoutEngine { } // Position elements in the cross axis - for (i = startLine; i < endLine; ++i) { child = node.getChildAt(i); @@ -670,11 +871,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 @@ -709,6 +910,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); + } } } @@ -735,19 +941,19 @@ public class LayoutEngine { !CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) { float nodeCrossAxisInnerSize = getLayoutDimension(node, getDim(crossAxis)) - getPaddingAndBorderAxis(node, crossAxis); - float remainingCrossDim = nodeCrossAxisInnerSize - linesCrossDim; + float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; float crossDimLead = 0; - float currentLead = getPaddingAndBorder(node, getLeading(crossAxis)); + float currentLead = getLeadingPaddingAndBorder(node, crossAxis); CSSAlign alignContent = getAlignContent(node); if (alignContent == CSSAlign.FLEX_END) { - currentLead = currentLead + remainingCrossDim; + currentLead = currentLead + remainingAlignContentDim; } else if (alignContent == CSSAlign.CENTER) { - currentLead = currentLead + remainingCrossDim / 2; + currentLead = currentLead + remainingAlignContentDim / 2; } else if (alignContent == CSSAlign.STRETCH) { if (nodeCrossAxisInnerSize > linesCrossDim) { - crossDimLead = (remainingCrossDim / linesCount); + crossDimLead = (remainingAlignContentDim / linesCount); } } @@ -781,16 +987,16 @@ public class LayoutEngine { continue; } - CSSAlign alignItem = getAlignItem(node, child); - if (alignItem == CSSAlign.FLEX_START) { - setLayoutPosition(child, getPos(crossAxis), currentLead + getMargin(child, getLeading(crossAxis))); - } else if (alignItem == CSSAlign.FLEX_END) { - setLayoutPosition(child, getPos(crossAxis), currentLead + lineHeight - getMargin(child,getTrailing(crossAxis)) - getLayoutDimension(child, getDim(crossAxis))); - } else if (alignItem == CSSAlign.CENTER) { + CSSAlign alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem == CSSAlign.FLEX_START) { + setLayoutPosition(child, getPos(crossAxis), currentLead + getLeadingMargin(child, crossAxis)); + } else if (alignContentAlignItem == CSSAlign.FLEX_END) { + setLayoutPosition(child, getPos(crossAxis), currentLead + lineHeight - getTrailingMargin(child, crossAxis) - getLayoutDimension(child, getDim(crossAxis))); + } else if (alignContentAlignItem == CSSAlign.CENTER) { float childHeight = getLayoutDimension(child, getDim(crossAxis)); setLayoutPosition(child, getPos(crossAxis), currentLead + (lineHeight - childHeight) / 2); - } else if (alignItem == CSSAlign.STRETCH) { - setLayoutPosition(child, getPos(crossAxis), currentLead + getMargin(child, getLeading(crossAxis))); + } else if (alignContentAlignItem == CSSAlign.STRETCH) { + setLayoutPosition(child, getPos(crossAxis), currentLead + getLeadingMargin(child, crossAxis)); // TODO(prenaux): Correctly set the height of items with undefined // (auto) crossAxis dimension. } @@ -800,16 +1006,21 @@ public class LayoutEngine { } } + 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) )); + + needsMainTrailingPos = true; } if (CSSConstants.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) { @@ -820,9 +1031,26 @@ 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); if (getPositionType(child) == CSSPositionType.ABSOLUTE) { diff --git a/src/java/src/com/facebook/csslayout/Spacing.java b/src/java/src/com/facebook/csslayout/Spacing.java index 32ab3a97..9fa61890 100644 --- a/src/java/src/com/facebook/csslayout/Spacing.java +++ b/src/java/src/com/facebook/csslayout/Spacing.java @@ -8,28 +8,124 @@ */ package com.facebook.csslayout; +import javax.annotation.Nullable; + /** - * 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; - public static final int ALL = 6; + /** + * 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 = 8; + + private final float[] mSpacing = newFullSpacingArray(); + @Nullable private float[] mDefaultSpacing = null; /** - * @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; + return true; + } + return false; + } + + /** + * 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 (mDefaultSpacing == null) { + mDefaultSpacing = newSpacingResultArray(); + } + if (!FloatUtil.floatsEqual(mDefaultSpacing[spacingType], value)) { + mDefaultSpacing[spacingType] = value; + return true; + } + return false; + } + + /** + * 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) { + 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; + } + + /** + * 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, @@ -39,65 +135,25 @@ public class Spacing { CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, CSSConstants.UNDEFINED, + CSSConstants.UNDEFINED, }; } - /** - * @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, defaultValue, defaultValue, + defaultValue, + defaultValue, + CSSConstants.UNDEFINED, + CSSConstants.UNDEFINED, + defaultValue, }; } - - /** - * 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. - */ - 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; - } } diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index 0e1ee66c..0526655c 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,24 +291,98 @@ 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(); { 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); + node_0.setMargin(Spacing.START, 10); + node_0.setMargin(Spacing.END, 10); } 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,67 +391,75 @@ public class LayoutEngineTest { } @Test - public void testCase4() + public void testCase6() { TestCSSNode root_node = new TestCSSNode(); { 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); + node_0.setMargin(Spacing.START, 10); + node_0.setMargin(Spacing.END, 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.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; - 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.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; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); } } 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 +469,134 @@ 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.setMargin(Spacing.LEFT, 10); + 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; + node_1 = node_0.getChildAt(0); + node_1.style.width = 100; + node_1.style.height = 100; + 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.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; + 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.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; + node_1.setMargin(Spacing.LEFT, 10); + 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); + } + } + + 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 +619,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 +643,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 +712,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 +736,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 +804,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 +828,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 +908,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,49 +945,123 @@ 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; - node_0.style.margin[Spacing.LEFT] = 5; - node_0.style.margin[Spacing.TOP] = 10; - addChildren(node_0, 2); + addChildren(node_0, 1); { 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; + 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.y = 10; - node_0.layout.x = 5; + 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(); + { + TestCSSNode node_0 = root_node; + node_0.style.width = 1000; + node_0.style.height = 1000; + 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.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.setMargin(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.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 +1071,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.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.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.setMargin(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 +1147,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 +1171,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 +1242,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 +1266,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 +1337,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 +1361,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 +1432,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 +1456,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 +1527,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 +1551,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 +1619,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 +1638,7 @@ public class LayoutEngineTest { } @Test - public void testCase16() + public void testCase30() { TestCSSNode root_node = new TestCSSNode(); { @@ -889,21 +1661,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 +1685,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 +1756,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 +1780,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 +1851,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 +1875,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 +1947,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 +1971,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 +2039,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 +2058,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 +2112,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 +2131,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(); { @@ -1136,26 +2175,28 @@ 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); + node_1.setMargin(Spacing.START, 5); + node_1.setMargin(Spacing.END, 5); } } 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 +2206,48 @@ 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.setMargin(Spacing.LEFT, 5); + 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); + } + } + + 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 +2266,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 +2290,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 +2345,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 +2355,7 @@ public class LayoutEngineTest { } @Test - public void testCase25() + public void testCase47() { TestCSSNode root_node = new TestCSSNode(); { @@ -1240,23 +2366,23 @@ 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); } } 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 +2392,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.setMargin(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(); { @@ -1280,10 +2444,12 @@ 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.setMargin(Spacing.START, 10); + node_2.setMargin(Spacing.END, 10); node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -1293,29 +2459,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 +2492,70 @@ 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.setMargin(Spacing.LEFT, 10); + 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; + } + } + } + + 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 +2571,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 +2590,7 @@ public class LayoutEngineTest { } @Test - public void testCase28() + public void testCase52() { TestCSSNode root_node = new TestCSSNode(); { @@ -1371,23 +2600,23 @@ 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); } } 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,22 +2626,61 @@ public class LayoutEngineTest { } @Test - public void testCase29() + public void testCase53() { 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.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.setMargin(Spacing.LEFT, 10); + } } 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.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(); + { + TestCSSNode node_0 = root_node; + node_0.setPadding(Spacing.LEFT, 5); + 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(); + { + 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; } @@ -1421,15 +2689,17 @@ public class LayoutEngineTest { } @Test - public void testCase30() + public void testCase55() { 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); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -1440,16 +2710,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,39 +2729,43 @@ public class LayoutEngineTest { } @Test - public void testCase31() + public void testCase56() { 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); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 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); + node_1.setMargin(Spacing.START, 5); + node_1.setMargin(Spacing.END, 5); } } 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 +2775,7 @@ public class LayoutEngineTest { } @Test - public void testCase32() + public void testCase57() { TestCSSNode root_node = new TestCSSNode(); { @@ -1511,26 +2785,28 @@ 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); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); } } 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,40 +2816,44 @@ public class LayoutEngineTest { } @Test - public void testCase33() + public void testCase58() { 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); + node_0.setPadding(Spacing.START, 50); + node_0.setPadding(Spacing.END, 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); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); } } 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 +2863,7 @@ public class LayoutEngineTest { } @Test - public void testCase34() + public void testCase59() { TestCSSNode root_node = new TestCSSNode(); { @@ -1597,10 +2877,12 @@ 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); + node_2.setMargin(Spacing.START, 16); + node_2.setMargin(Spacing.END, 16); } } } @@ -1608,24 +2890,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 +2918,7 @@ public class LayoutEngineTest { } @Test - public void testCase35() + public void testCase60() { TestCSSNode root_node = new TestCSSNode(); { @@ -1648,8 +2930,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,14 +2940,14 @@ public class LayoutEngineTest { } @Test - public void testCase36() + public void testCase61() { TestCSSNode root_node = new TestCSSNode(); { 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; @@ -1676,16 +2958,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 +2977,7 @@ public class LayoutEngineTest { } @Test - public void testCase37() + public void testCase62() { TestCSSNode root_node = new TestCSSNode(); { @@ -1706,8 +2988,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 +2998,7 @@ public class LayoutEngineTest { } @Test - public void testCase38() + public void testCase63() { TestCSSNode root_node = new TestCSSNode(); { @@ -1728,8 +3010,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 +3020,7 @@ public class LayoutEngineTest { } @Test - public void testCase39() + public void testCase64() { TestCSSNode root_node = new TestCSSNode(); { @@ -1761,26 +3043,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 +3072,7 @@ public class LayoutEngineTest { } @Test - public void testCase40() + public void testCase65() { TestCSSNode root_node = new TestCSSNode(); { @@ -1800,23 +3082,23 @@ 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); } } 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 +3108,7 @@ public class LayoutEngineTest { } @Test - public void testCase41() + public void testCase66() { TestCSSNode root_node = new TestCSSNode(); { @@ -1837,23 +3119,23 @@ 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); } } 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,20 +3145,20 @@ public class LayoutEngineTest { } @Test - public void testCase42() + public void testCase67() { TestCSSNode root_node = new TestCSSNode(); { 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(); { 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,20 +3167,20 @@ public class LayoutEngineTest { } @Test - public void testCase43() + public void testCase68() { TestCSSNode root_node = new TestCSSNode(); { 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(); { 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 +3189,7 @@ public class LayoutEngineTest { } @Test - public void testCase44() + public void testCase69() { TestCSSNode root_node = new TestCSSNode(); { @@ -1931,30 +3213,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,15 +3246,17 @@ public class LayoutEngineTest { } @Test - public void testCase45() + public void testCase70() { 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); + node_0.setPadding(Spacing.START, 5); + node_0.setPadding(Spacing.END, 5); addChildren(node_0, 1); { TestCSSNode node_1; @@ -1984,16 +3268,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 +3287,7 @@ public class LayoutEngineTest { } @Test - public void testCase46() + public void testCase71() { TestCSSNode root_node = new TestCSSNode(); { @@ -2023,21 +3307,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,15 +3331,17 @@ public class LayoutEngineTest { } @Test - public void testCase47() + public void testCase72() { 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); + node_0.setPadding(Spacing.START, 20); + node_0.setPadding(Spacing.END, 20); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2068,16 +3354,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 +3373,7 @@ public class LayoutEngineTest { } @Test - public void testCase48() + public void testCase73() { TestCSSNode root_node = new TestCSSNode(); { @@ -2097,7 +3383,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; } } @@ -2105,16 +3391,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 +3410,7 @@ public class LayoutEngineTest { } @Test - public void testCase49() + public void testCase74() { TestCSSNode root_node = new TestCSSNode(); { @@ -2134,7 +3420,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; } } @@ -2142,16 +3428,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 +3447,7 @@ public class LayoutEngineTest { } @Test - public void testCase50() + public void testCase75() { TestCSSNode root_node = new TestCSSNode(); { @@ -2180,21 +3466,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 +3490,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(); { @@ -2216,23 +3546,23 @@ 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); } } 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 +3572,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.setMargin(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(); { @@ -2256,28 +3625,28 @@ 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); } } 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 +3656,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.setPadding(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(); { @@ -2301,28 +3716,28 @@ 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); } } 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 +3747,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.setMargin(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 +3812,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 +3836,7 @@ public class LayoutEngineTest { } @Test - public void testCase55() + public void testCase84() { TestCSSNode root_node = new TestCSSNode(); { @@ -2394,16 +3855,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 +3874,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 +3933,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,22 +3957,24 @@ public class LayoutEngineTest { } @Test - public void testCase57() + public void testCase87() { 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); + node_0.setBorder(Spacing.START, 5); + node_0.setBorder(Spacing.END, 5); } 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,12 +3983,12 @@ public class LayoutEngineTest { } @Test - public void testCase58() + public void testCase88() { 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; @@ -2499,16 +4001,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,15 +4020,17 @@ public class LayoutEngineTest { } @Test - public void testCase59() + public void testCase89() { 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); + node_0.setBorder(Spacing.START, 1); + node_0.setBorder(Spacing.END, 1); addChildren(node_0, 1); { TestCSSNode node_1; @@ -2539,16 +4043,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 +4062,7 @@ public class LayoutEngineTest { } @Test - public void testCase60() + public void testCase90() { TestCSSNode root_node = new TestCSSNode(); { @@ -2569,27 +4073,29 @@ 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); + node_1.setPadding(Spacing.START, 20); + node_1.setPadding(Spacing.END, 20); } } 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 +4105,7 @@ public class LayoutEngineTest { } @Test - public void testCase61() + public void testCase91() { TestCSSNode root_node = new TestCSSNode(); { @@ -2609,23 +4115,23 @@ 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); } } 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,34 +4141,34 @@ public class LayoutEngineTest { } @Test - public void testCase62() + public void testCase92() { TestCSSNode root_node = new TestCSSNode(); { 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); } } 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 +4178,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.setBorder(Spacing.LEFT, 1); + addChildren(node_0, 1); + { + TestCSSNode node_1; + node_1 = node_0.getChildAt(0); + node_1.setMargin(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 +4228,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 = 35; node_0.layout.height = 18; } @@ -2694,7 +4238,7 @@ public class LayoutEngineTest { } @Test - public void testCase64() + public void testCase95() { TestCSSNode root_node = new TestCSSNode(); { @@ -2707,8 +4251,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 +4261,7 @@ public class LayoutEngineTest { } @Test - public void testCase65() + public void testCase96() { TestCSSNode root_node = new TestCSSNode(); { @@ -2729,8 +4273,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; node_0.layout.height = 18; } @@ -2739,7 +4283,7 @@ public class LayoutEngineTest { } @Test - public void testCase66() + public void testCase97() { TestCSSNode root_node = new TestCSSNode(); { @@ -2762,24 +4306,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 +4334,7 @@ public class LayoutEngineTest { } @Test - public void testCase67() + public void testCase98() { TestCSSNode root_node = new TestCSSNode(); { @@ -2815,24 +4359,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 +4387,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 +4466,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 = 37; 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 = 37; 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 = 37; } @@ -2896,7 +4494,7 @@ public class LayoutEngineTest { } @Test - public void testCase69() + public void testCase101() { TestCSSNode root_node = new TestCSSNode(); { @@ -2922,24 +4520,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 = 37; 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 = 37; 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 = 37; } @@ -2950,7 +4548,7 @@ public class LayoutEngineTest { } @Test - public void testCase70() + public void testCase102() { TestCSSNode root_node = new TestCSSNode(); { @@ -2970,16 +4568,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 = 37; 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 = 37; } @@ -2989,26 +4587,30 @@ public class LayoutEngineTest { } @Test - public void testCase71() + public void testCase103() { TestCSSNode root_node = new TestCSSNode(); { 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); + node_0.setPadding(Spacing.START, 10); + node_0.setPadding(Spacing.END, 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); addChildren(node_1, 1); { TestCSSNode node_2; @@ -3022,24 +4624,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 = 77; 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; node_1.layout.height = 37; 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; node_2.layout.height = 37; } @@ -3050,7 +4652,7 @@ public class LayoutEngineTest { } @Test - public void testCase72() + public void testCase104() { TestCSSNode root_node = new TestCSSNode(); { @@ -3069,21 +4671,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 +4695,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 +4758,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 +4777,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(); { @@ -3146,10 +4831,12 @@ 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.setMargin(Spacing.START, 20); + node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -3159,24 +4846,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; node_2.layout.height = 18; } @@ -3187,7 +4874,66 @@ 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.setMargin(Spacing.LEFT, 20); + 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"; + } + } + } + + 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 = 8; + node_2.layout.width = 172; + 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(); { @@ -3201,10 +4947,12 @@ 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.setMargin(Spacing.START, 20); + node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -3214,24 +4962,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 = 77; 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 = 77; 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 = 37; } @@ -3242,7 +4990,7 @@ public class LayoutEngineTest { } @Test - public void testCase76() + public void testCase111() { TestCSSNode root_node = new TestCSSNode(); { @@ -3264,16 +5012,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 +5031,7 @@ public class LayoutEngineTest { } @Test - public void testCase77() + public void testCase112() { TestCSSNode root_node = new TestCSSNode(); { @@ -3306,21 +5054,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 +5078,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 +5150,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 +5195,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 +5219,7 @@ public class LayoutEngineTest { } @Test - public void testCase80() + public void testCase116() { TestCSSNode root_node = new TestCSSNode(); { @@ -3441,16 +5238,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 +5257,7 @@ public class LayoutEngineTest { } @Test - public void testCase81() + public void testCase117() { TestCSSNode root_node = new TestCSSNode(); { @@ -3490,24 +5287,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 +5315,7 @@ public class LayoutEngineTest { } @Test - public void testCase82() + public void testCase118() { TestCSSNode root_node = new TestCSSNode(); { @@ -3536,16 +5333,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 +5352,7 @@ public class LayoutEngineTest { } @Test - public void testCase83() + public void testCase119() { TestCSSNode root_node = new TestCSSNode(); { @@ -3573,16 +5370,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 +5389,7 @@ public class LayoutEngineTest { } @Test - public void testCase84() + public void testCase120() { TestCSSNode root_node = new TestCSSNode(); { @@ -3611,16 +5408,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 +5427,7 @@ public class LayoutEngineTest { } @Test - public void testCase85() + public void testCase121() { TestCSSNode root_node = new TestCSSNode(); { @@ -3649,16 +5446,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 +5465,7 @@ public class LayoutEngineTest { } @Test - public void testCase86() + public void testCase122() { TestCSSNode root_node = new TestCSSNode(); { @@ -3686,16 +5483,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 +5502,7 @@ public class LayoutEngineTest { } @Test - public void testCase87() + public void testCase123() { TestCSSNode root_node = new TestCSSNode(); { @@ -3723,16 +5520,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 +5539,7 @@ public class LayoutEngineTest { } @Test - public void testCase88() + public void testCase124() { TestCSSNode root_node = new TestCSSNode(); { @@ -3752,23 +5549,23 @@ 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); } } 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 +5575,7 @@ public class LayoutEngineTest { } @Test - public void testCase89() + public void testCase125() { TestCSSNode root_node = new TestCSSNode(); { @@ -3788,23 +5585,23 @@ 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); } } 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 +5611,7 @@ public class LayoutEngineTest { } @Test - public void testCase90() + public void testCase126() { TestCSSNode root_node = new TestCSSNode(); { @@ -3824,23 +5621,23 @@ 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); } } 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,13 +5647,13 @@ public class LayoutEngineTest { } @Test - public void testCase91() + public void testCase127() { TestCSSNode root_node = new TestCSSNode(); { 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; @@ -3867,16 +5664,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 +5683,7 @@ public class LayoutEngineTest { } @Test - public void testCase92() + public void testCase128() { TestCSSNode root_node = new TestCSSNode(); { @@ -3908,24 +5705,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 +5733,7 @@ public class LayoutEngineTest { } @Test - public void testCase93() + public void testCase129() { TestCSSNode root_node = new TestCSSNode(); { @@ -3962,26 +5759,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 +5788,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 +5864,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 +5888,7 @@ public class LayoutEngineTest { } @Test - public void testCase95() + public void testCase132() { TestCSSNode root_node = new TestCSSNode(); { @@ -4049,8 +5902,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 +5912,7 @@ public class LayoutEngineTest { } @Test - public void testCase96() + public void testCase133() { TestCSSNode root_node = new TestCSSNode(); { @@ -4073,8 +5926,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 +5936,7 @@ public class LayoutEngineTest { } @Test - public void testCase97() + public void testCase134() { TestCSSNode root_node = new TestCSSNode(); { @@ -4099,8 +5952,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 +5962,7 @@ public class LayoutEngineTest { } @Test - public void testCase98() + public void testCase135() { TestCSSNode root_node = new TestCSSNode(); { @@ -4125,8 +5978,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 +5988,7 @@ public class LayoutEngineTest { } @Test - public void testCase99() + public void testCase136() { TestCSSNode root_node = new TestCSSNode(); { @@ -4149,8 +6002,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 +6012,7 @@ public class LayoutEngineTest { } @Test - public void testCase100() + public void testCase137() { TestCSSNode root_node = new TestCSSNode(); { @@ -4173,8 +6026,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,24 +6036,24 @@ public class LayoutEngineTest { } @Test - public void testCase101() + public void testCase138() { TestCSSNode root_node = new TestCSSNode(); { 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(); { 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,24 +6062,24 @@ public class LayoutEngineTest { } @Test - public void testCase102() + public void testCase139() { TestCSSNode root_node = new TestCSSNode(); { 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(); { 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 +6088,7 @@ public class LayoutEngineTest { } @Test - public void testCase103() + public void testCase140() { TestCSSNode root_node = new TestCSSNode(); { @@ -4259,26 +6112,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 +6141,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 +6220,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 +6249,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 +6328,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 +6357,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 +6437,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 +6466,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 +6548,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 +6577,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 +6653,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 +6672,7 @@ public class LayoutEngineTest { } @Test - public void testCase109() + public void testCase151() { TestCSSNode root_node = new TestCSSNode(); { @@ -4563,16 +6691,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 +6710,7 @@ public class LayoutEngineTest { } @Test - public void testCase110() + public void testCase152() { TestCSSNode root_node = new TestCSSNode(); { @@ -4601,16 +6729,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 +6748,7 @@ public class LayoutEngineTest { } @Test - public void testCase111() + public void testCase153() { TestCSSNode root_node = new TestCSSNode(); { @@ -4644,21 +6772,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 +6796,7 @@ public class LayoutEngineTest { } @Test - public void testCase112() + public void testCase154() { TestCSSNode root_node = new TestCSSNode(); { @@ -4690,21 +6818,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 +6842,7 @@ public class LayoutEngineTest { } @Test - public void testCase113() + public void testCase155() { TestCSSNode root_node = new TestCSSNode(); { @@ -4736,21 +6864,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 +6888,7 @@ public class LayoutEngineTest { } @Test - public void testCase114() + public void testCase156() { TestCSSNode root_node = new TestCSSNode(); { @@ -4782,16 +6910,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 +6929,7 @@ public class LayoutEngineTest { } @Test - public void testCase115() + public void testCase157() { TestCSSNode root_node = new TestCSSNode(); { @@ -4821,16 +6949,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 +6968,7 @@ public class LayoutEngineTest { } @Test - public void testCase116() + public void testCase158() { TestCSSNode root_node = new TestCSSNode(); { @@ -4860,16 +6988,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 +7007,7 @@ public class LayoutEngineTest { } @Test - public void testCase117() + public void testCase159() { TestCSSNode root_node = new TestCSSNode(); { @@ -4899,16 +7027,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 +7046,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 +7110,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 +7129,7 @@ public class LayoutEngineTest { } @Test - public void testCase119() + public void testCase162() { TestCSSNode root_node = new TestCSSNode(); { @@ -4985,16 +7153,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 +7172,7 @@ public class LayoutEngineTest { } @Test - public void testCase120() + public void testCase163() { TestCSSNode root_node = new TestCSSNode(); { @@ -5016,10 +7184,12 @@ 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.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; @@ -5040,24 +7210,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 +7238,7 @@ public class LayoutEngineTest { } @Test - public void testCase121() + public void testCase164() { TestCSSNode root_node = new TestCSSNode(); { @@ -5080,14 +7250,18 @@ 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.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; @@ -5108,24 +7282,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 +7310,7 @@ public class LayoutEngineTest { } @Test - public void testCase122() + public void testCase165() { TestCSSNode root_node = new TestCSSNode(); { @@ -5148,10 +7322,12 @@ 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); + node_1.setPadding(Spacing.START, 10); + node_1.setPadding(Spacing.END, 10); addChildren(node_1, 1); { TestCSSNode node_2; @@ -5168,24 +7344,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; } @@ -5196,7 +7372,533 @@ public class LayoutEngineTest { } @Test - public void testCase123() + 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); + } + + @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); + } + + @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); + } + + @Test + public void testCase177() { TestCSSNode root_node = new TestCSSNode(); { @@ -5213,197 +7915,227 @@ public class LayoutEngineTest { node_1 = node_0.getChildAt(0); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(1); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(2); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(3); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(4); node_1.style.width = 50; 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(5); node_1.style.alignSelf = CSSAlign.FLEX_START; node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(6); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(7); node_1.style.width = 50; 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(8); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(9); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(10); node_1.style.alignSelf = CSSAlign.FLEX_START; node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(11); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(12); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(13); node_1.style.alignSelf = CSSAlign.FLEX_START; node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); node_1 = node_0.getChildAt(14); node_1.style.width = 50; node_1.style.height = 50; - 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); + node_1.setMargin(Spacing.START, 10); + node_1.setMargin(Spacing.END, 10); } } 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 = 380; addChildren(node_0, 15); { 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 = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(1); - node_1.layout.y = 10; - node_1.layout.x = 80; + node_1.layout.top = 10; + node_1.layout.left = 80; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(2); - node_1.layout.y = 10; - node_1.layout.x = 150; + node_1.layout.top = 10; + node_1.layout.left = 150; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(3); - node_1.layout.y = 10; - node_1.layout.x = 220; + node_1.layout.top = 10; + node_1.layout.left = 220; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(4); - node_1.layout.y = 92.5f; - node_1.layout.x = 10; + node_1.layout.top = 92.5f; + node_1.layout.left = 10; node_1.layout.width = 50; node_1.layout.height = 100; node_1 = node_0.getChildAt(5); - node_1.layout.y = 92.5f; - node_1.layout.x = 80; + node_1.layout.top = 92.5f; + node_1.layout.left = 80; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(6); - node_1.layout.y = 92.5f; - node_1.layout.x = 150; + node_1.layout.top = 92.5f; + node_1.layout.left = 150; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(7); - node_1.layout.y = 92.5f; - node_1.layout.x = 220; + node_1.layout.top = 92.5f; + node_1.layout.left = 220; node_1.layout.width = 50; node_1.layout.height = 100; node_1 = node_0.getChildAt(8); - node_1.layout.y = 225; - node_1.layout.x = 10; + node_1.layout.top = 225; + node_1.layout.left = 10; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(9); - node_1.layout.y = 225; - node_1.layout.x = 80; + node_1.layout.top = 225; + node_1.layout.left = 80; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(10); - node_1.layout.y = 225; - node_1.layout.x = 150; + node_1.layout.top = 225; + node_1.layout.left = 150; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(11); - node_1.layout.y = 225; - node_1.layout.x = 220; + node_1.layout.top = 225; + node_1.layout.left = 220; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(12); - node_1.layout.y = 307.5f; - node_1.layout.x = 10; + node_1.layout.top = 307.5f; + node_1.layout.left = 10; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(13); - node_1.layout.y = 307.5f; - node_1.layout.x = 80; + node_1.layout.top = 307.5f; + node_1.layout.left = 80; node_1.layout.width = 50; node_1.layout.height = 50; node_1 = node_0.getChildAt(14); - node_1.layout.y = 307.5f; - node_1.layout.x = 150; + node_1.layout.top = 307.5f; + node_1.layout.left = 150; node_1.layout.width = 50; node_1.layout.height = 50; } diff --git a/src/transpile.js b/src/transpile.js index ab745dec..7ce1bae2 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -100,11 +100,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) { @@ -114,9 +118,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', @@ -244,6 +254,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.children\[ii\]/g, 'node->get_child(node->context, ii)')