Lots of changes that I forgot to properly commit
This commit is contained in:
@@ -21,31 +21,19 @@ static bool are_layout_equal(css_node_t *a, css_node_t *b) {
|
||||
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;
|
||||
css_dim_t dim;
|
||||
if (strcmp(text, "small") == 0) {
|
||||
if (type == CSS_MEASURE_GROW || type == CSS_MEASURE_SHRINK) {
|
||||
dim.dimensions[CSS_WIDTH] = 33;
|
||||
dim.dimensions[CSS_HEIGHT] = 18;
|
||||
return dim;
|
||||
if (width != width) {
|
||||
width = 1000000;
|
||||
}
|
||||
dim.dimensions[CSS_WIDTH] = width;
|
||||
if (strcmp(text, "small") == 0) {
|
||||
dim.dimensions[CSS_WIDTH] = fminf(33, width);
|
||||
dim.dimensions[CSS_HEIGHT] = 18;
|
||||
return dim;
|
||||
}
|
||||
if (strcmp(text, "loooooooooong with space") == 0) {
|
||||
if (type == CSS_MEASURE_GROW) {
|
||||
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_WIDTH] = width >= 171 ? 171 : fmaxf(100, width);
|
||||
dim.dimensions[CSS_HEIGHT] = width >= 171 ? 18 : 36;
|
||||
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) {
|
||||
layoutNode(style);
|
||||
layoutNode(style, CSS_UNDEFINED);
|
||||
|
||||
if (!are_layout_equal(style, expected_layout)) {
|
||||
printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", name);
|
||||
|
||||
printf("Input: ");
|
||||
print_style(style, 0);
|
||||
print_css_node(style, CSS_PRINT_STYLE);
|
||||
printf("Output: ");
|
||||
print_layout(style, 0);
|
||||
print_css_node(style, CSS_PRINT_LAYOUT);
|
||||
|
||||
printf("Expected: ");
|
||||
print_layout(expected_layout, 0);
|
||||
print_css_node(expected_layout, CSS_PRINT_LAYOUT);
|
||||
} else {
|
||||
printf("%sPASS%s %s\n", "\x1B[32m", "\x1B[0m", name);
|
||||
}
|
||||
|
@@ -5,4 +5,4 @@
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/** @nolint */
|
||||
|
||||
var layoutTestUtils = (function() {
|
||||
var iframe = (function() {
|
||||
@@ -238,42 +239,38 @@ var layoutTestUtils = (function() {
|
||||
reduceTest: reduceTest,
|
||||
text: function(text) {
|
||||
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
|
||||
// Comment this block of code if you want to use the browser to
|
||||
// generate proper sizes
|
||||
if (text === 'small') {
|
||||
if (type === 'grow' || type === 'shrink') {
|
||||
return {width: 33, height: 18}
|
||||
}
|
||||
return {width: width, height: 18};
|
||||
return {width: Math.min(33, width), height: 18};
|
||||
}
|
||||
if (text === 'loooooooooong with space') {
|
||||
if (type === 'grow') {
|
||||
return {width: 171, height: 18};
|
||||
}
|
||||
if (type === 'shrink') {
|
||||
return {width: 100, height: 36};
|
||||
}
|
||||
return {width: width, height: width >= 171 ? 18 : 36};
|
||||
var res = {
|
||||
width: width >= 171 ? 171 : Math.max(100, width),
|
||||
height: width >= 171 ? 18 : 36
|
||||
};
|
||||
return res
|
||||
}
|
||||
return;
|
||||
|
||||
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');
|
||||
span.style.display = 'flex';
|
||||
body.style.display = 'block';
|
||||
if (width === 'grow') {
|
||||
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.style.flexDirection = 'column';
|
||||
span.style.alignItems = 'flex-start';
|
||||
span.innerText = text;
|
||||
|
||||
div.appendChild(span);
|
||||
body.appendChild(div);
|
||||
var rect = span.getBoundingClientRect();
|
||||
|
100
src/Layout.c
100
src/Layout.c
@@ -77,9 +77,23 @@ static bool four_equal(float four[4]) {
|
||||
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);
|
||||
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) {
|
||||
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("top", node->style.position[CSS_TOP]);
|
||||
print_number_nan("bottom", node->style.position[CSS_BOTTOM]);
|
||||
}
|
||||
|
||||
if (node->children_count > 0) {
|
||||
printf("children: [\n");
|
||||
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);
|
||||
printf("]},\n");
|
||||
@@ -163,28 +178,11 @@ void print_style(css_node_t *node, int level) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_layout(css_node_t *node, int level) {
|
||||
indent(level);
|
||||
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");
|
||||
}
|
||||
void print_css_node(css_node_t *node, css_print_options_t options) {
|
||||
print_css_node_rec(node, options, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static css_position_t leading[2] = {
|
||||
/* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP,
|
||||
/* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT
|
||||
@@ -319,7 +317,7 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t 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 crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ?
|
||||
CSS_FLEX_DIRECTION_COLUMN :
|
||||
@@ -338,29 +336,39 @@ void layoutNode(css_node_t *node) {
|
||||
|
||||
if (isMeasureDefined(node)) {
|
||||
float width = CSS_UNDEFINED;
|
||||
css_measure_type_t type = CSS_MEASURE_VALUE;
|
||||
|
||||
if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
|
||||
width = node->style.dimensions[CSS_WIDTH];
|
||||
} else if (getPositionType(node) == CSS_POSITION_ABSOLUTE) {
|
||||
type = CSS_MEASURE_SHRINK;
|
||||
} else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]])) {
|
||||
width = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]];
|
||||
} 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(
|
||||
node->style.measure_context,
|
||||
type,
|
||||
width
|
||||
);
|
||||
if (!isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
|
||||
if (isRowUndefined) {
|
||||
node->layout.dimensions[CSS_WIDTH] = measure_dim.dimensions[CSS_WIDTH] +
|
||||
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] +
|
||||
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -410,8 +418,20 @@ void layoutNode(css_node_t *node) {
|
||||
getMarginAxis(child, mainAxis);
|
||||
|
||||
} 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.
|
||||
layoutNode(child);
|
||||
layoutNode(child, maxWidth);
|
||||
|
||||
// Absolute positioned elements do not take part of the layout, so we
|
||||
// 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
|
||||
// anything.
|
||||
if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) {
|
||||
|
||||
// The remaining available space that's needs to be allocated
|
||||
// The remaining available space that needs to be allocated
|
||||
float remainingMainDim = node->layout.dimensions[dim[mainAxis]] -
|
||||
getPaddingAndBorderAxis(node, mainAxis) -
|
||||
mainContentDim;
|
||||
@@ -463,8 +482,20 @@ void layoutNode(css_node_t *node) {
|
||||
child->layout.dimensions[dim[mainAxis]] = flexibleMainDim +
|
||||
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
|
||||
layoutNode(child);
|
||||
layoutNode(child, maxWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +510,7 @@ void layoutNode(css_node_t *node) {
|
||||
} else if (justifyContent == CSS_JUSTIFY_FLEX_END) {
|
||||
leadingMainDim = remainingMainDim;
|
||||
} else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) {
|
||||
remainingMainDim = fmaxf(remainingMainDim, 0);
|
||||
betweenMainDim = remainingMainDim /
|
||||
(flexibleChildrenCount + nonFlexibleChildrenCount - 1);
|
||||
} else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) {
|
||||
|
18
src/Layout.h
18
src/Layout.h
@@ -56,13 +56,6 @@ typedef struct {
|
||||
float dimensions[2];
|
||||
} css_layout_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
CSS_MEASURE_GROW = 0,
|
||||
CSS_MEASURE_SHRINK,
|
||||
CSS_MEASURE_VALUE
|
||||
} css_measure_type_t;
|
||||
|
||||
typedef struct {
|
||||
float dimensions[2];
|
||||
} css_dim_t;
|
||||
@@ -90,7 +83,7 @@ typedef struct {
|
||||
float border[4];
|
||||
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;
|
||||
} 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);
|
||||
|
||||
// Print utilities
|
||||
void print_style(css_node_t *node, int level);
|
||||
void print_layout(css_node_t *node, int level);
|
||||
typedef enum {
|
||||
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!
|
||||
void layoutNode(css_node_t *node);
|
||||
void layoutNode(css_node_t *node, float maxWidth);
|
||||
|
||||
#endif
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/** @nolint */
|
||||
|
||||
var computeLayout = (function() {
|
||||
|
||||
@@ -193,11 +194,7 @@ var computeLayout = (function() {
|
||||
var CSS_POSITION_RELATIVE = 'relative';
|
||||
var CSS_POSITION_ABSOLUTE = 'absolute';
|
||||
|
||||
var CSS_MEASURE_VALUE = 'value';
|
||||
var CSS_MEASURE_GROW = 'grow';
|
||||
var CSS_MEASURE_SHRINK = 'shrink';
|
||||
|
||||
return function layoutNode(node) {
|
||||
return 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 :
|
||||
@@ -216,29 +213,39 @@ var computeLayout = (function() {
|
||||
|
||||
if (isMeasureDefined(node)) {
|
||||
var/*float*/ width = CSS_UNDEFINED;
|
||||
var/*css_measure_type_t*/ type = CSS_MEASURE_VALUE;
|
||||
|
||||
if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
|
||||
width = node.style.width;
|
||||
} else if (getPositionType(node) == CSS_POSITION_ABSOLUTE) {
|
||||
type = CSS_MEASURE_SHRINK;
|
||||
} else if (!isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_ROW]])) {
|
||||
width = node.layout[dim[CSS_FLEX_DIRECTION_ROW]];
|
||||
} 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(
|
||||
/*!node->style.measure_context,*/
|
||||
type,
|
||||
width
|
||||
);
|
||||
if (!isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
|
||||
if (isRowUndefined) {
|
||||
node.layout.width = measure_dim.width +
|
||||
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
|
||||
}
|
||||
if (!isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {
|
||||
if (isColumnUndefined) {
|
||||
node.layout.height = measure_dim.height +
|
||||
getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -288,8 +295,20 @@ var computeLayout = (function() {
|
||||
getMarginAxis(child, mainAxis);
|
||||
|
||||
} 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.
|
||||
layoutNode(child);
|
||||
layoutNode(child, maxWidth);
|
||||
|
||||
// Absolute positioned elements do not take part of the layout, so we
|
||||
// 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
|
||||
// anything.
|
||||
if (!isUndefined(node.layout[dim[mainAxis]])) {
|
||||
|
||||
// The remaining available space that's needs to be allocated
|
||||
// The remaining available space that needs to be allocated
|
||||
var/*float*/ remainingMainDim = node.layout[dim[mainAxis]] -
|
||||
getPaddingAndBorderAxis(node, mainAxis) -
|
||||
mainContentDim;
|
||||
@@ -341,8 +359,20 @@ var computeLayout = (function() {
|
||||
child.layout[dim[mainAxis]] = flexibleMainDim +
|
||||
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
|
||||
layoutNode(child);
|
||||
layoutNode(child, maxWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +387,7 @@ var computeLayout = (function() {
|
||||
} else if (justifyContent === CSS_JUSTIFY_FLEX_END) {
|
||||
leadingMainDim = remainingMainDim;
|
||||
} else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {
|
||||
remainingMainDim = fmaxf(remainingMainDim, 0);
|
||||
betweenMainDim = remainingMainDim /
|
||||
(flexibleChildrenCount + nonFlexibleChildrenCount - 1);
|
||||
} else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -742,39 +742,28 @@ describe('Layout', function() {
|
||||
{width: 1, height: 0, top: 0, left: 0, children: [
|
||||
{width: 0, height: 0, top: 0, left: 0}
|
||||
]}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('should layout node with just text', function() {
|
||||
testLayout(
|
||||
{style: {measure: text('small')}},
|
||||
{width: 33, height: 18, top: 0, left: 0}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('should layout node with text and width', function() {
|
||||
testLayout(
|
||||
{style: {measure: text('small'), width: 10}},
|
||||
{width: 10, height: 18, top: 0, left: 0}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('should layout node with text, padding and margin', function() {
|
||||
testLayout(
|
||||
{style: {measure: text('loooooooooong with space'), padding: 5, margin: 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() {
|
||||
@@ -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() {
|
||||
function RNG(seed) {
|
||||
this.state = seed;
|
||||
@@ -849,7 +981,17 @@ describe('Layout', function() {
|
||||
randEnum(node, 0.5, 'flex', ['none', 1]);
|
||||
randEnum(node, 0.5, 'position', ['relative', 'absolute']);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@ document.getElementById('layout_code').value = computeLayout.toString()
|
||||
.replace(/node.children\[i\]/g, '&node.children[i]')
|
||||
.replace(/node\./g, 'node->')
|
||||
.replace(/child\./g, 'child->')
|
||||
.replace(/parent\./g, 'parent->')
|
||||
.replace(/var\/\*([^\/]+)\*\//g, '$1')
|
||||
.replace(/ === /g, ' == ')
|
||||
.replace(/\n /g, '\n')
|
||||
@@ -55,6 +56,7 @@ var layoutTestUtils = {
|
||||
};
|
||||
function describe(name, cb) { cb(); }
|
||||
function it(name, cb) { currentTest = name; cb(); }
|
||||
xit = it;
|
||||
</script>
|
||||
<script src="__tests__/Layout-test.js"></script>
|
||||
<script>
|
||||
|
Reference in New Issue
Block a user