Lots of changes that I forgot to properly commit

This commit is contained in:
Christopher Chedeau
2014-06-04 10:51:23 -07:00
parent e53bf49746
commit d2ce2420f4
9 changed files with 2904 additions and 1980 deletions

View File

@@ -21,31 +21,19 @@ static bool are_layout_equal(css_node_t *a, css_node_t *b) {
return true; return true;
} }
css_dim_t measure(void *context, css_measure_type_t type, float width) { css_dim_t measure(void *context, float width) {
const char *text = context; const char *text = context;
css_dim_t dim; css_dim_t dim;
if (strcmp(text, "small") == 0) { if (width != width) {
if (type == CSS_MEASURE_GROW || type == CSS_MEASURE_SHRINK) { width = 1000000;
dim.dimensions[CSS_WIDTH] = 33;
dim.dimensions[CSS_HEIGHT] = 18;
return dim;
} }
dim.dimensions[CSS_WIDTH] = width; if (strcmp(text, "small") == 0) {
dim.dimensions[CSS_WIDTH] = fminf(33, width);
dim.dimensions[CSS_HEIGHT] = 18; dim.dimensions[CSS_HEIGHT] = 18;
return dim; return dim;
} }
if (strcmp(text, "loooooooooong with space") == 0) { if (strcmp(text, "loooooooooong with space") == 0) {
if (type == CSS_MEASURE_GROW) { dim.dimensions[CSS_WIDTH] = width >= 171 ? 171 : fmaxf(100, width);
dim.dimensions[CSS_WIDTH] = 171;
dim.dimensions[CSS_HEIGHT] = 18;
return dim;
}
if (type == CSS_MEASURE_SHRINK) {
dim.dimensions[CSS_WIDTH] = 100;
dim.dimensions[CSS_HEIGHT] = 36;
return dim;
}
dim.dimensions[CSS_WIDTH] = width;
dim.dimensions[CSS_HEIGHT] = width >= 171 ? 18 : 36; dim.dimensions[CSS_HEIGHT] = width >= 171 ? 18 : 36;
return dim; return dim;
} }
@@ -57,18 +45,18 @@ css_dim_t measure(void *context, css_measure_type_t type, float width) {
} }
void test(const char *name, css_node_t *style, css_node_t *expected_layout) { void test(const char *name, css_node_t *style, css_node_t *expected_layout) {
layoutNode(style); layoutNode(style, CSS_UNDEFINED);
if (!are_layout_equal(style, expected_layout)) { if (!are_layout_equal(style, expected_layout)) {
printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", name); printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", name);
printf("Input: "); printf("Input: ");
print_style(style, 0); print_css_node(style, CSS_PRINT_STYLE);
printf("Output: "); printf("Output: ");
print_layout(style, 0); print_css_node(style, CSS_PRINT_LAYOUT);
printf("Expected: "); printf("Expected: ");
print_layout(expected_layout, 0); print_css_node(expected_layout, CSS_PRINT_LAYOUT);
} else { } else {
printf("%sPASS%s %s\n", "\x1B[32m", "\x1B[0m", name); printf("%sPASS%s %s\n", "\x1B[32m", "\x1B[0m", name);
} }

View File

@@ -5,4 +5,4 @@
#include <string.h> #include <string.h>
void test(const char *name, css_node_t *style, css_node_t *expected_layout); void test(const char *name, css_node_t *style, css_node_t *expected_layout);
css_dim_t measure(void *context, css_measure_type_t type, float width); css_dim_t measure(void *context, float width);

View File

@@ -1,3 +1,4 @@
/** @nolint */
var layoutTestUtils = (function() { var layoutTestUtils = (function() {
var iframe = (function() { var iframe = (function() {
@@ -238,42 +239,38 @@ var layoutTestUtils = (function() {
reduceTest: reduceTest, reduceTest: reduceTest,
text: function(text) { text: function(text) {
var body = iframeText.contentDocument.body; var body = iframeText.contentDocument.body;
var fn = function(type, width) { var fn = function(width) {
if (width === undefined || width !== width) {
width = Infinity;
}
// Constants for testing purposes between C/JS and other platforms // Constants for testing purposes between C/JS and other platforms
// Comment this block of code if you want to use the browser to // Comment this block of code if you want to use the browser to
// generate proper sizes // generate proper sizes
if (text === 'small') { if (text === 'small') {
if (type === 'grow' || type === 'shrink') { return {width: Math.min(33, width), height: 18};
return {width: 33, height: 18}
}
return {width: width, height: 18};
} }
if (text === 'loooooooooong with space') { if (text === 'loooooooooong with space') {
if (type === 'grow') { var res = {
return {width: 171, height: 18}; width: width >= 171 ? 171 : Math.max(100, width),
} height: width >= 171 ? 18 : 36
if (type === 'shrink') { };
return {width: 100, height: 36}; return res
}
return {width: width, height: width >= 171 ? 18 : 36};
} }
return; return;
var div = document.createElement('div'); var div = document.createElement('div');
div.style.width = (width === Infinity ? 10000000 : width) + 'px';
div.style.display = 'flex';
div.style.flexDirection = 'column';
div.style.alignItems = 'flex-start';
var span = document.createElement('span'); var span = document.createElement('span');
span.style.display = 'flex'; span.style.display = 'flex';
body.style.display = 'block'; span.style.flexDirection = 'column';
if (width === 'grow') { span.style.alignItems = 'flex-start';
span.style.position = 'absolute';
} else if (width === 'shrink') {
div.style.display = 'flex';
div.style.position = 'relative';
body.style.display = 'flex';
span.style.position = 'absolute';
} else {
span.style.width = width + 'px';
}
span.innerText = text; span.innerText = text;
div.appendChild(span); div.appendChild(span);
body.appendChild(div); body.appendChild(div);
var rect = span.getBoundingClientRect(); var rect = span.getBoundingClientRect();

View File

@@ -77,9 +77,23 @@ static bool four_equal(float four[4]) {
eq(four[0], four[3]); eq(four[0], four[3]);
} }
void print_style(css_node_t *node, int level) {
static void print_css_node_rec(
css_node_t *node,
css_print_options_t options,
int level
) {
indent(level); indent(level);
printf("{"); printf("{");
if (options & CSS_PRINT_LAYOUT) {
printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]);
printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]);
printf("top: %g, ", node->layout.position[CSS_TOP]);
printf("left: %g, ", node->layout.position[CSS_LEFT]);
}
if (options & CSS_PRINT_STYLE) {
if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) {
printf("flexDirection: 'row', "); printf("flexDirection: 'row', ");
} }
@@ -150,11 +164,12 @@ void print_style(css_node_t *node, int level) {
print_number_nan("right", node->style.position[CSS_RIGHT]); print_number_nan("right", node->style.position[CSS_RIGHT]);
print_number_nan("top", node->style.position[CSS_TOP]); print_number_nan("top", node->style.position[CSS_TOP]);
print_number_nan("bottom", node->style.position[CSS_BOTTOM]); print_number_nan("bottom", node->style.position[CSS_BOTTOM]);
}
if (node->children_count > 0) { if (node->children_count > 0) {
printf("children: [\n"); printf("children: [\n");
for (int i = 0; i < node->children_count; ++i) { for (int i = 0; i < node->children_count; ++i) {
print_style(&node->children[i], level + 1); print_css_node_rec(&node->children[i], options, level + 1);
} }
indent(level); indent(level);
printf("]},\n"); printf("]},\n");
@@ -163,26 +178,9 @@ void print_style(css_node_t *node, int level) {
} }
} }
void print_layout(css_node_t *node, int level) { void print_css_node(css_node_t *node, css_print_options_t options) {
indent(level); print_css_node_rec(node, options, 0);
printf("{");
printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]);
printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]);
printf("top: %g, ", node->layout.position[CSS_TOP]);
printf("left: %g, ", node->layout.position[CSS_LEFT]);
if (node->children_count > 0) {
printf("children: [\n");
for (int i = 0; i < node->children_count; ++i) {
print_layout(&node->children[i], level + 1);
} }
indent(level);
printf("]},\n");
} else {
printf("},\n");
}
}
static css_position_t leading[2] = { static css_position_t leading[2] = {
@@ -319,7 +317,7 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) {
return -getPosition(node, trailing[axis]); return -getPosition(node, trailing[axis]);
} }
void layoutNode(css_node_t *node) { void layoutNode(css_node_t *node, float parentMaxWidth) {
css_flex_direction_t mainAxis = getFlexDirection(node); css_flex_direction_t mainAxis = getFlexDirection(node);
css_flex_direction_t crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ? css_flex_direction_t crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ?
CSS_FLEX_DIRECTION_COLUMN : CSS_FLEX_DIRECTION_COLUMN :
@@ -338,29 +336,39 @@ void layoutNode(css_node_t *node) {
if (isMeasureDefined(node)) { if (isMeasureDefined(node)) {
float width = CSS_UNDEFINED; float width = CSS_UNDEFINED;
css_measure_type_t type = CSS_MEASURE_VALUE;
if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
width = node->style.dimensions[CSS_WIDTH]; width = node->style.dimensions[CSS_WIDTH];
} else if (getPositionType(node) == CSS_POSITION_ABSOLUTE) { } else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]])) {
type = CSS_MEASURE_SHRINK; width = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]];
} else { } else {
type = CSS_MEASURE_GROW; width = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);
} }
width -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
// 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 isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) &&
isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]);
// Let's not measure the text if we already know both dimensions
if (isRowUndefined || isColumnUndefined) {
css_dim_t measure_dim = node->style.measure( css_dim_t measure_dim = node->style.measure(
node->style.measure_context, node->style.measure_context,
type,
width width
); );
if (!isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { if (isRowUndefined) {
node->layout.dimensions[CSS_WIDTH] = measure_dim.dimensions[CSS_WIDTH] + node->layout.dimensions[CSS_WIDTH] = measure_dim.dimensions[CSS_WIDTH] +
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} }
if (!isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { if (isColumnUndefined) {
node->layout.dimensions[CSS_HEIGHT] = measure_dim.dimensions[CSS_HEIGHT] + node->layout.dimensions[CSS_HEIGHT] = measure_dim.dimensions[CSS_HEIGHT] +
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
} }
}
return; return;
} }
@@ -410,8 +418,20 @@ void layoutNode(css_node_t *node) {
getMarginAxis(child, mainAxis); getMarginAxis(child, mainAxis);
} else { } else {
float maxWidth = CSS_UNDEFINED;
if (mainAxis == CSS_FLEX_DIRECTION_ROW) {
// do nothing
} else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} else {
maxWidth = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
}
// This is the main recursive call. We layout non flexible children. // This is the main recursive call. We layout non flexible children.
layoutNode(child); layoutNode(child, maxWidth);
// Absolute positioned elements do not take part of the layout, so we // Absolute positioned elements do not take part of the layout, so we
// don't use them to compute mainContentDim // don't use them to compute mainContentDim
@@ -436,8 +456,7 @@ void layoutNode(css_node_t *node) {
// are all going to be packed together and we don't need to compute // are all going to be packed together and we don't need to compute
// anything. // anything.
if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) {
// The remaining available space that needs to be allocated
// The remaining available space that's needs to be allocated
float remainingMainDim = node->layout.dimensions[dim[mainAxis]] - float remainingMainDim = node->layout.dimensions[dim[mainAxis]] -
getPaddingAndBorderAxis(node, mainAxis) - getPaddingAndBorderAxis(node, mainAxis) -
mainContentDim; mainContentDim;
@@ -463,8 +482,20 @@ void layoutNode(css_node_t *node) {
child->layout.dimensions[dim[mainAxis]] = flexibleMainDim + child->layout.dimensions[dim[mainAxis]] = flexibleMainDim +
getPaddingAndBorderAxis(child, mainAxis); getPaddingAndBorderAxis(child, mainAxis);
float maxWidth = CSS_UNDEFINED;
if (mainAxis == CSS_FLEX_DIRECTION_ROW) {
// do nothing
} else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} else {
maxWidth = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
}
// And we recursively call the layout algorithm for this child // And we recursively call the layout algorithm for this child
layoutNode(child); layoutNode(child, maxWidth);
} }
} }
@@ -479,6 +510,7 @@ void layoutNode(css_node_t *node) {
} else if (justifyContent == CSS_JUSTIFY_FLEX_END) { } else if (justifyContent == CSS_JUSTIFY_FLEX_END) {
leadingMainDim = remainingMainDim; leadingMainDim = remainingMainDim;
} else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) { } else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) {
remainingMainDim = fmaxf(remainingMainDim, 0);
betweenMainDim = remainingMainDim / betweenMainDim = remainingMainDim /
(flexibleChildrenCount + nonFlexibleChildrenCount - 1); (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
} else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) { } else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) {

View File

@@ -56,13 +56,6 @@ typedef struct {
float dimensions[2]; float dimensions[2];
} css_layout_t; } css_layout_t;
typedef enum {
CSS_MEASURE_GROW = 0,
CSS_MEASURE_SHRINK,
CSS_MEASURE_VALUE
} css_measure_type_t;
typedef struct { typedef struct {
float dimensions[2]; float dimensions[2];
} css_dim_t; } css_dim_t;
@@ -90,7 +83,7 @@ typedef struct {
float border[4]; float border[4];
float dimensions[2]; float dimensions[2];
css_dim_t (*measure)(void *context, css_measure_type_t type, float width); css_dim_t (*measure)(void *context, float width);
void *measure_context; void *measure_context;
} css_style_t; } css_style_t;
@@ -108,10 +101,13 @@ void init_css_node_children(css_node_t *node, int children_count);
void free_css_node(css_node_t *node); void free_css_node(css_node_t *node);
// Print utilities // Print utilities
void print_style(css_node_t *node, int level); typedef enum {
void print_layout(css_node_t *node, int level); CSS_PRINT_LAYOUT = 1,
CSS_PRINT_STYLE = 2
} css_print_options_t;
void print_css_node(css_node_t *node, css_print_options_t options);
// Function that computes the layout! // Function that computes the layout!
void layoutNode(css_node_t *node); void layoutNode(css_node_t *node, float maxWidth);
#endif #endif

