diff --git a/.gitignore b/.gitignore
index cba7efc8..678859b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
a.out
+*.class
+/**/java/out/*
+/**/.idea/workspace.xml
diff --git a/Makefile b/Makefile
index f0711fe6..046f6597 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,26 @@
FILES=src/__tests__/Layout-test.c src/Layout.c src/Layout-test-utils.c
-all: c test
+all: c c_test java java_test
-c:
- @node ./src/transpile.js
+c: transpile_all
-test:
+c_test: c
@gcc -std=c99 -Werror -Wno-padded $(FILES) -lm && ./a.out
@rm a.out
+java: transpile_all src/java
+ @javac -cp ./lib/junit4.jar -sourcepath ./src/java/src:./src/java/tests src/java/tests/com/facebook/csslayout/*.java
+
+java_test: java
+ @java -cp ./src/java/src:./src/java/tests:./lib/junit4.jar org.junit.runner.JUnitCore \
+ com.facebook.csslayout.LayoutEngineTest \
+ com.facebook.csslayout.LayoutCachingTest \
+ com.facebook.csslayout.CSSNodeTest
+
+transpile_all: ./src/transpile.js
+ @node ./src/transpile.js
+
debug:
@gcc -ggdb $(FILES) -lm && lldb ./a.out
@rm a.out
diff --git a/lib/junit4.jar b/lib/junit4.jar
new file mode 100644
index 00000000..954851e6
Binary files /dev/null and b/lib/junit4.jar differ
diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js
new file mode 100644
index 00000000..9d35526f
--- /dev/null
+++ b/src/JavaTranspiler.js
@@ -0,0 +1,110 @@
+function __transpileToJavaCommon(code) {
+ return code
+ .replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED')
+ .replace(/css_flex_direction_t/g, 'CSSFlexDirection')
+ .replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.')
+ .replace(/css_align_t/g, 'CSSAlign')
+ .replace(/CSS_ALIGN_/g, 'CSSAlign.')
+ .replace(/CSS_POSITION_/g, 'CSSPositionType.')
+ .replace(/css_justify_t/g, 'CSSJustify')
+ .replace(/CSS_JUSTIFY_/g, 'CSSJustify.')
+ .replace(/css_dim_t/g, 'MeasureOutput')
+ .replace(/bool/g, 'boolean')
+ .replace(/^(\s+)([^\s]+)\s+\+=/gm, '$1$2 = $2 +') // Expand +=
+ .replace(/leading\[([^\]]+)\]/g, 'getLeading($1)')
+ .replace(/trailing\[([^\]]+)\]/g, 'getTrailing($1)')
+ .replace(/pos\[([^\]]+)\]/g, 'getPos($1)')
+ .replace(/dim\[([^\]]+)\]/g, 'getDim($1)')
+ .replace(/isUndefined/g, 'FloatUtil.isUndefined')
+
+ // Since Java doesn't store its attributes in arrays, we need to use setters/getters to access
+ // the appropriate layout/style fields
+ .replace(
+ /(\w+)\.layout\[((?:getLeading|getPos)\([^\)]+\))\]\s+=\s+([^;]+);/gm,
+ 'setLayoutPosition($1, $2, $3);')
+ .replace(/(\w+)\.layout\[((?:getLeading|getPos)\([^\]]+\))\]/g, 'getLayoutPosition($1, $2)')
+ .replace(
+ /(\w+)\.layout\[(getDim\([^\)]+\))\]\s+=\s+([^;]+);/gm,
+ 'setLayoutDimension($1, $2, $3);')
+ .replace(/(\w+)\.layout\[(getDim\([^\]]+\))\]/g, 'getLayoutDimension($1, $2)')
+ .replace(/(\w+)\.style\[((?:getLeading|getPos)\([^\]]+\))\]/g, 'getStylePosition($1, $2)')
+ .replace(/(\w+)\.style\[(getDim\([^\]]+\))\]/g, 'getStyleDimension($1, $2)');
+}
+
+function __transpileSingleTestToJava(code) {
+ return __transpileToJavaCommon(code)
+ .replace(/new_test_css_node/g, 'new TestCSSNode')
+ .replace( // style.dimensions[CSS_WIDTH] => style.width
+ /(style|layout)\.dimensions\[CSS_(WIDTH|HEIGHT)\]/g,
+ function (str, match1, match2) {
+ return match1 + '.' + match2.toLowerCase();
+ })
+ .replace( // layout.position[CSS_TOP] => layout.y
+ /layout\.position\[CSS_(TOP|LEFT)\]/g,
+ function (str, match1) {
+ return 'layout.' + (match1 == 'TOP' ? 'y' : 'x');
+ })
+ .replace( // style.position[CSS_TOP] => style.positionTop
+ /style\.(position|margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g,
+ function (str, match1, match2) {
+ return 'style.' + match1 + match2[0] + match2.substring(1).toLowerCase();
+ })
+ .replace(/get_child\(.*context\,\s([^\)]+)\)/g, 'getChildAt($1)')
+ .replace(/init_css_node_children/g, 'addChildren')
+ .replace(/css_node_t(\s)\*/g, 'TestCSSNode$1')
+ .replace(/\->/g, '.')
+ .replace(/(\d+\.\d+)/g, '$1f')
+ .replace( // style.flex_direction => style.flexDirection
+ /style\.([^_\s]+)_(\w)(\w+)/g,
+ function (str, match1, match2, match3) {
+ return 'style.' + match1 + match2.toUpperCase() + match3;
+ })
+ .replace(/(\w+)\.measure\s+=\s+.+/, '$1.setMeasureFunction(sTestMeasureFunction);');
+}
+
+function indent(code) {
+ return code
+ .split('\n')
+ .map(function(line) { return ' ' + line; })
+ .join('\n');
+}
+
+var JavaTranspiler = {
+ transpileLayoutEngine: function(code) {
+ return indent(
+ __transpileToJavaCommon(code)
+ .replace(/function\s+layoutNode.*/, '')
+ .replace('node.style.measure', 'node.measure')
+ .replace(/\.children\.length/g, '.getChildCount()')
+ .replace(/node.children\[i\]/g, 'node.getChildAt(i)')
+ .replace(/fmaxf/g, 'Math.max')
+ .replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages
+ .replace(/var\/\*([^\/]+)\*\//g, '$1')
+ .replace(/ === /g, ' == ')
+ .replace(/\n /g, '\n')
+ .replace(/\/[*]!([^*]+)[*]\//g, '$1')
+ .replace(/css_node_t\*/g, 'CSSNode'));
+ },
+
+ transpileCConstDefs: function(cConstDefs) {
+ return indent(
+ cConstDefs
+ .replace(/#define\s+(\w+)\s+(\"[^\"]+\")/g, 'public static final String $1 = $2;')
+ .replace(/#define\s+(\w+)\s+(.+)/g, 'public static final float $1 = $2f;'));
+ },
+
+ transpileCTestsArray: function(allTestsInC) {
+ var allTestsInJava = [];
+ for (var i = 0; i < allTestsInC.length; i++) {
+ allTestsInJava[i] =
+ " @Test\n" +
+ " public void testCase" + i + "()\n" +
+ __transpileSingleTestToJava(allTestsInC[i]);
+ }
+ return allTestsInJava.join('\n\n');
+ },
+}
+
+if (typeof module !== 'undefined') {
+ module.exports = JavaTranspiler;
+}
diff --git a/src/Layout.c b/src/Layout.c
index 6118b2e6..0e3c9fea 100644
--- a/src/Layout.c
+++ b/src/Layout.c
@@ -398,7 +398,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
// 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 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ css_flex_direction_t 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]) &&
@@ -491,7 +491,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
// If there are flexible children in the mix, they are going to fill the
// remaining space
- if (flexibleChildrenCount) {
+ if (flexibleChildrenCount != 0) {
float flexibleMainDim = remainingMainDim / totalFlexible;
// The non flexible children can overflow the container, in this case
@@ -675,7 +675,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
// 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 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ css_flex_direction_t 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]) &&
@@ -692,7 +692,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) {
}
}
for (int ii = 0; ii < 2; ii++) {
- css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ css_flex_direction_t 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 cf229c72..01858307 100755
--- a/src/Layout.js
+++ b/src/Layout.js
@@ -237,7 +237,7 @@ 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(
- /*!node->context,*/
+ /*(c)!node->context,*/
width
);
if (isRowUndefined) {
@@ -273,7 +273,7 @@ var computeLayout = (function() {
// 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 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node.layout[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
@@ -366,7 +366,7 @@ var computeLayout = (function() {
// If there are flexible children in the mix, they are going to fill the
// remaining space
- if (flexibleChildrenCount) {
+ if (flexibleChildrenCount != 0) {
var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible;
// The non flexible children can overflow the container, in this case
@@ -550,7 +550,7 @@ var computeLayout = (function() {
// 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 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (!isUndefined(node.layout[dim[axis]]) &&
!isDimDefined(child, axis) &&
isPosDefined(child, leading[axis]) &&
@@ -567,7 +567,7 @@ var computeLayout = (function() {
}
}
for (var/*int*/ ii = 0; ii < 2; ii++) {
- var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ var/*css_flex_direction_t*/ axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
if (isPosDefined(child, trailing[axis]) &&
!isPosDefined(child, leading[axis])) {
child.layout[leading[axis]] =
diff --git a/src/java/.idea/.name b/src/java/.idea/.name
new file mode 100644
index 00000000..4cc7a509
--- /dev/null
+++ b/src/java/.idea/.name
@@ -0,0 +1 @@
+css-layout
\ No newline at end of file
diff --git a/src/java/.idea/compiler.xml b/src/java/.idea/compiler.xml
new file mode 100644
index 00000000..217af471
--- /dev/null
+++ b/src/java/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/.idea/copyright/profiles_settings.xml b/src/java/.idea/copyright/profiles_settings.xml
new file mode 100644
index 00000000..3572571a
--- /dev/null
+++ b/src/java/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/java/.idea/encodings.xml b/src/java/.idea/encodings.xml
new file mode 100644
index 00000000..e206d70d
--- /dev/null
+++ b/src/java/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/java/.idea/misc.xml b/src/java/.idea/misc.xml
new file mode 100644
index 00000000..97320410
--- /dev/null
+++ b/src/java/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/.idea/modules.xml b/src/java/.idea/modules.xml
new file mode 100644
index 00000000..8123b62d
--- /dev/null
+++ b/src/java/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/java/.idea/scopes/scope_settings.xml b/src/java/.idea/scopes/scope_settings.xml
new file mode 100644
index 00000000..922003b8
--- /dev/null
+++ b/src/java/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/java/.idea/uiDesigner.xml b/src/java/.idea/uiDesigner.xml
new file mode 100644
index 00000000..3b000203
--- /dev/null
+++ b/src/java/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/src/java/.idea/vcs.xml b/src/java/.idea/vcs.xml
new file mode 100644
index 00000000..def6a6a1
--- /dev/null
+++ b/src/java/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/java/java.iml b/src/java/java.iml
new file mode 100644
index 00000000..22ef4acb
--- /dev/null
+++ b/src/java/java.iml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/src/com/facebook/csslayout/CSSAlign.java b/src/java/src/com/facebook/csslayout/CSSAlign.java
new file mode 100644
index 00000000..dbdfc420
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSAlign.java
@@ -0,0 +1,9 @@
+package com.facebook.csslayout;
+
+public enum CSSAlign {
+ AUTO,
+ FLEX_START,
+ CENTER,
+ FLEX_END,
+ STRETCH,
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSConstants.java b/src/java/src/com/facebook/csslayout/CSSConstants.java
new file mode 100644
index 00000000..26c31d15
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSConstants.java
@@ -0,0 +1,6 @@
+package com.facebook.csslayout;
+
+public class CSSConstants {
+
+ public static final float UNDEFINED = Float.NaN;
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSFlexDirection.java b/src/java/src/com/facebook/csslayout/CSSFlexDirection.java
new file mode 100644
index 00000000..ed8a8f83
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSFlexDirection.java
@@ -0,0 +1,6 @@
+package com.facebook.csslayout;
+
+public enum CSSFlexDirection {
+ COLUMN,
+ ROW,
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSJustify.java b/src/java/src/com/facebook/csslayout/CSSJustify.java
new file mode 100644
index 00000000..5a4ca9a4
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSJustify.java
@@ -0,0 +1,9 @@
+package com.facebook.csslayout;
+
+public enum CSSJustify {
+ FLEX_START,
+ CENTER,
+ FLEX_END,
+ SPACE_BETWEEN,
+ SPACE_AROUND,
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSLayout.java b/src/java/src/com/facebook/csslayout/CSSLayout.java
new file mode 100644
index 00000000..be3f30ac
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSLayout.java
@@ -0,0 +1,39 @@
+package com.facebook.csslayout;
+
+/**
+ * Where the output of {@link LayoutEngine#layoutNode(CSSNode, float)} will go in the CSSNode.
+ */
+public class CSSLayout {
+
+ public float x;
+ public float y;
+ public float width = CSSConstants.UNDEFINED;
+ public float height = CSSConstants.UNDEFINED;
+
+ /**
+ * This should always get called before calling {@link LayoutEngine#layoutNode(CSSNode, float)}
+ */
+ public void resetResult() {
+ x = 0;
+ y = 0;
+ width = CSSConstants.UNDEFINED;
+ height = CSSConstants.UNDEFINED;
+ }
+
+ public void copy(CSSLayout layout) {
+ x = layout.x;
+ y = layout.y;
+ width = layout.width;
+ height = layout.height;
+ }
+
+ @Override
+ public String toString() {
+ return "layout: {" +
+ "x: " + x + ", " +
+ "y: " + y + ", " +
+ "width: " + width + ", " +
+ "height: " + height +
+ "}";
+ }
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java
new file mode 100644
index 00000000..da6d8714
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSNode.java
@@ -0,0 +1,338 @@
+package com.facebook.csslayout;
+
+import java.util.ArrayList;
+
+/**
+ * A CSS Node. It has a style object you can manipulate at {@link #style}. After calling
+ * {@link #calculateLayout()}, {@link #layout} will be filled with the results of the layout.
+ */
+public class CSSNode {
+
+ private static enum LayoutState {
+ /**
+ * Some property of this node or its children has changes and the current values in
+ * {@link #layout} are not valid.
+ */
+ DIRTY,
+
+ /**
+ * This node has a new layout relative to the last time {@link #markLayoutApplied()} was called.
+ */
+ HAS_NEW_LAYOUT,
+
+ /**
+ * {@link #layout} is valid for the node's properties and this layout has been marked as
+ * having been applied.
+ */
+ UP_TO_DATE,
+ }
+
+ // Only one copy kept around to keep from allocating a bunch of MeasureOutput objects
+ // NOT THREAD SAFE! NOT RE-ENTRANT SAFE!
+ private static final MeasureOutput MEASURE_OUTPUT = new MeasureOutput();
+
+ public static interface MeasureFunction {
+
+ /**
+ * Should measure the given node and put the result in the given MeasureOutput.
+ *
+ * NB: measure is NOT guaranteed to be threadsafe/re-entrant safe!
+ */
+ public void measure(CSSNode node, float width, MeasureOutput measureOutput);
+ }
+
+ // VisibleForTesting
+ /*package*/ final CSSStyle style = new CSSStyle();
+ /*package*/ final CSSLayout layout = new CSSLayout();
+ /*package*/ final CachedCSSLayout lastLayout = new CachedCSSLayout();
+
+ // 4 is kinda arbitrary, but the default of 10 seems really high for an average View.
+ private final ArrayList mChildren = new ArrayList(4);
+
+ private CSSNode mParent;
+ private MeasureFunction mMeasureFunction = null;
+ private LayoutState mLayoutState = LayoutState.DIRTY;
+
+ public int getChildCount() {
+ return mChildren.size();
+ }
+
+ public CSSNode getChildAt(int i) {
+ return mChildren.get(i);
+ }
+
+ public void addChildAt(CSSNode child, int i) {
+ if (child.mParent != null) {
+ throw new IllegalStateException("Child already has a parent, it must be removed first.");
+ }
+
+ mChildren.add(i, child);
+ child.mParent = this;
+ dirty();
+ }
+
+ public void removeChildAt(int i) {
+ mChildren.remove(i).mParent = null;
+ dirty();
+ }
+
+ public CSSNode getParent() {
+ return mParent;
+ }
+
+ public void setMeasureFunction(MeasureFunction measureFunction) {
+ dirtyIfDifferent(mMeasureFunction, measureFunction);
+ mMeasureFunction = measureFunction;
+ }
+
+ public boolean isMeasureDefined() {
+ return mMeasureFunction != null;
+ }
+
+ /*package*/ MeasureOutput measure(float width) {
+ if (!isMeasureDefined()) {
+ throw new RuntimeException("Measure function isn't defined!");
+ }
+ MEASURE_OUTPUT.height = CSSConstants.UNDEFINED;
+ MEASURE_OUTPUT.width = CSSConstants.UNDEFINED;
+ mMeasureFunction.measure(this, width, MEASURE_OUTPUT);
+ return MEASURE_OUTPUT;
+ }
+
+ /**
+ * Performs the actual layout and saves the results in {@link #layout}
+ */
+ public void calculateLayout() {
+ resetLayoutResultRecursive();
+ LayoutEngine.layoutNode(this, CSSConstants.UNDEFINED);
+ }
+
+ /**
+ * See {@link LayoutState#DIRTY}.
+ */
+ /*package*/ boolean isDirty() {
+ return mLayoutState == LayoutState.DIRTY;
+ }
+
+ /**
+ * See {@link LayoutState#HAS_NEW_LAYOUT}.
+ */
+ public boolean hasNewLayout() {
+ return mLayoutState == LayoutState.HAS_NEW_LAYOUT;
+ }
+
+ protected void dirty() {
+ if (mLayoutState == LayoutState.DIRTY) {
+ return;
+ } else if (mLayoutState == LayoutState.HAS_NEW_LAYOUT) {
+ throw new IllegalStateException(
+ "Previous layout was ignored! markLayoutApplied() never called");
+ }
+
+ mLayoutState = LayoutState.DIRTY;
+
+ if (mParent != null) {
+ mParent.dirty();
+ }
+ }
+
+ /*package*/ void markHasNewLayout() {
+ mLayoutState = LayoutState.HAS_NEW_LAYOUT;
+ }
+
+ /**
+ * Tells the node that the current values in {@link #layout} have been applied. Subsequent calls
+ * to {@link #hasNewLayout()} will return false until this node is laid out with new parameters.
+ * You must call this each time the layout is generated if the node has a new layout.
+ */
+ public void markLayoutApplied() {
+ if (!hasNewLayout()) {
+ throw new IllegalStateException("Expected node to have a new layout to apply!");
+ }
+
+ mLayoutState = LayoutState.UP_TO_DATE;
+ }
+
+ @Override
+ public String toString() {
+ String layoutString = layout.toString();
+
+ if (getChildCount() == 0) {
+ return layoutString;
+ }
+
+ layoutString += ", children: [\n";
+
+ for (int i = 0; i < getChildCount(); i++) {
+ String childString = getChildAt(i).toString();
+ childString = childString.replaceAll("\n", "\n\t");
+ layoutString += "\t" + childString + "\n";
+ }
+
+ layoutString += "]";
+
+ return layoutString;
+ }
+
+ private void resetLayoutResultRecursive() {
+ layout.resetResult();
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).resetLayoutResultRecursive();
+ }
+ }
+
+ protected void dirtyIfDifferent(float f1, float f2) {
+ if (!FloatUtil.floatsEqual(f1, f2)) {
+ dirty();
+ }
+ }
+
+ private static boolean objectsEqual(T o1, T o2) {
+ if (o1 == null) {
+ return o2 == null;
+ }
+ return o1.equals(o2);
+ }
+
+ protected void dirtyIfDifferent(T o1, T o2) {
+ if (!objectsEqual(o1, o2)) {
+ dirty();
+ }
+ }
+
+ public void setFlexDirection(CSSFlexDirection flexDirection) {
+ dirtyIfDifferent(style.flexDirection, flexDirection);
+ style.flexDirection = flexDirection;
+ }
+
+ public void setJustifyContent(CSSJustify justifyContent) {
+ dirtyIfDifferent(style.justifyContent, justifyContent);
+ style.justifyContent = justifyContent;
+ }
+
+ public void setAlignItems(CSSAlign alignItems) {
+ dirtyIfDifferent(style.alignItems, alignItems);
+ style.alignItems = alignItems;
+ }
+
+ public void setAlignSelf(CSSAlign alignSelf) {
+ dirtyIfDifferent(style.alignSelf, alignSelf);
+ style.alignSelf = alignSelf;
+ }
+
+ public void setPositionType(CSSPositionType positionType) {
+ dirtyIfDifferent(style.positionType, positionType);
+ style.positionType = positionType;
+ }
+
+ public void setFlex(float flex) {
+ dirtyIfDifferent(style.flex, flex);
+ style.flex = flex;
+ }
+
+ public void setMarginTop(float marginTop) {
+ dirtyIfDifferent(style.marginTop, marginTop);
+ style.marginTop = marginTop;
+ }
+
+ public void setMarginBottom(float marginBottom) {
+ dirtyIfDifferent(style.marginBottom, marginBottom);
+ style.marginBottom = marginBottom;
+ }
+
+ public void setMarginLeft(float marginLeft) {
+ dirtyIfDifferent(style.marginLeft, marginLeft);
+ style.marginLeft = marginLeft;
+ }
+
+ public void setMarginRight(float marginRight) {
+ dirtyIfDifferent(style.marginRight, marginRight);
+ style.marginRight = marginRight;
+ }
+
+ public void setPaddingTop(float paddingTop) {
+ dirtyIfDifferent(style.paddingTop, paddingTop);
+ style.paddingTop = paddingTop;
+ }
+
+ public void setPaddingBottom(float paddingBottom) {
+ dirtyIfDifferent(style.paddingBottom, paddingBottom);
+ style.paddingBottom = paddingBottom;
+ }
+
+ public void setPaddingLeft(float paddingLeft) {
+ dirtyIfDifferent(style.paddingLeft, paddingLeft);
+ style.paddingLeft = paddingLeft;
+ }
+
+ public void setPaddingRight(float paddingRight) {
+ dirtyIfDifferent(style.paddingRight, paddingRight);
+ style.paddingRight = paddingRight;
+ }
+
+ public void setPositionTop(float positionTop) {
+ dirtyIfDifferent(style.positionTop, positionTop);
+ style.positionTop = positionTop;
+ }
+
+ public void setPositionBottom(float positionBottom) {
+ dirtyIfDifferent(style.positionBottom, positionBottom);
+ style.positionBottom = positionBottom;
+ }
+
+ public void setPositionLeft(float positionLeft) {
+ dirtyIfDifferent(style.positionLeft, positionLeft);
+ style.positionLeft = positionLeft;
+ }
+
+ public void setPositionRight(float positionRight) {
+ dirtyIfDifferent(style.positionRight, positionRight);
+ style.positionRight = positionRight;
+ }
+
+ public void setBorderTop(float borderTop) {
+ dirtyIfDifferent(style.borderTop, borderTop);
+ style.borderTop = borderTop;
+ }
+
+ public void setBorderBottom(float borderBottom) {
+ dirtyIfDifferent(style.borderBottom, borderBottom);
+ style.borderBottom = borderBottom;
+ }
+
+ public void setBorderLeft(float borderLeft) {
+ dirtyIfDifferent(style.borderLeft, borderLeft);
+ style.borderLeft = borderLeft;
+ }
+
+ public void setBorderRight(float borderRight) {
+ dirtyIfDifferent(style.borderRight, borderRight);
+ style.borderRight = borderRight;
+ }
+
+ public void setStyleWidth(float width) {
+ dirtyIfDifferent(style.width, width);
+ style.width = width;
+ }
+
+ public void setStyleHeight(float height) {
+ dirtyIfDifferent(style.height, height);
+ style.height = height;
+ }
+
+ public float getLayoutX() {
+ return layout.x;
+ }
+
+ public float getLayoutY() {
+ return layout.y;
+ }
+
+ public float getLayoutWidth() {
+ return layout.width;
+ }
+
+ public float getLayoutHeight() {
+ return layout.height;
+ }
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSPositionType.java b/src/java/src/com/facebook/csslayout/CSSPositionType.java
new file mode 100644
index 00000000..fa2e1e42
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSPositionType.java
@@ -0,0 +1,6 @@
+package com.facebook.csslayout;
+
+public enum CSSPositionType {
+ RELATIVE,
+ ABSOLUTE,
+}
diff --git a/src/java/src/com/facebook/csslayout/CSSStyle.java b/src/java/src/com/facebook/csslayout/CSSStyle.java
new file mode 100644
index 00000000..3d9e7278
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CSSStyle.java
@@ -0,0 +1,37 @@
+package com.facebook.csslayout;
+
+/**
+ * The CSS style definition for a {@link CSSNode}.
+ */
+public class CSSStyle {
+
+ public CSSFlexDirection flexDirection = CSSFlexDirection.COLUMN;
+ public CSSJustify justifyContent = CSSJustify.FLEX_START;
+ public CSSAlign alignItems = CSSAlign.FLEX_START;
+ public CSSAlign alignSelf = CSSAlign.AUTO;
+ public CSSPositionType positionType = CSSPositionType.RELATIVE;
+ public float flex;
+
+ public float marginTop;
+ public float marginBottom;
+ public float marginLeft;
+ public float marginRight;
+
+ public float paddingTop;
+ public float paddingBottom;
+ public float paddingLeft;
+ public float paddingRight;
+
+ public float positionTop = CSSConstants.UNDEFINED;
+ public float positionBottom = CSSConstants.UNDEFINED;
+ public float positionLeft = CSSConstants.UNDEFINED;
+ public float positionRight = CSSConstants.UNDEFINED;
+
+ public float borderTop;
+ public float borderBottom;
+ public float borderLeft;
+ public float borderRight;
+
+ public float width = CSSConstants.UNDEFINED;
+ public float height = CSSConstants.UNDEFINED;
+}
diff --git a/src/java/src/com/facebook/csslayout/CachedCSSLayout.java b/src/java/src/com/facebook/csslayout/CachedCSSLayout.java
new file mode 100644
index 00000000..2f81884d
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/CachedCSSLayout.java
@@ -0,0 +1,13 @@
+package com.facebook.csslayout;
+
+/**
+ * CSSLayout with additional information about the conditions under which it was generated.
+ * {@link #requestedWidth} and {@link #requestedHeight} are the width and height the parent set on
+ * this node before calling layout visited us.
+ */
+public class CachedCSSLayout extends CSSLayout {
+
+ public float requestedWidth = CSSConstants.UNDEFINED;
+ public float requestedHeight = CSSConstants.UNDEFINED;
+ public float parentMaxWidth = CSSConstants.UNDEFINED;
+}
diff --git a/src/java/src/com/facebook/csslayout/FloatUtil.java b/src/java/src/com/facebook/csslayout/FloatUtil.java
new file mode 100644
index 00000000..a3390f4e
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/FloatUtil.java
@@ -0,0 +1,17 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.csslayout;
+
+public class FloatUtil {
+
+ public static boolean isUndefined(float f) {
+ return Float.compare(f, CSSConstants.UNDEFINED) == 0;
+ }
+
+ public static boolean floatsEqual(float f1, float f2) {
+ if (isUndefined(f1)) {
+ return isUndefined(f2);
+ }
+ return Math.abs(f2 - f1) < .00001;
+ }
+}
diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java
new file mode 100644
index 00000000..68b6f9d6
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java
@@ -0,0 +1,650 @@
+package com.facebook.csslayout;
+
+/**
+ * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float)}.
+ */
+public class LayoutEngine {
+
+ private static enum PositionIndex {
+ TOP,
+ LEFT,
+ BOTTOM,
+ RIGHT,
+ }
+
+ private static enum DimensionIndex {
+ WIDTH,
+ HEIGHT,
+ }
+
+ private static void setLayoutPosition(CSSNode node, PositionIndex position, float value) {
+ switch (position) {
+ case TOP:
+ node.layout.y = value;
+ break;
+ case LEFT:
+ node.layout.x = value;
+ break;
+ default:
+ throw new RuntimeException("Didn't get TOP or LEFT!");
+ }
+ }
+
+ private static float getLayoutPosition(CSSNode node, PositionIndex position) {
+ switch (position) {
+ case TOP:
+ return node.layout.y;
+ case LEFT:
+ return node.layout.x;
+ default:
+ throw new RuntimeException("Didn't get TOP or LEFT!");
+ }
+ }
+
+ private static void setLayoutDimension(CSSNode node, DimensionIndex dimension, float value) {
+ switch (dimension) {
+ case WIDTH:
+ node.layout.width = value;
+ break;
+ case HEIGHT:
+ node.layout.height = value;
+ break;
+ default:
+ throw new RuntimeException("Someone added a third dimension...");
+ }
+ }
+
+ private static float getLayoutDimension(CSSNode node, DimensionIndex dimension) {
+ switch (dimension) {
+ case WIDTH:
+ return node.layout.width;
+ case HEIGHT:
+ return node.layout.height;
+ default:
+ throw new RuntimeException("Someone added a third dimension...");
+ }
+ }
+
+ private static float getStylePosition(CSSNode node, PositionIndex position) {
+ switch (position) {
+ case TOP:
+ return node.style.positionTop;
+ case BOTTOM:
+ return node.style.positionBottom;
+ case LEFT:
+ return node.style.positionLeft;
+ case RIGHT:
+ return node.style.positionRight;
+ default:
+ throw new RuntimeException("Someone added a new cardinal direction...");
+ }
+ }
+
+ private static float getStyleDimension(CSSNode node, DimensionIndex dimension) {
+ switch (dimension) {
+ case WIDTH:
+ return node.style.width;
+ case HEIGHT:
+ return node.style.height;
+ default:
+ throw new RuntimeException("Someone added a third dimension...");
+ }
+ }
+
+ private static PositionIndex getLeading(CSSFlexDirection axis) {
+ return axis == CSSFlexDirection.COLUMN ? PositionIndex.TOP : PositionIndex.LEFT;
+ }
+
+ private static PositionIndex getTrailing(CSSFlexDirection axis) {
+ return axis == CSSFlexDirection.COLUMN ? PositionIndex.BOTTOM : PositionIndex.RIGHT;
+ }
+
+ private static PositionIndex getPos(CSSFlexDirection axis) {
+ return axis == CSSFlexDirection.COLUMN ? PositionIndex.TOP : PositionIndex.LEFT;
+ }
+
+ private static DimensionIndex getDim(CSSFlexDirection axis) {
+ return axis == CSSFlexDirection.COLUMN ? DimensionIndex.HEIGHT : DimensionIndex.WIDTH;
+ }
+
+ private static boolean isDimDefined(CSSNode node, CSSFlexDirection axis) {
+ return !FloatUtil.isUndefined(getStyleDimension(node, getDim(axis)));
+ }
+
+ private static boolean isPosDefined(CSSNode node, PositionIndex position) {
+ return !FloatUtil.isUndefined(getStylePosition(node, position));
+ }
+
+ private static float getPosition(CSSNode node, PositionIndex position) {
+ float result = getStylePosition(node, position);
+ return FloatUtil.isUndefined(result) ? 0 : result;
+ }
+
+ private static float getMargin(CSSNode node, PositionIndex position) {
+ switch (position) {
+ case TOP:
+ return node.style.marginTop;
+ case BOTTOM:
+ return node.style.marginBottom;
+ case LEFT:
+ return node.style.marginLeft;
+ case RIGHT:
+ return node.style.marginRight;
+ default:
+ throw new RuntimeException("Someone added a new cardinal direction...");
+ }
+ }
+
+ private static float getPadding(CSSNode node, PositionIndex position) {
+ switch (position) {
+ case TOP:
+ return node.style.paddingTop;
+ case BOTTOM:
+ return node.style.paddingBottom;
+ case LEFT:
+ return node.style.paddingLeft;
+ case RIGHT:
+ return node.style.paddingRight;
+ default:
+ throw new RuntimeException("Someone added a new cardinal direction...");
+ }
+ }
+
+ private static float getBorder(CSSNode node, PositionIndex position) {
+ switch (position) {
+ case TOP:
+ return node.style.borderTop;
+ case BOTTOM:
+ return node.style.borderBottom;
+ case LEFT:
+ return node.style.borderLeft;
+ case RIGHT:
+ return node.style.borderRight;
+ default:
+ throw new RuntimeException("Someone added a new cardinal direction...");
+ }
+ }
+
+ private static float getPaddingAndBorder(CSSNode node, PositionIndex position) {
+ return getPadding(node, position) + getBorder(node, position);
+ }
+
+ private static float getMarginAxis(CSSNode node, CSSFlexDirection axis) {
+ return getMargin(node, getLeading(axis)) + getMargin(node, getTrailing(axis));
+ }
+
+ private static float getPaddingAndBorderAxis(CSSNode node, CSSFlexDirection axis) {
+ return getPaddingAndBorder(
+ node,
+ getLeading(axis)) + getPaddingAndBorder(node, getTrailing(axis));
+ }
+
+ private static void setDimensionFromStyle(CSSNode node, CSSFlexDirection axis) {
+ // The parent already computed us a width or height. We just skip it
+ if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(axis)))) {
+ return;
+ }
+ // We only run if there's a width or height defined
+ if (!isDimDefined(node, axis)) {
+ return;
+ }
+
+ // The dimensions can never be smaller than the padding and border
+ float maxLayoutDimension = Math.max(
+ getStyleDimension(node, getDim(axis)),
+ getPaddingAndBorderAxis(node, axis));
+ setLayoutDimension(node, getDim(axis), maxLayoutDimension);
+ }
+
+ private static float getRelativePosition(CSSNode node, CSSFlexDirection axis) {
+ float lead = getStylePosition(node, getLeading(axis));
+ if (!FloatUtil.isUndefined(lead)) {
+ return lead;
+ }
+ return -getPosition(node, getTrailing(axis));
+ }
+
+ private static float getFlex(CSSNode node) {
+ return node.style.flex;
+ }
+
+ private static CSSFlexDirection getFlexDirection(CSSNode node) {
+ return node.style.flexDirection;
+ }
+
+ private static CSSPositionType getPositionType(CSSNode node) {
+ return node.style.positionType;
+ }
+
+ private static CSSAlign getAlignItem(CSSNode node, CSSNode child) {
+ if (child.style.alignSelf != CSSAlign.AUTO) {
+ return child.style.alignSelf;
+ }
+ return node.style.alignItems;
+ }
+
+ private static CSSJustify getJustifyContent(CSSNode node) {
+ return node.style.justifyContent;
+ }
+
+ private static boolean isFlex(CSSNode node) {
+ return getPositionType(node) == CSSPositionType.RELATIVE && getFlex(node) > 0;
+ }
+
+ private static boolean isMeasureDefined(CSSNode node) {
+ return node.isMeasureDefined();
+ }
+
+ private static float getDimWithMargin(CSSNode node, CSSFlexDirection axis) {
+ return getLayoutDimension(node, getDim(axis)) +
+ getMargin(node, getLeading(axis)) +
+ getMargin(node, getTrailing(axis));
+ }
+
+ private static boolean needsRelayout(CSSNode node, float parentMaxWidth) {
+ return node.isDirty() ||
+ !FloatUtil.floatsEqual(node.lastLayout.requestedHeight, node.layout.height) ||
+ !FloatUtil.floatsEqual(node.lastLayout.requestedWidth, node.layout.width) ||
+ !FloatUtil.floatsEqual(node.lastLayout.parentMaxWidth, parentMaxWidth);
+ }
+
+ /*package*/ static void layoutNode(CSSNode node, float parentMaxWidth) {
+ if (needsRelayout(node, parentMaxWidth)) {
+ node.lastLayout.requestedWidth = node.layout.width;
+ node.lastLayout.requestedHeight = node.layout.height;
+ node.lastLayout.parentMaxWidth = parentMaxWidth;
+
+ layoutNodeImpl(node, parentMaxWidth);
+ node.markHasNewLayout();
+
+ node.lastLayout.copy(node.layout);
+ } else {
+ node.layout.copy(node.lastLayout);
+ }
+ }
+
+ private static void layoutNodeImpl(CSSNode node, float parentMaxWidth) {
+
+ /** START_GENERATED **/
+
+ CSSFlexDirection mainAxis = getFlexDirection(node);
+ CSSFlexDirection crossAxis = mainAxis == CSSFlexDirection.ROW ?
+ CSSFlexDirection.COLUMN :
+ CSSFlexDirection.ROW;
+
+ // Handle width and height style attributes
+ setDimensionFromStyle(node, mainAxis);
+ setDimensionFromStyle(node, crossAxis);
+
+ // The position is set by the parent, but we need to complete it with a
+ // delta composed of the margin and left/top/right/bottom
+ setLayoutPosition(node, getLeading(mainAxis), getLayoutPosition(node, getLeading(mainAxis)) + getMargin(node, getLeading(mainAxis)) +
+ getRelativePosition(node, mainAxis));
+ setLayoutPosition(node, getLeading(crossAxis), getLayoutPosition(node, getLeading(crossAxis)) + getMargin(node, getLeading(crossAxis)) +
+ getRelativePosition(node, crossAxis));
+
+ if (isMeasureDefined(node)) {
+ float width = CSSConstants.UNDEFINED;
+ if (isDimDefined(node, CSSFlexDirection.ROW)) {
+ width = node.style.width;
+ } else if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.ROW)))) {
+ width = getLayoutDimension(node, getDim(CSSFlexDirection.ROW));
+ } else {
+ width = parentMaxWidth -
+ getMarginAxis(node, CSSFlexDirection.ROW);
+ }
+ width -= getPaddingAndBorderAxis(node, CSSFlexDirection.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.
+ boolean isRowUndefined = !isDimDefined(node, CSSFlexDirection.ROW) &&
+ FloatUtil.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.ROW)));
+ boolean isColumnUndefined = !isDimDefined(node, CSSFlexDirection.COLUMN) &&
+ FloatUtil.isUndefined(getLayoutDimension(node, getDim(CSSFlexDirection.COLUMN)));
+
+ // Let's not measure the text if we already know both dimensions
+ if (isRowUndefined || isColumnUndefined) {
+ MeasureOutput measure_dim = node.measure(
+ width
+ );
+ if (isRowUndefined) {
+ node.layout.width = measure_dim.width +
+ getPaddingAndBorderAxis(node, CSSFlexDirection.ROW);
+ }
+ if (isColumnUndefined) {
+ node.layout.height = measure_dim.height +
+ getPaddingAndBorderAxis(node, CSSFlexDirection.COLUMN);
+ }
+ }
+ return;
+ }
+
+ // Pre-fill some dimensions straight from the parent
+ for (int i = 0; i < node.getChildCount(); ++i) {
+ CSSNode 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 &&
+ getPositionType(child) == CSSPositionType.RELATIVE &&
+ !FloatUtil.isUndefined(getLayoutDimension(node, getDim(crossAxis))) &&
+ !isDimDefined(child, crossAxis) &&
+ !isPosDefined(child, getLeading(crossAxis))) {
+ setLayoutDimension(child, getDim(crossAxis), Math.max(
+ getLayoutDimension(node, getDim(crossAxis)) -
+ getPaddingAndBorderAxis(node, crossAxis) -
+ getMarginAxis(child, crossAxis),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, crossAxis)
+ ));
+ } 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;
+ if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(axis))) &&
+ !isDimDefined(child, axis) &&
+ isPosDefined(child, getLeading(axis)) &&
+ isPosDefined(child, getTrailing(axis))) {
+ setLayoutDimension(child, getDim(axis), Math.max(
+ getLayoutDimension(node, getDim(axis)) -
+ getPaddingAndBorderAxis(node, axis) -
+ getMarginAxis(child, axis) -
+ getPosition(child, getLeading(axis)) -
+ getPosition(child, getTrailing(axis)),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, axis)
+ ));
+ }
+ }
+ }
+ }
+
+ // Layout non flexible children and count children by type
+
+ // mainContentDim is accumulation of the dimensions and margin of all the
+ // non flexible children. This will be used in order to either set the
+ // dimensions of the node if none already exist, or to compute the
+ // remaining space left for the flexible children.
+ float mainContentDim = 0;
+
+ // There are three kind of children, non flexible, flexible and absolute.
+ // We need to know how many there are in order to distribute the space.
+ int flexibleChildrenCount = 0;
+ float totalFlexible = 0;
+ int nonFlexibleChildrenCount = 0;
+ for (int i = 0; i < node.getChildCount(); ++i) {
+ CSSNode child = node.getChildAt(i);
+
+ // It only makes sense to consider a child flexible if we have a computed
+ // dimension for the node.
+ if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(mainAxis))) && isFlex(child)) {
+ flexibleChildrenCount++;
+ totalFlexible = totalFlexible + getFlex(child);
+
+ // Even if we don't know its exact size yet, we already know the padding,
+ // border and margin. We'll use this partial information to compute the
+ // remaining space.
+ mainContentDim = mainContentDim + getPaddingAndBorderAxis(child, mainAxis) +
+ 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 = parentMaxWidth -
+ getMarginAxis(node, CSSFlexDirection.ROW) -
+ getPaddingAndBorderAxis(node, CSSFlexDirection.ROW);
+ }
+
+ // This is the main recursive call. We layout non flexible children.
+ layoutNode(child, maxWidth);
+
+ // Absolute positioned elements do not take part of the layout, so we
+ // don't use them to compute mainContentDim
+ if (getPositionType(child) == CSSPositionType.RELATIVE) {
+ nonFlexibleChildrenCount++;
+ // At this point we know the final size and margin of the element.
+ mainContentDim = mainContentDim + getDimWithMargin(child, mainAxis);
+ }
+ }
+ }
+
+
+ // Layout flexible children and allocate empty space
+
+ // In order to position the elements in the main axis, we have two
+ // controls. The space between the beginning and the first element
+ // and the space between each two elements.
+ float leadingMainDim = 0;
+ float betweenMainDim = 0;
+
+ // If the dimensions of the current node is defined by its children, they
+ // are all going to be packed together and we don't need to compute
+ // anything.
+ if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) {
+ // The remaining available space that needs to be allocated
+ float remainingMainDim = getLayoutDimension(node, getDim(mainAxis)) -
+ getPaddingAndBorderAxis(node, mainAxis) -
+ mainContentDim;
+
+ // If there are flexible children in the mix, they are going to fill the
+ // remaining space
+ if (flexibleChildrenCount != 0) {
+ float flexibleMainDim = remainingMainDim / totalFlexible;
+
+ // The non flexible children can overflow the container, in this case
+ // we should just assume that there is no space available.
+ if (flexibleMainDim < 0) {
+ flexibleMainDim = 0;
+ }
+ // 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 = 0; i < node.getChildCount(); ++i) {
+ CSSNode 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 = getLayoutDimension(node, getDim(CSSFlexDirection.ROW)) -
+ getPaddingAndBorderAxis(node, CSSFlexDirection.ROW);
+ } else {
+ maxWidth = parentMaxWidth -
+ getMarginAxis(node, CSSFlexDirection.ROW) -
+ getPaddingAndBorderAxis(node, CSSFlexDirection.ROW);
+ }
+
+ // And we recursively call the layout algorithm for this child
+ layoutNode(child, maxWidth);
+ }
+ }
+
+ // We use justifyContent to figure out how to allocate the remaining
+ // space available
+ } else {
+ CSSJustify justifyContent = getJustifyContent(node);
+ if (justifyContent == CSSJustify.FLEX_START) {
+ // Do nothing
+ } else if (justifyContent == CSSJustify.CENTER) {
+ leadingMainDim = remainingMainDim / 2;
+ } else if (justifyContent == CSSJustify.FLEX_END) {
+ leadingMainDim = remainingMainDim;
+ } else if (justifyContent == CSSJustify.SPACE_BETWEEN) {
+ remainingMainDim = Math.max(remainingMainDim, 0);
+ betweenMainDim = remainingMainDim /
+ (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
+ } else if (justifyContent == CSSJustify.SPACE_AROUND) {
+ // Space on the edges is half of the space between elements
+ betweenMainDim = remainingMainDim /
+ (flexibleChildrenCount + nonFlexibleChildrenCount);
+ leadingMainDim = betweenMainDim / 2;
+ }
+ }
+ }
+
+ // Position elements in the main axis and compute dimensions
+
+ // At this point, all the children have their dimensions set. We need to
+ // find their position. In order to do that, we accumulate data in
+ // variables that are also useful to compute the total dimensions of the
+ // container!
+ float crossDim = 0;
+ float mainDim = leadingMainDim +
+ getPaddingAndBorder(node, getLeading(mainAxis));
+ for (int i = 0; i < node.getChildCount(); ++i) {
+ CSSNode child = node.getChildAt(i);
+
+ if (getPositionType(child) == CSSPositionType.ABSOLUTE &&
+ isPosDefined(child, getLeading(mainAxis))) {
+ // In case the child is position absolute and has left/top being
+ // defined, we override the position to whatever the user said
+ // (and margin/border).
+ setLayoutPosition(child, getPos(mainAxis), getPosition(child, getLeading(mainAxis)) +
+ getBorder(node, getLeading(mainAxis)) +
+ getMargin(child, getLeading(mainAxis)));
+ } else {
+ // If the child is position absolute (without top/left) or relative,
+ // we put it at the current accumulated offset.
+ setLayoutPosition(child, getPos(mainAxis), getLayoutPosition(child, getPos(mainAxis)) + mainDim);
+ }
+
+ // Now that we placed the element, we need to update the variables
+ // We only need to do that for relative elements. Absolute elements
+ // do not take part in that phase.
+ if (getPositionType(child) == CSSPositionType.RELATIVE) {
+ // The main dimension is the sum of all the elements dimension plus
+ // the spacing.
+ mainDim = mainDim + betweenMainDim + getDimWithMargin(child, mainAxis);
+ // The cross dimension is the max of the elements dimension since there
+ // can only be one element in that cross dimension.
+ crossDim = Math.max(crossDim, getDimWithMargin(child, crossAxis));
+ }
+ }
+
+ // 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 (FloatUtil.isUndefined(getLayoutDimension(node, getDim(mainAxis)))) {
+ setLayoutDimension(node, getDim(mainAxis), Math.max(
+ // We're missing the last padding at this point to get the final
+ // dimension
+ mainDim + getPaddingAndBorder(node, getTrailing(mainAxis)),
+ // We can never assign a width smaller than the padding and borders
+ getPaddingAndBorderAxis(node, mainAxis)
+ ));
+ }
+
+ if (FloatUtil.isUndefined(getLayoutDimension(node, getDim(crossAxis)))) {
+ setLayoutDimension(node, getDim(crossAxis), Math.max(
+ // For the cross dim, we add both sides at the end because the value
+ // is aggregate via a max function. Intermediate negative values
+ // can mess this computation otherwise
+ crossDim + getPaddingAndBorderAxis(node, crossAxis),
+ getPaddingAndBorderAxis(node, crossAxis)
+ ));
+ }
+
+
+ // Position elements in the cross axis
+
+ for (int i = 0; i < node.getChildCount(); ++i) {
+ CSSNode child = node.getChildAt(i);
+
+ if (getPositionType(child) == CSSPositionType.ABSOLUTE &&
+ isPosDefined(child, getLeading(crossAxis))) {
+ // In case the child is absolutely positionned and has a
+ // top/left/bottom/right being set, we override all the previously
+ // computed positions to set it correctly.
+ setLayoutPosition(child, getPos(crossAxis), getPosition(child, getLeading(crossAxis)) +
+ getBorder(node, getLeading(crossAxis)) +
+ getMargin(child, getLeading(crossAxis)));
+
+ } else {
+ float leadingCrossDim = getPaddingAndBorder(node, getLeading(crossAxis));
+
+ // For a relative children, we're either using alignItems (parent) or
+ // 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) {
+ // You can only stretch if the dimension has not already been set
+ // previously.
+ if (!isDimDefined(child, crossAxis)) {
+ setLayoutDimension(child, getDim(crossAxis), Math.max(
+ getLayoutDimension(node, getDim(crossAxis)) -
+ getPaddingAndBorderAxis(node, crossAxis) -
+ getMarginAxis(child, crossAxis),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, crossAxis)
+ ));
+ }
+ } else {
+ // The remaining space between the parent dimensions+padding and child
+ // dimensions+margin.
+ float remainingCrossDim = getLayoutDimension(node, getDim(crossAxis)) -
+ getPaddingAndBorderAxis(node, crossAxis) -
+ getDimWithMargin(child, crossAxis);
+
+ if (alignItem == CSSAlign.CENTER) {
+ leadingCrossDim = leadingCrossDim + remainingCrossDim / 2;
+ } else { // CSSAlign.FLEX_END
+ leadingCrossDim = leadingCrossDim + remainingCrossDim;
+ }
+ }
+ }
+
+ // And we apply the position
+ setLayoutPosition(child, getPos(crossAxis), getLayoutPosition(child, getPos(crossAxis)) + leadingCrossDim);
+ }
+ }
+
+ // Calculate dimensions for absolutely positioned elements
+
+ for (int i = 0; i < node.getChildCount(); ++i) {
+ CSSNode 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;
+ if (!FloatUtil.isUndefined(getLayoutDimension(node, getDim(axis))) &&
+ !isDimDefined(child, axis) &&
+ isPosDefined(child, getLeading(axis)) &&
+ isPosDefined(child, getTrailing(axis))) {
+ setLayoutDimension(child, getDim(axis), Math.max(
+ getLayoutDimension(node, getDim(axis)) -
+ getPaddingAndBorderAxis(node, axis) -
+ getMarginAxis(child, axis) -
+ getPosition(child, getLeading(axis)) -
+ getPosition(child, getTrailing(axis)),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, axis)
+ ));
+ }
+ }
+ for (int ii = 0; ii < 2; ii++) {
+ CSSFlexDirection axis = (ii != 0) ? CSSFlexDirection.ROW : CSSFlexDirection.COLUMN;
+ if (isPosDefined(child, getTrailing(axis)) &&
+ !isPosDefined(child, getLeading(axis))) {
+ setLayoutPosition(child, getLeading(axis), getLayoutDimension(node, getDim(axis)) -
+ getLayoutDimension(child, getDim(axis)) -
+ getPosition(child, getTrailing(axis)));
+ }
+ }
+ }
+ }
+ }
+ /** END_GENERATED **/
+}
diff --git a/src/java/src/com/facebook/csslayout/MeasureOutput.java b/src/java/src/com/facebook/csslayout/MeasureOutput.java
new file mode 100644
index 00000000..52231dcc
--- /dev/null
+++ b/src/java/src/com/facebook/csslayout/MeasureOutput.java
@@ -0,0 +1,10 @@
+package com.facebook.csslayout;
+
+/**
+ * POJO to hold the output of the measure function.
+ */
+public class MeasureOutput {
+
+ public float width;
+ public float height;
+}
diff --git a/src/java/tests/com/facebook/csslayout/CSSNodeTest.java b/src/java/tests/com/facebook/csslayout/CSSNodeTest.java
new file mode 100644
index 00000000..049a78e5
--- /dev/null
+++ b/src/java/tests/com/facebook/csslayout/CSSNodeTest.java
@@ -0,0 +1,42 @@
+package com.facebook.csslayout;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Tests for {@link CSSNode}.
+ */
+public class CSSNodeTest {
+
+ @Test
+ public void testAddChildGetParent() {
+ CSSNode parent = new CSSNode();
+ CSSNode child = new CSSNode();
+
+ assertNull(child.getParent());
+ assertEquals(0, parent.getChildCount());
+
+ parent.addChildAt(child, 0);
+
+ assertEquals(1, parent.getChildCount());
+ assertEquals(child, parent.getChildAt(0));
+ assertEquals(parent, child.getParent());
+
+ parent.removeChildAt(0);
+
+ assertNull(child.getParent());
+ assertEquals(0, parent.getChildCount());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testCannotAddChildToMultipleParents() {
+ CSSNode parent1 = new CSSNode();
+ CSSNode parent2 = new CSSNode();
+ CSSNode child = new CSSNode();
+
+ parent1.addChildAt(child, 0);
+ parent2.addChildAt(child, 0);
+ }
+}
diff --git a/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java
new file mode 100644
index 00000000..2ba3be9d
--- /dev/null
+++ b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java
@@ -0,0 +1,180 @@
+package com.facebook.csslayout;
+
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+
+/**
+ * Tests for {@link LayoutEngine} and {@link CSSNode} to make sure layouts are only generated when
+ * needed.
+ */
+public class LayoutCachingTest {
+
+ private void assertTreeHasNewLayout(boolean expectedHasNewLayout, CSSNode root) {
+ assertEquals(expectedHasNewLayout, root.hasNewLayout());
+
+ for (int i = 0; i < root.getChildCount(); i++) {
+ assertTreeHasNewLayout(expectedHasNewLayout, root.getChildAt(i));
+ }
+ }
+
+ private void markLayoutAppliedForTree(CSSNode root) {
+ root.markLayoutApplied();
+ for (int i = 0; i < root.getChildCount(); i++) {
+ markLayoutAppliedForTree(root.getChildAt(i));
+ }
+ }
+
+ @Test
+ public void testCachesFullTree() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+ }
+
+ @Test
+ public void testInvalidatesCacheWhenChildAdded() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ CSSNode c0c1 = new CSSNode();
+ c0c1.setStyleWidth(200);
+ c0c1.setStyleHeight(200);
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+
+ c0.addChildAt(c0c1, 1);
+
+ root.calculateLayout();
+ assertTrue(root.hasNewLayout());
+ assertTrue(c0.hasNewLayout());
+ assertTrue(c0c1.hasNewLayout());
+
+ assertFalse(c0c0.hasNewLayout());
+ assertFalse(c1.hasNewLayout());
+ }
+
+ @Test
+ public void testInvalidatesCacheWhenEnumPropertyChanges() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+
+ c1.setAlignSelf(CSSAlign.CENTER);
+ root.calculateLayout();
+
+ assertTrue(root.hasNewLayout());
+ assertTrue(c1.hasNewLayout());
+
+ assertFalse(c0.hasNewLayout());
+ assertFalse(c0c0.hasNewLayout());
+ }
+
+ @Test
+ public void testInvalidatesCacheWhenFloatPropertyChanges() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+
+ c1.setMarginLeft(10);
+ root.calculateLayout();
+
+ assertTrue(root.hasNewLayout());
+ assertTrue(c1.hasNewLayout());
+
+ assertFalse(c0.hasNewLayout());
+ assertFalse(c0c0.hasNewLayout());
+ }
+
+ @Test
+ public void testInvalidatesFullTreeWhenParentWidthChanges() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+
+ c0.setStyleWidth(200);
+ root.calculateLayout();
+
+ assertTrue(root.hasNewLayout());
+ assertTrue(c0.hasNewLayout());
+ assertTrue(c0c0.hasNewLayout());
+
+ assertFalse(c1.hasNewLayout());
+ }
+
+ @Test
+ public void testDoesNotInvalidateCacheWhenPropertyIsTheSame() {
+ CSSNode root = new CSSNode();
+ CSSNode c0 = new CSSNode();
+ CSSNode c1 = new CSSNode();
+ CSSNode c0c0 = new CSSNode();
+ root.addChildAt(c0, 0);
+ root.addChildAt(c1, 1);
+ c0.addChildAt(c0c0, 0);
+ root.setStyleWidth(200);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(true, root);
+ markLayoutAppliedForTree(root);
+
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+
+ root.setStyleWidth(200);
+ root.calculateLayout();
+ assertTreeHasNewLayout(false, root);
+ }
+}
diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java
new file mode 100644
index 00000000..368ed3c1
--- /dev/null
+++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java
@@ -0,0 +1,3722 @@
+package com.facebook.csslayout;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for {@link LayoutEngine}
+ */
+public class LayoutEngineTest {
+
+ private static CSSNode.MeasureFunction sTestMeasureFunction = new CSSNode.MeasureFunction() {
+
+ @Override
+ public void measure(CSSNode node, float width, MeasureOutput measureOutput) {
+ if (FloatUtil.isUndefined(width)) {
+ width = 10000000;
+ }
+
+ TestCSSNode testNode = (TestCSSNode) node;
+ if (testNode.context.equals(TestConstants.SMALL_TEXT)) {
+ measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH);
+ measureOutput.height = TestConstants.SMALL_HEIGHT;
+ } else if (testNode.context.equals(TestConstants.LONG_TEXT)) {
+ measureOutput.width = width >= TestConstants.BIG_WIDTH ?
+ TestConstants.BIG_WIDTH : Math.max(TestConstants.BIG_MIN_WIDTH, width);
+ measureOutput.height = width >= TestConstants.BIG_WIDTH ?
+ TestConstants.SMALL_HEIGHT : TestConstants.BIG_HEIGHT;
+ } else {
+ throw new RuntimeException("Got unknown test: " + testNode.context);
+ }
+ }
+ };
+
+ private static class TestCSSNode extends CSSNode {
+
+ public String context = null;
+
+ public TestCSSNode getChildAt(int i) {
+ return (TestCSSNode) super.getChildAt(i);
+ }
+ }
+
+ private static void test(String message, CSSNode style, CSSNode expectedLayout) {
+ style.calculateLayout();
+ assertLayoutsEqual(message, style, expectedLayout);
+ }
+
+ private static void addChildren(TestCSSNode node, int numChildren) {
+ for (int i = 0; i < numChildren; i++) {
+ node.addChildAt(new TestCSSNode(), i);
+ }
+ }
+
+ private static void assertLayoutsEqual(String message, CSSNode actual, CSSNode expected) {
+ Assert.assertTrue(
+ message + "\nActual:\n" + actual.toString() + "\nExpected:\n" + expected.toString(),
+ areLayoutsEqual(actual, expected));
+ }
+
+ private static boolean areLayoutsEqual(CSSNode a, CSSNode b) {
+ boolean doNodesHaveSameLayout =
+ areFloatsEqual(a.layout.x, b.layout.x) &&
+ areFloatsEqual(a.layout.y, b.layout.y) &&
+ areFloatsEqual(a.layout.width, b.layout.width) &&
+ areFloatsEqual(a.layout.height, b.layout.height);
+ if (!doNodesHaveSameLayout) {
+ return false;
+ }
+ for (int i = 0; i < a.getChildCount(); i++) {
+ if (!areLayoutsEqual(a.getChildAt(i), b.getChildAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean areFloatsEqual(float a, float b) {
+ return Math.abs(a - b) < .00001f;
+ }
+
+ /** START_GENERATED **/
+ @Test
+ public void testCase0()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.height = 200;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 200;
+ }
+
+ test("should layout a single node with width and height", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase1()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 500;
+ node_1.style.height = 500;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 250;
+ node_1.style.height = 250;
+ node_1 = node_0.getChildAt(2);
+ node_1.style.width = 125;
+ node_1.style.height = 125;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 500;
+ node_1.layout.height = 500;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 500;
+ node_1.layout.x = 0;
+ node_1.layout.width = 250;
+ node_1.layout.height = 250;
+ node_1 = node_0.getChildAt(2);
+ node_1.layout.y = 750;
+ node_1.layout.x = 0;
+ node_1.layout.width = 125;
+ node_1.layout.height = 125;
+ }
+ }
+
+ test("should layout node with children", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase2()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 500;
+ node_1.style.height = 500;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 500;
+ node_1.style.height = 500;
+ addChildren(node_1, 2);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.width = 250;
+ node_2.style.height = 250;
+ node_2 = node_1.getChildAt(1);
+ node_2.style.width = 250;
+ node_2.style.height = 250;
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 500;
+ node_1.layout.height = 500;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 500;
+ node_1.layout.x = 0;
+ node_1.layout.width = 500;
+ node_1.layout.height = 500;
+ addChildren(node_1, 2);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 250;
+ node_2.layout.height = 250;
+ node_2 = node_1.getChildAt(1);
+ node_2.layout.y = 250;
+ node_2.layout.x = 0;
+ node_2.layout.width = 250;
+ node_2.layout.height = 250;
+ }
+ }
+ }
+
+ test("should layout node with nested children", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase3()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.height = 200;
+ node_0.style.marginLeft = 10;
+ node_0.style.marginTop = 10;
+ node_0.style.marginRight = 10;
+ node_0.style.marginBottom = 10;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 10;
+ node_0.layout.x = 10;
+ node_0.layout.width = 100;
+ node_0.layout.height = 200;
+ }
+
+ test("should layout node with margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase4()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ node_0.style.marginLeft = 10;
+ node_0.style.marginTop = 10;
+ node_0.style.marginRight = 10;
+ node_0.style.marginBottom = 10;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1.style.marginLeft = 50;
+ node_1.style.marginTop = 50;
+ node_1.style.marginRight = 50;
+ node_1.style.marginBottom = 50;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1.style.marginLeft = 25;
+ node_1.style.marginTop = 25;
+ node_1.style.marginRight = 25;
+ node_1.style.marginBottom = 25;
+ node_1 = node_0.getChildAt(2);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1.style.marginLeft = 10;
+ node_1.style.marginTop = 10;
+ node_1.style.marginRight = 10;
+ node_1.style.marginBottom = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 10;
+ node_0.layout.x = 10;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 50;
+ node_1.layout.x = 50;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 225;
+ node_1.layout.x = 25;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(2);
+ node_1.layout.y = 360;
+ node_1.layout.x = 10;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with several children", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase5()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 300;
+ node_1.style.height = 150;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 100;
+ node_1.layout.width = 300;
+ node_1.layout.height = 150;
+ }
+ }
+
+ test("should layout node with row flex direction", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase6()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 300;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 300;
+ node_1.style.height = 150;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 300;
+ node_0.layout.height = 350;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 200;
+ node_1.layout.x = 0;
+ node_1.layout.width = 300;
+ node_1.layout.height = 150;
+ }
+ }
+
+ test("should layout node based on children main dimensions", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase7()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 1;
+ node_1.style.width = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 200;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 200;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 800;
+ }
+ }
+
+ test("should layout node with flex", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase8()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1.style.width = 1000;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.flex = 1;
+ node_2.style.width = 1000;
+ addChildren(node_2, 1);
+ {
+ TestCSSNode node_3;
+ node_3 = node_2.getChildAt(0);
+ node_3.style.flex = 1;
+ node_3.style.width = 1000;
+ }
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 1000;
+ node_1.layout.height = 1000;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 1000;
+ node_2.layout.height = 1000;
+ addChildren(node_2, 1);
+ {
+ TestCSSNode node_3;
+ node_3 = node_2.getChildAt(0);
+ node_3.layout.y = 0;
+ node_3.layout.x = 0;
+ node_3.layout.width = 1000;
+ node_3.layout.height = 1000;
+ }
+ }
+ }
+ }
+
+ test("should layout node with flex recursively", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase9()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ node_0.style.marginLeft = 5;
+ node_0.style.marginTop = 10;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1.style.marginLeft = 15;
+ node_1.style.marginTop = 50;
+ node_1.style.marginBottom = 20;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1.style.marginLeft = 30;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 10;
+ node_0.layout.x = 5;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 50;
+ node_1.layout.x = 15;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 170;
+ node_1.layout.x = 30;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with targeted margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase10()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.FLEX_START;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with justifyContent: flex-start", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase11()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.FLEX_END;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 800;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 900;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with justifyContent: flex-end", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase12()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.SPACE_BETWEEN;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 900;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with justifyContent: space-between", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase13()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.SPACE_AROUND;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 200;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 700;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with justifyContent: space-around", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase14()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.CENTER;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 400;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 500;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with justifyContent: center", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase15()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 1000;
+ }
+ }
+
+ test("should layout node with flex override height", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase16()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.FLEX_START;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 200;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with alignItems: flex-start", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase17()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.CENTER;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 200;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 400;
+ node_1.layout.width = 200;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 450;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with alignItems: center", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase18()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.FLEX_END;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 200;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 800;
+ node_1.layout.width = 200;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 900;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with alignItems: flex-end", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase19()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.FLEX_END;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 200;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.alignSelf = CSSAlign.CENTER;
+ node_1.style.width = 100;
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 800;
+ node_1.layout.width = 200;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 450;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with alignSelf overrides alignItems", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase20()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.STRETCH;
+ node_0.style.width = 1000;
+ node_0.style.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.height = 100;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1000;
+ node_0.layout.height = 1000;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 1000;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout node with alignItem: stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase21()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout empty node", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase22()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginLeft = 5;
+ node_1.style.marginTop = 5;
+ node_1.style.marginRight = 5;
+ node_1.style.marginBottom = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 10;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 5;
+ node_1.layout.x = 5;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout child with margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase23()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.height = 200;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 200;
+ }
+ }
+
+ test("should not shrink children if not enough space", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase24()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.CENTER;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ }
+
+ test("should layout for center", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase25()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.FLEX_END;
+ node_0.style.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginTop = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout flex-end taking into account margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase26()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignItems = CSSAlign.FLEX_END;
+ addChildren(node_1, 2);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.marginLeft = 10;
+ node_2.style.marginTop = 10;
+ node_2.style.marginRight = 10;
+ node_2.style.marginBottom = 10;
+ node_2 = node_1.getChildAt(1);
+ node_2.style.height = 100;
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 20;
+ node_0.layout.height = 120;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 20;
+ node_1.layout.height = 120;
+ addChildren(node_1, 2);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 10;
+ node_2.layout.x = 10;
+ node_2.layout.width = 0;
+ node_2.layout.height = 0;
+ node_2 = node_1.getChildAt(1);
+ node_2.layout.y = 20;
+ node_2.layout.x = 20;
+ node_2.layout.width = 0;
+ node_2.layout.height = 100;
+ }
+ }
+ }
+
+ test("should layout alignItems with margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase27()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout flex inside of an empty element", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase28()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.alignItems = CSSAlign.STRETCH;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginLeft = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 10;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout alignItems stretch and margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase29()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 5;
+ node_0.style.paddingTop = 5;
+ node_0.style.paddingRight = 5;
+ node_0.style.paddingBottom = 5;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 10;
+ }
+
+ test("should layout node with padding", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase30()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 5;
+ node_0.style.paddingTop = 5;
+ node_0.style.paddingRight = 5;
+ node_0.style.paddingBottom = 5;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 10;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 5;
+ node_1.layout.x = 5;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with padding and a child", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase31()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 5;
+ node_0.style.paddingTop = 5;
+ node_0.style.paddingRight = 5;
+ node_0.style.paddingBottom = 5;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginLeft = 5;
+ node_1.style.marginTop = 5;
+ node_1.style.marginRight = 5;
+ node_1.style.marginBottom = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 20;
+ node_0.layout.height = 20;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 10;
+ node_1.layout.x = 10;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with padding and a child with margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase32()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ node_1.style.paddingLeft = 10;
+ node_1.style.paddingTop = 10;
+ node_1.style.paddingRight = 10;
+ node_1.style.paddingBottom = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 20;
+ node_0.layout.height = 20;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 20;
+ node_1.layout.height = 20;
+ }
+ }
+
+ test("should layout node with padding and stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase33()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 50;
+ node_0.style.paddingTop = 50;
+ node_0.style.paddingRight = 50;
+ node_0.style.paddingBottom = 50;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ node_1.style.paddingLeft = 10;
+ node_1.style.paddingTop = 10;
+ node_1.style.paddingRight = 10;
+ node_1.style.paddingBottom = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 120;
+ node_0.layout.height = 120;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 50;
+ node_1.layout.x = 50;
+ node_1.layout.width = 20;
+ node_1.layout.height = 20;
+ }
+ }
+
+ test("should layout node with inner & outer padding and stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase34()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.marginLeft = 16;
+ node_2.style.marginTop = 16;
+ node_2.style.marginRight = 16;
+ node_2.style.marginBottom = 16;
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 32;
+ node_0.layout.height = 32;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 32;
+ node_1.layout.height = 32;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 16;
+ node_2.layout.x = 16;
+ node_2.layout.width = 0;
+ node_2.layout.height = 0;
+ }
+ }
+ }
+
+ test("should layout node with stretch and child with margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase35()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.positionLeft = 5;
+ node_0.style.positionTop = 5;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 5;
+ node_0.layout.x = 5;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ }
+
+ test("should layout node with top and left", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase36()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.SPACE_AROUND;
+ node_0.style.height = 10;
+ node_0.style.paddingTop = 5;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 10;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 7.5f;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with height, padding and space-around", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase37()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.positionBottom = 5;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = -5;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ }
+
+ test("should layout node with bottom", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase38()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.positionTop = 10;
+ node_0.style.positionBottom = 5;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 10;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ }
+
+ test("should layout node with both top and bottom", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase39()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 500;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.width = 50;
+ node_1 = node_0.getChildAt(2);
+ node_1.style.flex = 1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 500;
+ node_0.layout.height = 0;
+ addChildren(node_0, 3);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 250;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 250;
+ node_1.layout.width = 50;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(2);
+ node_1.layout.y = 0;
+ node_1.layout.x = 250;
+ node_1.layout.width = 250;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with position: absolute", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase40()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.marginRight = 15;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with child with position: absolute and margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase41()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.CENTER;
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.paddingRight = 12;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 12;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with position: absolute, padding and alignSelf: center", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase42()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 5;
+ node_0.style.paddingBottom = 20;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 20;
+ }
+
+ test("should work with height smaller than paddingBottom", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase43()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 5;
+ node_0.style.paddingLeft = 20;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 20;
+ node_0.layout.height = 0;
+ }
+
+ test("should work with width smaller than paddingLeft", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase44()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.width = 400;
+ }
+ node_1 = node_0.getChildAt(1);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ node_1.style.width = 200;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 400;
+ node_0.layout.height = 0;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 400;
+ node_1.layout.height = 0;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 400;
+ node_2.layout.height = 0;
+ }
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with specified width and stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase45()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 5;
+ node_0.style.paddingTop = 5;
+ node_0.style.paddingRight = 5;
+ node_0.style.paddingBottom = 5;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 10;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 5;
+ node_1.layout.x = 5;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with padding and child with position absolute", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase46()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 10;
+ node_1.style.positionTop = 10;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 10;
+ node_1.layout.x = 10;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with position absolute, top and left", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase47()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.paddingLeft = 20;
+ node_0.style.paddingTop = 20;
+ node_0.style.paddingRight = 20;
+ node_0.style.paddingBottom = 20;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 40;
+ node_0.layout.height = 40;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 20;
+ node_1.layout.x = 5;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with padding and child position absolute, left", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase48()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.marginTop = 5;
+ node_1.style.positionTop = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 10;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with position: absolute, top and marginTop", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase49()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.marginLeft = 5;
+ node_1.style.positionLeft = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 10;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with position: absolute, left and marginLeft", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase50()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.SPACE_AROUND;
+ node_0.style.height = 200;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1 = node_0.getChildAt(1);
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 200;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with space-around and child position absolute", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase51()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 700;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1.style.marginLeft = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 700;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 5;
+ node_1.layout.width = 695;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with flex and main margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase52()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 700;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 1;
+ node_1.style.paddingRight = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 700;
+ node_0.layout.height = 0;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 347.5f;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 347.5f;
+ node_1.layout.width = 352.5f;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with multiple flex and padding", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase53()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 700;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 1;
+ node_1.style.marginLeft = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 700;
+ node_0.layout.height = 0;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 347.5f;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 352.5f;
+ node_1.layout.width = 347.5f;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with multiple flex and margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase54()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 300;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.height = 600;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 300;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 600;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 600;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with flex and overflow", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase55()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.width = 600;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.flex = 1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 600;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with flex and position absolute", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase56()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 500;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 1;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.flex = 1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 500;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 500;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 500;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with double flex and position absolute", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase57()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.borderLeft = 5;
+ node_0.style.borderTop = 5;
+ node_0.style.borderRight = 5;
+ node_0.style.borderBottom = 5;
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 10;
+ }
+
+ test("should layout node with borderWidth", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase58()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.borderTop = 1;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionTop = -1;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 1;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with borderWidth and position: absolute, top", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase59()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.borderLeft = 1;
+ node_0.style.borderTop = 1;
+ node_0.style.borderRight = 1;
+ node_0.style.borderBottom = 1;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 2;
+ node_0.layout.height = 2;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 1;
+ node_1.layout.x = 6;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with borderWidth and position: absolute, top. cross axis", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase60()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 50;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ node_1.style.marginLeft = 20;
+ node_1.style.paddingLeft = 20;
+ node_1.style.paddingTop = 20;
+ node_1.style.paddingRight = 20;
+ node_1.style.paddingBottom = 20;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 50;
+ node_0.layout.height = 40;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 20;
+ node_1.layout.width = 40;
+ node_1.layout.height = 40;
+ }
+ }
+
+ test("should correctly take into account min padding for stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase61()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.borderRight = 5;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 5;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 5;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout node with negative width", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase62()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.borderRight = 1;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginRight = -8;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 1;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should handle negative margin and min padding correctly", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase63()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.setMeasureFunction(sTestMeasureFunction);
+ node_0.context = "small";
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 34.671875f;
+ node_0.layout.height = 18;
+ }
+
+ test("should layout node with just text", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase64()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 10;
+ node_0.setMeasureFunction(sTestMeasureFunction);
+ node_0.context = "small";
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 10;
+ node_0.layout.height = 18;
+ }
+
+ test("should layout node with text and width", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase65()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.setMeasureFunction(sTestMeasureFunction);
+ node_0.context = "loooooooooong with space";
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 172.421875f;
+ node_0.layout.height = 18;
+ }
+
+ test("should layout node with text, padding and margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase66()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 300;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.alignSelf = CSSAlign.STRETCH;
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 300;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 300;
+ node_1.layout.height = 0;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 300;
+ node_2.layout.height = 0;
+ }
+ }
+ }
+
+ test("should layout node with nested alignSelf: stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase67()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flexDirection = CSSFlexDirection.ROW;
+ node_1.style.width = 500;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.flex = 1;
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 500;
+ node_0.layout.height = 18;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 500;
+ node_1.layout.height = 18;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 500;
+ node_2.layout.height = 18;
+ }
+ }
+ }
+
+ test("should layout node with text and flex", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase68()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 130;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignItems = CSSAlign.STRETCH;
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 130;
+ node_0.layout.height = 36;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 130;
+ node_1.layout.height = 36;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 130;
+ node_2.layout.height = 36;
+ }
+ }
+ }
+
+ test("should layout node with text and stretch", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase69()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 200;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.alignItems = CSSAlign.STRETCH;
+ node_1.style.alignSelf = CSSAlign.STRETCH;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.width = 130;
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 200;
+ node_0.layout.height = 36;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 36;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 130;
+ node_2.layout.height = 36;
+ }
+ }
+ }
+
+ test("should layout node with text stretch and width", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase70()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.setMeasureFunction(sTestMeasureFunction);
+ node_1.context = "loooooooooong with space";
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 36;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100.453125f;
+ node_1.layout.height = 36;
+ }
+ }
+
+ test("should layout node with text bounded by parent", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase71()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.paddingLeft = 10;
+ node_0.style.paddingTop = 10;
+ node_0.style.paddingRight = 10;
+ node_0.style.paddingBottom = 10;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.marginLeft = 10;
+ node_1.style.marginTop = 10;
+ node_1.style.marginRight = 10;
+ node_1.style.marginBottom = 10;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 76;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 20;
+ node_1.layout.x = 20;
+ node_1.layout.width = 100.453125f;
+ node_1.layout.height = 36;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 0;
+ node_2.layout.x = 0;
+ node_2.layout.width = 100.453125f;
+ node_2.layout.height = 36;
+ }
+ }
+ }
+
+ test("should layout node with text bounded by grand-parent", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase72()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.justifyContent = CSSJustify.SPACE_BETWEEN;
+ node_0.style.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.height = 900;
+ node_1 = node_0.getChildAt(1);
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 900;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 900;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout space-between when remaining space is negative", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase73()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.flexDirection = CSSFlexDirection.ROW;
+ node_0.style.justifyContent = CSSJustify.FLEX_END;
+ node_0.style.width = 200;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 900;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 200;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = -700;
+ node_1.layout.width = 900;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout flex-end when remaining space is negative", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase74()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flexDirection = CSSFlexDirection.ROW;
+ node_1.style.width = 200;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.marginLeft = 20;
+ node_2.style.marginTop = 20;
+ node_2.style.marginRight = 20;
+ node_2.style.marginBottom = 20;
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 200;
+ node_0.layout.height = 58;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 58;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 20;
+ node_2.layout.x = 20;
+ node_2.layout.width = 172.421875f;
+ node_2.layout.height = 18;
+ }
+ }
+ }
+
+ test("should layout text with flexDirection row", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase75()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 200;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.marginLeft = 20;
+ node_2.style.marginTop = 20;
+ node_2.style.marginRight = 20;
+ node_2.style.marginBottom = 20;
+ node_2.setMeasureFunction(sTestMeasureFunction);
+ node_2.context = "loooooooooong with space";
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 200;
+ node_0.layout.height = 76;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 76;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 20;
+ node_2.layout.x = 20;
+ node_2.layout.width = 160;
+ node_2.layout.height = 36;
+ }
+ }
+ }
+
+ test("should layout with text and margin", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase76()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 0;
+ node_1.style.positionTop = 0;
+ node_1.style.positionRight = 0;
+ node_1.style.positionBottom = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 100;
+ node_1.layout.height = 100;
+ }
+ }
+
+ test("should layout with position absolute, top, left, bottom, right", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase77()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.flex = 2.5f;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 7.5f;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 25;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 25;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 75;
+ }
+ }
+
+ test("should layout with arbitrary flex", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase78()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ node_0.style.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1 = node_0.getChildAt(1);
+ node_1.style.flex = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout with negative flex", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase79()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.width = 50;
+ node_1.style.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 0;
+ node_1.style.positionRight = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 50;
+ node_0.layout.height = 100;
+ addChildren(node_0, 2);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 50;
+ node_1.layout.height = 100;
+ node_1 = node_0.getChildAt(1);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 50;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should layout with position: absolute and another sibling", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase80()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionTop = 0;
+ node_1.style.positionBottom = 20;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 80;
+ }
+ }
+
+ test("should calculate height properly with position: absolute top and bottom", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase81()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 200;
+ node_0.style.height = 200;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.justifyContent = CSSJustify.CENTER;
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionLeft = 0;
+ node_1.style.positionTop = 0;
+ node_1.style.positionRight = 0;
+ node_1.style.positionBottom = 0;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.style.width = 100;
+ node_2.style.height = 100;
+ }
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 200;
+ node_0.layout.height = 200;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 0;
+ node_1.layout.width = 200;
+ node_1.layout.height = 200;
+ addChildren(node_1, 1);
+ {
+ TestCSSNode node_2;
+ node_2 = node_1.getChildAt(0);
+ node_2.layout.y = 50;
+ node_2.layout.x = 0;
+ node_2.layout.width = 100;
+ node_2.layout.height = 100;
+ }
+ }
+ }
+
+ test("should layout with complicated position: absolute and justifyContent: center combo", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase82()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionBottom = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 100;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should calculate top properly with position: absolute bottom", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase83()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.positionRight = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 100;
+ node_1.layout.width = 0;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should calcluate left properly with position: absolute right", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase84()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.height = 10;
+ node_1.style.positionBottom = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 90;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 10;
+ }
+ }
+
+ test("should calculate top properly with position: absolute bottom and height", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase85()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ node_0.style.width = 100;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.width = 10;
+ node_1.style.positionRight = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 100;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = 90;
+ node_1.layout.width = 10;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should calcluate left properly with position: absolute right and width", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase86()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.height = 10;
+ node_1.style.positionBottom = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = -10;
+ node_1.layout.x = 0;
+ node_1.layout.width = 0;
+ node_1.layout.height = 10;
+ }
+ }
+
+ test("should calcluate top properly with position: absolute right, width, and no parent dimensions", root_node, root_layout);
+ }
+
+ @Test
+ public void testCase87()
+ {
+ TestCSSNode root_node = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_node;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.style.positionType = CSSPositionType.ABSOLUTE;
+ node_1.style.width = 10;
+ node_1.style.positionRight = 0;
+ }
+ }
+
+ TestCSSNode root_layout = new TestCSSNode();
+ {
+ TestCSSNode node_0 = root_layout;
+ node_0.layout.y = 0;
+ node_0.layout.x = 0;
+ node_0.layout.width = 0;
+ node_0.layout.height = 0;
+ addChildren(node_0, 1);
+ {
+ TestCSSNode node_1;
+ node_1 = node_0.getChildAt(0);
+ node_1.layout.y = 0;
+ node_1.layout.x = -10;
+ node_1.layout.width = 10;
+ node_1.layout.height = 0;
+ }
+ }
+
+ test("should calcluate left properly with position: absolute right, width, and no parent dimensions", root_node, root_layout);
+ }
+ /** END_GENERATED **/
+}
diff --git a/src/java/tests/com/facebook/csslayout/TestConstants.java b/src/java/tests/com/facebook/csslayout/TestConstants.java
new file mode 100644
index 00000000..2add7935
--- /dev/null
+++ b/src/java/tests/com/facebook/csslayout/TestConstants.java
@@ -0,0 +1,17 @@
+package com.facebook.csslayout;
+
+/**
+ * Generated constants used in {@link LayoutEngineTest}.
+ */
+public class TestConstants {
+
+ /** START_GENERATED **/
+ public static final float SMALL_WIDTH = 34.671875f;
+ public static final float SMALL_HEIGHT = 18f;
+ public static final float BIG_WIDTH = 172.421875f;
+ public static final float BIG_HEIGHT = 36f;
+ public static final float BIG_MIN_WIDTH = 100.453125f;
+ public static final String SMALL_TEXT = "small";
+ public static final String LONG_TEXT = "loooooooooong with space";
+ /** END_GENERATED **/
+}
diff --git a/src/transpile.js b/src/transpile.js
index cae5f91f..e09bf7e6 100644
--- a/src/transpile.js
+++ b/src/transpile.js
@@ -1,6 +1,7 @@
var layoutTestUtils = require('./Layout-test-utils.js');
var computeLayout = require('./Layout.js');
var fs = require('fs');
+var JavaTranspiler = require('./JavaTranspiler.js');
var currentTest = '';
var allTests = [];
@@ -223,6 +224,7 @@ function transpileAnnotatedJStoC(jsCode) {
.replace(/var\/\*([^\/]+)\*\//g, '$1')
.replace(/ === /g, ' == ')
.replace(/\n /g, '\n')
+ .replace(/\/\*\(c\)!([^*]+)\*\//g, '$1')
.replace(/\/[*]!([^*]+)[*]\//g, '$1')
.split('\n').slice(1, -1).join('\n');
}
@@ -250,6 +252,10 @@ function generateFile(fileName, generatedContent) {
}
-generateFile(__dirname + '/__tests__/Layout-test.c', allTests.map(printLayout).join('\n\n'));
+var allTestsInC = allTests.map(printLayout);
+generateFile(__dirname + '/__tests__/Layout-test.c', allTestsInC.join('\n\n'));
generateFile(__dirname + '/Layout-test-utils.c', makeConstDefs());
generateFile(__dirname + '/Layout.c', transpileAnnotatedJStoC(computeLayout.toString()));
+generateFile(__dirname + '/java/src/com/facebook/csslayout/LayoutEngine.java', JavaTranspiler.transpileLayoutEngine(computeLayout.toString()));
+generateFile(__dirname + '/java/tests/com/facebook/csslayout/TestConstants.java', JavaTranspiler.transpileCConstDefs(makeConstDefs()));
+generateFile(__dirname + '/java/tests/com/facebook/csslayout/LayoutEngineTest.java', JavaTranspiler.transpileCTestsArray(allTestsInC));