diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..40bc7223 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,28 @@ +{ + "browser": true, + "shadow": true, + "globals": { + "jasmine": true, + "describe": true, + "beforeEach": true, + "afterEach": true, + "spyOn": true, + "it": true, + "xit": true, + "expect": true, + "require": true, + "global": true, + "__dirname": true, + "module": true, + "console": true, + "setTimeout": true, + "define": true + }, + "rules": { + "quotes": "single", + "strict": 0, + "no-console": false, + "no-shadow": false, + "no-underscore-dangle": false + } +} diff --git a/.gitignore b/.gitignore index a4268a07..b7fd170c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ a.out /**/.idea/workspace.xml /lib/ /node_modules/ +npm-debug.log diff --git a/README.md b/README.md index 3e4f0807..c9696f43 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ computeLayout( To run the tests -- For the JS tests: Open `RunLayoutTests.html` and `RunLayoutRandomTests.html` in Chrome +- For the JS tests: Open `RunLayoutTests.html` and `RunLayoutRandomTests.html` in Chrome or run `$ npm test` - For the C and Java tests: run `make` in your terminal. It will also transpile the JS code Supported Attributes diff --git a/karma.conf.js b/karma.conf.js index 9968bef7..61ca91f9 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -39,4 +39,4 @@ module.exports = function (config) { singleRun: false }); -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index 28b8c570..f97cafbe 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Reimplementation of CSS layout using pure JavaScript", "main": "src/main.js", "scripts": { + "pretest": "./node_modules/eslint/bin/eslint.js src", "test": "./node_modules/karma/bin/karma start ./karma.conf.js --single-run" }, "repository": { @@ -17,6 +18,7 @@ }, "homepage": "https://github.com/facebook/css-layout", "devDependencies": { + "eslint": "^0.14.1", "jasmine-core": "^2.2.0", "karma": "^0.12.31", "karma-chrome-launcher": "^0.1.7", diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index d2f5db0b..a4dddc77 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -52,7 +52,7 @@ function __transpileSingleTestToJava(code) { .replace( // layout.position[CSS_TOP] => layout.y /layout\.position\[CSS_(TOP|LEFT)\]/g, function (str, match1) { - return 'layout.' + (match1 == 'TOP' ? 'y' : 'x'); + return 'layout.' + (match1 === 'TOP' ? 'y' : 'x'); }) .replace( // style.position[CSS_TOP] => style.positionTop /style\.(position)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, @@ -97,7 +97,7 @@ var JavaTranspiler = { .replace(/var\/\*([^\/]+)\*\//g, '$1') .replace(/ === /g, ' == ') .replace(/ !== /g, ' != ') - .replace(/\n /g, '\n') + .replace(/\n {2}/g, '\n') .replace(/\/[*]!([^*]+)[*]\//g, '$1') .replace(/css_node_t\*/g, 'CSSNode')); }, @@ -118,8 +118,8 @@ var JavaTranspiler = { __transpileSingleTestToJava(allTestsInC[i]); } return allTestsInJava.join('\n\n'); - }, -} + } +}; if (typeof module !== 'undefined') { module.exports = JavaTranspiler; diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index dc9da523..dbea07a9 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -44,21 +44,22 @@ var layoutTestUtils = (function() { }; } + var _cachedIframe; + function renderIframe() { var iframe = document.createElement('iframe'); document.body.appendChild(iframe); return iframe; } - var cachedIframe; - function getIframe() { - if (cachedIframe) { - return cachedIframe; + function getIframe(iframe) { + if (_cachedIframe) { + return _cachedIframe; } var doc = iframe.contentDocument; - if(doc.readyState === 'complete') { + if (doc.readyState === 'complete') { var style = document.createElement('style'); style.textContent = (function() {/* body, div { @@ -87,7 +88,7 @@ var layoutTestUtils = (function() { } */} + '').slice(15, -4); doc.head.appendChild(style); - cachedIframe = iframe; + _cachedIframe = iframe; return iframe; } else { setTimeout(getIframe, 0); @@ -96,7 +97,7 @@ var layoutTestUtils = (function() { if (typeof window !== 'undefined') { var iframe = renderIframe(); - getIframe(); + getIframe(iframe); } if (typeof computeLayout === 'object') { @@ -262,9 +263,12 @@ var layoutTestUtils = (function() { var isModified = true; function rec(node) { + var key; + var value; + // Style - for (var key in node.style) { - var value = node.style[key]; + for (key in node.style) { + value = node.style[key]; delete node.style[key]; if (isWorking()) { node.style[key] = value; @@ -273,8 +277,8 @@ var layoutTestUtils = (function() { } } // Round values - for (var key in node.style) { - var value = node.style[key]; + for (key in node.style) { + value = node.style[key]; if (value > 100) { node.style[key] = Math.round(value / 100) * 100; } else if (value > 10) { @@ -292,7 +296,7 @@ var layoutTestUtils = (function() { } // Children for (var i = 0; node.children && i < node.children.length; ++i) { - var value = node.children[i]; + value = node.children[i]; node.children.splice(i, 1); if (isWorking()) { if (!node.children) { @@ -348,7 +352,7 @@ var layoutTestUtils = (function() { var texts = { small: 'small', - big: 'loooooooooong with space', + big: 'loooooooooong with space' }; var preDefinedTextSizes = { @@ -368,7 +372,7 @@ var layoutTestUtils = (function() { smallHeight: measureTextSizes(texts.small, 0).height, bigWidth: measureTextSizes(texts.big).width, bigHeight: measureTextSizes(texts.big, 0).height, - bigMinWidth: measureTextSizes(texts.big, 0).width, + bigMinWidth: measureTextSizes(texts.big, 0).width }; } @@ -384,7 +388,7 @@ var layoutTestUtils = (function() { }, testFillNodes: testFillNodes, testExtractNodes: testExtractNodes, - testRandomLayout: function(node, i) { + testRandomLayout: function(node) { expect({node: node, layout: computeCSSLayout(node)}) .toEqual({node: node, layout: computeDOMLayout(node)}); }, diff --git a/src/Layout.c b/src/Layout.c index 97fc5fe1..b31e7e3b 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -336,6 +336,7 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { /** START_GENERATED **/ + css_flex_direction_t mainAxis = getFlexDirection(node); css_flex_direction_t crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ? CSS_FLEX_DIRECTION_COLUMN : @@ -374,25 +375,30 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // Let's not measure the text if we already know both dimensions if (isRowUndefined || isColumnUndefined) { - css_dim_t measure_dim = node->measure( + css_dim_t measureDim = node->measure( node->context, width ); if (isRowUndefined) { - node->layout.dimensions[CSS_WIDTH] = measure_dim.dimensions[CSS_WIDTH] + + node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); } if (isColumnUndefined) { - node->layout.dimensions[CSS_HEIGHT] = measure_dim.dimensions[CSS_HEIGHT] + + node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } return; } + int i; + int ii; + css_node_t* child; + css_flex_direction_t axis; + // Pre-fill some dimensions straight from the parent - for (int i = 0; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) == CSS_ALIGN_STRETCH && @@ -409,8 +415,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node->layout.dimensions[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && @@ -438,7 +444,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We want to execute the next two loops one per line with flex-wrap int startLine = 0; int endLine = 0; - int nextOffset = 0; + // int nextOffset = 0; int alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables float linesCrossDim = 0; @@ -457,8 +463,10 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { int flexibleChildrenCount = 0; float totalFlexible = 0; int nonFlexibleChildrenCount = 0; - for (int i = startLine; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + + float maxWidth; + for (i = startLine; i < node->children_count; ++i) { + child = node->get_child(node->context, i); float nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed @@ -474,16 +482,16 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { 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 = CSS_UNDEFINED; + if (mainAxis != CSS_FLEX_DIRECTION_ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + + if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + } } // This is the main recursive call. We layout non flexible children. @@ -544,21 +552,19 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We iterate over the full array and only apply the action on flexible // children. This is faster than actually allocating a new array that // contains only flexible children. - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); if (isFlex(child)) { // At this point we know the final size of the element in the main // dimension child->layout.dimensions[dim[mainAxis]] = flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis); - float maxWidth = CSS_UNDEFINED; - if (mainAxis == CSS_FLEX_DIRECTION_ROW) { - // do nothing - } else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + 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 { + } else if (mainAxis != CSS_FLEX_DIRECTION_ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); @@ -573,9 +579,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // space available } else { css_justify_t justifyContent = getJustifyContent(node); - if (justifyContent == CSS_JUSTIFY_FLEX_START) { - // Do nothing - } else if (justifyContent == CSS_JUSTIFY_CENTER) { + if (justifyContent == CSS_JUSTIFY_CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { leadingMainDim = remainingMainDim; @@ -605,8 +609,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { float mainDim = leadingMainDim + getPaddingAndBorder(node, leading[mainAxis]); - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); if (getPositionType(child) == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) { @@ -638,7 +642,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { float containerMainAxis = node->layout.dimensions[dim[mainAxis]]; // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. - if (isUndefined(node->layout.dimensions[dim[mainAxis]])) { + if (isUndefined(containerMainAxis)) { containerMainAxis = fmaxf( // We're missing the last padding at this point to get the final // dimension @@ -661,8 +665,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // Position elements in the cross axis - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); if (getPositionType(child) == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) { @@ -680,9 +684,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // alignSelf (child) in order to determine the position in the cross axis if (getPositionType(child) == CSS_POSITION_RELATIVE) { css_align_t alignItem = getAlignItem(node, child); - if (alignItem == CSS_ALIGN_FLEX_START) { - // Do nothing - } else if (alignItem == CSS_ALIGN_STRETCH) { + if (alignItem == CSS_ALIGN_STRETCH) { // You can only stretch if the dimension has not already been set // previously. if (!isDimDefined(child, crossAxis)) { @@ -694,7 +696,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { getPaddingAndBorderAxis(child, crossAxis) ); } - } else { + } else if (alignItem != CSS_ALIGN_FLEX_START) { // The remaining space between the parent dimensions+padding and child // dimensions+margin. float remainingCrossDim = containerCrossAxis - @@ -743,13 +745,13 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // Calculate dimensions for absolutely positioned elements - for (int i = 0; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node->layout.dimensions[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && @@ -765,8 +767,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { ); } } - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (isPosDefined(child, trailing[axis]) && !isPosDefined(child, leading[axis])) { child->layout.position[leading[axis]] = diff --git a/src/Layout.js b/src/Layout.js index 6f6a63ab..d3e0bd40 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -7,8 +7,44 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - var computeLayout = (function() { + + var CSS_UNDEFINED; + + var CSS_FLEX_DIRECTION_ROW = 'row'; + var CSS_FLEX_DIRECTION_COLUMN = 'column'; + + // var CSS_JUSTIFY_FLEX_START = 'flex-start'; + var CSS_JUSTIFY_CENTER = 'center'; + var CSS_JUSTIFY_FLEX_END = 'flex-end'; + var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between'; + var CSS_JUSTIFY_SPACE_AROUND = 'space-around'; + + var CSS_ALIGN_FLEX_START = 'flex-start'; + var CSS_ALIGN_CENTER = 'center'; + // var CSS_ALIGN_FLEX_END = 'flex-end'; + var CSS_ALIGN_STRETCH = 'stretch'; + + var CSS_POSITION_RELATIVE = 'relative'; + var CSS_POSITION_ABSOLUTE = 'absolute'; + + var leading = { + row: 'left', + column: 'top' + }; + var trailing = { + row: 'right', + column: 'bottom' + }; + var pos = { + row: 'left', + column: 'top' + }; + var dim = { + row: 'width', + column: 'height' + }; + function capitalizeFirst(str) { return str.charAt(0).toUpperCase() + str.slice(1); } @@ -166,6 +202,13 @@ var computeLayout = (function() { return 0; } + function fmaxf(a, b) { + if (a > b) { + return a; + } + return b; + } + // When the user specifically sets a value for width or height function setDimensionFromStyle(node, axis) { // The parent already computed us a width or height. We just skip it @@ -193,31 +236,8 @@ var computeLayout = (function() { return -getPosition(node, trailing[axis]); } - var leading = { - row: 'left', - column: 'top' - }; - var trailing = { - row: 'right', - column: 'bottom' - }; - var pos = { - row: 'left', - column: 'top' - }; - var dim = { - row: 'width', - column: 'height' - }; - - function fmaxf(a, b) { - if (a > b) { - return a; - } - return b; - } - 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 : @@ -256,25 +276,30 @@ var computeLayout = (function() { // 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*/ measureDim = node.style.measure( /*(c)!node->context,*/ width ); if (isRowUndefined) { - node.layout.width = measure_dim.width + + node.layout.width = measureDim.width + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); } if (isColumnUndefined) { - node.layout.height = measure_dim.height + + node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } return; } + var/*int*/ i; + var/*int*/ ii; + var/*css_node_t**/ child; + var/*css_flex_direction_t*/ axis; + // Pre-fill some dimensions straight from the parent - for (var/*int*/ i = 0; i < node.children.length; ++i) { - var/*css_node_t**/ child = node.children[i]; + for (i = 0; i < node.children.length; ++i) { + child = node.children[i]; // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) === CSS_ALIGN_STRETCH && @@ -288,11 +313,11 @@ var computeLayout = (function() { // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); - } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (var/*int*/ ii = 0; ii < 2; ii++) { - var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node.layout[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && @@ -320,7 +345,7 @@ var computeLayout = (function() { // We want to execute the next two loops one per line with flex-wrap var/*int*/ startLine = 0; var/*int*/ endLine = 0; - var/*int*/ nextOffset = 0; + // var/*int*/ nextOffset = 0; var/*int*/ alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables var/*float*/ linesCrossDim = 0; @@ -339,8 +364,10 @@ var computeLayout = (function() { var/*int*/ flexibleChildrenCount = 0; var/*float*/ totalFlexible = 0; var/*int*/ nonFlexibleChildrenCount = 0; - for (var/*int*/ i = startLine; i < node.children.length; ++i) { - var/*css_node_t**/ child = node.children[i]; + + var/*float*/ maxWidth; + for (i = startLine; i < node.children.length; ++i) { + child = node.children[i]; var/*float*/ nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed @@ -356,16 +383,16 @@ 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 = CSS_UNDEFINED; + if (mainAxis !== CSS_FLEX_DIRECTION_ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + + if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] - + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + } } // This is the main recursive call. We layout non flexible children. @@ -426,21 +453,19 @@ var computeLayout = (function() { // We iterate over the full array and only apply the action on flexible // children. This is faster than actually allocating a new array that // contains only flexible children. - for (var/*int*/ i = startLine; i < endLine; ++i) { - var/*css_node_t**/ child = node.children[i]; + for (i = startLine; i < endLine; ++i) { + child = node.children[i]; if (isFlex(child)) { // At this point we know the final size of the element in the main // dimension child.layout[dim[mainAxis]] = flexibleMainDim * getFlex(child) + 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 = CSS_UNDEFINED; + if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { maxWidth = node.layout[dim[CSS_FLEX_DIRECTION_ROW]] - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - } else { + } else if (mainAxis !== CSS_FLEX_DIRECTION_ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); @@ -455,9 +480,7 @@ var computeLayout = (function() { // space available } else { var/*css_justify_t*/ justifyContent = getJustifyContent(node); - if (justifyContent === CSS_JUSTIFY_FLEX_START) { - // Do nothing - } else if (justifyContent === CSS_JUSTIFY_CENTER) { + if (justifyContent === CSS_JUSTIFY_CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent === CSS_JUSTIFY_FLEX_END) { leadingMainDim = remainingMainDim; @@ -487,8 +510,8 @@ var computeLayout = (function() { var/*float*/ mainDim = leadingMainDim + getPaddingAndBorder(node, leading[mainAxis]); - for (var/*int*/ i = startLine; i < endLine; ++i) { - var/*css_node_t**/ child = node.children[i]; + for (i = startLine; i < endLine; ++i) { + child = node.children[i]; if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) { @@ -520,7 +543,7 @@ var computeLayout = (function() { var/*float*/ containerMainAxis = node.layout[dim[mainAxis]]; // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. - if (isUndefined(node.layout[dim[mainAxis]])) { + if (isUndefined(containerMainAxis)) { containerMainAxis = fmaxf( // We're missing the last padding at this point to get the final // dimension @@ -543,8 +566,8 @@ var computeLayout = (function() { // Position elements in the cross axis - for (var/*int*/ i = startLine; i < endLine; ++i) { - var/*css_node_t**/ child = node.children[i]; + for (i = startLine; i < endLine; ++i) { + child = node.children[i]; if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) { @@ -562,9 +585,7 @@ var computeLayout = (function() { // alignSelf (child) in order to determine the position in the cross axis if (getPositionType(child) === CSS_POSITION_RELATIVE) { var/*css_align_t*/ alignItem = getAlignItem(node, child); - if (alignItem === CSS_ALIGN_FLEX_START) { - // Do nothing - } else if (alignItem === CSS_ALIGN_STRETCH) { + if (alignItem === CSS_ALIGN_STRETCH) { // You can only stretch if the dimension has not already been set // previously. if (!isDimDefined(child, crossAxis)) { @@ -576,7 +597,7 @@ var computeLayout = (function() { getPaddingAndBorderAxis(child, crossAxis) ); } - } else { + } else if (alignItem !== CSS_ALIGN_FLEX_START) { // The remaining space between the parent dimensions+padding and child // dimensions+margin. var/*float*/ remainingCrossDim = containerCrossAxis - @@ -625,13 +646,13 @@ var computeLayout = (function() { // Calculate dimensions for absolutely positioned elements - for (var/*int*/ i = 0; i < node.children.length; ++i) { - var/*css_node_t**/ child = node.children[i]; - if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + for (i = 0; i < node.children.length; ++i) { + child = node.children[i]; + if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (var/*int*/ ii = 0; ii < 2; ii++) { - var/*css_flex_direction_t*/ axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node.layout[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && @@ -647,8 +668,8 @@ var computeLayout = (function() { ); } } - for (var/*int*/ ii = 0; ii < 2; ii++) { - var/*css_flex_direction_t*/ axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (isPosDefined(child, trailing[axis]) && !isPosDefined(child, leading[axis])) { child.layout[leading[axis]] = @@ -661,30 +682,11 @@ var computeLayout = (function() { } } - var CSS_UNDEFINED = undefined; - - var CSS_FLEX_DIRECTION_ROW = 'row'; - var CSS_FLEX_DIRECTION_COLUMN = 'column'; - - var CSS_JUSTIFY_FLEX_START = 'flex-start'; - var CSS_JUSTIFY_CENTER = 'center'; - var CSS_JUSTIFY_FLEX_END = 'flex-end'; - var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between'; - var CSS_JUSTIFY_SPACE_AROUND = 'space-around'; - - var CSS_ALIGN_FLEX_START = 'flex-start'; - var CSS_ALIGN_CENTER = 'center'; - var CSS_ALIGN_FLEX_END = 'flex-end'; - var CSS_ALIGN_STRETCH = 'stretch'; - - var CSS_POSITION_RELATIVE = 'relative'; - var CSS_POSITION_ABSOLUTE = 'absolute'; - return { computeLayout: layoutNode, fillNodes: fillNodes, extractNodes: extractNodes - } + }; })(); // UMD (Universal Module Definition) diff --git a/src/__tests__/Layout-random-test.js b/src/__tests__/Layout-random-test.js index d8cae15f..40d9004c 100644 --- a/src/__tests__/Layout-random-test.js +++ b/src/__tests__/Layout-random-test.js @@ -11,8 +11,6 @@ var testRandomLayout = layoutTestUtils.testRandomLayout; var computeLayout = layoutTestUtils.computeLayout; var computeDOMLayout = layoutTestUtils.computeDOMLayout; var reduceTest = layoutTestUtils.reduceTest; -var text = layoutTestUtils.text; -var texts = layoutTestUtils.texts; describe('Random layout', function() { @@ -39,14 +37,7 @@ describe('Random layout', function() { node.style[attribute] = enumValues[Math.floor(rng.nextFloat() * enumValues.length)]; } } - function randChildren(node, chance) { - while (rng.nextFloat() < chance) { - if (!node.children) { - node.children = []; - } - node.children.push(generateRandomNode()); - } - } + function randSpacing(node, chance, type, suffix, min, max) { randMinMax(node, chance, type + suffix, min, max); randMinMax(node, chance, type + 'Left' + suffix, min, max); @@ -88,10 +79,29 @@ describe('Random layout', function() { delete node.style.position; } + function randChildren(node, chance) { + while (rng.nextFloat() < chance) { + if (!node.children) { + node.children = []; + } + node.children.push(generateRandomNode()); + } + } + randChildren(node, 0.4); return node; } + function checkRandomLayout(i, node) { + it('should layout randomly #' + i + '.', function(node) { + if (JSON.stringify(computeLayout(node)) !== JSON.stringify(computeDOMLayout(node))) { + node = reduceTest(node); + } + + testRandomLayout(node, i); + }.bind(this, node)); + } + for (var i = 0; i < 100; ++i) { var node = generateRandomNode(); // The iframe's body has a natural width of 300 that it doesn't really make @@ -101,13 +111,7 @@ describe('Random layout', function() { delete node.style.flex; delete node.style.position; - it('should layout randomly #' + i +'.', function(node) { - if (JSON.stringify(computeLayout(node)) !== JSON.stringify(computeDOMLayout(node))) { - node = reduceTest(node); - } - - testRandomLayout(node, i); - }.bind(this, node)); + checkRandomLayout.call(this, i, node); } }); diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index 9fbb7d42..6f766a2a 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -20,22 +20,22 @@ describe('Javascript Only', function() { testFillNodes( {}, {layout: {width: undefined, height: undefined, top: 0, left: 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: []} ]} - ) - }) + ); + }); it('should pull out just the layout object from root', function() { testExtractNodes( {layout: {width: undefined, height: undefined, top: 0, left: 0}}, {width: undefined, height: undefined, top: 0, left: 0} - ) - }) + ); + }); it('should pull out just the layout object from root and children', function() { testExtractNodes( {layout: {width: undefined, height: undefined, top: 0, left: 0}, children: [ @@ -44,8 +44,8 @@ describe('Javascript Only', function() { {width: undefined, height: undefined, top: 0, left: 0, children: [ {width: undefined, height: undefined, top: 0, left: 0} ]} - ) - }) + ); + }); }); @@ -86,7 +86,7 @@ describe('Layout', function() { {width: 500, height: 500, top: 0, left: 0}, {width: 500, height: 500, top: 500, left: 0, children: [ {width: 250, height: 250, top: 0, left: 0}, - {width: 250, height: 250, top: 250, left: 0}, + {width: 250, height: 250, top: 250, left: 0} ]} ]} ); @@ -253,7 +253,7 @@ describe('Layout', function() { it('should layout node with flex override height', function() { testLayout( {style: {width: 1000, height: 1000}, children: [ - {style: {width: 100, height: 100, flex: 1}}, + {style: {width: 100, height: 100, flex: 1}} ]}, {width: 1000, height: 1000, top: 0, left: 0, children: [ {width: 100, height: 1000, top: 0, left: 0} @@ -269,7 +269,7 @@ describe('Layout', function() { ]}, {width: 1000, height: 1000, top: 0, left: 0, children: [ {width: 200, height: 100, top: 0, left: 0}, - {width: 100, height: 100, top: 100, left: 0}, + {width: 100, height: 100, top: 100, left: 0} ]} ); }); @@ -282,7 +282,7 @@ describe('Layout', function() { ]}, {width: 1000, height: 1000, top: 0, left: 0, children: [ {width: 200, height: 100, top: 0, left: 400}, - {width: 100, height: 100, top: 100, left: 450}, + {width: 100, height: 100, top: 100, left: 450} ]} ); }); @@ -295,7 +295,7 @@ describe('Layout', function() { ]}, {width: 1000, height: 1000, top: 0, left: 0, children: [ {width: 200, height: 100, top: 0, left: 800}, - {width: 100, height: 100, top: 100, left: 900}, + {width: 100, height: 100, top: 100, left: 900} ]} ); }); @@ -308,7 +308,7 @@ describe('Layout', function() { ]}, {width: 1000, height: 1000, top: 0, left: 0, children: [ {width: 200, height: 100, top: 0, left: 800}, - {width: 100, height: 100, top: 100, left: 450}, + {width: 100, height: 100, top: 100, left: 450} ]} ); }); @@ -350,7 +350,7 @@ describe('Layout', function() { testLayout( {style: {height: 100}, children: [ {style: {height: 100}}, - {style: {height: 200}}, + {style: {height: 200}} ]}, {width: 0, height: 100, top: 0, left: 0, children: [ {width: 0, height: 100, top: 0, left: 0}, @@ -397,7 +397,7 @@ describe('Layout', function() { it('should layout flex inside of an empty element', function() { testLayout( {style: {}, children: [ - {style: {flex: 1}}, + {style: {flex: 1}} ]}, {width: 0, height: 0, top: 0, left: 0, children: [ {width: 0, height: 0, top: 0, left: 0} @@ -519,7 +519,7 @@ describe('Layout', function() { {style: {width: 500, flexDirection: 'row'}, children: [ {style: {flex: 1}}, {style: {position: 'absolute', width: 50}}, - {style: {flex: 1}}, + {style: {flex: 1}} ]}, {width: 500, height: 0, top: 0, left: 0, children: [ {width: 250, height: 0, top: 0, left: 0}, @@ -686,7 +686,7 @@ describe('Layout', function() { {width: 347.5, height: 0, top: 0, left: 0}, {width: 347.5, height: 0, top: 0, left: 352.5} ]} - ) + ); }); it('should layout node with flex and overflow', function() { @@ -721,16 +721,16 @@ describe('Layout', function() { ]}, {width: 0, height: 500, top: 0, left: 0, children: [ {width: 0, height: 500, top: 0, left: 0}, - {width: 0, height: 0, top: 500, left: 0}, + {width: 0, height: 0, top: 500, left: 0} ]} - ) + ); }); it('should layout node with borderWidth', function() { testLayout( {style: {borderWidth: 5}}, {width: 10, height: 10, top: 0, left: 0} - ) + ); }); it('should layout node with borderWidth and position: absolute, top', function() { @@ -741,7 +741,7 @@ describe('Layout', function() { {width: 0, height: 1, top: 0, left: 0, children: [ {width: 0, height: 0, top: 0, left: 0} ]} - ) + ); }); it('should layout node with borderWidth and position: absolute, top. cross axis', function() { @@ -752,7 +752,7 @@ describe('Layout', function() { {width: 2, height: 2, top: 0, left: 0, children: [ {width: 0, height: 0, top: 1, left: 6} ]} - ) + ); }); it('should correctly take into account min padding for stretch', function() { @@ -968,7 +968,7 @@ describe('Layout', function() { ]}, {width: 100, height: 100, top: 0, left: 0, children: [ {width: 0, height: 25, top: 0, left: 0}, - {width: 0, height: 75, top: 25, left: 0}, + {width: 0, height: 75, top: 25, left: 0} ]} ); }); @@ -981,7 +981,7 @@ describe('Layout', function() { ]}, {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: 0, left: 0} ]} ); }); @@ -994,7 +994,7 @@ describe('Layout', function() { ]}, {width: 50, height: 100, top: 0, left: 0, children: [ {width: 50, height: 100, top: 0, left: 0}, - {width: 50, height: 0, top: 100, left: 0}, + {width: 50, height: 0, top: 100, left: 0} ]} ); }); @@ -1186,7 +1186,7 @@ describe('Layout', function() { {style: {flexWrap: 'wrap', flexDirection: 'row', width: 100}, children: [ {style: {width: 40, height: 10}}, {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: 0}, @@ -1200,7 +1200,7 @@ describe('Layout', function() { testLayout( {style: {height: 100, flexWrap: 'wrap'}, children: [ {style: {height: 100}}, - {style: {height: 200}}, + {style: {height: 200}} ]}, {width: 0, height: 100, top: 0, left: 0, children: [ {width: 0, height: 100, top: 0, left: 0}, @@ -1245,4 +1245,3 @@ describe('Layout', function() { }); }); - diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index b4e38548..83558abf 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -283,6 +283,7 @@ public class LayoutEngine { /** START_GENERATED **/ + CSSFlexDirection mainAxis = getFlexDirection(node); CSSFlexDirection crossAxis = mainAxis == CSSFlexDirection.ROW ? CSSFlexDirection.COLUMN : @@ -321,24 +322,29 @@ public class LayoutEngine { // Let's not measure the text if we already know both dimensions if (isRowUndefined || isColumnUndefined) { - MeasureOutput measure_dim = node.measure( + MeasureOutput measureDim = node.measure( width ); if (isRowUndefined) { - node.layout.width = measure_dim.width + + node.layout.width = measureDim.width + getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); } if (isColumnUndefined) { - node.layout.height = measure_dim.height + + node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSSFlexDirection.COLUMN); } } return; } + int i; + int ii; + CSSNode child; + CSSFlexDirection axis; + // Pre-fill some dimensions straight from the parent - for (int i = 0; i < node.getChildCount(); ++i) { - CSSNode child = node.getChildAt(i); + for (i = 0; i < node.getChildCount(); ++i) { + child = node.getChildAt(i); // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) == CSSAlign.STRETCH && @@ -355,8 +361,8 @@ public class LayoutEngine { } else if (getPositionType(child) == CSSPositionType.ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - CSSFlexDirection axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(axis))) && !isDimDefined(child, axis) && isPosDefined(child, getLeading(axis)) && @@ -384,7 +390,7 @@ public class LayoutEngine { // We want to execute the next two loops one per line with flex-wrap int startLine = 0; int endLine = 0; - int nextOffset = 0; + // int nextOffset = 0; int alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables float linesCrossDim = 0; @@ -403,8 +409,10 @@ public class LayoutEngine { int flexibleChildrenCount = 0; float totalFlexible = 0; int nonFlexibleChildrenCount = 0; - for (int i = startLine; i < node.getChildCount(); ++i) { - CSSNode child = node.getChildAt(i); + + float maxWidth; + for (i = startLine; i < node.getChildCount(); ++i) { + child = node.getChildAt(i); float nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed @@ -420,16 +428,16 @@ public class LayoutEngine { getMarginAxis(child, mainAxis); } else { - float maxWidth = CSSConstants.UNDEFINED; - if (mainAxis == CSSFlexDirection.ROW) { - // do nothing - } else if (isDimDefined(node, CSSFlexDirection.ROW)) { - maxWidth = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) - - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); - } else { + maxWidth = CSSConstants.UNDEFINED; + if (mainAxis != CSSFlexDirection.ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSSFlexDirection.ROW) - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + + if (isDimDefined(node, CSSFlexDirection.ROW)) { + maxWidth = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) - + getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); + } } // This is the main recursive call. We layout non flexible children. @@ -490,21 +498,19 @@ public class LayoutEngine { // We iterate over the full array and only apply the action on flexible // children. This is faster than actually allocating a new array that // contains only flexible children. - for (int i = startLine; i < endLine; ++i) { - CSSNode child = node.getChildAt(i); + for (i = startLine; i < endLine; ++i) { + child = node.getChildAt(i); if (isFlex(child)) { // At this point we know the final size of the element in the main // dimension setLayoutDimension(child, getDim(mainAxis), flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis)); - float maxWidth = CSSConstants.UNDEFINED; - if (mainAxis == CSSFlexDirection.ROW) { - // do nothing - } else if (isDimDefined(node, CSSFlexDirection.ROW)) { + maxWidth = CSSConstants.UNDEFINED; + if (isDimDefined(node, CSSFlexDirection.ROW)) { maxWidth = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); - } else { + } else if (mainAxis != CSSFlexDirection.ROW) { maxWidth = parentMaxWidth - getMarginAxis(node, CSSFlexDirection.ROW) - getPaddingAndBorderAxis(node, CSSFlexDirection.ROW); @@ -519,9 +525,7 @@ public class LayoutEngine { // space available } else { CSSJustify justifyContent = getJustifyContent(node); - if (justifyContent == CSSJustify.FLEX_START) { - // Do nothing - } else if (justifyContent == CSSJustify.CENTER) { + if (justifyContent == CSSJustify.CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent == CSSJustify.FLEX_END) { leadingMainDim = remainingMainDim; @@ -551,8 +555,8 @@ public class LayoutEngine { float mainDim = leadingMainDim + getPaddingAndBorder(node, getLeading(mainAxis)); - for (int i = startLine; i < endLine; ++i) { - CSSNode child = node.getChildAt(i); + for (i = startLine; i < endLine; ++i) { + child = node.getChildAt(i); if (getPositionType(child) == CSSPositionType.ABSOLUTE && isPosDefined(child, getLeading(mainAxis))) { @@ -584,7 +588,7 @@ public class LayoutEngine { float containerMainAxis = getLayoutDimension(node, getDim(mainAxis)); // 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)))) { + if (CSSConstants.isUndefined(containerMainAxis)) { containerMainAxis = Math.max( // We're missing the last padding at this point to get the final // dimension @@ -607,8 +611,8 @@ public class LayoutEngine { // Position elements in the cross axis - for (int i = startLine; i < endLine; ++i) { - CSSNode child = node.getChildAt(i); + for (i = startLine; i < endLine; ++i) { + child = node.getChildAt(i); if (getPositionType(child) == CSSPositionType.ABSOLUTE && isPosDefined(child, getLeading(crossAxis))) { @@ -626,9 +630,7 @@ public class LayoutEngine { // alignSelf (child) in order to determine the position in the cross axis if (getPositionType(child) == CSSPositionType.RELATIVE) { CSSAlign alignItem = getAlignItem(node, child); - if (alignItem == CSSAlign.FLEX_START) { - // Do nothing - } else if (alignItem == CSSAlign.STRETCH) { + if (alignItem == CSSAlign.STRETCH) { // You can only stretch if the dimension has not already been set // previously. if (!isDimDefined(child, crossAxis)) { @@ -640,7 +642,7 @@ public class LayoutEngine { getPaddingAndBorderAxis(child, crossAxis) )); } - } else { + } else if (alignItem != CSSAlign.FLEX_START) { // The remaining space between the parent dimensions+padding and child // dimensions+margin. float remainingCrossDim = containerCrossAxis - @@ -689,13 +691,13 @@ public class LayoutEngine { // Calculate dimensions for absolutely positioned elements - for (int i = 0; i < node.getChildCount(); ++i) { - CSSNode child = node.getChildAt(i); + for (i = 0; i < node.getChildCount(); ++i) { + child = node.getChildAt(i); if (getPositionType(child) == CSSPositionType.ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - CSSFlexDirection axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; if (!CSSConstants.isUndefined(getLayoutDimension(node, getDim(axis))) && !isDimDefined(child, axis) && isPosDefined(child, getLeading(axis)) && @@ -711,8 +713,8 @@ public class LayoutEngine { )); } } - for (int ii = 0; ii < 2; ii++) { - CSSFlexDirection axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN; if (isPosDefined(child, getTrailing(axis)) && !isPosDefined(child, getLeading(axis))) { setLayoutPosition(child, getLeading(axis), getLayoutDimension(node, getDim(axis)) - diff --git a/src/main.js b/src/main.js index d34443e2..ac5c1084 100644 --- a/src/main.js +++ b/src/main.js @@ -20,5 +20,5 @@ layout.computeLayout(node); node = layout.extractNodes(node); return node; - } -})); \ No newline at end of file + }; +})); diff --git a/src/transpile.js b/src/transpile.js index 6354f40e..9dbdc6af 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -9,7 +9,6 @@ var layoutTestUtils = require('./Layout-test-utils.js'); var computeLayout = require('./Layout.js').computeLayout; -var fillNodes = require('./Layout.js').fillNodes; var fs = require('fs'); var JavaTranspiler = require('./JavaTranspiler.js'); @@ -32,7 +31,7 @@ global.layoutTestUtils = { }; global.describe = function(name, cb) { - if(name == 'Layout') { + if (name === 'Layout') { cb(); } }; @@ -46,6 +45,14 @@ function printLayout(test) { var level = 1; var res = []; + function indent(level) { + var result = ''; + for (var i = 0; i < level; ++i) { + result += ' '; + } + return result; + } + function add(str) { if (str.length > 0) { str = indent(level) + str; @@ -54,18 +61,7 @@ function printLayout(test) { } function isEmpty(obj) { - for (var key in obj) { - return false; - } - return true; - } - - function indent(level) { - var result = ''; - for (var i = 0; i < level; ++i) { - result += ' '; - } - return result; + return !Object.keys(obj).length; } add('{'); @@ -78,24 +74,22 @@ function printLayout(test) { if (!isEmpty(test.node.style) || test.node.children && test.node.children.length) { add('css_node_t *node_0 = root_node;'); } - function rec_style(node) { + function recStyle(node) { function addStyle(str) { add('node_' + (level - 3) + '->style.' + str); } - function addEnum(node, js_key, c_key, dict) { - if (js_key in node.style) { - addStyle(c_key + ' = ' + dict[node.style[js_key]] + ';'); + function addEnum(node, jsKey, cKey, dict) { + if (jsKey in node.style) { + addStyle(cKey + ' = ' + dict[node.style[jsKey]] + ';'); } } - function addFloat(positive, node, js_key, c_key) { - if (js_key in node.style) { - if (positive === 'positive' && node.style[js_key] < 0) { - // do nothing - } else { - addStyle(c_key + ' = ' + node.style[js_key] + ';'); + function addFloat(positive, node, jsKey, cKey) { + if (jsKey in node.style) { + if (positive !== 'positive' || node.style[jsKey] >= 0) { + addStyle(cKey + ' = ' + node.style[jsKey] + ';'); } } } @@ -163,21 +157,21 @@ function printLayout(test) { addMeasure(node); if (node.children) { - add('init_css_node_children(node_' + (level - 3) +', ' + node.children.length + ');'); + add('init_css_node_children(node_' + (level - 3) + ', ' + node.children.length + ');'); add('{'); level++; add('css_node_t *node_' + (level - 3) + ';'); for (var i = 0; i < node.children.length; ++i) { add('node_' + (level - 3) + ' = node_' + (level - 4) + '->get_child(node_' + (level - 4) + '->context, ' + i + ');'); - rec_style(node.children[i]); + recStyle(node.children[i]); } level--; add('}'); } } - rec_style(test.node); + recStyle(test.node); level--; add('}'); add(''); @@ -188,7 +182,7 @@ function printLayout(test) { level++; add('css_node_t *node_0 = root_layout;'); - function rec_layout(node) { + function recLayout(node) { function addLayout(str) { add('node_' + (level - 3) + '->layout.' + str); } @@ -199,21 +193,21 @@ function printLayout(test) { addLayout('dimensions[CSS_HEIGHT] = ' + node.height + ';'); if (node.children) { - add('init_css_node_children(node_' + (level - 3) +', ' + node.children.length + ');'); + add('init_css_node_children(node_' + (level - 3) + ', ' + node.children.length + ');'); add('{'); level++; add('css_node_t *node_' + (level - 3) + ';'); for (var i = 0; i < node.children.length; ++i) { add('node_' + (level - 3) + ' = node_' + (level - 4) + '->get_child(node_' + (level - 4) + '->context, ' + i + ');'); - rec_layout(node.children[i]); + recLayout(node.children[i]); } level--; add('}'); } } - rec_layout(test.expectedLayout); + recLayout(test.expectedLayout); level--; add('}'); add(''); @@ -242,13 +236,14 @@ function transpileAnnotatedJStoC(jsCode) { .replace(/var\/\*([^\/]+)\*\//g, '$1') .replace(/ === /g, ' == ') .replace(/ !== /g, ' != ') - .replace(/\n /g, '\n') + .replace(/\n {2}/g, '\n') .replace(/\/\*\(c\)!([^*]+)\*\//g, '$1') .replace(/\/[*]!([^*]+)[*]\//g, '$1') .split('\n').slice(1, -1).join('\n'); } function makeConstDefs() { + /* eslint no-multi-spaces: 3 */ var lines = [ '#define SMALL_WIDTH ' + layoutTestUtils.textSizes.smallWidth, '#define SMALL_HEIGHT ' + layoutTestUtils.textSizes.smallHeight,