diff --git a/.eslintrc b/.eslintrc index 46a76d7a..40bc7223 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,7 +15,8 @@ "__dirname": true, "module": true, "console": true, - "setTimeout": true + "setTimeout": true, + "define": true }, "rules": { "quotes": "single", diff --git a/package.json b/package.json index b4dafba7..f97cafbe 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "css-layout", "version": "0.0.1", "description": "Reimplementation of CSS layout using pure JavaScript", - "main": "src/Layout.js", + "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" diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index d32dee31..dbea07a9 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -100,8 +100,10 @@ var layoutTestUtils = (function() { getIframe(iframe); } - if (typeof computeLayout === 'function') { - var realComputeLayout = computeLayout; + if (typeof computeLayout === 'object') { + var fillNodes = computeLayout.fillNodes; + var extractNodes = computeLayout.extractNodes; + var realComputeLayout = computeLayout.computeLayout; } function roundLayout(layout) { @@ -143,34 +145,6 @@ var layoutTestUtils = (function() { } function computeCSSLayout(rootNode) { - function fillNodes(node) { - node.layout = { - width: undefined, - height: undefined, - top: 0, - left: 0 - }; - if (!node.style) { - node.style = {}; - } - - if (!node.children || node.style.measure) { - node.children = []; - } - node.children.forEach(fillNodes); - } - - function extractNodes(node) { - var layout = node.layout; - delete node.layout; - if (node.children.length > 0) { - layout.children = node.children.map(extractNodes); - } else { - delete node.children; - } - return layout; - } - fillNodes(rootNode); realComputeLayout(rootNode); return roundLayout(extractNodes(rootNode)); @@ -257,6 +231,14 @@ var layoutTestUtils = (function() { return namedLayout; } + function testFillNodes(node, filledNode) { + expect(fillNodes(node)).toEqual(filledNode); + } + + function testExtractNodes(node, extractedNode) { + expect(extractNodes(node)).toEqual(extractedNode); + } + function testNamedLayout(name, layoutA, layoutB) { expect(nameLayout(name, layoutA)) .toEqual(nameLayout(name, layoutB)); @@ -404,6 +386,8 @@ var layoutTestUtils = (function() { testNamedLayout('expected-dom', expectedLayout, domLayout); testNamedLayout('layout-dom', layout, domLayout); }, + testFillNodes: testFillNodes, + testExtractNodes: testExtractNodes, 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 766d9110..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 : diff --git a/src/Layout.js b/src/Layout.js index fe366e99..d3e0bd40 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -62,6 +62,34 @@ var computeLayout = (function() { return 0; } + function fillNodes(node) { + node.layout = { + width: undefined, + height: undefined, + top: 0, + left: 0 + }; + if (!node.style) { + node.style = {}; + } + + if (!node.children || node.style.measure) { + node.children = []; + } + node.children.forEach(fillNodes); + return node; + } + + function extractNodes(node) { + var layout = node.layout; + delete node.layout; + if (node.children && node.children.length > 0) { + layout.children = node.children.map(extractNodes); + } else { + delete node.children; + } + return layout; + } function getPositiveSpacing(node, type, suffix, location) { var key = type + capitalizeFirst(location) + suffix; @@ -208,7 +236,8 @@ var computeLayout = (function() { return -getPosition(node, trailing[axis]); } - return function layoutNode(node, parentMaxWidth) { + 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 : @@ -651,9 +680,30 @@ var computeLayout = (function() { } } } + } + + return { + computeLayout: layoutNode, + fillNodes: fillNodes, + extractNodes: extractNodes }; })(); -if (typeof module === 'object') { - module.exports = computeLayout; -} +// UMD (Universal Module Definition) +// See https://github.com/umdjs/umd for reference +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.returnExports = factory(); + } +}(this, function () { + return computeLayout; +})); diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index ac48f38a..6f766a2a 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -9,10 +9,46 @@ /* globals layoutTestUtils */ var testLayout = layoutTestUtils.testLayout; +var testFillNodes = layoutTestUtils.testFillNodes; +var testExtractNodes = layoutTestUtils.testExtractNodes; var text = layoutTestUtils.text; var texts = layoutTestUtils.texts; var textSizes = layoutTestUtils.textSizes; +describe('Javascript Only', function() { + it('should fill root node with layout, style, and children', function() { + testFillNodes( + {}, + {layout: {width: undefined, height: undefined, top: 0, left: 0}, style: {}, children: []} + ); + }); + 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: [ + {layout: {width: undefined, height: undefined, top: 0, left: 0}} + ]}, + {width: undefined, height: undefined, top: 0, left: 0, children: [ + {width: undefined, height: undefined, top: 0, left: 0} + ]} + ); + }); + +}); + describe('Layout', function() { it('should layout a single node with width and height', function() { testLayout({ diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index a9d38ce1..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 : diff --git a/src/main.js b/src/main.js new file mode 100644 index 00000000..ac5c1084 --- /dev/null +++ b/src/main.js @@ -0,0 +1,24 @@ +// UMD (Universal Module Definition) +// See https://github.com/umdjs/umd for reference +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.returnExports = factory(); + } +}(this, function () { + var layout = require('./Layout.js'); + return function(node) { + node = layout.fillNodes(node); + layout.computeLayout(node); + node = layout.extractNodes(node); + return node; + }; +})); diff --git a/src/transpile.js b/src/transpile.js index 1881807d..9dbdc6af 100644 --- a/src/transpile.js +++ b/src/transpile.js @@ -8,7 +8,7 @@ */ var layoutTestUtils = require('./Layout-test-utils.js'); -var computeLayout = require('./Layout.js'); +var computeLayout = require('./Layout.js').computeLayout; var fs = require('fs'); var JavaTranspiler = require('./JavaTranspiler.js'); @@ -30,7 +30,11 @@ global.layoutTestUtils = { textSizes: layoutTestUtils.textSizes }; -global.describe = function(name, cb) { cb(); }; +global.describe = function(name, cb) { + if (name === 'Layout') { + cb(); + } +}; global.it = function(name, cb) { currentTest = name; cb(); }; global.xit = function() { /* ignore skipped tests */ };