View File

@@ -1,3 +1,4 @@
/** @nolint */
var computeLayout = (function() { var computeLayout = (function() {
@@ -193,11 +194,7 @@ var computeLayout = (function() {
var CSS_POSITION_RELATIVE = 'relative'; var CSS_POSITION_RELATIVE = 'relative';
var CSS_POSITION_ABSOLUTE = 'absolute'; var CSS_POSITION_ABSOLUTE = 'absolute';
var CSS_MEASURE_VALUE = 'value'; return function layoutNode(node, parentMaxWidth) {
var CSS_MEASURE_GROW = 'grow';
var CSS_MEASURE_SHRINK = 'shrink';
return function layoutNode(node) {
var/*css_flex_direction_t*/ mainAxis = getFlexDirection(node); var/*css_flex_direction_t*/ mainAxis = getFlexDirection(node);
var/*css_flex_direction_t*/ crossAxis = mainAxis === CSS_FLEX_DIRECTION_ROW ? var/*css_flex_direction_t*/ crossAxis = mainAxis === CSS_FLEX_DIRECTION_ROW ?
CSS_FLEX_DIRECTION_COLUMN : CSS_FLEX_DIRECTION_COLUMN :
@@ -216,29 +213,39 @@ var computeLayout = (function() {
if (isMeasureDefined(node)) { if (isMeasureDefined(node)) {
var/*float*/ width = CSS_UNDEFINED; var/*float*/ width = CSS_UNDEFINED;
var/*css_measure_type_t*/ type = CSS_MEASURE_VALUE;
if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
width = node.style.width; width = node.style.width;
} else if (getPositionType(node) == CSS_POSITION_ABSOLUTE) { } else if (!isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_ROW]])) {
type = CSS_MEASURE_SHRINK; width = node.layout[dim[CSS_FLEX_DIRECTION_ROW]];
} else { } else {
type = CSS_MEASURE_GROW; width = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);
} }
width -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
// 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*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) &&
isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]);
// Let's not measure the text if we already know both dimensions
if (isRowUndefined || isColumnUndefined) {
var/*css_dim_t*/ measure_dim = node.style.measure( var/*css_dim_t*/ measure_dim = node.style.measure(
/*!node->style.measure_context,*/ /*!node->style.measure_context,*/
type,
width width
); );
if (!isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { if (isRowUndefined) {
node.layout.width = measure_dim.width + node.layout.width = measure_dim.width +
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} }
if (!isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { if (isColumnUndefined) {
node.layout.height = measure_dim.height + node.layout.height = measure_dim.height +
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
} }
}
return; return;
} }
@@ -288,8 +295,20 @@ var computeLayout = (function() {
getMarginAxis(child, mainAxis); getMarginAxis(child, mainAxis);
} else { } else {
var/*float*/ maxWidth = CSS_UNDEFINED;
if (mainAxis === CSS_FLEX_DIRECTION_ROW) {
// do nothing
} else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} else {
maxWidth = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
}
// This is the main recursive call. We layout non flexible children. // This is the main recursive call. We layout non flexible children.
layoutNode(child); layoutNode(child, maxWidth);
// Absolute positioned elements do not take part of the layout, so we // Absolute positioned elements do not take part of the layout, so we
// don't use them to compute mainContentDim // don't use them to compute mainContentDim
@@ -314,8 +333,7 @@ var computeLayout = (function() {
// are all going to be packed together and we don't need to compute // are all going to be packed together and we don't need to compute
// anything. // anything.
if (!isUndefined(node.layout[dim[mainAxis]])) { if (!isUndefined(node.layout[dim[mainAxis]])) {
// The remaining available space that needs to be allocated
// The remaining available space that's needs to be allocated
var/*float*/ remainingMainDim = node.layout[dim[mainAxis]] - var/*float*/ remainingMainDim = node.layout[dim[mainAxis]] -
getPaddingAndBorderAxis(node, mainAxis) - getPaddingAndBorderAxis(node, mainAxis) -
mainContentDim; mainContentDim;
@@ -341,8 +359,20 @@ var computeLayout = (function() {
child.layout[dim[mainAxis]] = flexibleMainDim + child.layout[dim[mainAxis]] = flexibleMainDim +
getPaddingAndBorderAxis(child, mainAxis); getPaddingAndBorderAxis(child, mainAxis);
var/*float*/ maxWidth = CSS_UNDEFINED;
if (mainAxis === CSS_FLEX_DIRECTION_ROW) {
// do nothing
} else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
} else {
maxWidth = parentMaxWidth -
getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) -
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
}
// And we recursively call the layout algorithm for this child // And we recursively call the layout algorithm for this child
layoutNode(child); layoutNode(child, maxWidth);
} }
} }
@@ -357,6 +387,7 @@ var computeLayout = (function() {
} else if (justifyContent === CSS_JUSTIFY_FLEX_END) { } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {
leadingMainDim = remainingMainDim; leadingMainDim = remainingMainDim;
} else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) { } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {
remainingMainDim = fmaxf(remainingMainDim, 0);
betweenMainDim = remainingMainDim / betweenMainDim = remainingMainDim /
(flexibleChildrenCount + nonFlexibleChildrenCount - 1); (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
} else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) { } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {

File diff suppressed because it is too large Load Diff

View File

@@ -742,39 +742,28 @@ describe('Layout', function() {
{width: 1, height: 0, top: 0, left: 0, children: [ {width: 1, height: 0, top: 0, left: 0, children: [
{width: 0, height: 0, top: 0, left: 0} {width: 0, height: 0, top: 0, left: 0}
]} ]}
) );
}); });
it('should layout node with just text', function() { it('should layout node with just text', function() {
testLayout( testLayout(
{style: {measure: text('small')}}, {style: {measure: text('small')}},
{width: 33, height: 18, top: 0, left: 0} {width: 33, height: 18, top: 0, left: 0}
) );
}); });
it('should layout node with text and width', function() { it('should layout node with text and width', function() {
testLayout( testLayout(
{style: {measure: text('small'), width: 10}}, {style: {measure: text('small'), width: 10}},
{width: 10, height: 18, top: 0, left: 0} {width: 10, height: 18, top: 0, left: 0}
) );
}); });
it('should layout node with text, padding and margin', function() { it('should layout node with text, padding and margin', function() {
testLayout( testLayout(
{style: {measure: text('loooooooooong with space'), padding: 5, margin: 5}}, {style: {measure: text('loooooooooong with space'), padding: 5, margin: 5}},
{width: 181, height: 28, top: 5, left: 5} {width: 181, height: 28, top: 5, left: 5}
) );
});
it('should layout node with text and position absolute', function() {
testLayout(
{style: {}, children: [
{style: {measure: text('loooooooooong with space'), position: 'absolute'}}
]},
{width: 0, height: 0, top: 0, left: 0, children: [
{width: 100, height: 36, top: 0, left: 0}
]}
)
}); });
it('should layout node with nested alignSelf: stretch', function() { it('should layout node with nested alignSelf: stretch', function() {
@@ -792,6 +781,149 @@ describe('Layout', function() {
); );
}); });
it('should layout node with text and flex', function() {
testLayout(
{style: {}, children: [
{style: {width: 500, flexDirection: 'row'}, children: [
{style: {flex: 1, measure: text('loooooooooong with space')}}
]}
]},
{width: 500, height: 18, top: 0, left: 0, children: [
{width: 500, height: 18, top: 0, left: 0, children: [
{width: 500, height: 18, top: 0, left: 0}
]}
]}
);
});
it('should layout node with text and stretch', function() {
testLayout(
{style: {width: 130}, children: [
{style: {alignSelf: 'stretch', alignItems: 'stretch'}, children: [
{style: {measure: text('loooooooooong with space')}}
]}
]},
{width: 130, height: 36, top: 0, left: 0, children: [
{width: 130, height: 36, top: 0, left: 0, children: [
{width: 130, height: 36, top: 0, left: 0}
]}
]}
);
});
it('should layout node with text stretch and width', function() {
testLayout(
{style: {width: 200}, children: [
{style: {alignSelf: 'stretch', alignItems: 'stretch'}, children: [
{style: {width: 130, measure: text('loooooooooong with space')}}
]}
]},
{width: 200, height: 36, top: 0, left: 0, children: [
{width: 200, height: 36, top: 0, left: 0, children: [
{width: 130, height: 36, top: 0, left: 0}
]}
]}
);
});
it('should layout node with text bounded by parent', function() {
testLayout(
{style: {width: 100}, children: [
{style: {measure: text('loooooooooong with space')}}
]},
{width: 100, height: 36, top: 0, left: 0, children: [
{width: 100, height: 36, top: 0, left: 0}
]}
);
});
it('should layout node with text bounded by grand-parent', function() {
testLayout(
{style: {width: 100, padding: 10}, children: [
{style: {margin: 10}, children: [
{style: {measure: text('loooooooooong with space')}}
]}
]},
{width: 100, height: 76, top: 0, left: 0, children: [
{width: 100, height: 36, top: 20, left: 20, children: [
{width: 100, height: 36, top: 0, left: 0}
]}
]}
);
});
it('should layout space-between when remaining space is negative', function() {
testLayout(
{style: {height: 100, justifyContent: 'space-between'}, children: [
{style: {height: 900}},
{style: {}}
]},
{width: 0, height: 100, top: 0, left: 0, children: [
{width: 0, height: 900, top: 0, left: 0},
{width: 0, height: 0, top: 900, left: 0}
]}
);
});
it('should layout flex-end when remaining space is negative', function() {
testLayout(
{style: {width: 200, 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: -700}
]}
);
});
it('should layout text with flexDirection row', function() {
testLayout(
{style: {}, children: [
{style: {width: 200, flexDirection: 'row'}, children: [
{style: {margin: 20, measure: text('loooooooooong with space')}}
]}
]},
{width: 200, height: 58, top: 0, left: 0, children: [
{width: 200, height: 58, top: 0, left: 0, children: [
{width: 171, height: 18, top: 20, left: 20}
]}
]}
);
});
it('should layout with text and margin', function() {
testLayout(
{style: {}, children: [
{style: {width: 200}, children: [
{style: {margin: 20, measure: text('loooooooooong with space')}}
]}
]},
{width: 200, height: 76, top: 0, left: 0, children: [
{width: 200, height: 76, top: 0, left: 0, children: [
{width: 160, height: 36, top: 20, left: 20}
]}
]}
);
});
xit('should layout text with alignItems: stretch', function() {
testLayout(
{style: {width: 80, padding: 7, alignItems: 'stretch', measure: text('loooooooooong with space')}},
{width: 80, height: 68, top: 0, left: 0}
);
});
xit('should layout node with text and position absolute', function() {
testLayout(
{style: {}, children: [
{style: {measure: text('loooooooooong with space'), position: 'absolute'}}
]},
{width: 0, height: 0, top: 0, left: 0, children: [
{width: 100, height: 36, top: 0, left: 0}
]}
)
});
it('should layout randomly', function() { it('should layout randomly', function() {
function RNG(seed) { function RNG(seed) {
this.state = seed; this.state = seed;
@@ -849,7 +981,17 @@ describe('Layout', function() {
randEnum(node, 0.5, 'flex', ['none', 1]); randEnum(node, 0.5, 'flex', ['none', 1]);
randEnum(node, 0.5, 'position', ['relative', 'absolute']); randEnum(node, 0.5, 'position', ['relative', 'absolute']);
randEnum(node, 0.5, 'measure', [text('small'), text('loooooooooong with space')]); randEnum(node, 0.5, 'measure', [text('small'), text('loooooooooong with space')]);
randChildren(node, 0.2);
if (node.style.measure) {
// align-items: stretch on a text node makes it wrap in a different way.
// We don't yet support this use case
delete node.style.alignItems;
// Text that is position: absolute behaves very strangely
delete node.style.position;
}
randChildren(node, 0.4);
return node; return node;
} }

View File

@@ -24,6 +24,7 @@ document.getElementById('layout_code').value = computeLayout.toString()
.replace(/node.children\[i\]/g, '&node.children[i]') .replace(/node.children\[i\]/g, '&node.children[i]')
.replace(/node\./g, 'node->') .replace(/node\./g, 'node->')
.replace(/child\./g, 'child->') .replace(/child\./g, 'child->')
.replace(/parent\./g, 'parent->')
.replace(/var\/\*([^\/]+)\*\//g, '$1') .replace(/var\/\*([^\/]+)\*\//g, '$1')
.replace(/ === /g, ' == ') .replace(/ === /g, ' == ')
.replace(/\n /g, '\n') .replace(/\n /g, '\n')
@@ -55,6 +56,7 @@ var layoutTestUtils = {
}; };
function describe(name, cb) { cb(); } function describe(name, cb) { cb(); }
function it(name, cb) { currentTest = name; cb(); } function it(name, cb) { currentTest = name; cb(); }
xit = it;
</script> </script>
<script src="__tests__/Layout-test.js"></script> <script src="__tests__/Layout-test.js"></script>
<script> <script>